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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-rx.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-rx.c -- Assembler for the Renesas RX
2 163 khays
   Copyright 2008, 2009, 2010, 2011
3 16 khays
   Free Software Foundation, Inc.
4
 
5
   This file is part of GAS, the GNU Assembler.
6
 
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to the Free
19
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20
   02110-1301, USA.  */
21
 
22
#include "as.h"
23
#include "struc-symbol.h"
24
#include "obstack.h"
25
#include "safe-ctype.h"
26
#include "dwarf2dbg.h"
27
#include "libbfd.h"
28
#include "elf/common.h"
29
#include "elf/rx.h"
30
#include "rx-defs.h"
31
#include "filenames.h"
32
#include "listing.h"
33
#include "sb.h"
34
#include "macro.h"
35
 
36
#define RX_OPCODE_BIG_ENDIAN 0
37
 
38
const char comment_chars[]        = ";";
39
/* Note that input_file.c hand checks for '#' at the beginning of the
40
   first line of the input file.  This is because the compiler outputs
41
   #NO_APP at the beginning of its output.  */
42
const char line_comment_chars[]   = "#";
43
const char line_separator_chars[] = "!";
44
 
45
const char EXP_CHARS[]            = "eE";
46
const char FLT_CHARS[]            = "dD";
47
 
48
/* ELF flags to set in the output file header.  */
49
static int elf_flags = 0;
50
 
51
bfd_boolean rx_use_conventional_section_names = FALSE;
52
static bfd_boolean rx_use_small_data_limit = FALSE;
53
 
54 163 khays
static bfd_boolean rx_pid_mode = FALSE;
55
static int rx_num_int_regs = 0;
56
int rx_pid_register;
57
int rx_gp_register;
58
 
59 16 khays
enum options
60
{
61
  OPTION_BIG = OPTION_MD_BASE,
62
  OPTION_LITTLE,
63
  OPTION_32BIT_DOUBLES,
64
  OPTION_64BIT_DOUBLES,
65
  OPTION_CONVENTIONAL_SECTION_NAMES,
66
  OPTION_RENESAS_SECTION_NAMES,
67
  OPTION_SMALL_DATA_LIMIT,
68 163 khays
  OPTION_RELAX,
69
  OPTION_PID,
70
  OPTION_INT_REGS,
71 16 khays
};
72
 
73
#define RX_SHORTOPTS ""
74
const char * md_shortopts = RX_SHORTOPTS;
75
 
76
/* Assembler options.  */
77
struct option md_longopts[] =
78
{
79
  {"mbig-endian-data", no_argument, NULL, OPTION_BIG},
80
  {"mlittle-endian-data", no_argument, NULL, OPTION_LITTLE},
81
  /* The next two switches are here because the
82
     generic parts of the linker testsuite uses them.  */
83
  {"EB", no_argument, NULL, OPTION_BIG},
84
  {"EL", no_argument, NULL, OPTION_LITTLE},
85
  {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
86
  {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
87
  /* This option is here mainly for the binutils testsuites,
88
     as many of their tests assume conventional section naming.  */
89
  {"muse-conventional-section-names", no_argument, NULL, OPTION_CONVENTIONAL_SECTION_NAMES},
90
  {"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES},
91
  {"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT},
92
  {"relax", no_argument, NULL, OPTION_RELAX},
93 163 khays
  {"mpid", no_argument, NULL, OPTION_PID},
94
  {"mint-register", required_argument, NULL, OPTION_INT_REGS},
95 16 khays
  {NULL, no_argument, NULL, 0}
96
};
97
size_t md_longopts_size = sizeof (md_longopts);
98
 
99
int
100
md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
101
{
102
  switch (c)
103
    {
104
    case OPTION_BIG:
105
      target_big_endian = 1;
106
      return 1;
107
 
108
    case OPTION_LITTLE:
109
      target_big_endian = 0;
110
      return 1;
111
 
112
    case OPTION_32BIT_DOUBLES:
113
      elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES;
114
      return 1;
115
 
116
    case OPTION_64BIT_DOUBLES:
117
      elf_flags |= E_FLAG_RX_64BIT_DOUBLES;
118
      return 1;
119
 
120
    case OPTION_CONVENTIONAL_SECTION_NAMES:
121
      rx_use_conventional_section_names = TRUE;
122
      return 1;
123
 
124
    case OPTION_RENESAS_SECTION_NAMES:
125
      rx_use_conventional_section_names = FALSE;
126
      return 1;
127
 
128
    case OPTION_SMALL_DATA_LIMIT:
129
      rx_use_small_data_limit = TRUE;
130
      return 1;
131
 
132
    case OPTION_RELAX:
133
      linkrelax = 1;
134
      return 1;
135 163 khays
 
136
    case OPTION_PID:
137
      rx_pid_mode = TRUE;
138
      elf_flags |= E_FLAG_RX_PID;
139
      return 1;
140
 
141
    case OPTION_INT_REGS:
142
      rx_num_int_regs = atoi (optarg);
143
      return 1;
144 16 khays
    }
145
  return 0;
146
}
147
 
148
void
149
md_show_usage (FILE * stream)
150
{
151
  fprintf (stream, _(" RX specific command line options:\n"));
152
  fprintf (stream, _("  --mbig-endian-data\n"));
153
  fprintf (stream, _("  --mlittle-endian-data [default]\n"));
154
  fprintf (stream, _("  --m32bit-doubles [default]\n"));
155
  fprintf (stream, _("  --m64bit-doubles\n"));
156
  fprintf (stream, _("  --muse-conventional-section-names\n"));
157
  fprintf (stream, _("  --muse-renesas-section-names [default]\n"));
158
  fprintf (stream, _("  --msmall-data-limit\n"));
159 163 khays
  fprintf (stream, _("  --mrelax\n"));
160
  fprintf (stream, _("  --mpid\n"));
161
  fprintf (stream, _("  --mint-register=<value>\n"));
162 16 khays
}
163
 
164
static void
165
s_bss (int ignore ATTRIBUTE_UNUSED)
166
{
167
  int temp;
168
 
169
  temp = get_absolute_expression ();
170
  subseg_set (bss_section, (subsegT) temp);
171
  demand_empty_rest_of_line ();
172
}
173
 
174
static void
175
rx_float_cons (int ignore ATTRIBUTE_UNUSED)
176
{
177
  if (elf_flags & E_FLAG_RX_64BIT_DOUBLES)
178
    return float_cons ('d');
179
  return float_cons ('f');
180
}
181
 
182
static char *
183
rx_strcasestr (const char *string, const char *sub)
184
{
185
  int subl;
186
  int strl;
187
 
188
  if (!sub || !sub[0])
189
    return (char *)string;
190
 
191
  subl = strlen (sub);
192
  strl = strlen (string);
193
 
194
  while (strl >= subl)
195
    {
196
      /* strncasecmp is in libiberty.  */
197
      if (strncasecmp (string, sub, subl) == 0)
198
        return (char *)string;
199
 
200
      string ++;
201
      strl --;
202
    }
203
  return NULL;
204
}
205
 
206
static void
207
rx_include (int ignore)
208
{
209
  FILE * try;
210
  char * path;
211
  char * filename;
212
  char * current_filename;
213
  char * eof;
214
  char * p;
215
  char * d;
216
  char * f;
217
  char   end_char;
218
  size_t len;
219
 
220
  /* The RX version of the .INCLUDE pseudo-op does not
221
     have to have the filename inside double quotes.  */
222
  SKIP_WHITESPACE ();
223
  if (*input_line_pointer == '"')
224
    {
225
      /* Treat as the normal GAS .include pseudo-op.  */
226
      s_include (ignore);
227
      return;
228
    }
229
 
230
  /* Get the filename.  Spaces are allowed, NUL characters are not.  */
231
  filename = input_line_pointer;
232
  eof = find_end_of_line (filename, FALSE);
233
  input_line_pointer = eof;
234
 
235
  while (eof >= filename && (* eof == ' ' || * eof == '\n'))
236
    -- eof;
237
  end_char = *(++ eof);
238
  * eof = 0;
239
  if (eof == filename)
240
    {
241
      as_bad (_("no filename following .INCLUDE pseudo-op"));
242
      * eof = end_char;
243
      return;
244
    }
245
 
246
  as_where (& current_filename, NULL);
247
  f = (char *) xmalloc (strlen (current_filename) + strlen (filename) + 1);
248
 
249
  /* Check the filename.  If [@]..FILE[@] is found then replace
250
     this with the current assembler source filename, stripped
251
     of any directory prefixes or extensions.  */
252
  if ((p = rx_strcasestr (filename, "..file")) != NULL)
253
    {
254
      char * c;
255
 
256
      len = 6; /* strlen ("..file"); */
257
 
258
      if (p > filename && p[-1] == '@')
259
        -- p, ++len;
260
 
261
      if (p[len] == '@')
262
        len ++;
263
 
264
      for (d = c = current_filename; *c; c++)
265
        if (IS_DIR_SEPARATOR (* c))
266
          d = c + 1;
267
      for (c = d; *c; c++)
268
        if (*c == '.')
269
          break;
270
 
271
      sprintf (f, "%.*s%.*s%.*s", (int) (p - filename), filename,
272
               (int) (c - d), d,
273
               (int) (strlen (filename) - ((p + len) - filename)),
274
               p + len);
275
    }
276
  else
277
    strcpy (f, filename);
278
 
279
  /* RX .INCLUDE semantics say that 'filename' is located by:
280
 
281
     1. If filename is absolute, just try that.  Otherwise...
282
 
283
     2. If the current source file includes a directory component
284
        then prepend that to the filename and try.  Otherwise...
285
 
286
     3. Try any directories specified by the -I command line
287
        option(s).
288
 
289
     4 .Try a directory specifed by the INC100 environment variable.  */
290
 
291
  if (IS_ABSOLUTE_PATH (f))
292
    try = fopen (path = f, FOPEN_RT);
293
  else
294
    {
295
      char * env = getenv ("INC100");
296
 
297
      try = NULL;
298
 
299
      len = strlen (current_filename);
300
      if ((size_t) include_dir_maxlen > len)
301
        len = include_dir_maxlen;
302
      if (env && strlen (env) > len)
303
        len = strlen (env);
304
 
305
      path = (char *) xmalloc (strlen (f) + len + 5);
306
 
307
      if (current_filename != NULL)
308
        {
309
          for (d = NULL, p = current_filename; *p; p++)
310
            if (IS_DIR_SEPARATOR (* p))
311
              d = p;
312
 
313
          if (d != NULL)
314
            {
315
              sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename,
316
                       f);
317
              try = fopen (path, FOPEN_RT);
318
            }
319
        }
320
 
321
      if (try == NULL)
322
        {
323
          int i;
324
 
325
          for (i = 0; i < include_dir_count; i++)
326
            {
327
              sprintf (path, "%s/%s", include_dirs[i], f);
328
              if ((try = fopen (path, FOPEN_RT)) != NULL)
329
                break;
330
            }
331
        }
332
 
333
      if (try == NULL && env != NULL)
334
        {
335
          sprintf (path, "%s/%s", env, f);
336
          try = fopen (path, FOPEN_RT);
337
        }
338
 
339
      free (f);
340
    }
341
 
342
  if (try == NULL)
343
    {
344
      as_bad (_("unable to locate include file: %s"), filename);
345
      free (path);
346
    }
347
  else
348
    {
349
      fclose (try);
350
      register_dependency (path);
351
      input_scrub_insert_file (path);
352
    }
353
 
354
  * eof = end_char;
355
}
356
 
357
static void
358
parse_rx_section (char * name)
359
{
360
  asection * sec;
361
  int   type;
362
  int   attr = SHF_ALLOC | SHF_EXECINSTR;
363
  int   align = 2;
364
  char  end_char;
365
 
366
  do
367
    {
368
      char * p;
369
 
370
      SKIP_WHITESPACE ();
371
      for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++)
372
        ;
373
      end_char = *p;
374
      *p = 0;
375
 
376
      if (strcasecmp (input_line_pointer, "ALIGN") == 0)
377
        {
378
          *p = end_char;
379
 
380
          if (end_char == ' ')
381
            while (ISSPACE (*p))
382
              p++;
383
 
384
          if (*p == '=')
385
            {
386
              ++ p;
387
              while (ISSPACE (*p))
388
                p++;
389
              switch (*p)
390
                {
391
                case '2': align = 2; break;
392
                case '4': align = 4; break;
393
                case '8': align = 8; break;
394
                default:
395
                  as_bad (_("unrecognised alignment value in .SECTION directive: %s"), p);
396
                  ignore_rest_of_line ();
397
                  return;
398
                }
399
              ++ p;
400
            }
401
 
402
          end_char = *p;
403
        }
404
      else if (strcasecmp (input_line_pointer, "CODE") == 0)
405
        attr = SHF_ALLOC | SHF_EXECINSTR;
406
      else if (strcasecmp (input_line_pointer, "DATA") == 0)
407
        attr = SHF_ALLOC | SHF_WRITE;
408
      else if (strcasecmp (input_line_pointer, "ROMDATA") == 0)
409
        attr = SHF_ALLOC;
410
      else
411
        {
412
          as_bad (_("unknown parameter following .SECTION directive: %s"),
413
                  input_line_pointer);
414
 
415
          *p = end_char;
416
          input_line_pointer = p + 1;
417
          ignore_rest_of_line ();
418
          return;
419
        }
420
 
421
      *p = end_char;
422
      input_line_pointer = p + 1;
423
    }
424
  while (end_char != '\n' && end_char != 0);
425
 
426
  if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL)
427
    {
428
      if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2"))
429
        type = SHT_NULL;
430
      else
431
        type = SHT_NOBITS;
432
 
433
      obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
434
    }
435
  else /* Try not to redefine a section, especially B_1.  */
436
    {
437
      int flags = sec->flags;
438
 
439
      type = elf_section_type (sec);
440
 
441
      attr = ((flags & SEC_READONLY) ? 0 : SHF_WRITE)
442
        | ((flags & SEC_ALLOC) ? SHF_ALLOC : 0)
443
        | ((flags & SEC_CODE) ? SHF_EXECINSTR : 0)
444
        | ((flags & SEC_MERGE) ? SHF_MERGE : 0)
445
        | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0)
446
        | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0);
447
 
448
      obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
449
    }
