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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 163 khays
/* tc-rl78.c -- Assembler for the Renesas RL78
2
   Copyright 2011
3
   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/rl78.h"
30
#include "rl78-defs.h"
31
#include "filenames.h"
32
#include "listing.h"
33
#include "sb.h"
34
#include "macro.h"
35
 
36
const char comment_chars[]        = ";";
37
/* Note that input_file.c hand checks for '#' at the beginning of the
38
   first line of the input file.  This is because the compiler outputs
39
   #NO_APP at the beginning of its output.  */
40
const char line_comment_chars[]   = "#";
41
const char line_separator_chars[] = "|";
42
 
43
const char EXP_CHARS[]            = "eE";
44
const char FLT_CHARS[]            = "dD";
45
 
46
/*------------------------------------------------------------------*/
47
 
48
char * rl78_lex_start;
49
char * rl78_lex_end;
50
 
51
typedef struct rl78_bytesT
52
{
53
  char prefix[1];
54
  int n_prefix;
55
  char base[4];
56
  int n_base;
57
  char ops[8];
58
  int n_ops;
59
  struct
60
  {
61
    expressionS  exp;
62
    char         offset;
63
    char         nbits;
64
    char         type; /* RL78REL_*.  */
65
    int          reloc;
66
    fixS *       fixP;
67
  } fixups[2];
68
  int n_fixups;
69
  struct
70
  {
71
    char type;
72
    char field_pos;
73
    char val_ofs;
74
  } relax[2];
75
  int n_relax;
76
  int link_relax;
77
  fixS *link_relax_fixP;
78
  char times_grown;
79
  char times_shrank;
80
} rl78_bytesT;
81
 
82
static rl78_bytesT rl78_bytes;
83
 
84 166 khays
void
85
rl78_linkrelax_addr16 (void)
86
{
87
  rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
88
}
89
 
90
void
91
rl78_linkrelax_branch (void)
92
{
93
  rl78_bytes.link_relax |= RL78_RELAXA_BRA;
94
}
95
 
96 163 khays
static void
97
rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
98
{
99
  rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp;
100
  rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits;
101
  rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits;
102
  rl78_bytes.fixups[rl78_bytes.n_fixups].type = type;
103
  rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md;
104
  rl78_bytes.n_fixups ++;
105
}
106
 
107
#define rl78_field_fixup(exp, offset, nbits, type)      \
108
  rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
109
 
110
#define rl78_op_fixup(exp, offset, nbits, type)         \
111
  rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
112
 
113
void
114
rl78_prefix (int p)
115
{
116
  rl78_bytes.prefix[0] = p;
117
  rl78_bytes.n_prefix = 1;
118
}
119
 
120
int
121
rl78_has_prefix ()
122
{
123
  return rl78_bytes.n_prefix;
124
}
125
 
126
void
127
rl78_base1 (int b1)
128
{
129
  rl78_bytes.base[0] = b1;
130
  rl78_bytes.n_base = 1;
131
}
132
 
133
void
134
rl78_base2 (int b1, int b2)
135
{
136
  rl78_bytes.base[0] = b1;
137
  rl78_bytes.base[1] = b2;
138
  rl78_bytes.n_base = 2;
139
}
140
 
141
void
142
rl78_base3 (int b1, int b2, int b3)
143
{
144
  rl78_bytes.base[0] = b1;
145
  rl78_bytes.base[1] = b2;
146
  rl78_bytes.base[2] = b3;
147
  rl78_bytes.n_base = 3;
148
}
149
 
150
void
151
rl78_base4 (int b1, int b2, int b3, int b4)
152
{
153
  rl78_bytes.base[0] = b1;
154
  rl78_bytes.base[1] = b2;
155
  rl78_bytes.base[2] = b3;
156
  rl78_bytes.base[3] = b4;
157
  rl78_bytes.n_base = 4;
158
}
159
 
160
#define F_PRECISION 2
161
 
162
void
163
rl78_op (expressionS exp, int nbytes, int type)
164
{
165
  int v = 0;
166
 
167
  if ((exp.X_op == O_constant || exp.X_op == O_big)
168
      && type != RL78REL_PCREL)
169
    {
170
      if (exp.X_op == O_big && exp.X_add_number <= 0)
171
        {
172
          LITTLENUM_TYPE w[2];
173
          char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
174
 
175
          gen_to_words (w, F_PRECISION, 8);
176
          ip[3] = w[0] >> 8;
177
          ip[2] = w[0];
178
          ip[1] = w[1] >> 8;
179
          ip[0] = w[1];
180
          rl78_bytes.n_ops += 4;
181
        }
182
      else
183
        {
184
          v = exp.X_add_number;
185
          while (nbytes)
186
            {
187
              rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
188
              v >>= 8;
189
              nbytes --;
190
            }
191
        }
192
    }
193
  else
194
    {
195
      rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
196
      memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
197
      rl78_bytes.n_ops += nbytes;
198
    }
199
}
200
 
