Fix region length calculations when regions end with .align padding.
[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 314
af858dae
JE
315 /* Emit "orh ha%addr_expr,ireg_src2,r31". */
316 pseudo[0].opcode = 0xec000000 | (the_insn.opcode & 0x03e00000)
317 | (atmp << 16);
673a54e3 318 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_HA);
305d537e
JE
319
320 /* Emit "l%addr_expr(r31),ireg_dest". We pick up the fixup
321 information from the original instruction. */
322 pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
673a54e3 323 pseudo[1].fi[0].fup = the_insn.fi[0].fup | OP_SEL_L;
305d537e
JE
324
325 num_opcodes = 2;
252b5132
RH
326 break;
327
305d537e 328 case E_U32:
673a54e3
JE
329 if (the_insn.fi[0].exp.X_add_symbol == NULL
330 && the_insn.fi[0].exp.X_op_symbol == NULL
331 && (the_insn.fi[0].exp.X_add_number < (1 << 16)
332 && the_insn.fi[0].exp.X_add_number >= 0))
252b5132 333 break;
305d537e
JE
334
335 /* Emit "$(opcode)h h%const,ireg_src2,r31". */
336 pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
337 | (atmp << 16);
673a54e3 338 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
305d537e
JE
339
340 /* Emit "$(opcode) l%const,r31,ireg_dest". */
341 pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
342 | (atmp << 21);
673a54e3 343 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
305d537e
JE
344
345 num_opcodes = 2;
252b5132
RH
346 break;
347
305d537e 348 case E_AND:
673a54e3
JE
349 if (the_insn.fi[0].exp.X_add_symbol == NULL
350 && the_insn.fi[0].exp.X_op_symbol == NULL
351 && (the_insn.fi[0].exp.X_add_number < (1 << 16)
352 && the_insn.fi[0].exp.X_add_number >= 0))
252b5132 353 break;
305d537e
JE
354
355 /* Emit "andnot h%const,ireg_src2,r31". */
356 pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
357 | (atmp << 16);
673a54e3
JE
358 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
359 pseudo[0].fi[0].exp.X_add_number =
360 -1 - the_insn.fi[0].exp.X_add_number;
305d537e
JE
361
362 /* Emit "andnot l%const,r31,ireg_dest". */
363 pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
364 | (atmp << 21);
673a54e3
JE
365 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
366 pseudo[1].fi[0].exp.X_add_number =
367 -1 - the_insn.fi[0].exp.X_add_number;
305d537e
JE
368
369 num_opcodes = 2;
252b5132
RH
370 break;
371
372 case E_S32:
673a54e3
JE
373 if (the_insn.fi[0].exp.X_add_symbol == NULL
374 && the_insn.fi[0].exp.X_op_symbol == NULL
375 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
376 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
252b5132 377 break;
305d537e
JE
378
379 /* Emit "orh h%const,r0,r31". */
252b5132 380 pseudo[0].opcode = 0xec000000 | (atmp << 16);
673a54e3 381 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
305d537e
JE
382
383 /* Emit "or l%const,r31,r31". */
252b5132 384 pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
673a54e3 385 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
305d537e
JE
386
387 /* Emit "r31,ireg_src2,ireg_dest". */
252b5132 388 pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
673a54e3 389 pseudo[2].fi[0].fup = OP_IMM_S16;
305d537e
JE
390
391 num_opcodes = 3;
252b5132
RH
392 break;
393
394 default:
395 as_fatal (_("failed sanity check."));
396 }
397
398 the_insn = pseudo[0];
305d537e
JE
399
400 /* Warn if an opcode is expanded after a delayed branch. */
401 if (num_opcodes > 1 && last_expand == 1)
252b5132 402 as_warn (_("Expanded opcode after delayed branch: `%s'"), str);
305d537e
JE
403
404 /* Warn if an opcode is expanded in dual mode. */
405 if (num_opcodes > 1 && dual_mode != DUAL_OFF)
252b5132 406 as_warn (_("Expanded opcode in dual mode: `%s'"), str);
305d537e
JE
407
408 /* Notify if any expansions happen. */
409 if (target_warn_expand && num_opcodes > 1)
410 as_warn (_("An instruction was expanded (%s)"), str);
252b5132
RH
411 }
412
413 i = 0;
414 do
305d537e 415 {
673a54e3
JE
416 int tmp;
417
305d537e
JE
418 /* Output the opcode. Note that the i860 always reads instructions
419 as little-endian data. */
420 destp = frag_more (4);
421 number_to_chars_littleendian (destp, the_insn.opcode, 4);
252b5132 422
305d537e 423 /* Check for expanded opcode after branch or in dual mode. */
673a54e3
JE
424 last_expand = the_insn.fi[0].pcrel;
425
426 /* Output the symbol-dependent stuff. Only btne and bte will ever
427 loop more than once here, since only they (possibly) have more
428 than one fixup. */
429 for (tmp = 0; tmp < fc; tmp++)
430 {
431 if (the_insn.fi[tmp].fup != OP_NONE)
432 {
433 fixS *fix;
434 fix = fix_new_exp (frag_now,
435 destp - frag_now->fr_literal,
436 4,
437 &the_insn.fi[tmp].exp,
438 the_insn.fi[tmp].pcrel,
439 the_insn.fi[tmp].reloc);
440
441 /* Despite the odd name, this is a scratch field. We use
442 it to encode operand type information. */
443 fix->fx_addnumber = the_insn.fi[tmp].fup;
444 }
445 }
252b5132
RH
446 the_insn = pseudo[++i];
447 }
305d537e 448 while (--num_opcodes > 0);
252b5132
RH
449
450}
451
305d537e 452/* Assemble the instruction pointed to by STR. */
252b5132 453static void
7734b6e9 454i860_process_insn (char *str)
252b5132
RH
455{
456 char *s;
457 const char *args;
458 char c;
252b5132 459 struct i860_opcode *insn;
305d537e 460 char *args_start;
252b5132
RH
461 unsigned long opcode;
462 unsigned int mask;
463 int match = 0;
464 int comma = 0;
465
305d537e
JE
466#if 1 /* For compiler warnings. */
467 args = 0;
468 insn = 0;
469 args_start = 0;
470 opcode = 0;
471#endif
252b5132 472
3882b010 473 for (s = str; ISLOWER (*s) || *s == '.' || *s == '3'
305d537e 474 || *s == '2' || *s == '1'; ++s)
252b5132 475 ;
305d537e 476
252b5132
RH
477 switch (*s)
478 {
252b5132
RH
479 case '\0':
480 break;
481
482 case ',':
483 comma = 1;
484
485 /*FALLTHROUGH*/
486
487 case ' ':
488 *s++ = '\0';
489 break;
490
491 default:
492 as_fatal (_("Unknown opcode: `%s'"), str);
493 }
494
305d537e 495 /* Check for dual mode ("d.") opcode prefix. */
252b5132 496 if (strncmp (str, "d.", 2) == 0)
305d537e 497 {
252b5132
RH
498 if (dual_mode == DUAL_ON)
499 dual_mode = DUAL_ONDDOT;
500 else
501 dual_mode = DUAL_DDOT;
502 str += 2;
503 }
504
505 if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL)
506 {
507 if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
508 str -= 2;
509 as_bad (_("Unknown opcode: `%s'"), str);
510 return;
511 }
305d537e 512
252b5132 513 if (comma)
305d537e
JE
514 *--s = ',';
515
516 args_start = s;
252b5132
RH
517 for (;;)
518 {
673a54e3 519 int t;
252b5132
RH
520 opcode = insn->match;
521 memset (&the_insn, '\0', sizeof (the_insn));
b645cb17 522 fc = 0;
673a54e3
JE
523 for (t = 0; t < MAX_FIXUPS; t++)
524 {
525 the_insn.fi[t].reloc = BFD_RELOC_NONE;
526 the_insn.fi[t].pcrel = 0;
527 the_insn.fi[t].fup = OP_NONE;
528 }
252b5132 529
305d537e
JE
530 /* Build the opcode, checking as we go that the operands match. */
531 for (args = insn->args; ; ++args)
252b5132 532 {
673a54e3
JE
533 if (fc > MAX_FIXUPS)
534 abort ();
535
252b5132
RH
536 switch (*args)
537 {
538
305d537e
JE
539 /* End of args. */
540 case '\0':
252b5132 541 if (*s == '\0')
305d537e 542 match = 1;
252b5132
RH
543 break;
544
305d537e 545 /* These must match exactly. */
252b5132 546 case '+':
305d537e 547 case '(':
252b5132
RH
548 case ')':
549 case ',':
550 case ' ':
551 if (*s++ == *args)
552 continue;
553 break;
554
305d537e
JE
555 /* Must be at least one digit. */
556 case '#':
3882b010 557 if (ISDIGIT (*s++))
252b5132 558 {
3882b010 559 while (ISDIGIT (*s))
305d537e 560 ++s;
252b5132
RH
561 continue;
562 }
563 break;
564
305d537e
JE
565 /* Next operand must be a register. */
566 case '1':
252b5132
RH
567 case '2':
568 case 'd':
305d537e
JE
569 /* Check for register prefix if necessary. */
570 if (reg_prefix && *s != reg_prefix)
571 goto error;
87505968 572 else if (reg_prefix)
305d537e
JE
573 s++;
574
252b5132
RH
575 switch (*s)
576 {
305d537e
JE
577 /* Frame pointer. */
578 case 'f':
252b5132
RH
579 s++;
580 if (*s++ == 'p')
581 {
582 mask = 0x3;
583 break;
584 }
585 goto error;
586
305d537e
JE
587 /* Stack pointer. */
588 case 's':
252b5132
RH
589 s++;
590 if (*s++ == 'p')
591 {
592 mask = 0x2;
593 break;
594 }
595 goto error;
596
305d537e
JE
597 /* Any register r0..r31. */
598 case 'r':
252b5132 599 s++;
3882b010 600 if (!ISDIGIT (c = *s++))
252b5132
RH
601 {
602 goto error;
603 }
3882b010 604 if (ISDIGIT (*s))
252b5132
RH
605 {
606 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
305d537e 607 goto error;
252b5132
RH
608 }
609 else
305d537e 610 c -= '0';
252b5132
RH
611 mask = c;
612 break;
613
305d537e
JE
614 /* Not this opcode. */
615 default:
252b5132
RH
616 goto error;
617 }
305d537e
JE
618
619 /* Obtained the register, now place it in the opcode. */
252b5132
RH
620 switch (*args)
621 {
252b5132
RH
622 case '1':
623 opcode |= mask << 11;
624 continue;
625
626 case '2':
627 opcode |= mask << 21;
628 continue;
629
630 case 'd':
631 opcode |= mask << 16;
632 continue;
633
634 }
635 break;
636
305d537e
JE
637 /* Next operand is a floating point register. */
638 case 'e':
252b5132
RH
639 case 'f':
640 case 'g':
305d537e
JE
641 /* Check for register prefix if necessary. */
642 if (reg_prefix && *s != reg_prefix)
643 goto error;
87505968 644 else if (reg_prefix)
305d537e
JE
645 s++;
646
3882b010 647 if (*s++ == 'f' && ISDIGIT (*s))
252b5132
RH
648 {
649 mask = *s++;
3882b010 650 if (ISDIGIT (*s))
252b5132
RH
651 {
652 mask = 10 * (mask - '0') + (*s++ - '0');
653 if (mask >= 32)
654 {
655 break;
656 }
657 }
658 else
305d537e
JE
659 mask -= '0';
660
252b5132
RH
661 switch (*args)
662 {
663
664 case 'e':
665 opcode |= mask << 11;
666 continue;
667
668 case 'f':
669 opcode |= mask << 21;
670 continue;
671
672 case 'g':
673 opcode |= mask << 16;
305d537e
JE
674 if ((opcode & (1 << 10)) && mask != 0
675 && (mask == ((opcode >> 11) & 0x1f)))
676 as_warn (_("Pipelined instruction: fsrc1 = fdest"));
252b5132
RH
677 continue;
678 }
679 }
680 break;
681
305d537e
JE
682 /* Next operand must be a control register. */
683 case 'c':
684 /* Check for register prefix if necessary. */
685 if (reg_prefix && *s != reg_prefix)
686 goto error;
87505968 687 else if (reg_prefix)
305d537e
JE
688 s++;
689
252b5132
RH
690 if (strncmp (s, "fir", 3) == 0)
691 {
692 opcode |= 0x0 << 21;
693 s += 3;
694 continue;
695 }
696 if (strncmp (s, "psr", 3) == 0)
697 {
698 opcode |= 0x1 << 21;
699 s += 3;
700 continue;
701 }
702 if (strncmp (s, "dirbase", 7) == 0)
703 {
704 opcode |= 0x2 << 21;
705 s += 7;
706 continue;
707 }
708 if (strncmp (s, "db", 2) == 0)
709 {
710 opcode |= 0x3 << 21;
711 s += 2;
712 continue;
713 }
714 if (strncmp (s, "fsr", 3) == 0)
715 {
716 opcode |= 0x4 << 21;
717 s += 3;
718 continue;
719 }
720 if (strncmp (s, "epsr", 4) == 0)
721 {
722 opcode |= 0x5 << 21;
723 s += 4;
724 continue;
725 }
14218d5f
JE
726 /* The remaining control registers are XP only. */
727 if (target_xp && strncmp (s, "bear", 4) == 0)
728 {
729 opcode |= 0x6 << 21;
730 s += 4;
731 continue;
732 }
733 if (target_xp && strncmp (s, "ccr", 3) == 0)
734 {
735 opcode |= 0x7 << 21;
736 s += 3;
737 continue;
738 }
739 if (target_xp && strncmp (s, "p0", 2) == 0)
740 {
741 opcode |= 0x8 << 21;
742 s += 2;
743 continue;
744 }
745 if (target_xp && strncmp (s, "p1", 2) == 0)
746 {
747 opcode |= 0x9 << 21;
748 s += 2;
749 continue;
750 }
751 if (target_xp && strncmp (s, "p2", 2) == 0)
752 {
753 opcode |= 0xa << 21;
754 s += 2;
755 continue;
756 }
757 if (target_xp && strncmp (s, "p3", 2) == 0)
758 {
759 opcode |= 0xb << 21;
760 s += 2;
761 continue;
762 }
252b5132
RH
763 break;
764
305d537e
JE
765 /* 5-bit immediate in src1. */
766 case '5':
767 if (! i860_get_expression (s))
252b5132
RH
768 {
769 s = expr_end;
673a54e3
JE
770 the_insn.fi[fc].fup |= OP_IMM_U5;
771 fc++;
252b5132
RH
772 continue;
773 }
774 break;
775
305d537e
JE
776 /* 26-bit immediate, relative branch (lbroff). */
777 case 'l':
673a54e3
JE
778 the_insn.fi[fc].pcrel = 1;
779 the_insn.fi[fc].fup |= OP_IMM_BR26;
252b5132
RH
780 goto immediate;
781
305d537e
JE
782 /* 16-bit split immediate, relative branch (sbroff). */
783 case 'r':
673a54e3
JE
784 the_insn.fi[fc].pcrel = 1;
785 the_insn.fi[fc].fup |= OP_IMM_BR16;
252b5132
RH
786 goto immediate;
787
305d537e
JE
788 /* 16-bit split immediate. */
789 case 's':
673a54e3 790 the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
305d537e
JE
791 goto immediate;
792
793 /* 16-bit split immediate, byte aligned (st.b). */
794 case 'S':
673a54e3 795 the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
305d537e
JE
796 goto immediate;
797
798 /* 16-bit split immediate, half-word aligned (st.s). */
799 case 'T':
673a54e3 800 the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2);
305d537e
JE
801 goto immediate;
802
803 /* 16-bit split immediate, word aligned (st.l). */
804 case 'U':
673a54e3 805 the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4);
305d537e
JE
806 goto immediate;
807
808 /* 16-bit immediate. */
809 case 'i':
673a54e3 810 the_insn.fi[fc].fup |= OP_IMM_S16;
305d537e
JE
811 goto immediate;
812
813 /* 16-bit immediate, byte aligned (ld.b). */
814 case 'I':
673a54e3 815 the_insn.fi[fc].fup |= OP_IMM_S16;
305d537e
JE
816 goto immediate;
817
818 /* 16-bit immediate, half-word aligned (ld.s). */
819 case 'J':
673a54e3 820 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2);
252b5132
RH
821 goto immediate;
822
305d537e
JE
823 /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l). */
824 case 'K':
825 if (insn->name[0] == 'l')
673a54e3 826 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4);
252b5132 827 else
673a54e3 828 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4);
305d537e
JE
829 goto immediate;
830
831 /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d). */
832 case 'L':
673a54e3 833 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8);
252b5132
RH
834 goto immediate;
835
305d537e
JE
836 /* 16-bit immediate, quad-word aligned (fld.q, fst.q). */
837 case 'M':
673a54e3 838 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16);
252b5132
RH
839
840 /*FALLTHROUGH*/
841
305d537e
JE
842 /* Handle the immediate for either the Intel syntax or
843 SVR4 syntax. The Intel syntax is "ha%immediate"
844 whereas SVR4 syntax is "[immediate]@ha". */
252b5132 845 immediate:
87505968 846 if (target_intel_syntax == 0)
305d537e 847 {
87505968
JE
848 /* AT&T/SVR4 syntax. */
849 if (*s == ' ')
850 s++;
851
852 /* Note that if i860_get_expression() fails, we will still
853 have created U entries in the symbol table for the
854 'symbols' in the input string. Try not to create U
855 symbols for registers, etc. */
856 if (! i860_get_expression (s))
857 s = expr_end;
858 else
859 goto error;
860
861 if (strncmp (s, "@ha", 3) == 0)
862 {
863 the_insn.fi[fc].fup |= OP_SEL_HA;
864 s += 3;
865 }
866 else if (strncmp (s, "@h", 2) == 0)
867 {
868 the_insn.fi[fc].fup |= OP_SEL_H;
869 s += 2;
870 }
871 else if (strncmp (s, "@l", 2) == 0)
872 {
873 the_insn.fi[fc].fup |= OP_SEL_L;
874 s += 2;
875 }
876 else if (strncmp (s, "@gotoff", 7) == 0
877 || strncmp (s, "@GOTOFF", 7) == 0)
878 {
879 as_bad (_("Assembler does not yet support PIC"));
880 the_insn.fi[fc].fup |= OP_SEL_GOTOFF;
881 s += 7;
882 }
883 else if (strncmp (s, "@got", 4) == 0
884 || strncmp (s, "@GOT", 4) == 0)
885 {
886 as_bad (_("Assembler does not yet support PIC"));
887 the_insn.fi[fc].fup |= OP_SEL_GOT;
888 s += 4;
889 }
890 else if (strncmp (s, "@plt", 4) == 0
891 || strncmp (s, "@PLT", 4) == 0)
892 {
893 as_bad (_("Assembler does not yet support PIC"));
894 the_insn.fi[fc].fup |= OP_SEL_PLT;
895 s += 4;
896 }
305d537e 897
87505968
JE
898 the_insn.expand = insn->expand;
899 fc++;
673a54e3 900
87505968 901 continue;
252b5132 902 }
87505968 903 else
252b5132 904 {
87505968
JE
905 /* Intel syntax. */
906 if (*s == ' ')
907 s++;
908 if (strncmp (s, "ha%", 3) == 0)
909 {
910 the_insn.fi[fc].fup |= OP_SEL_HA;
911 s += 3;
912 }
913 else if (strncmp (s, "h%", 2) == 0)
914 {
915 the_insn.fi[fc].fup |= OP_SEL_H;
916 s += 2;
917 }
918 else if (strncmp (s, "l%", 2) == 0)
919 {
920 the_insn.fi[fc].fup |= OP_SEL_L;
921 s += 2;
922 }
923 the_insn.expand = insn->expand;
924
925 /* Note that if i860_get_expression() fails, we will still
926 have created U entries in the symbol table for the
927 'symbols' in the input string. Try not to create U
928 symbols for registers, etc. */
929 if (! i860_get_expression (s))
930 s = expr_end;
931 else
932 goto error;
933
934 fc++;
935 continue;
252b5132 936 }
252b5132
RH
937 break;
938
939 default:
940 as_fatal (_("failed sanity check."));
941 }
942 break;
943 }
944 error:
945 if (match == 0)
946 {
947 /* Args don't match. */
305d537e
JE
948 if (insn[1].name != NULL
949 && ! strcmp (insn->name, insn[1].name))
252b5132
RH
950 {
951 ++insn;
305d537e 952 s = args_start;
252b5132
RH
953 continue;
954 }
955 else
956 {
305d537e 957 as_bad (_("Illegal operands for %s"), insn->name);
252b5132
RH
958 return;
959 }
960 }
961 break;
962 }
963
07c7854e
JE
964 /* Set the dual bit on this instruction if necessary. */
965 if (dual_mode != DUAL_OFF)
966 {
967 if ((opcode & 0xfc000000) == 0x48000000 || opcode == 0xb0000000)
968 {
0acc96e1
JE
969 /* The instruction is a flop or a fnop, so set its dual bit
970 (but check that it is 8-byte aligned). */
971 if (((frag_now->fr_address + frag_now_fix_octets ()) & 7) == 0)
972 opcode |= (1 << 9);
973 else
974 as_bad (_("'d.%s' must be 8-byte aligned"), insn->name);
975
07c7854e
JE
976 if (dual_mode == DUAL_DDOT)
977 dual_mode = DUAL_OFF;
978 else if (dual_mode == DUAL_ONDDOT)
979 dual_mode = DUAL_ON;
980 }
981 else if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
982 as_bad (_("Prefix 'd.' invalid for instruction `%s'"), insn->name);
983 }
984
252b5132 985 the_insn.opcode = opcode;
14218d5f
JE
986
987 /* Only recognize XP instructions when the user has requested it. */
988 if (insn->expand == XP_ONLY && ! target_xp)
989 as_bad (_("Unknown opcode: `%s'"), insn->name);
252b5132
RH
990}
991
992static int
7734b6e9 993i860_get_expression (char *str)
252b5132
RH
994{
995 char *save_in;
996 segT seg;
997
998 save_in = input_line_pointer;
999 input_line_pointer = str;
673a54e3 1000 seg = expression (&the_insn.fi[fc].exp);
252b5132
RH
1001 if (seg != absolute_section
1002 && seg != undefined_section
1003 && ! SEG_NORMAL (seg))
1004 {
1005 the_insn.error = _("bad segment");
1006 expr_end = input_line_pointer;
1007 input_line_pointer = save_in;
1008 return 1;
1009 }
1010 expr_end = input_line_pointer;
1011 input_line_pointer = save_in;
1012 return 0;
1013}
1014
305d537e
JE
1015/* Turn a string in input_line_pointer into a floating point constant of
1016 type TYPE, and store the appropriate bytes in *LITP. The number of
1017 LITTLENUMS emitted is stored in *SIZEP. An error message is returned,
1018 or NULL on OK. */
252b5132 1019
305d537e 1020/* Equal to MAX_PRECISION in atof-ieee.c. */
252b5132
RH
1021#define MAX_LITTLENUMS 6
1022
1023char *
7734b6e9 1024md_atof (int type, char *litP, int *sizeP)
252b5132
RH
1025{
1026 int prec;
1027 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1028 LITTLENUM_TYPE *wordP;
1029 char *t;
252b5132
RH
1030
1031 switch (type)
1032 {
252b5132
RH
1033 case 'f':
1034 case 'F':
1035 case 's':
1036 case 'S':
1037 prec = 2;
1038 break;
1039
1040 case 'd':
1041 case 'D':
1042 case 'r':
1043 case 'R':
1044 prec = 4;
1045 break;
1046
1047 case 'x':
1048 case 'X':
1049 prec = 6;
1050 break;
1051
1052 case 'p':
1053 case 'P':
1054 prec = 6;
1055 break;
1056
1057 default:
1058 *sizeP = 0;
1059 return _("Bad call to MD_ATOF()");
1060 }
1061 t = atof_ieee (input_line_pointer, type, words);
1062 if (t)
1063 input_line_pointer = t;
1064 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1065 for (wordP = words; prec--;)
1066 {
1067 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1068 litP += sizeof (LITTLENUM_TYPE);
1069 }
1070 return 0;
1071}
1072
305d537e 1073/* Write out in current endian mode. */
252b5132 1074void
7734b6e9 1075md_number_to_chars (char *buf, valueT val, int n)
252b5132 1076{
305d537e
JE
1077 if (target_big_endian)
1078 number_to_chars_bigendian (buf, val, n);
1079 else
1080 number_to_chars_littleendian (buf, val, n);
252b5132
RH
1081}
1082
305d537e 1083/* This should never be called for i860. */
252b5132 1084int
7734b6e9
JE
1085md_estimate_size_before_relax (register fragS *fragP ATTRIBUTE_UNUSED,
1086 segT segtype ATTRIBUTE_UNUSED)
252b5132
RH
1087{
1088 as_fatal (_("i860_estimate_size_before_relax\n"));
1089}
1090
305d537e 1091#ifdef DEBUG_I860
252b5132 1092static void
7734b6e9 1093print_insn (struct i860_it *insn)
252b5132
RH
1094{
1095 if (insn->error)
305d537e
JE
1096 fprintf (stderr, "ERROR: %s\n", insn->error);
1097
1098 fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode);
1099 fprintf (stderr, "expand = 0x%x\t", insn->expand);
1100 fprintf (stderr, "reloc = %s\t\n",
1101 bfd_get_reloc_code_name (insn->reloc));
252b5132
RH
1102 fprintf (stderr, "exp = {\n");
1103 fprintf (stderr, "\t\tX_add_symbol = %s\n",
1104 insn->exp.X_add_symbol ?
1105 (S_GET_NAME (insn->exp.X_add_symbol) ?
1106 S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
1107 fprintf (stderr, "\t\tX_op_symbol = %s\n",
1108 insn->exp.X_op_symbol ?
1109 (S_GET_NAME (insn->exp.X_op_symbol) ?
1110 S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
305d537e 1111 fprintf (stderr, "\t\tX_add_number = %lx\n",
252b5132
RH
1112 insn->exp.X_add_number);
1113 fprintf (stderr, "}\n");
1114}
305d537e
JE
1115#endif /* DEBUG_I860 */
1116
252b5132 1117\f
305d537e 1118#ifdef OBJ_ELF
5a38dc70 1119const char *md_shortopts = "VQ:";
305d537e 1120#else
5a38dc70 1121const char *md_shortopts = "";
305d537e
JE
1122#endif
1123
305d537e
JE
1124#define OPTION_EB (OPTION_MD_BASE + 0)
1125#define OPTION_EL (OPTION_MD_BASE + 1)
1126#define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)
14218d5f 1127#define OPTION_XP (OPTION_MD_BASE + 3)
87505968 1128#define OPTION_INTEL_SYNTAX (OPTION_MD_BASE + 4)
305d537e 1129
252b5132 1130struct option md_longopts[] = {
305d537e
JE
1131 { "EB", no_argument, NULL, OPTION_EB },
1132 { "EL", no_argument, NULL, OPTION_EL },
1133 { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
14218d5f 1134 { "mxp", no_argument, NULL, OPTION_XP },
87505968 1135 { "mintel-syntax",no_argument, NULL, OPTION_INTEL_SYNTAX },
305d537e 1136 { NULL, no_argument, NULL, 0 }
252b5132 1137};
305d537e
JE
1138size_t md_longopts_size = sizeof (md_longopts);
1139
252b5132 1140int
7734b6e9 1141md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
252b5132 1142{
305d537e
JE
1143 switch (c)
1144 {
1145 case OPTION_EB:
1146 target_big_endian = 1;
1147 break;
1148
1149 case OPTION_EL:
1150 target_big_endian = 0;
1151 break;
1152
1153 case OPTION_WARN_EXPAND:
1154 target_warn_expand = 1;
1155 break;
1156
14218d5f
JE
1157 case OPTION_XP:
1158 target_xp = 1;
1159 break;
1160
87505968
JE
1161 case OPTION_INTEL_SYNTAX:
1162 target_intel_syntax = 1;
1163 break;
1164
305d537e
JE
1165#ifdef OBJ_ELF
1166 /* SVR4 argument compatibility (-V): print version ID. */
1167 case 'V':
1168 print_version_id ();
1169 break;
1170
1171 /* SVR4 argument compatibility (-Qy, -Qn): controls whether
1172 a .comment section should be emitted or not (ignored). */
1173 case 'Q':
1174 break;
1175#endif
1176
1177 default:
1178 return 0;
1179 }
1180
1181 return 1;
252b5132
RH
1182}
1183
1184void
7734b6e9 1185md_show_usage (FILE *stream)
252b5132 1186{
305d537e
JE
1187 fprintf (stream, _("\
1188 -EL generate code for little endian mode (default)\n\
1189 -EB generate code for big endian mode\n\
14218d5f 1190 -mwarn-expand warn if pseudo operations are expanded\n\
87505968
JE
1191 -mxp enable i860XP support (disabled by default)\n\
1192 -mintel-syntax enable Intel syntax (default to AT&T/SVR4)\n"));
305d537e
JE
1193#ifdef OBJ_ELF
1194 /* SVR4 compatibility flags. */
1195 fprintf (stream, _("\
1196 -V print assembler version number\n\
1197 -Qy, -Qn ignored\n"));
1198#endif
252b5132 1199}
305d537e 1200
252b5132 1201\f
305d537e
JE
1202/* We have no need to default values of symbols. */
1203symbolS *
7734b6e9 1204md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
305d537e
JE
1205{
1206 return 0;
1207}
1208
305d537e 1209/* The i860 denotes auto-increment with '++'. */
252b5132 1210void
7734b6e9 1211md_operand (expressionS *exp)
252b5132 1212{
305d537e 1213 char *s;
252b5132 1214
f869cfc6 1215 for (s = input_line_pointer; *s; s++)
252b5132 1216 {
305d537e 1217 if (s[0] == '+' && s[1] == '+')
252b5132 1218 {
305d537e
JE
1219 input_line_pointer += 2;
1220 exp->X_op = O_register;
1221 break;
252b5132 1222 }
305d537e
JE
1223 }
1224}
1225
305d537e
JE
1226/* Round up a section size to the appropriate boundary. */
1227valueT
7734b6e9
JE
1228md_section_align (segT segment ATTRIBUTE_UNUSED,
1229 valueT size ATTRIBUTE_UNUSED)
305d537e
JE
1230{
1231 /* Byte alignment is fine. */
1232 return size;
1233}
1234
305d537e 1235/* On the i860, a PC-relative offset is relative to the address of the
eb9618da 1236 offset plus its size. */
305d537e 1237long
7734b6e9 1238md_pcrel_from (fixS *fixP)
305d537e
JE
1239{
1240 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1241}
252b5132 1242
305d537e
JE
1243/* Determine the relocation needed for non PC-relative 16-bit immediates.
1244 Also adjust the given immediate as necessary. Finally, check that
1245 all constraints (such as alignment) are satisfied. */
1246static bfd_reloc_code_real_type
7734b6e9 1247obtain_reloc_for_imm16 (fixS *fix, long *val)
305d537e
JE
1248{
1249 valueT fup = fix->fx_addnumber;
4a4f25cf 1250 bfd_reloc_code_real_type reloc;
305d537e
JE
1251
1252 if (fix->fx_pcrel)
1253 abort ();
1254
1255 /* Check alignment restrictions. */
1256 if ((fup & OP_ALIGN2) && (*val & 0x1))
1257 as_bad_where (fix->fx_file, fix->fx_line,
1258 _("This immediate requires 0 MOD 2 alignment"));
1259 else if ((fup & OP_ALIGN4) && (*val & 0x3))
1260 as_bad_where (fix->fx_file, fix->fx_line,
1261 _("This immediate requires 0 MOD 4 alignment"));
1262 else if ((fup & OP_ALIGN8) && (*val & 0x7))
1263 as_bad_where (fix->fx_file, fix->fx_line,
1264 _("This immediate requires 0 MOD 8 alignment"));
1265 else if ((fup & OP_ALIGN16) && (*val & 0xf))
1266 as_bad_where (fix->fx_file, fix->fx_line,
1267 _("This immediate requires 0 MOD 16 alignment"));
1268
1269 if (fup & OP_SEL_HA)
1270 {
1271 *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0);
1272 reloc = BFD_RELOC_860_HIGHADJ;
1273 }
1274 else if (fup & OP_SEL_H)
1275 {
1276 *val >>= 16;
1277 reloc = BFD_RELOC_860_HIGH;
1278 }
1279 else if (fup & OP_SEL_L)
1280 {
1281 int num_encode;
1282 if (fup & OP_IMM_SPLIT16)
252b5132 1283 {
305d537e 1284 if (fup & OP_ENCODE1)
252b5132 1285 {
305d537e
JE
1286 num_encode = 1;
1287 reloc = BFD_RELOC_860_SPLIT1;
1288 }
1289 else if (fup & OP_ENCODE2)
1290 {
1291 num_encode = 2;
1292 reloc = BFD_RELOC_860_SPLIT2;
252b5132
RH
1293 }
1294 else
1295 {
305d537e
JE
1296 num_encode = 0;
1297 reloc = BFD_RELOC_860_SPLIT0;
252b5132 1298 }
305d537e
JE
1299 }
1300 else
1301 {
1302 if (fup & OP_ENCODE1)
252b5132 1303 {
305d537e
JE
1304 num_encode = 1;
1305 reloc = BFD_RELOC_860_LOW1;
252b5132 1306 }
305d537e 1307 else if (fup & OP_ENCODE2)
252b5132 1308 {
305d537e
JE
1309 num_encode = 2;
1310 reloc = BFD_RELOC_860_LOW2;
1311 }
1312 else if (fup & OP_ENCODE3)
1313 {
1314 num_encode = 3;
1315 reloc = BFD_RELOC_860_LOW3;
252b5132
RH
1316 }
1317 else
1318 {
305d537e
JE
1319 num_encode = 0;
1320 reloc = BFD_RELOC_860_LOW0;
252b5132 1321 }
252b5132 1322 }
305d537e
JE
1323
1324 /* Preserve size encode bits. */
1325 *val &= ~((1 << num_encode) - 1);
252b5132 1326 }
305d537e
JE
1327 else
1328 {
1329 /* No selector. What reloc do we generate (???)? */
1330 reloc = BFD_RELOC_32;
1331 }
1332
1333 return reloc;
252b5132
RH
1334}
1335
305d537e
JE
1336/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1337 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1338 we will have to generate a reloc entry. */
94f592af
NC
1339
1340void
7734b6e9 1341md_apply_fix3 (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
305d537e 1342{
305d537e 1343 char *buf;
a161fe53 1344 long val = *valP;
305d537e
JE
1345 unsigned long insn;
1346 valueT fup;
252b5132 1347
305d537e 1348 buf = fix->fx_frag->fr_literal + fix->fx_where;
252b5132 1349
305d537e
JE
1350 /* Recall that earlier we stored the opcode little-endian. */
1351 insn = bfd_getl32 (buf);
252b5132 1352
305d537e
JE
1353 /* We stored a fix-up in this oddly-named scratch field. */
1354 fup = fix->fx_addnumber;
1355
1356 /* Determine the necessary relocations as well as inserting an
1357 immediate into the instruction. */
673a54e3 1358 if (fup & OP_IMM_U5)
252b5132 1359 {
305d537e
JE
1360 if (val & ~0x1f)
1361 as_bad_where (fix->fx_file, fix->fx_line,
1362 _("5-bit immediate too large"));
1363 if (fix->fx_addsy)
1364 as_bad_where (fix->fx_file, fix->fx_line,
1365 _("5-bit field must be absolute"));
1366
1367 insn |= (val & 0x1f) << 11;
1368 bfd_putl32 (insn, buf);
1369 fix->fx_r_type = BFD_RELOC_NONE;
1370 fix->fx_done = 1;
252b5132 1371 }
305d537e 1372 else if (fup & OP_IMM_S16)
252b5132 1373 {
305d537e 1374 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
252b5132 1375
305d537e 1376 /* Insert the immediate. */
ded0649c
JE
1377 if (fix->fx_addsy)
1378 fix->fx_done = 0;
1379 else
1380 {
1381 insn |= val & 0xffff;
1382 bfd_putl32 (insn, buf);
1383 fix->fx_r_type = BFD_RELOC_NONE;
1384 fix->fx_done = 1;
1385 }
305d537e
JE
1386 }
1387 else if (fup & OP_IMM_U16)
94f592af
NC
1388 abort ();
1389
305d537e
JE
1390 else if (fup & OP_IMM_SPLIT16)
1391 {
1392 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
1393
1394 /* Insert the immediate. */
ded0649c
JE
1395 if (fix->fx_addsy)
1396 fix->fx_done = 0;
1397 else
1398 {
1399 insn |= val & 0x7ff;
1400 insn |= (val & 0xf800) << 5;
1401 bfd_putl32 (insn, buf);
1402 fix->fx_r_type = BFD_RELOC_NONE;
1403 fix->fx_done = 1;
1404 }
4a4f25cf 1405 }
305d537e 1406 else if (fup & OP_IMM_BR16)
252b5132 1407 {
305d537e
JE
1408 if (val & 0x3)
1409 as_bad_where (fix->fx_file, fix->fx_line,
1410 _("A branch offset requires 0 MOD 4 alignment"));
1411
1412 val = val >> 2;
1413
1414 /* Insert the immediate. */
ded0649c
JE
1415 if (fix->fx_addsy)
1416 {
1417 fix->fx_done = 0;
1418 fix->fx_r_type = BFD_RELOC_860_PC16;
1419 }
1420 else
1421 {
1422 insn |= (val & 0x7ff);
1423 insn |= ((val & 0xf800) << 5);
1424 bfd_putl32 (insn, buf);
1425 fix->fx_r_type = BFD_RELOC_NONE;
1426 fix->fx_done = 1;
1427 }
252b5132 1428 }
305d537e 1429 else if (fup & OP_IMM_BR26)
252b5132 1430 {
305d537e
JE
1431 if (val & 0x3)
1432 as_bad_where (fix->fx_file, fix->fx_line,
1433 _("A branch offset requires 0 MOD 4 alignment"));
252b5132 1434
305d537e 1435 val >>= 2;
252b5132 1436
305d537e 1437 /* Insert the immediate. */
ded0649c
JE
1438 if (fix->fx_addsy)
1439 {
1440 fix->fx_r_type = BFD_RELOC_860_PC26;
1441 fix->fx_done = 0;
1442 }
1443 else
1444 {
1445 insn |= (val & 0x3ffffff);
1446 bfd_putl32 (insn, buf);
1447 fix->fx_r_type = BFD_RELOC_NONE;
1448 fix->fx_done = 1;
1449 }
305d537e
JE
1450 }
1451 else if (fup != OP_NONE)
1452 {
4a4f25cf 1453 as_bad_where (fix->fx_file, fix->fx_line,
d444b726 1454 _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
305d537e
JE
1455 abort ();
1456 }
1457 else
1458 {
1459 /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
1460 reach here (???). */
ded0649c
JE
1461 if (fix->fx_addsy)
1462 {
1463 fix->fx_r_type = BFD_RELOC_32;
1464 fix->fx_done = 0;
1465 }
1466 else
1467 {
1468 insn |= (val & 0xffffffff);
1469 bfd_putl32 (insn, buf);
1470 fix->fx_r_type = BFD_RELOC_NONE;
1471 fix->fx_done = 1;
1472 }
305d537e 1473 }
252b5132
RH
1474}
1475
305d537e
JE
1476/* Generate a machine dependent reloc from a fixup. */
1477arelent*
7734b6e9
JE
1478tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1479 fixS *fixp)
252b5132 1480{
305d537e 1481 arelent *reloc;
252b5132 1482
305d537e
JE
1483 reloc = xmalloc (sizeof (*reloc));
1484 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1485 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1486 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1487 reloc->addend = fixp->fx_offset;
1488 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
252b5132 1489
305d537e 1490 if (! reloc->howto)
252b5132 1491 {
305d537e
JE
1492 as_bad_where (fixp->fx_file, fixp->fx_line,
1493 "Cannot represent %s relocation in object file",
1494 bfd_get_reloc_code_name (fixp->fx_r_type));
252b5132 1495 }
305d537e 1496 return reloc;
252b5132 1497}
e15f6d30
JE
1498
1499/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
1500 of an rs_align_code fragment. */
1501
1502void
1503i860_handle_align (fragS *fragp)
1504{
1505 /* Instructions are always stored little-endian on the i860. */
1506 static const unsigned char le_nop[] = { 0x00, 0x00, 0x00, 0xA0 };
1507
1508 int bytes;
1509 char *p;
1510
1511 if (fragp->fr_type != rs_align_code)
1512 return;
1513
1514 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
1515 p = fragp->fr_literal + fragp->fr_fix;
1516
1517 /* Make sure we are on a 4-byte boundary, in case someone has been
1518 putting data into a text section. */
1519 if (bytes & 3)
1520 {
1521 int fix = bytes & 3;
1522 memset (p, 0, fix);
1523 p += fix;
1524 fragp->fr_fix += fix;
1525 }
1526
1527 memcpy (p, le_nop, 4);
1528 fragp->fr_var = 4;
1529}
1530
14d3f364
JE
1531/* This is called after a user-defined label is seen. We check
1532 if the label has a double colon (valid in Intel syntax mode only),
1533 in which case it should be externalized. */
1534
1535void
1536i860_check_label (symbolS *labelsym)
1537{
1538 /* At this point, the current line pointer is sitting on the character
1539 just after the first colon on the label. */
1540 if (target_intel_syntax && *input_line_pointer == ':')
1541 {
1542 S_SET_EXTERNAL (labelsym);
1543 input_line_pointer++;
1544 }
1545}
1546
This page took 0.305843 seconds and 4 git commands to generate.