450
 
451
  bfd_set_section_alignment (stdoutput, now_seg, align);
452
}
453
 
454
static void
455
rx_section (int ignore)
456
{
457
  char * p;
458
 
459
  /* The as100 assembler supports a different syntax for the .section
460
     pseudo-op.  So check for it and handle it here if necessary. */
461
  SKIP_WHITESPACE ();
462
 
463
  /* Peek past the section name to see if arguments follow.  */
464
  for (p = input_line_pointer; *p; p++)
465
    if (*p == ',' || *p == '\n')
466
      break;
467
 
468
  if (*p == ',')
469
    {
470
      int len = p - input_line_pointer;
471
 
472
      while (ISSPACE (*++p))
473
        ;
474
 
475
      if (*p != '"' && *p != '#')
476
        {
477
          char * name = (char *) xmalloc (len + 1);
478
 
479
          strncpy (name, input_line_pointer, len);
480
          name[len] = 0;
481
 
482
          input_line_pointer = p;
483
          parse_rx_section (name);
484
          return;
485
        }
486
    }
487
 
488
  obj_elf_section (ignore);
489
}
490
 
491
static void
492
rx_list (int ignore ATTRIBUTE_UNUSED)
493
{
494
  SKIP_WHITESPACE ();
495
 
496
  if (strncasecmp (input_line_pointer, "OFF", 3))
497
    listing_list (0);
498
  else if (strncasecmp (input_line_pointer, "ON", 2))
499
    listing_list (1);
500
  else
501
    as_warn (_("expecting either ON or OFF after .list"));
502
}
503
 
504
/* Like the .rept pseudo op, but supports the
505
   use of ..MACREP inside the repeated region.  */
506
 
507
static void
508
rx_rept (int ignore ATTRIBUTE_UNUSED)
509
{
510
  int count = get_absolute_expression ();
511
 
512
  do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP");
513
}
514
 
515
/* Like cons() accept that strings are allowed.  */
516
 
517
static void
518
rx_cons (int size)
519
{
520
  SKIP_WHITESPACE ();
521
 
522
  if (* input_line_pointer == '"')
523
    stringer (8+0);
524
  else
525
    cons (size);
526
}
527
 
528
static void
529
rx_nop (int ignore ATTRIBUTE_UNUSED)
530
{
531
  ignore_rest_of_line ();
532
}
533
 
534
static void
535
rx_unimp (int idx)
536
{
537
  as_warn (_("The \".%s\" pseudo-op is not implemented\n"),
538
           md_pseudo_table[idx].poc_name);
539
  ignore_rest_of_line ();
540
}
541
 
542
/* The target specific pseudo-ops which we support.  */
543
const pseudo_typeS md_pseudo_table[] =
544
{
545
  /* These are unimplemented.  They're listed first so that we can use
546
     the poc_value as the index into this array, to get the name of
547
     the pseudo.  So, keep these (1) first, and (2) in order, with (3)
548
     the poc_value's in sequence.  */
549
  { "btglb",    rx_unimp,       0 },
550
  { "call",     rx_unimp,       1 },
551
  { "einsf",    rx_unimp,       2 },
552
  { "fb",       rx_unimp,       3 },
553
  { "fbsym",    rx_unimp,       4 },
554
  { "id",       rx_unimp,       5 },
555
  { "initsct",  rx_unimp,       6 },
556
  { "insf",     rx_unimp,       7 },
557
  { "instr",    rx_unimp,       8 },
558
  { "lbba",     rx_unimp,       9 },
559
  { "len",      rx_unimp,       10 },
560
  { "optj",     rx_unimp,       11 },
561
  { "rvector",  rx_unimp,       12 },
562
  { "sb",       rx_unimp,       13 },
563
  { "sbbit",    rx_unimp,       14 },
564
  { "sbsym",    rx_unimp,       15 },
565
  { "sbsym16",  rx_unimp,       16 },
566
 
567
  /* These are the do-nothing pseudos.  */
568
  { "stk",      rx_nop,         0 },
569
  /* The manual documents ".stk" but the compiler emits ".stack".  */
570
  { "stack",    rx_nop,         0 },
571
 
572
  /* These are Renesas as100 assembler pseudo-ops that we do support.  */
573
  { "addr",     rx_cons,        3 },
574
  { "align",    s_align_bytes,  2 },
575
  { "byte",     rx_cons,        1 },
576
  { "fixed",    float_cons,    'f' },
577
  { "form",     listing_psize,  0 },
578
  { "glb",      s_globl,        0 },
579
  { "include",  rx_include,     0 },
580
  { "list",     rx_list,        0 },
581
  { "lword",    rx_cons,        4 },
582
  { "mrepeat",  rx_rept,        0 },
583
  { "section",  rx_section,     0 },
584
 
585
  /* FIXME: The following pseudo-ops place their values (and associated
586
     label if present) in the data section, regardless of whatever
587
     section we are currently in.  At the moment this code does not
588
     implement that part of the semantics.  */
589
  { "blka",     s_space,        3 },
590
  { "blkb",     s_space,        1 },
591
  { "blkd",     s_space,        8 },
592
  { "blkf",     s_space,        4 },
593
  { "blkl",     s_space,        4 },
594
  { "blkw",     s_space,        2 },
595
 
596
  /* Our "standard" pseudos. */
597
  { "double",   rx_float_cons,  0 },
598
  { "bss",      s_bss,          0 },
599
  { "3byte",    cons,           3 },
600
  { "int",      cons,           4 },
601
  { "word",     cons,           4 },
602
 
603
  /* End of list marker.  */
604
  { NULL,       NULL,           0 }
605
};
606
 
607
static asymbol * gp_symbol;
608 163 khays
static asymbol * rx_pid_symbol;
609 16 khays
 
610 163 khays
static symbolS * rx_pidreg_symbol;
611
static symbolS * rx_gpreg_symbol;
612
 
613 16 khays
void
614
md_begin (void)
615
{
616 163 khays
  /* Make the __gp and __pid_base symbols now rather
617
     than after the symbol table is frozen.  We only do this
618
     when supporting small data limits because otherwise we
619
     pollute the symbol table.  */
620
 
621
  /* The meta-registers %pidreg and %gpreg depend on what other
622
     options are specified.  The __rx_*_defined symbols exist so we
623
     can .ifdef asm code based on what options were passed to gas,
624
     without needing a preprocessor  */
625
 
626
  if (rx_pid_mode)
627
    {
628
      rx_pid_register = 13 - rx_num_int_regs;
629
      rx_pid_symbol = symbol_get_bfdsym (symbol_find_or_make ("__pid_base"));
630
      rx_pidreg_symbol = symbol_find_or_make ("__rx_pidreg_defined");
631
      S_SET_VALUE (rx_pidreg_symbol, rx_pid_register);
632
      S_SET_SEGMENT (rx_pidreg_symbol, absolute_section);
633
    }
634
 
635 16 khays
  if (rx_use_small_data_limit)
636 163 khays
    {
637
      if (rx_pid_mode)
638
        rx_gp_register = rx_pid_register - 1;
639
      else
640
        rx_gp_register = 13 - rx_num_int_regs;
641
      gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
642
      rx_gpreg_symbol = symbol_find_or_make ("__rx_gpreg_defined");
643
      S_SET_VALUE (rx_gpreg_symbol, rx_gp_register);
644
      S_SET_SEGMENT (rx_gpreg_symbol, absolute_section);
645
    }
646 16 khays
}
647
 