201
/* This gets complicated when the field spans bytes, because fields
202
   are numbered from the MSB of the first byte as zero, and bits are
203
   stored LSB towards the LSB of the byte.  Thus, a simple four-bit
204
   insertion of 12 at position 4 of 0x00 yields: 0x0b.  A three-bit
205
   insertion of b'MXL at position 7 is like this:
206
 
207
     - - - -  - - - -   - - - -  - - - -
208
                    M   X L               */
209
 
210
void
211
rl78_field (int val, int pos, int sz)
212
{
213
  int valm;
214
  int bytep, bitp;
215
 
216
  if (sz > 0)
217
    {
218
      if (val < 0 || val >= (1 << sz))
219
        as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
220
    }
221
  else
222
    {
223
      sz = - sz;
224
      if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
225
        as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
226
    }
227
 
228
  /* This code points at 'M' in the above example.  */
229
  bytep = pos / 8;
230
  bitp = pos % 8;
231
 
232
  while (bitp + sz > 8)
233
    {
234
      int ssz = 8 - bitp;
235
      int svalm;
236
 
237
      svalm = val >> (sz - ssz);
238
      svalm = svalm & ((1 << ssz) - 1);
239
      svalm = svalm << (8 - bitp - ssz);
240
      gas_assert (bytep < rl78_bytes.n_base);
241
      rl78_bytes.base[bytep] |= svalm;
242
 
243
      bitp = 0;
244
      sz -= ssz;
245
      bytep ++;
246
    }
247
  valm = val & ((1 << sz) - 1);
248
  valm = valm << (8 - bitp - sz);
249
  gas_assert (bytep < rl78_bytes.n_base);
250
  rl78_bytes.base[bytep] |= valm;
251
}
252
 
253
/*------------------------------------------------------------------*/
254
 
255 166 khays
enum options
256
{
257
  OPTION_RELAX = OPTION_MD_BASE,
258
};
259
 
260 163 khays
#define RL78_SHORTOPTS ""
261
const char * md_shortopts = RL78_SHORTOPTS;
262
 
263
/* Assembler options.  */
264
struct option md_longopts[] =
265
{
266 166 khays
  {"relax", no_argument, NULL, OPTION_RELAX},
267 163 khays
  {NULL, no_argument, NULL, 0}
268
};
269
size_t md_longopts_size = sizeof (md_longopts);
270
 
271
int
272 166 khays
md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
273 163 khays
{
274 166 khays
  switch (c)
275
    {
276
    case OPTION_RELAX:
277
      linkrelax = 1;
278
      return 1;
279
 
280
    }
281 163 khays
  return 0;
282
}
283
 
284
void
285
md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
286
{
287
}
288
 
289
 
290
static void
291
s_bss (int ignore ATTRIBUTE_UNUSED)
292
{
293
  int temp;
294
 
295
  temp = get_absolute_expression ();
296
  subseg_set (bss_section, (subsegT) temp);
297
  demand_empty_rest_of_line ();
298
}
299
 
300
/* The target specific pseudo-ops which we support.  */
301
const pseudo_typeS md_pseudo_table[] =
302
{
303
  /* Our "standard" pseudos. */
304
  { "double",   float_cons,    'd' },
305
  { "bss",      s_bss,          0 },
306
  { "3byte",    cons,           3 },
307
  { "int",      cons,           4 },
308
  { "word",     cons,           4 },
309
 
310
  /* End of list marker.  */
311
  { NULL,       NULL,           0 }
312
};
313
 
314
void
315
md_begin (void)
316
{
317
}
318
 
319
void
320
rl78_md_end (void)
321
{
322
}
323
 
324
/* Write a value out to the object file, using the appropriate endianness.  */
325
void
326
md_number_to_chars (char * buf, valueT val, int n)
327
{
328
  number_to_chars_littleendian (buf, val, n);
329
}
330
 
331
static struct
332
{
333
  char * fname;
334
  int    reloc;
335
}
336
reloc_functions[] =
337
{
338
  { "lo16", BFD_RELOC_RL78_LO16 },
339
  { "hi16", BFD_RELOC_RL78_HI16 },
340
  { "hi8",  BFD_RELOC_RL78_HI8 },
341
  { 0, 0 }
342
};
343
 
