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