648
char * rx_lex_start;
649
char * rx_lex_end;
650
 
651
typedef struct rx_bytesT
652
{
653
  char base[4];
654
  int n_base;
655
  char ops[8];
656
  int n_ops;
657
  struct
658
  {
659
    expressionS  exp;
660
    char         offset;
661
    char         nbits;
662
    char         type; /* RXREL_*.  */
663
    int          reloc;
664
    fixS *       fixP;
665
  } fixups[2];
666
  int n_fixups;
667
  struct
668
  {
669
    char type;
670
    char field_pos;
671
    char val_ofs;
672
  } relax[2];
673
  int n_relax;
674
  int link_relax;
675
  fixS *link_relax_fixP;
676
  char times_grown;
677
  char times_shrank;
678
} rx_bytesT;
679
 
680
static rx_bytesT rx_bytes;
681
 
682
void
683
rx_relax (int type, int pos)
684
{
685
  rx_bytes.relax[rx_bytes.n_relax].type = type;
686
  rx_bytes.relax[rx_bytes.n_relax].field_pos = pos;
687
  rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops;
688
  rx_bytes.n_relax ++;
689
}
690
 
691
void
692
rx_linkrelax_dsp (int pos)
693
{
694
  switch (pos)
695
    {
696
    case 4:
697
      rx_bytes.link_relax |= RX_RELAXA_DSP4;
698
      break;
699
    case 6:
700
      rx_bytes.link_relax |= RX_RELAXA_DSP6;
701
      break;
702
    case 14:
703
      rx_bytes.link_relax |= RX_RELAXA_DSP14;
704
      break;
705
    }
706
}
707
 
708
void
709
rx_linkrelax_imm (int pos)
710
{
711
  switch (pos)
712
    {
713
    case 6:
714
      rx_bytes.link_relax |= RX_RELAXA_IMM6;
715
      break;
716
    case 12:
717
      rx_bytes.link_relax |= RX_RELAXA_IMM12;
718
      break;
719
    }
720
}
721
 
722
void
723
rx_linkrelax_branch (void)
724
{
725
  rx_bytes.link_relax |= RX_RELAXA_BRA;
726
}
727
 
728
static void
729
rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
730
{
731
  rx_bytes.fixups[rx_bytes.n_fixups].exp = exp;
732
  rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits;
733
  rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits;
734
  rx_bytes.fixups[rx_bytes.n_fixups].type = type;
735
  rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md;
736
  rx_bytes.n_fixups ++;
737
}
738
 
739
#define rx_field_fixup(exp, offset, nbits, type)        \
740
  rx_fixup (exp, offset, nbits, type)
741
 
742
#define rx_op_fixup(exp, offset, nbits, type)           \
743
  rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
744
 
745
void
746
rx_base1 (int b1)
747
{
748
  rx_bytes.base[0] = b1;
749
  rx_bytes.n_base = 1;
750
}
751
 
752
void
753
rx_base2 (int b1, int b2)
754
{
755
  rx_bytes.base[0] = b1;
756
  rx_bytes.base[1] = b2;
757
  rx_bytes.n_base = 2;
758
}
759
 
760
void
761
rx_base3 (int b1, int b2, int b3)
762
{
763
  rx_bytes.base[0] = b1;
764
  rx_bytes.base[1] = b2;
765
  rx_bytes.base[2] = b3;
766
  rx_bytes.n_base = 3;
767
}
768
 
769
void
770
rx_base4 (int b1, int b2, int b3, int b4)
771
{
772
  rx_bytes.base[0] = b1;
773
  rx_bytes.base[1] = b2;
774
  rx_bytes.base[2] = b3;
775
  rx_bytes.base[3] = b4;
776
  rx_bytes.n_base = 4;
777
}
778
 
779
/* This gets complicated when the field spans bytes, because fields
780
   are numbered from the MSB of the first byte as zero, and bits are
781
   stored LSB towards the LSB of the byte.  Thus, a simple four-bit
782
   insertion of 12 at position 4 of 0x00 yields: 0x0b.  A three-bit
783
   insertion of b'MXL at position 7 is like this:
784
 
785
     - - - -  - - - -   - - - -  - - - -
786
                    M   X L               */
787
 
788
void
789
rx_field (int val, int pos, int sz)
790
{
791
  int valm;
792
  int bytep, bitp;
793
 
794
  if (sz > 0)
795
    {
796
      if (val < 0 || val >= (1 << sz))
797
        as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
798
    }
799
  else
800
    {
801
      sz = - sz;
802
      if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
803
        as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
804
    }
805
 
806
  /* This code points at 'M' in the above example.  */
807
  bytep = pos / 8;
808
  bitp = pos % 8;
809
 
810
  while (bitp + sz > 8)
811
    {
812
      int ssz = 8 - bitp;
813
      int svalm;
814
 
815
      svalm = val >> (sz - ssz);
816
      svalm = svalm & ((1 << ssz) - 1);
817
      svalm = svalm << (8 - bitp - ssz);
818
      gas_assert (bytep < rx_bytes.n_base);
819
      rx_bytes.base[bytep] |= svalm;
820
 
821
      bitp = 0;
822
      sz -= ssz;
823
      bytep ++;
824
    }
825
  valm = val & ((1 << sz) - 1);
826
  valm = valm << (8 - bitp - sz);
827
  gas_assert (bytep < rx_bytes.n_base);
828
  rx_bytes.base[bytep] |= valm;
829
}
830
 
831
/* Special case of the above, for 3-bit displacements of 2..9.  */
832
 
833
void
834
rx_disp3 (expressionS exp, int pos)
835
{
836
  rx_field_fixup (exp, pos, 3, RXREL_PCREL);
837
}
838
 
839
/* Special case of the above, for split 5-bit displacements.  Assumes
840
   the displacement has been checked with rx_disp5op.  */
841
/* ---- -432 1--- 0--- */
842
 
843
void
844
rx_field5s (expressionS exp)
845
{
846
  int val;
847
 
848
  val = exp.X_add_number;
849
  rx_bytes.base[0] |= val >> 2;
850
  rx_bytes.base[1] |= (val << 6) & 0x80;
851
  rx_bytes.base[1] |= (val << 3) & 0x08;
852
}
853
 
854
/* ---- ---- 4--- 3210 */
855
 
856
void
857
rx_field5s2 (expressionS exp)
858
{
859
  int val;
860
 
861
  val = exp.X_add_number;
862
  rx_bytes.base[1] |= (val << 3) & 0x80;
863
  rx_bytes.base[1] |= (val     ) & 0x0f;
864
}
865
 
866
#define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
867
 
868
#define F_PRECISION 2
869
 
870
void
871
rx_op (expressionS exp, int nbytes, int type)
872
{
873
  int v = 0;
874
 
875
  if ((exp.X_op == O_constant || exp.X_op == O_big)
876
      && type != RXREL_PCREL)
877
    {
878
      if (exp.X_op == O_big && exp.X_add_number <= 0)
879
        {
880
          LITTLENUM_TYPE w[2];
881
          char * ip = rx_bytes.ops + rx_bytes.n_ops;
882
 
883
          gen_to_words (w, F_PRECISION, 8);
884
#if RX_OPCODE_BIG_ENDIAN
885
          ip[0] = w[0] >> 8;
886
          ip[1] = w[0];
887
          ip[2] = w[1] >> 8;
888
          ip[3] = w[1];
889
#else
890
          ip[3] = w[0] >> 8;
891
          ip[2] = w[0];
892
          ip[1] = w[1] >> 8;
893
          ip[0] = w[1];
894
#endif
895
          rx_bytes.n_ops += 4;
896
        }
897
      else
898
        {
899
          v = exp.X_add_number;
900
          while (nbytes)
901
            {
902
#if RX_OPCODE_BIG_ENDIAN
903
              OP ((v >> (8 * (nbytes - 1))) & 0xff);
904
#else
905
              OP (v & 0xff);
906
              v >>= 8;
907
#endif
908
              nbytes --;
909
            }
910
        }
911
    }
912
  else
913
    {
914
      rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type);
915
      memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes);
916
      rx_bytes.n_ops += nbytes;
917
    }
918
}
919
 
920
int
921
rx_wrap (void)
922
{
923
  return 0;
924
}
925
 
926
#define APPEND(B, N_B)                                 \
927
  if (rx_bytes.N_B)                                    \
928
    {                                                  \
929
      memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B);  \
930
      idx += rx_bytes.N_B;                             \
931
    }
932
 
933
void
934
rx_frag_init (fragS * fragP)
935
{
936
  if (rx_bytes.n_relax || rx_bytes.link_relax)
937
    {
938
      fragP->tc_frag_data = malloc (sizeof (rx_bytesT));
939
      memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
940
    }
941
  else
942
    fragP->tc_frag_data = 0;
943
}
944
 
945
/* Handle the as100's version of the .equ pseudo-op.  It has the syntax:
946
   <symbol_name> .equ <expression>   */
947
 
948
static void
949
rx_equ (char * name, char * expression)
950
{
951
  char   saved_name_end_char;
952
  char * name_end;
953
  char * saved_ilp;
954
 
955
  while (ISSPACE (* name))
956
    name ++;
957
 
958
  for (name_end = name + 1; *name_end; name_end ++)
959
    if (! ISALNUM (* name_end))
960
      break;
961
 
962
  saved_name_end_char = * name_end;
963
  * name_end = 0;
964
 
965
  saved_ilp = input_line_pointer;
966
  input_line_pointer = expression;
967
 
968
  equals (name, 1);
969
 
970
  input_line_pointer = saved_ilp;
971
  * name_end = saved_name_end_char;
972
}
973
 
974
/* Look for Renesas as100 pseudo-ops that occur after a symbol name
975
   rather than at the start of a line.  (eg .EQU or .DEFINE).  If one
976
   is found, process it and return TRUE otherwise return FALSE.  */
977
 