344
void
345
md_operand (expressionS * exp ATTRIBUTE_UNUSED)
346
{
347
  int reloc = 0;
348
  int i;
349
 
350
  for (i = 0; reloc_functions[i].fname; i++)
351
    {
352
      int flen = strlen (reloc_functions[i].fname);
353
 
354
      if (input_line_pointer[0] == '%'
355
          && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
356
          && input_line_pointer[flen + 1] == '(')
357
        {
358
          reloc = reloc_functions[i].reloc;
359
          input_line_pointer += flen + 2;
360
          break;
361
        }
362
    }
363
  if (reloc == 0)
364
    return;
365
 
366
  expression (exp);
367
  if (* input_line_pointer == ')')
368
    input_line_pointer ++;
369
 
370
  exp->X_md = reloc;
371
}
372
 
373
void
374
rl78_frag_init (fragS * fragP)
375
{
376 166 khays
  if (rl78_bytes.n_relax || rl78_bytes.link_relax)
377
    {
378
      fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
379
      memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
380
    }
381
  else
382
    fragP->tc_frag_data = 0;
383 163 khays
}
384
 
385 166 khays
/* When relaxing, we need to output a reloc for any .align directive
386
   so that we can retain this alignment as we adjust opcode sizes.  */
387
void
388
rl78_handle_align (fragS * frag)
389
{
390
  if (linkrelax
391
      && (frag->fr_type == rs_align
392
          || frag->fr_type == rs_align_code)
393
      && frag->fr_address + frag->fr_fix > 0
394
      && frag->fr_offset > 0
395
      && now_seg != bss_section)
396
    {
397
      fix_new (frag, frag->fr_fix, 0,
398
               &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
399
               0, BFD_RELOC_RL78_RELAX);
400
      /* For the purposes of relaxation, this relocation is attached
401
         to the byte *after* the alignment - i.e. the byte that must
402
         remain aligned.  */
403
      fix_new (frag->fr_next, 0, 0,
404
               &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
405
               0, BFD_RELOC_RL78_RELAX);
406
    }
407
}
408
 
409 163 khays
char *
410
md_atof (int type, char * litP, int * sizeP)
411
{
412
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
413
}
414
 
415
symbolS *
416
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
417
{
418
  return NULL;
419
}
420
 
421
#define APPEND(B, N_B)                                 \
422
  if (rl78_bytes.N_B)                                  \
423
    {                                                  \
424
      memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B);  \
425
      idx += rl78_bytes.N_B;                           \
426
    }
427
 
428
 
