OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-i860.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.