978
static bfd_boolean
979
scan_for_infix_rx_pseudo_ops (char * str)
980
{
981
  char * p;
982
  char * pseudo_op;
983
  char * dot = strchr (str, '.');
984
 
985
  if (dot == NULL || dot == str)
986
    return FALSE;
987
 
988
  /* A real pseudo-op must be preceeded by whitespace.  */
989
  if (dot[-1] != ' ' && dot[-1] != '\t')
990
    return FALSE;
991
 
992
  pseudo_op = dot + 1;
993
 
994
  if (!ISALNUM (* pseudo_op))
995
    return FALSE;
996
 
997
  for (p = pseudo_op + 1; ISALNUM (* p); p++)
998
    ;
999
 
1000
  if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0)
1001
    rx_equ (str, p);
1002
  else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0)
1003
    as_warn (_("The .DEFINE pseudo-op is not implemented"));
1004
  else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0)
1005
    as_warn (_("The .MACRO pseudo-op is not implemented"));
1006
  else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0)
1007
    as_warn (_("The .BTEQU pseudo-op is not implemented."));
1008
  else
1009
    return FALSE;
1010
 
1011
  return TRUE;
1012
}
1013
 
1014
void
1015
md_assemble (char * str)
1016
{
1017
  char * bytes;
1018
  int idx = 0;
1019
  int i, rel;
1020
  fragS * frag_then = frag_now;
1021
  expressionS  *exp;
1022
 
1023
  memset (& rx_bytes, 0, sizeof (rx_bytes));
1024
 
1025
  rx_lex_init (str, str + strlen (str));
1026
  if (scan_for_infix_rx_pseudo_ops (str))
1027
    return;
1028
  rx_parse ();
1029
 
1030
  /* This simplifies the relaxation code.  */
1031
  if (rx_bytes.n_relax || rx_bytes.link_relax)
1032
    {
1033
      /* We do it this way because we want the frag to have the
1034
         rx_bytes in it, which we initialize above.  */
1035
      bytes = frag_more (12);
1036
      frag_then = frag_now;
1037
      frag_variant (rs_machine_dependent,
1038
 
1039
 
1040
 
1041
 
1042
 
1043
 
1044
      frag_then->fr_opcode = bytes;
1045
      frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops;
1046
      frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops;
1047
    }
1048
  else
1049
    {
1050
      bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
1051
      frag_then = frag_now;
1052
    }
1053
 
1054
  APPEND (base, n_base);
1055
  APPEND (ops, n_ops);
1056
 
1057
  if (rx_bytes.link_relax && rx_bytes.n_fixups)
1058
    {
1059
      fixS * f;
1060
 
1061
      f = fix_new (frag_then,
1062
                   (char *) bytes - frag_then->fr_literal,
1063
                   0,
1064
                   abs_section_sym,
1065
                   rx_bytes.link_relax | rx_bytes.n_fixups,
1066
                   0,
1067
                   BFD_RELOC_RX_RELAX);
1068
      frag_then->tc_frag_data->link_relax_fixP = f;
1069
    }
1070
 
1071
  for (i = 0; i < rx_bytes.n_fixups; i ++)
1072
    {
1073
      /* index: [nbytes][type] */
1074
      static int reloc_map[5][4] =
1075
        {
1076
          { 0,                  0,                0,                  BFD_RELOC_RX_DIR3U_PCREL },
1077
          { BFD_RELOC_8,        BFD_RELOC_RX_8U,  BFD_RELOC_RX_NEG8,  BFD_RELOC_8_PCREL },
1078
          { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL },
1079
          { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL },
1080
          { BFD_RELOC_RX_32_OP, BFD_RELOC_32,     BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL },
1081
        };
1082
      fixS * f;
1083
 
1084
      idx = rx_bytes.fixups[i].offset / 8;
1085
      rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1086
 
1087
      if (rx_bytes.fixups[i].reloc)
1088
        rel = rx_bytes.fixups[i].reloc;
1089
 
1090
      if (frag_then->tc_frag_data)
1091
        exp = & frag_then->tc_frag_data->fixups[i].exp;
1092
      else
1093
        exp = & rx_bytes.fixups[i].exp;
1094
 
1095
      f = fix_new_exp (frag_then,
1096
                       (char *) bytes + idx - frag_then->fr_literal,
1097
                       rx_bytes.fixups[i].nbits / 8,
1098
                       exp,
1099
                       rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0,
1100
                       rel);
1101
      if (frag_then->tc_frag_data)
1102
        frag_then->tc_frag_data->fixups[i].fixP = f;
1103
    }
1104
 
1105
  dwarf2_emit_insn (idx);
1106
}
1107
 
1108
void
1109
rx_md_end (void)
1110
{
1111
}
1112
 
1113
/* Write a value out to the object file, using the appropriate endianness.  */
1114
 
1115
void
1116
md_number_to_chars (char * buf, valueT val, int n)
1117
{
1118
  if (target_big_endian)
1119
    number_to_chars_bigendian (buf, val, n);
1120
  else
1121
    number_to_chars_littleendian (buf, val, n);
1122
}
1123
 
1124
static struct
1125
{
1126
  char * fname;
1127
  int    reloc;
1128
}
1129
reloc_functions[] =
1130
{
1131
  { "gp", BFD_RELOC_GPREL16 },
1132
  { 0, 0 }
1133
};
1134
 
1135
void
1136
md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1137
{
1138
  int reloc = 0;
1139
  int i;
1140
 
1141
  for (i = 0; reloc_functions[i].fname; i++)
1142
    {
1143
      int flen = strlen (reloc_functions[i].fname);
1144
 
1145
      if (input_line_pointer[0] == '%'
1146
          && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1147
          && input_line_pointer[flen + 1] == '(')
1148
        {
1149
          reloc = reloc_functions[i].reloc;
1150
          input_line_pointer += flen + 2;
1151
          break;
1152
        }
1153
    }
1154
  if (reloc == 0)
1155
    return;
1156
 
1157
  expression (exp);
1158
  if (* input_line_pointer == ')')
1159
    input_line_pointer ++;
1160
 
1161
  exp->X_md = reloc;
1162
}
1163
 
1164
valueT
1165
md_section_align (segT segment, valueT size)
1166
{
1167
  int align = bfd_get_section_alignment (stdoutput, segment);
1168
  return ((size + (1 << align) - 1) & (-1 << align));
1169
}
1170
 
1171
                                /* NOP - 1 cycle */
1172
static unsigned char nop_1[] = { 0x03};
1173
                                /* MOV.L R0,R0 - 1 cycle */
1174
static unsigned char nop_2[] = { 0xef, 0x00};
1175
                                /* MAX R0,R0 - 1 cycle */
1176
static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1177
                                /* MUL #1,R0 - 1 cycle */
1178
static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1179
                                /* MUL #1,R0 - 1 cycle */
1180
static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1181
                                /* MUL #1,R0 - 1 cycle */
1182
static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1183
                                /* BRA.S .+7 - 1 cycle */
1184
static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
1185
 
1186
static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
1187
#define BIGGEST_NOP 7
1188
 
1189
/* When relaxing, we need to output a reloc for any .align directive
1190
   so that we can retain this alignment as we adjust opcode sizes.  */
1191
void
1192
rx_handle_align (fragS * frag)
1193
{
1194
  /* If handling an alignment frag, use an optimal NOP pattern.
1195
     Only do this if a fill value has not already been provided.
1196
     FIXME: This test fails if the provided fill value is zero.  */
1197
  if ((frag->fr_type == rs_align
1198
       || frag->fr_type == rs_align_code)
1199
      && subseg_text_p (now_seg))
1200
    {
1201
      int count = (frag->fr_next->fr_address
1202 163 khays
                   - frag->fr_address
1203 16 khays
                   - frag->fr_fix);
1204
      unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
1205
 
1206
      if (* base == 0)
1207
        {
1208
          if (count > BIGGEST_NOP)
1209
            {
1210
              base[0] = 0x2e;
1211
              base[1] = count;
1212
              frag->fr_var = 2;
1213
            }
1214
          else if (count > 0)
1215
            {
1216
              memcpy (base, nops[count], count);
1217
              frag->fr_var = count;
1218
            }
1219
        }
1220
    }
1221
 
1222
  if (linkrelax
1223
      && (frag->fr_type == rs_align
1224
          || frag->fr_type == rs_align_code)
1225
      && frag->fr_address + frag->fr_fix > 0
1226
      && frag->fr_offset > 0
1227
      && now_seg != bss_section)
1228
    {
1229
      fix_new (frag, frag->fr_fix, 0,
1230
               &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1231
               0, BFD_RELOC_RX_RELAX);
1232
      /* For the purposes of relaxation, this relocation is attached
1233
         to the byte *after* the alignment - i.e. the byte that must
1234
         remain aligned.  */
1235
      fix_new (frag->fr_next, 0, 0,
1236
               &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1237
               0, BFD_RELOC_RX_RELAX);
1238
    }
1239
}
1240
 
1241
char *
1242
md_atof (int type, char * litP, int * sizeP)
1243
{
1244
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
1245
}
1246
 
1247
symbolS *
1248
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1249
{
1250
  return NULL;
1251
}
1252
 
1253
/*----------------------------------------------------------------------*/
1254
/* To recap: we estimate everything based on md_estimate_size, then
1255
   adjust based on rx_relax_frag.  When it all settles, we call
1256
   md_convert frag to update the bytes.  The relaxation types and
1257
   relocations are in fragP->tc_frag_data, which is a copy of that
1258
   rx_bytes.
1259
 
1260
   Our scheme is as follows: fr_fix has the size of the smallest
1261
   opcode (like BRA.S).  We store the number of total bytes we need in
1262
   fr_subtype.  When we're done relaxing, we use fr_subtype and the
1263
   existing opcode bytes to figure out what actual opcode we need to
1264
   put in there.  If the fixup isn't resolvable now, we use the
1265
   maximal size.  */
1266
 
1267
#define TRACE_RELAX 0
1268
#define tprintf if (TRACE_RELAX) printf
1269
 
1270
typedef enum
1271
{
1272
  OT_other,
1273
  OT_bra,
1274
  OT_beq,
1275
  OT_bne,
1276
  OT_bsr,
1277
  OT_bcc
1278
} op_type_T;
1279
 
1280
/* We're looking for these types of relaxations:
1281
 
1282
   BRA.S        00001dsp
1283
   BRA.B        00101110 dspppppp
1284
   BRA.W        00111000 dspppppp pppppppp
1285
   BRA.A        00000100 dspppppp pppppppp pppppppp
1286
 
1287
   BEQ.S        00010dsp
1288
   BEQ.B        00100000 dspppppp
1289
   BEQ.W        00111010 dspppppp pppppppp
1290
 
1291
   BNE.S        00011dsp
1292
   BNE.B        00100001 dspppppp
1293
   BNE.W        00111011 dspppppp pppppppp
1294
 
1295
   BSR.W        00111001 dspppppp pppppppp
1296
   BSR.A        00000101 dspppppp pppppppp pppppppp
1297
 
1298
   Bcc.B        0010cond dspppppp
1299
 
1300
   Additionally, we can synthesize longer conditional branches using
1301
   pairs of opcodes, one with an inverted conditional (flip LSB):
1302
 
1303
   Bcc.W        0010ncnd 00000110 00111000 dspppppp pppppppp
1304
   Bcc.A        0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1305
   BEQ.A        00011100 00000100 dspppppp pppppppp pppppppp
1306
   BNE.A        00010100 00000100 dspppppp pppppppp pppppppp  */
1307
 
1308
/* Given the opcode bytes at OP, figure out which opcode it is and
1309
   return the type of opcode.  We use this to re-encode the opcode as
1310
   a different size later.  */
1311
 
1312
static op_type_T
1313
rx_opcode_type (char * op)
1314
{
1315
  unsigned char b = (unsigned char) op[0];
1316
 
1317
  switch (b & 0xf8)
1318
    {
1319
    case 0x08: return OT_bra;
1320
    case 0x10: return OT_beq;
1321
    case 0x18: return OT_bne;
1322
    }
1323
 
1324
  switch (b)
1325
    {
1326
    case 0x2e: return OT_bra;
1327
    case 0x38: return OT_bra;
1328
    case 0x04: return OT_bra;
1329
 
1330
    case 0x20: return OT_beq;
1331
    case 0x3a: return OT_beq;
1332
 
1333
    case 0x21: return OT_bne;
1334
    case 0x3b: return OT_bne;
1335
 
1336
    case 0x39: return OT_bsr;
1337
    case 0x05: return OT_bsr;
1338
    }
1339
 
1340
  if ((b & 0xf0) == 0x20)
1341
    return OT_bcc;
1342
 
1343
  return OT_other;
1344
}
1345
 
1346
/* Returns zero if *addrP has the target address.  Else returns nonzero
1347
   if we cannot compute the target address yet.  */
1348
 
1349
static int
1350
rx_frag_fix_value (fragS *    fragP,
1351
                   segT       segment,
1352
                   int        which,
1353
                   addressT * addrP,
1354
                   int        need_diff,
1355
                   addressT * sym_addr)
1356
{
1357
  addressT addr = 0;
1358
  rx_bytesT * b = fragP->tc_frag_data;
1359
  expressionS * exp = & b->fixups[which].exp;
1360
 
1361
  if (need_diff && exp->X_op != O_subtract)
1362
    return 1;
1363
 
1364
  if (exp->X_add_symbol)
1365
    {
1366
      if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1367
        return 1;
1368
      if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1369
        return 1;
1370
      addr += S_GET_VALUE (exp->X_add_symbol);
1371
    }
1372
 
1373
  if (exp->X_op_symbol)
1374
    {
1375
      if (exp->X_op != O_subtract)
1376
        return 1;
1377
      if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1378
        return 1;
1379
      if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1380
        return 1;
1381
      addr -= S_GET_VALUE (exp->X_op_symbol);
1382
    }
1383
  if (sym_addr)
1384
    * sym_addr = addr;
1385
  addr += exp->X_add_number;
1386
  * addrP = addr;
1387
  return 0;
1388
}
1389
 
1390
/* Estimate how big the opcode is after this relax pass.  The return
1391
   value is the difference between fr_fix and the actual size.  We
1392
   compute the total size in rx_relax_frag and store it in fr_subtype,
1393
   sowe only need to subtract fx_fix and return it.  */
1394
 
1395
int
1396
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1397
{
1398
  int opfixsize;
1399
  int delta;
1400
 
1401
  tprintf ("\033[32m  est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1402
           (unsigned long) (fragP->fr_address
1403
                            + (fragP->fr_opcode - fragP->fr_literal)),
1404
           (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1405
           fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1406
 
1407
  /* This is the size of the opcode that's accounted for in fr_fix.  */
1408
  opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1409
  /* This is the size of the opcode that isn't.  */
1410
  delta = (fragP->fr_subtype - opfixsize);
1411
 
1412
  tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1413
  return delta;
1414
}
1415
 
1416
/* Given the new addresses for this relax pass, figure out how big
1417
   each opcode must be.  We store the total number of bytes needed in
1418
   fr_subtype.  The return value is the difference between the size
1419
   after the last pass and the size after this pass, so we use the old
1420
   fr_subtype to calculate the difference.  */
1421
 
1422
int
1423
rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1424
{
1425
  addressT addr0, sym_addr;
1426
  addressT mypc;
1427
  int disp;
1428
  int oldsize = fragP->fr_subtype;
1429
  int newsize = oldsize;
1430
  op_type_T optype;
1431
   /* Index of relaxation we care about.  */
1432
  int ri;
1433
 
1434
  tprintf ("\033[36mrelax frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d str %ld\033[0m\n",
1435
           (unsigned long) (fragP->fr_address
1436
                            + (fragP->fr_opcode - fragP->fr_literal)),
1437
           (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1438
           fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1439
 
1440
  optype = rx_opcode_type (fragP->fr_opcode);
1441
 
1442
  /* In the one case where we have both a disp and imm relaxation, we want
1443
     the imm relaxation here.  */
1444
  ri = 0;
1445
  if (fragP->tc_frag_data->n_relax > 1
1446
      && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1447
    ri = 1;
1448
 
1449
  /* Try to get the target address.  */
1450
  if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1451
                         fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1452
                         & sym_addr))
1453
    {
1454
      /* If we don't, we must use the maximum size for the linker.
1455
         Note that we don't use synthetically expanded conditionals
1456
         for this.  */
1457
      switch (fragP->tc_frag_data->relax[ri].type)
1458
        {
1459
        case RX_RELAX_BRANCH:
1460
          switch (optype)
1461
            {
1462
            case OT_bra:
1463
            case OT_bsr:
1464
              newsize = 4;
1465
              break;
1466
            case OT_beq:
1467
            case OT_bne:
1468
              newsize = 3;
1469
              break;
1470
            case OT_bcc:
1471
              newsize = 2;
1472
              break;
1473
            case OT_other:
1474
              newsize = oldsize;
1475
              break;
1476
            }
1477
          break;
1478
 
1479
        case RX_RELAX_IMM:
1480
          newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1481
          break;
1482
        }
1483
      fragP->fr_subtype = newsize;
1484
      tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1485
      return newsize - oldsize;
1486
    }
1487
 
1488
  mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1489
  if (sym_addr > mypc)
1490
    addr0 += stretch;
1491
 
1492
  switch (fragP->tc_frag_data->relax[ri].type)
1493
    {
1494
    case  RX_RELAX_BRANCH:
1495
      tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
1496
               (unsigned long) addr0, (unsigned long) mypc,
1497
               (long) (addr0 - mypc));
1498
      disp = (int) addr0 - (int) mypc;
1499
 
1500
      switch (optype)
1501
        {
1502
        case OT_bcc:
1503
          if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1504
            /* bcc.b */
1505
            newsize = 2;
1506
          else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1507
            /* bncc.b/bra.w */
1508
            newsize = 5;
1509
          else
1510
            /* bncc.b/bra.a */
1511
            newsize = 6;
1512
          break;
1513
 
1514
        case OT_beq:
1515
        case OT_bne:
1516
          if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1517
            /* beq.s */
1518
            newsize = 1;
1519
          else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1520
            /* beq.b */
1521
            newsize = 2;
1522
          else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1523
            /* beq.w */
1524
            newsize = 3;
1525
          else
1526
            /* bne.s/bra.a */
1527
            newsize = 5;
1528
          break;
1529
 
1530
        case OT_bra:
1531
        case OT_bsr:
1532
          if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1533
            /* bra.s */
1534
            newsize = 1;
1535
          else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1536
            /* bra.b */
1537
            newsize = 2;
1538
          else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1539
            /* bra.w */
1540
            newsize = 3;
1541
          else
1542
            /* bra.a */
1543
            newsize = 4;
1544
          break;
1545
 
1546
        case OT_other:
1547
          break;
1548
        }
1549
      tprintf (" - newsize %d\n", newsize);
1550
      break;
1551
 
1552
    case RX_RELAX_IMM:
1553
      tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
1554
               (unsigned long) addr0, (unsigned long) mypc,
1555
               fragP->tc_frag_data->relax[ri].field_pos,
1556
               fragP->tc_frag_data->relax[ri].val_ofs);
1557
 
1558
      newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1559
 
1560
      if ((long) addr0 >= -128 && (long) addr0 <= 127)
1561
        newsize += 1;
1562
      else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1563
        newsize += 2;
1564
      else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1565
        newsize += 3;
1566
      else
1567
        newsize += 4;
1568
      break;
1569
 
1570
    default:
1571
      break;
1572
    }
1573
 
1574
  if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1575
    switch (optype)
1576
      {
1577
      case OT_bra:
1578
      case OT_bcc:
1579
      case OT_beq:
1580
      case OT_bne:
1581
        break;
1582
      case OT_bsr:
1583
        if (newsize < 3)
1584
          newsize = 3;
1585
        break;
1586
      case OT_other:
1587
        break;
1588
      }
1589
 
1590
  /* This prevents infinite loops in align-heavy sources.  */
1591
  if (newsize < oldsize)
1592
    {
1593
      if (fragP->tc_frag_data->times_shrank > 10
1594
         && fragP->tc_frag_data->times_grown > 10)
1595
       newsize = oldsize;
1596
      if (fragP->tc_frag_data->times_shrank < 20)
1597
       fragP->tc_frag_data->times_shrank ++;
1598
    }
1599
  else if (newsize > oldsize)
1600
    {
1601
      if (fragP->tc_frag_data->times_grown < 20)
1602
       fragP->tc_frag_data->times_grown ++;
1603
    }
1604
 
1605
  fragP->fr_subtype = newsize;
1606
  tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1607
  return newsize - oldsize;
1608
}
1609
 
1610
/* This lets us test for the opcode type and the desired size in a
1611
   switch statement.  */
1612
#define OPCODE(type,size) ((type) * 16 + (size))
1613
 
1614
/* Given the opcode stored in fr_opcode and the number of bytes we
1615
   think we need, encode a new opcode.  We stored a pointer to the
1616
   fixup for this opcode in the tc_frag_data structure.  If we can do
1617
   the fixup here, we change the relocation type to "none" (we test
1618
   for that in tc_gen_reloc) else we change it to the right type for
1619
   the new (biggest) opcode.  */
1620
 
1621
void
1622
md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
1623
                 segT    segment ATTRIBUTE_UNUSED,
1624
                 fragS * fragP ATTRIBUTE_UNUSED)
1625
{
1626
  rx_bytesT * rxb = fragP->tc_frag_data;
1627
  addressT addr0, mypc;
1628
  int disp;
1629
  int reloc_type, reloc_adjust;
1630
  char * op = fragP->fr_opcode;
1631
  int keep_reloc = 0;
1632
  int ri;
1633
  int fi = (rxb->n_fixups > 1) ? 1 : 0;
1634
  fixS * fix = rxb->fixups[fi].fixP;
1635
 
1636
  tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1637
           (unsigned long) (fragP->fr_address
1638
                            + (fragP->fr_opcode - fragP->fr_literal)),
1639
           (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1640
           fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
1641
           fragP->fr_subtype);
1642
 
1643
#if TRACE_RELAX
1644
  {
1645
    int i;
1646
 
1647
    printf ("lit %08x opc %08x", (int) fragP->fr_literal, (int) fragP->fr_opcode);
1648
    for (i = 0; i < 10; i++)
1649
      printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1650
    printf ("\n");
1651
  }
1652
#endif
1653
 
1654
  /* In the one case where we have both a disp and imm relaxation, we want
1655
     the imm relaxation here.  */
1656
  ri = 0;
1657
  if (fragP->tc_frag_data->n_relax > 1
1658
      && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1659
    ri = 1;
1660
 
1661
  /* We used a new frag for this opcode, so the opcode address should
1662
     be the frag address.  */
1663
  mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1664
 
1665
  /* Try to get the target address.  If we fail here, we just use the
1666
     largest format.  */
1667
  if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1668
                         fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1669
    {
1670
      /* We don't know the target address.  */
1671
      keep_reloc = 1;
1672
      addr0 = 0;
1673
      disp = 0;
1674
    }
1675
  else
1676
    {
1677
      /* We know the target address, and it's in addr0.  */
1678
      disp = (int) addr0 - (int) mypc;
1679
    }
1680
 
1681
  if (linkrelax)
1682
    keep_reloc = 1;
1683
 
1684
  reloc_type = BFD_RELOC_NONE;
1685
  reloc_adjust = 0;
1686
 
1687
  tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1688
           rx_opcode_type (fragP->fr_opcode), disp,
1689
           (unsigned long) addr0, (unsigned long) mypc);
1690
  switch (fragP->tc_frag_data->relax[ri].type)
1691
    {
1692
    case RX_RELAX_BRANCH:
1693
      switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1694
        {
1695
        case OPCODE (OT_bra, 1): /* BRA.S - no change.  */
1696
          op[0] = 0x08 + (disp & 7);
1697
          break;
1698
        case OPCODE (OT_bra, 2): /* BRA.B - 8 bit.  */
1699
          op[0] = 0x2e;
1700
          op[1] = disp;
1701
          reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1702
          reloc_adjust = 1;
1703
          break;
1704
        case OPCODE (OT_bra, 3): /* BRA.W - 16 bit.  */
1705
          op[0] = 0x38;
1706
#if RX_OPCODE_BIG_ENDIAN
1707
          op[1] = (disp >> 8) & 0xff;
1708
          op[2] = disp;
1709
#else
1710
          op[2] = (disp >> 8) & 0xff;
1711
          op[1] = disp;
1712
#endif
1713
          reloc_adjust = 1;
1714
          reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1715
          break;
1716
        case OPCODE (OT_bra, 4): /* BRA.A - 24 bit.  */
1717
          op[0] = 0x04;
1718
#if RX_OPCODE_BIG_ENDIAN
1719
          op[1] = (disp >> 16) & 0xff;
1720
          op[2] = (disp >> 8) & 0xff;
1721
          op[3] = disp;
1722
#else
1723
          op[3] = (disp >> 16) & 0xff;
1724
          op[2] = (disp >> 8) & 0xff;
1725
          op[1] = disp;
1726
#endif
1727
          reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1728
          reloc_adjust = 1;
1729
          break;
1730
 
1731
        case OPCODE (OT_beq, 1): /* BEQ.S - no change.  */
1732
          op[0] = 0x10 + (disp & 7);
1733
          break;
1734
        case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit.  */
1735
          op[0] = 0x20;
1736
          op[1] = disp;
1737
          reloc_adjust = 1;
1738
          reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1739
          break;
1740
        case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit.  */
1741
          op[0] = 0x3a;
1742
#if RX_OPCODE_BIG_ENDIAN
1743
          op[1] = (disp >> 8) & 0xff;
1744
          op[2] = disp;
1745
#else
1746
          op[2] = (disp >> 8) & 0xff;
1747
          op[1] = disp;
1748
#endif
1749
          reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1750
          reloc_adjust = 1;
1751
          break;
1752
        case OPCODE (OT_beq, 5): /* BEQ.A - synthetic.  */
1753 160 khays
          op[0] = 0x1d; /* bne.s .+5.  */
1754 16 khays
          op[1] = 0x04; /* bra.a dsp:24.  */
1755
          disp -= 1;
1756
#if RX_OPCODE_BIG_ENDIAN
1757
          op[2] = (disp >> 16) & 0xff;
1758
          op[3] = (disp >> 8) & 0xff;
1759
          op[4] = disp;
1760
#else
1761
          op[4] = (disp >> 16) & 0xff;
1762
          op[3] = (disp >> 8) & 0xff;
1763
          op[2] = disp;
1764
#endif
1765
          reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1766
          reloc_adjust = 2;
1767
          break;
1768
 
1769
        case OPCODE (OT_bne, 1): /* BNE.S - no change.  */
1770
          op[0] = 0x18 + (disp & 7);
1771
          break;
1772
        case OPCODE (OT_bne, 2): /* BNE.B - 8 bit.  */
1773
          op[0] = 0x21;
1774
          op[1] = disp;
1775
          reloc_adjust = 1;
1776
          reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1777
          break;
1778
        case OPCODE (OT_bne, 3): /* BNE.W - 16 bit.  */
1779
          op[0] = 0x3b;
1780
#if RX_OPCODE_BIG_ENDIAN
1781
          op[1] = (disp >> 8) & 0xff;
1782
          op[2] = disp;
1783
#else
1784
          op[2] = (disp >> 8) & 0xff;
1785
          op[1] = disp;
1786
#endif
1787
          reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1788
          reloc_adjust = 1;
1789
          break;
1790
        case OPCODE (OT_bne, 5): /* BNE.A - synthetic.  */
1791 160 khays
          op[0] = 0x15; /* beq.s .+5.  */
1792 16 khays
          op[1] = 0x04; /* bra.a dsp:24.  */
1793
          disp -= 1;
1794
#if RX_OPCODE_BIG_ENDIAN
1795
          op[2] = (disp >> 16) & 0xff;
1796
          op[3] = (disp >> 8) & 0xff;
1797
          op[4] = disp;
1798
#else
1799
          op[4] = (disp >> 16) & 0xff;
1800
          op[3] = (disp >> 8) & 0xff;
1801
          op[2] = disp;
1802
#endif
1803
          reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1804
          reloc_adjust = 2;
1805
          break;
1806
 
1807
        case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit.  */
1808
          op[0] = 0x39;
1809
#if RX_OPCODE_BIG_ENDIAN
1810
          op[1] = (disp >> 8) & 0xff;
1811
          op[2] = disp;
1812
#else
1813
          op[2] = (disp >> 8) & 0xff;
1814
          op[1] = disp;
1815
#endif
1816
          reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1817
          reloc_adjust = 0;
1818
          break;
1819
        case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit.  */
1820
          op[0] = 0x05;
1821
#if RX_OPCODE_BIG_ENDIAN
1822
          op[1] = (disp >> 16) & 0xff;
1823
          op[2] = (disp >> 8) & 0xff;
1824
          op[3] = disp;
1825
#else
1826
          op[3] = (disp >> 16) & 0xff;
1827
          op[2] = (disp >> 8) & 0xff;
1828
          op[1] = disp;
1829
#endif
1830
          reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1831
          reloc_adjust = 0;
1832
          break;
1833
 
1834
        case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit.  */
1835
          op[1] = disp;
1836
          reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1837
          break;
1838
        case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic.  */
1839
          op[0] ^= 1; /* Invert condition.  */
1840
          op[1] = 5;  /* Displacement.  */
1841
          op[2] = 0x38;
1842
          disp -= 2;
1843
#if RX_OPCODE_BIG_ENDIAN
1844
          op[3] = (disp >> 8) & 0xff;
1845
          op[4] = disp;
1846
#else
1847
          op[4] = (disp >> 8) & 0xff;
1848
          op[3] = disp;
1849
#endif
1850
          reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1851
          reloc_adjust = 2;
1852
          break;
1853
        case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic.  */
1854
          op[0] ^= 1; /* Invert condition.  */
1855
          op[1] = 6;  /* Displacement.  */
1856
          op[2] = 0x04;
1857
          disp -= 2;
1858
#if RX_OPCODE_BIG_ENDIAN
1859
          op[3] = (disp >> 16) & 0xff;
1860
          op[4] = (disp >> 8) & 0xff;
1861
          op[5] = disp;
1862
#else
1863
          op[5] = (disp >> 16) & 0xff;
1864
          op[4] = (disp >> 8) & 0xff;
1865
          op[3] = disp;
1866
#endif
1867
          reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1868
          reloc_adjust = 2;
1869
          break;
1870
 
1871
        default:
1872
          /* These are opcodes we'll relax in th linker, later.  */
1873
          if (rxb->n_fixups)
1874
            reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1875
          break;
1876
        }
1877
      break;
1878
 
1879
    case RX_RELAX_IMM:
1880
      {
1881
        int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1882
        int li;
1883
        char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1884
 
1885
        switch (nbytes)
1886
          {
1887
          case 1:
1888
            li = 1;
1889
            imm[0] = addr0;
1890
            reloc_type = BFD_RELOC_8;
1891
            break;
1892
          case 2:
1893
            li = 2;
1894
#if RX_OPCODE_BIG_ENDIAN
1895
            imm[1] = addr0;
1896
            imm[0] = addr0 >> 8;
1897
#else
1898
            imm[0] = addr0;
1899
            imm[1] = addr0 >> 8;
1900
#endif
1901
            reloc_type = BFD_RELOC_RX_16_OP;
1902
            break;
1903
          case 3:
1904
            li = 3;
1905
#if RX_OPCODE_BIG_ENDIAN
1906
            imm[2] = addr0;
1907
            imm[1] = addr0 >> 8;
1908
            imm[0] = addr0 >> 16;
1909
#else
1910
            imm[0] = addr0;
1911
            imm[1] = addr0 >> 8;
1912
            imm[2] = addr0 >> 16;
1913
#endif
1914
            reloc_type = BFD_RELOC_RX_24_OP;
1915
            break;
1916
          case 4:
1917
            li = 0;
1918
#if RX_OPCODE_BIG_ENDIAN
1919
            imm[3] = addr0;
1920
            imm[2] = addr0 >> 8;
1921
            imm[1] = addr0 >> 16;
1922
            imm[0] = addr0 >> 24;
1923
#else
1924
            imm[0] = addr0;
1925
            imm[1] = addr0 >> 8;
1926
            imm[2] = addr0 >> 16;
1927
            imm[3] = addr0 >> 24;
1928
#endif
1929
            reloc_type = BFD_RELOC_RX_32_OP;
1930
            break;
1931
          default:
1932
            as_bad (_("invalid immediate size"));
1933
            li = -1;
1934
          }
1935
 
1936
        switch (fragP->tc_frag_data->relax[ri].field_pos)
1937
          {
1938
          case 6:
1939
            op[0] &= 0xfc;
1940
            op[0] |= li;
1941
            break;
1942
          case 12:
1943
            op[1] &= 0xf3;
1944
            op[1] |= li << 2;
1945
            break;
1946
          case 20:
1947
            op[2] &= 0xf3;
1948
            op[2] |= li << 2;
1949
            break;
1950
          default:
1951
            as_bad (_("invalid immediate field position"));
1952
          }
1953
      }
1954
      break;
1955
 
1956
    default:
1957
      if (rxb->n_fixups)
1958
        {
1959
          reloc_type = fix->fx_r_type;
1960
          reloc_adjust = 0;
1961
        }
1962
      break;
1963
    }
1964
 
1965
  if (rxb->n_fixups)
1966
    {
1967
 
1968
      fix->fx_r_type = reloc_type;
1969
      fix->fx_where += reloc_adjust;
1970
      switch (reloc_type)
1971
        {
1972
        case BFD_RELOC_NONE:
1973
          fix->fx_size = 0;
1974
          break;
1975
        case BFD_RELOC_8:
1976
          fix->fx_size = 1;
1977
          break;
1978
        case BFD_RELOC_16_PCREL:
1979
        case BFD_RELOC_RX_16_OP:
1980
          fix->fx_size = 2;
1981
          break;
1982
        case BFD_RELOC_24_PCREL:
1983
        case BFD_RELOC_RX_24_OP:
1984
          fix->fx_size = 3;
1985
          break;
1986
        case BFD_RELOC_RX_32_OP:
1987
          fix->fx_size = 4;
1988
          break;
1989
        }
1990
    }
1991
 
1992
  fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1993
  tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1994
          fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1995
  fragP->fr_var = 0;
1996
 
1997
  if (fragP->fr_next != NULL
1998
          && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1999
              != fragP->fr_fix))
2000
    as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
2001
            (long) fragP->fr_fix,
2002
            (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
2003
}
2004
 
2005
#undef OPCODE
2006
 
2007
int
2008
rx_validate_fix_sub (struct fix * f)
2009
{
2010
  /* We permit the subtraction of two symbols in a few cases.  */
2011
  /* mov #sym1-sym2, R3 */
2012
  if (f->fx_r_type == BFD_RELOC_RX_32_OP)
2013
    return 1;
2014
  /* .long sym1-sym2 */
2015
  if (f->fx_r_type == BFD_RELOC_RX_DIFF
2016
      && ! f->fx_pcrel
2017
      && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
2018
    return 1;
2019
  return 0;
2020
}
2021
 
2022
long
2023
md_pcrel_from_section (fixS * fixP, segT sec)
2024
{
2025
  long rv;
2026
 
2027
  if (fixP->fx_addsy != NULL
2028
      && (! S_IS_DEFINED (fixP->fx_addsy)
2029
          || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2030
    /* The symbol is undefined (or is defined but not in this section).
2031
       Let the linker figure it out.  */
2032
    return 0;
2033
 
2034
  rv = fixP->fx_frag->fr_address + fixP->fx_where;
2035
  switch (fixP->fx_r_type)
2036
    {
2037
    case BFD_RELOC_RX_DIR3U_PCREL:
2038
      return rv;
2039
    default:
2040
      return rv - 1;
2041
    }
2042
}
2043
 
2044
void
2045
rx_cons_fix_new (fragS *        frag,
2046
                 int            where,
2047
                 int            size,
2048
                 expressionS *  exp)
2049
{
2050
  bfd_reloc_code_real_type type;
2051
 
2052
  switch (size)
2053
    {
2054
    case 1:
2055
      type = BFD_RELOC_8;
2056
      break;
2057
    case 2:
2058
      type = BFD_RELOC_16;
2059
      break;
2060
    case 3:
2061
      type = BFD_RELOC_24;
2062
      break;
2063
    case 4:
2064
      type = BFD_RELOC_32;
2065
      break;
2066
    default:
2067
      as_bad (_("unsupported constant size %d\n"), size);
2068
      return;
2069
    }
2070
 
2071
  if (exp->X_op == O_subtract && exp->X_op_symbol)
2072
    {
2073
      if (size != 4 && size != 2 && size != 1)
2074
        as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2075
      else
2076
        type = BFD_RELOC_RX_DIFF;
2077
    }
2078
 
2079
  fix_new_exp (frag, where, (int) size, exp, 0, type);
2080
}
2081
 
2082
void
2083
md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2084
              valueT *     t ATTRIBUTE_UNUSED,
2085
              segT         s ATTRIBUTE_UNUSED)
2086
{
2087
  /* Instruction bytes are always little endian.  */
2088
  char * op;
2089
  unsigned long val;
2090
 
2091
  if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2092
    return;
2093
  if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2094
    return;
2095
 
2096
#define OP2(x) op[target_big_endian ? 1-x : x]
2097
#define OP3(x) op[target_big_endian ? 2-x : x]
2098
#define OP4(x) op[target_big_endian ? 3-x : x]
2099
 
2100
  op = f->fx_frag->fr_literal + f->fx_where;
2101
  val = (unsigned long) * t;
2102
 
2103
  /* Opcode words are always the same endian.  Data words are either
2104
     big or little endian.  */
2105
 
2106
  switch (f->fx_r_type)
2107
    {
2108
    case BFD_RELOC_NONE:
2109
      break;
2110
 
2111
    case BFD_RELOC_RX_RELAX:
2112
      f->fx_done = 1;
2113
      break;
2114
 
2115
    case BFD_RELOC_RX_DIR3U_PCREL:
2116
      if (val < 3 || val > 10)
2117
        as_bad_where (f->fx_file, f->fx_line,
2118
                      _("jump not 3..10 bytes away (is %d)"), (int) val);
2119
      op[0] &= 0xf8;
2120
      op[0] |= val & 0x07;
2121
      break;
2122
 
2123
    case BFD_RELOC_8:
2124
    case BFD_RELOC_8_PCREL:
2125
    case BFD_RELOC_RX_8U:
2126
      op[0] = val;
2127
      break;
2128
 
2129
    case BFD_RELOC_16:
2130
      OP2(1) = val & 0xff;
2131
      OP2(0) = (val >> 8) & 0xff;
2132
      break;
2133
 
2134
    case BFD_RELOC_16_PCREL:
2135
    case BFD_RELOC_RX_16_OP:
2136
    case BFD_RELOC_RX_16U:
2137
#if RX_OPCODE_BIG_ENDIAN
2138
      op[1] = val & 0xff;
2139
      op[0] = (val >> 8) & 0xff;
2140
#else
2141
      op[0] = val & 0xff;
2142
      op[1] = (val >> 8) & 0xff;
2143
#endif
2144
      break;
2145
 
2146
    case BFD_RELOC_24:
2147
      OP3(0) = val & 0xff;
2148
      OP3(1) = (val >> 8) & 0xff;
2149
      OP3(2) = (val >> 16) & 0xff;
2150
      break;
2151
 
2152
    case BFD_RELOC_24_PCREL:
2153
    case BFD_RELOC_RX_24_OP:
2154
    case BFD_RELOC_RX_24U:
2155
#if RX_OPCODE_BIG_ENDIAN
2156
      op[2] = val & 0xff;
2157
      op[1] = (val >> 8) & 0xff;
2158
      op[0] = (val >> 16) & 0xff;
2159
#else
2160
      op[0] = val & 0xff;
2161
      op[1] = (val >> 8) & 0xff;
2162
      op[2] = (val >> 16) & 0xff;
2163
#endif
2164
      break;
2165
 
2166
    case BFD_RELOC_RX_DIFF:
2167
      switch (f->fx_size)
2168
        {
2169
        case 1:
2170
          op[0] = val & 0xff;
2171
          break;
2172
        case 2:
2173
          OP2(0) = val & 0xff;
2174
          OP2(1) = (val >> 8) & 0xff;
2175
          break;
2176
        case 4:
2177
          OP4(0) = val & 0xff;
2178
          OP4(1) = (val >> 8) & 0xff;
2179
          OP4(2) = (val >> 16) & 0xff;
2180
          OP4(3) = (val >> 24) & 0xff;
2181
          break;
2182
        }
2183
      break;
2184
 
2185
    case BFD_RELOC_32:
2186
      OP4(0) = val & 0xff;
2187
      OP4(1) = (val >> 8) & 0xff;
2188
      OP4(2) = (val >> 16) & 0xff;
2189
      OP4(3) = (val >> 24) & 0xff;
2190
      break;
2191
 
2192
    case BFD_RELOC_RX_32_OP:
2193
#if RX_OPCODE_BIG_ENDIAN
2194
      op[3] = val & 0xff;
2195
      op[2] = (val >> 8) & 0xff;
2196
      op[1] = (val >> 16) & 0xff;
2197
      op[0] = (val >> 24) & 0xff;
2198
#else
2199
      op[0] = val & 0xff;
2200
      op[1] = (val >> 8) & 0xff;
2201
      op[2] = (val >> 16) & 0xff;
2202
      op[3] = (val >> 24) & 0xff;
2203
#endif
2204
      break;
2205
 
2206
    case BFD_RELOC_RX_NEG8:
2207
      op[0] = - val;
2208
      break;
2209
 
2210
    case BFD_RELOC_RX_NEG16:
2211
      val = -val;
2212
#if RX_OPCODE_BIG_ENDIAN
2213
      op[1] = val & 0xff;
2214
      op[0] = (val >> 8) & 0xff;
2215
#else
2216
      op[0] = val & 0xff;
2217
      op[1] = (val >> 8) & 0xff;
2218
#endif
2219
      break;
2220
 
2221
    case BFD_RELOC_RX_NEG24:
2222
      val = -val;
2223
#if RX_OPCODE_BIG_ENDIAN
2224
      op[2] = val & 0xff;
2225
      op[1] = (val >> 8) & 0xff;
2226
      op[0] = (val >> 16) & 0xff;
2227
#else
2228
      op[0] = val & 0xff;
2229
      op[1] = (val >> 8) & 0xff;
2230
      op[2] = (val >> 16) & 0xff;
2231
#endif
2232
      break;
2233
 
2234
    case BFD_RELOC_RX_NEG32:
2235
      val = -val;
2236
#if RX_OPCODE_BIG_ENDIAN
2237
      op[3] = val & 0xff;
2238
      op[2] = (val >> 8) & 0xff;
2239
      op[1] = (val >> 16) & 0xff;
2240
      op[0] = (val >> 24) & 0xff;
2241
#else
2242
      op[0] = val & 0xff;
2243
      op[1] = (val >> 8) & 0xff;
2244
      op[2] = (val >> 16) & 0xff;
2245
      op[3] = (val >> 24) & 0xff;
2246
#endif
2247
      break;
2248
 
2249
    case BFD_RELOC_RX_GPRELL:
2250
      val >>= 1;
2251
    case BFD_RELOC_RX_GPRELW:
2252
      val >>= 1;
2253
    case BFD_RELOC_RX_GPRELB:
2254
#if RX_OPCODE_BIG_ENDIAN
2255
      op[1] = val & 0xff;
2256
      op[0] = (val >> 8) & 0xff;
2257
#else
2258
      op[0] = val & 0xff;
2259
      op[1] = (val >> 8) & 0xff;
2260
#endif
2261
      break;
2262
 
2263
    default:
2264
      as_bad (_("Unknown reloc in md_apply_fix: %s"),
2265
              bfd_get_reloc_code_name (f->fx_r_type));
2266
      break;
2267
    }
2268
 
2269
  if (f->fx_addsy == NULL)
2270
    f->fx_done = 1;
2271
}
2272
 
2273
arelent **
2274 163 khays
tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
2275 16 khays
{
2276
  static arelent * reloc[5];
2277 163 khays
  bfd_boolean is_opcode = FALSE;
2278 16 khays
 
2279
  if (fixp->fx_r_type == BFD_RELOC_NONE)
2280
    {
2281
      reloc[0] = NULL;
2282
      return reloc;
2283
    }
2284
 
2285
  if (fixp->fx_subsy
2286
      && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2287
    {
2288
      fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2289
      fixp->fx_subsy = NULL;
2290
    }
2291
 
2292
  reloc[0]                 = (arelent *) xmalloc (sizeof (arelent));
2293
  reloc[0]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2294
  * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2295
  reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2296
  reloc[0]->addend        = fixp->fx_offset;
2297
 
2298
  if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
2299
      && fixp->fx_subsy)
2300
    {
2301
      fixp->fx_r_type = BFD_RELOC_RX_DIFF;
2302 163 khays
      is_opcode = TRUE;
2303 16 khays
    }
2304 163 khays
  else if (sec)
2305
    is_opcode = sec->flags & SEC_CODE;
2306
 
2307 16 khays
  /* Certain BFD relocations cannot be translated directly into
2308
     a single (non-Red Hat) RX relocation, but instead need
2309
     multiple RX relocations - handle them here.  */
2310
  switch (fixp->fx_r_type)
2311
    {
2312
    case BFD_RELOC_RX_DIFF:
2313
      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2314
 
2315
      reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2316
      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2317
      * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2318
      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2319
      reloc[1]->addend        = 0;
2320
      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2321
 
2322
      reloc[2]                = (arelent *) xmalloc (sizeof (arelent));
2323
      reloc[2]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2324
      reloc[2]->addend        = 0;
2325
      reloc[2]->sym_ptr_ptr   = reloc[1]->sym_ptr_ptr;
2326
      reloc[2]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2327
 
2328
      reloc[3]                = (arelent *) xmalloc (sizeof (arelent));
2329
      switch (fixp->fx_size)
2330
        {
2331
        case 1:
2332
          reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2333
          break;
2334
        case 2:
2335
          if (!is_opcode && target_big_endian)
2336
            reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
2337 163 khays
          else if (is_opcode)
2338
            reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2339 16 khays
          else
2340
            reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2341
          break;
2342
        case 4:
2343
          if (!is_opcode && target_big_endian)
2344
            reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
2345
          else
2346
            reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2347
          break;
2348
        }
2349
      reloc[3]->addend      = 0;
2350
      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2351
      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2352
 
2353
      reloc[4] = NULL;
2354
      break;
2355
 
2356
    case BFD_RELOC_RX_GPRELL:
2357
      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2358
 
2359
      reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2360
      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2361
      if (gp_symbol == NULL)
2362
        {
2363
          if (symbol_table_frozen)
2364
            {
2365
              symbolS * gp;
2366
 
2367
              gp = symbol_find ("__gp");
2368
              if (gp == NULL)
2369
                as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2370
              else
2371
                gp_symbol = symbol_get_bfdsym (gp);
2372
            }
2373
          else
2374
            gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2375
        }
2376
      * reloc[1]->sym_ptr_ptr = gp_symbol;
2377
      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2378
      reloc[1]->addend        = 0;
2379
      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2380
 
2381
      reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2382
      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2383
      reloc[2]->addend      = 0;
2384
      reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2385
      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2386
 
2387
      reloc[3]              = (arelent *) xmalloc (sizeof (arelent));
2388
      reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2389
      reloc[3]->addend      = 0;
2390
      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2391
      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2392
 
2393
      reloc[4] = NULL;
2394
      break;
2395
 
2396
    case BFD_RELOC_RX_GPRELW:
2397
      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2398
 
2399
      reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2400
      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2401
      if (gp_symbol == NULL)
2402
        {
2403
          if (symbol_table_frozen)
2404
            {
2405
              symbolS * gp;
2406
 
2407
              gp = symbol_find ("__gp");
2408
              if (gp == NULL)
2409
                as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2410
              else
2411
                gp_symbol = symbol_get_bfdsym (gp);
2412
            }
2413
          else
2414
            gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2415
        }
2416
      * reloc[1]->sym_ptr_ptr = gp_symbol;
2417
      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2418
      reloc[1]->addend        = 0;
2419
      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2420
 
2421
      reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2422
      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2423
      reloc[2]->addend      = 0;
2424
      reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2425
      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2426
 
2427
      reloc[3]              = (arelent *) xmalloc (sizeof (arelent));
2428
      reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2429
      reloc[3]->addend      = 0;
2430
      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2431
      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2432
 
2433
      reloc[4] = NULL;
2434
      break;
2435
 
2436
    case BFD_RELOC_RX_GPRELB:
2437
      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2438
 
2439
      reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2440
      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2441
      if (gp_symbol == NULL)
2442
        {
2443
          if (symbol_table_frozen)
2444
            {
2445
              symbolS * gp;
2446
 
2447
              gp = symbol_find ("__gp");
2448
              if (gp == NULL)
2449
                as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2450
              else
2451
                gp_symbol = symbol_get_bfdsym (gp);
2452
            }
2453
          else
2454
            gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2455
        }
2456
      * reloc[1]->sym_ptr_ptr = gp_symbol;
2457
      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2458
      reloc[1]->addend        = 0;
2459
      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2460
 
2461
      reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2462
      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2463
      reloc[2]->addend      = 0;
2464
      reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2465
      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2466
 
2467
      reloc[3]              = (arelent *) xmalloc (sizeof (arelent));
2468
      reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2469
      reloc[3]->addend      = 0;
2470
      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2471
      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2472
 
2473
      reloc[4] = NULL;
2474
      break;
2475
 
2476
    case BFD_RELOC_RX_NEG32:
2477
      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2478
 
2479
      reloc[1]              = (arelent *) xmalloc (sizeof (arelent));
2480
      reloc[1]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG);
2481
      reloc[1]->addend      = 0;
2482
      reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2483
      reloc[1]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2484
 
2485
      reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2486
      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2487
      reloc[2]->addend      = 0;
2488
      reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2489
      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2490
 
2491
      reloc[3] = NULL;
2492
      break;
2493
 
2494
    default:
2495
      reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2496
      reloc[1] = NULL;
2497
      break;
2498
    }
2499
 
2500
  return reloc;
2501
}
2502
 
2503
/* Set the ELF specific flags.  */
2504
 
2505
void
2506
rx_elf_final_processing (void)
2507
{
2508
  elf_elfheader (stdoutput)->e_flags |= elf_flags;
2509
}
2510
 
2511
/* Scan the current input line for occurances of Renesas
2512
   local labels and replace them with the GAS version.  */
2513
 
2514
void
2515
rx_start_line (void)
2516
{
2517
  int in_double_quote = 0;
2518
  int in_single_quote = 0;
2519
  int done = 0;
2520
  char * p = input_line_pointer;
2521
 
2522
  /* Scan the line looking for question marks.  Skip past quote enclosed regions.  */
2523
  do
2524
    {
2525
      switch (*p)
2526
        {
2527
        case '\n':
2528
        case 0:
2529
          done = 1;
2530
          break;
2531
 
2532
        case '"':
2533
          in_double_quote = ! in_double_quote;
2534
          break;
2535
 
2536
        case '\'':
2537
          in_single_quote = ! in_single_quote;
2538
          break;
2539
 
2540
        case '?':
2541
          if (in_double_quote || in_single_quote)
2542
            break;
2543
 
2544
          if (p[1] == ':')
2545
            *p = '1';
2546
          else if (p[1] == '+')
2547
            {
2548
              p[0] = '1';
2549
              p[1] = 'f';
2550
            }
2551
          else if (p[1] == '-')
2552
            {
2553
              p[0] = '1';
2554
              p[1] = 'b';
2555
            }
2556
          break;
2557
 
2558
        default:
2559
          break;
2560
        }
2561
 
2562
      p ++;
2563
    }
2564
  while (! done);
2565
}

powered by: WebSVN 2.1.0

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