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