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