429
void
430
md_assemble (char * str)
431
{
432
  char * bytes;
433
  fragS * frag_then = frag_now;
434
  int idx = 0;
435
  int i;
436
  int rel;
437
  expressionS  *exp;
438
 
439
  /*printf("\033[32mASM: %s\033[0m\n", str);*/
440
 
441
  dwarf2_emit_insn (0);
442
 
443
  memset (& rl78_bytes, 0, sizeof (rl78_bytes));
444
 
445
  rl78_lex_init (str, str + strlen (str));
446
 
447
  rl78_parse ();
448
 
449 166 khays
  /* This simplifies the relaxation code.  */
450
  if (rl78_bytes.link_relax)
451
    {
452
      int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
453
      /* We do it this way because we want the frag to have the
454
         rl78_bytes in it, which we initialize above.  */
455
      bytes = frag_more (olen);
456
      frag_then = frag_now;
457
      frag_variant (rs_machine_dependent,
458
                    olen /* max_chars */,
459
 
460
                    olen /* subtype */,
461
 
462
 
463
 
464
      frag_then->fr_opcode = bytes;
465
      frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
466
      frag_then->fr_subtype = olen;
467
      frag_then->fr_var = 0;
468
    }
469
  else
470
    {
471
      bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
472
      frag_then = frag_now;
473
    }
474 163 khays
 
475
  APPEND (prefix, n_prefix);
476
  APPEND (base, n_base);
477
  APPEND (ops, n_ops);
478
 
479 166 khays
  if (rl78_bytes.link_relax)
480
    {
481
      fixS * f;
482
 
483
      f = fix_new (frag_then,
484
                   (char *) bytes - frag_then->fr_literal,
485
                   0,
486
                   abs_section_sym,
487
                   rl78_bytes.link_relax | rl78_bytes.n_fixups,
488
                   0,
489
                   BFD_RELOC_RL78_RELAX);
490
      frag_then->tc_frag_data->link_relax_fixP = f;
491
    }
492
 
493 163 khays
  for (i = 0; i < rl78_bytes.n_fixups; i ++)
494
    {
495
      /* index: [nbytes][type] */
496
      static int reloc_map[5][4] =
497
        {
498
          { 0,            0 },
499
          { BFD_RELOC_8,  BFD_RELOC_8_PCREL },
500
          { BFD_RELOC_16, BFD_RELOC_16_PCREL },
501
          { BFD_RELOC_24, BFD_RELOC_24_PCREL },
502
          { BFD_RELOC_32, BFD_RELOC_32_PCREL },
503
        };
504
      fixS * f;
505
 
506
      idx = rl78_bytes.fixups[i].offset / 8;
507
      rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
508
 
509
      if (rl78_bytes.fixups[i].reloc)
510
        rel = rl78_bytes.fixups[i].reloc;
511
 
512
      if (frag_then->tc_frag_data)
513
        exp = & frag_then->tc_frag_data->fixups[i].exp;
514
      else
515
        exp = & rl78_bytes.fixups[i].exp;
516
 
517
      f = fix_new_exp (frag_then,
518
                       (char *) bytes + idx - frag_then->fr_literal,
519
                       rl78_bytes.fixups[i].nbits / 8,
520
                       exp,
521
                       rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
522
                       rel);
523
      if (frag_then->tc_frag_data)
524
        frag_then->tc_frag_data->fixups[i].fixP = f;
525
    }
526
}
527
 
528
void
529
rl78_cons_fix_new (fragS *      frag,
530
                 int            where,
531
                 int            size,
532
                 expressionS *  exp)
533
{
534
  bfd_reloc_code_real_type type;
535
 
536
  switch (size)
537
    {
538
    case 1:
539
      type = BFD_RELOC_8;
540
      break;
541
    case 2:
542
      type = BFD_RELOC_16;
543
      break;
544
    case 3:
545
      type = BFD_RELOC_24;
546
      break;
547
    case 4:
548
      type = BFD_RELOC_32;
549
      break;
550
    default:
551
      as_bad (_("unsupported constant size %d\n"), size);
552
      return;
553
    }
554
 
555
  if (exp->X_op == O_subtract && exp->X_op_symbol)
556
    {
557
      if (size != 4 && size != 2 && size != 1)
558
        as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
559
      else
560
        type = BFD_RELOC_RL78_DIFF;
561
    }
562
 
563
  fix_new_exp (frag, where, (int) size, exp, 0, type);
564
}
565
 
566
/* No relaxation just yet */
567
int
568
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
569
{
570
  return 0;
571
}
572 166 khays
 
573 163 khays
arelent **
574
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
575
{
576
  static arelent * reloc[8];
577
  int rp;
578
 
579
  if (fixp->fx_r_type == BFD_RELOC_NONE)
580
    {
581
      reloc[0] = NULL;
582
      return reloc;
583
    }
584
 
585
  if (fixp->fx_subsy
586
      && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
587
    {
588
      fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
589
      fixp->fx_subsy = NULL;
590
    }
591
 
592
  reloc[0]                 = (arelent *) xmalloc (sizeof (arelent));
593
  reloc[0]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
594
  * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
595
  reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
596
  reloc[0]->addend        = fixp->fx_offset;
597
 
598
  if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
599
      && fixp->fx_subsy)
600
    {
601
      fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
602
    }
603
 
604
#define OPX(REL,SYM,ADD)                                                        \
605
  reloc[rp]                = (arelent *) xmalloc (sizeof (arelent));            \
606
  reloc[rp]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));         \
607
  reloc[rp]->howto         = bfd_reloc_type_lookup (stdoutput, REL);            \
608
  reloc[rp]->addend        = ADD;                                               \
609
  * reloc[rp]->sym_ptr_ptr = SYM;                                               \
610
  reloc[rp]->address       = fixp->fx_frag->fr_address + fixp->fx_where;        \
611
  reloc[++rp] = NULL
612
#define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
613
#define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
614
#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
615
#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
616
 
617
  rp = 1;
618
 
619
  /* Certain BFD relocations cannot be translated directly into
620
     a single (non-Red Hat) RL78 relocation, but instead need
621
     multiple RL78 relocations - handle them here.  */
622
  switch (fixp->fx_r_type)
