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