623
    {
624
    case BFD_RELOC_RL78_DIFF:
625
      SYM0 ();
626
      OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
627
      OP(OP_SUBTRACT);
628
 
629
      switch (fixp->fx_size)
630
        {
631
        case 1:
632
          OP(ABS8);
633
          break;
634
        case 2:
635
          OP (ABS16);
636
          break;
637
        case 4:
638
          OP (ABS32);
639
          break;
640
        }
641
      break;
642
 
643
    case BFD_RELOC_RL78_NEG32:
644
      SYM0 ();
645
      OP (OP_NEG);
646
      OP (ABS32);
647
      break;
648
 
649
    case BFD_RELOC_RL78_LO16:
650
      SYM0 ();
651
      OPIMM (0xffff);
652
      OP (OP_AND);
653
      OP (ABS16);
654
      break;
655
 
656
    case BFD_RELOC_RL78_HI16:
657
      SYM0 ();
658
      OPIMM (16);
659
      OP (OP_SHRA);
660
      OP (ABS16);
661
      break;
662
 
663
    case BFD_RELOC_RL78_HI8:
664
      SYM0 ();
665
      OPIMM (16);
666
      OP (OP_SHRA);
667
      OPIMM (0xff);
668
      OP (OP_AND);
669
      OP (ABS8);
670
      break;
671
 
672
    default:
673
      reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
674
      reloc[1] = NULL;
675
      break;
676
    }
677
 
678
  return reloc;
679
}
680
 
681
int
682
rl78_validate_fix_sub (struct fix * f)
683
{
684
  /* We permit the subtraction of two symbols in a few cases.  */
685
  /* mov #sym1-sym2, R3 */
686
  if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
687
    return 1;
688
  /* .long sym1-sym2 */
689
  if (f->fx_r_type == BFD_RELOC_RL78_DIFF
690
      && ! f->fx_pcrel
691
      && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
692
    return 1;
693
  return 0;
694
}
695
 
696
long
697
md_pcrel_from_section (fixS * fixP, segT sec)
698
{
699
  long rv;
700
 
701
  if (fixP->fx_addsy != NULL
702
      && (! S_IS_DEFINED (fixP->fx_addsy)
703
          || S_GET_SEGMENT (fixP->fx_addsy) != sec))
704
    /* The symbol is undefined (or is defined but not in this section).
705
       Let the linker figure it out.  */
706
    return 0;
707
 
708
  rv = fixP->fx_frag->fr_address + fixP->fx_where;
709
  switch (fixP->fx_r_type)
710
    {
711
    case BFD_RELOC_8_PCREL:
712
      rv += 1;
713
      break;
714
    case BFD_RELOC_16_PCREL:
715
      rv += 2;
716
      break;
717
    default:
718
      break;
719
    }
720
  return rv;
721
}
722
 
723
void
724
md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
725
              valueT *     t ATTRIBUTE_UNUSED,
726
              segT         s ATTRIBUTE_UNUSED)
727
{
728
  char * op;
729
  unsigned long val;
730
 
731
  if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
732
    return;
733
  if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
734
    return;
735
 
736
  op = f->fx_frag->fr_literal + f->fx_where;
737
  val = (unsigned long) * t;
738
 
739
  switch (f->fx_r_type)
740
    {
741
    case BFD_RELOC_NONE:
742
      break;
743
 
744 166 khays
    case BFD_RELOC_RL78_RELAX:
745
      f->fx_done = 1;
746
      break;
747
 
748 163 khays
    case BFD_RELOC_8:
749
    case BFD_RELOC_8_PCREL:
750
      op[0] = val;
751
      break;
752
 
753
    case BFD_RELOC_16:
754
    case BFD_RELOC_16_PCREL:
755
      op[0] = val;
756
      op[1] = val >> 8;
757
      break;
758
 
759
    case BFD_RELOC_24:
760
      op[0] = val;
761
      op[1] = val >> 8;
762
      op[2] = val >> 16;
763
      break;
764
 
765
    case BFD_RELOC_32:
766
    case BFD_RELOC_RL78_DIFF:
767
      op[0] = val;
768
      op[1] = val >> 8;
769
      op[2] = val >> 16;
770
      op[3] = val >> 24;
771
      break;
772
 
773
    default:
774
      as_bad (_("Unknown reloc in md_apply_fix: %s"),
775
              bfd_get_reloc_code_name (f->fx_r_type));
776
      break;
777
    }
778
 
779
  if (f->fx_addsy == NULL)
780
    f->fx_done = 1;
781
}
782
 
783
valueT
784
md_section_align (segT segment, valueT size)
785
{
786
  int align = bfd_get_section_alignment (stdoutput, segment);
787
  return ((size + (1 << align) - 1) & (-1 << align));
788
}
789
 
790
void
791
md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
792
                 segT    segment ATTRIBUTE_UNUSED,
793
                 fragS * fragP ATTRIBUTE_UNUSED)
794
{
795
  /* No relaxation yet */
796 166 khays
  fragP->fr_var = 0;
797 163 khays
}

powered by: WebSVN 2.1.0

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