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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-m32c.c] - Blame information for rev 438

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

Line No. Rev Author Line
1 205 julius
/* tc-m32c.c -- Assembler for the Renesas M32C.
2
   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation.
3
   Contributed by RedHat.
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
19
   the Free Software Foundation, 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "as.h"
23
#include "subsegs.h"     
24
#include "symcat.h"
25
#include "opcodes/m32c-desc.h"
26
#include "opcodes/m32c-opc.h"
27
#include "cgen.h"
28
#include "elf/common.h"
29
#include "elf/m32c.h"
30
#include "libbfd.h"
31
#include "safe-ctype.h"
32
 
33
/* Structure to hold all of the different components
34
   describing an individual instruction.  */
35
typedef struct
36
{
37
  const CGEN_INSN *     insn;
38
  const CGEN_INSN *     orig_insn;
39
  CGEN_FIELDS           fields;
40
#if CGEN_INT_INSN_P
41
  CGEN_INSN_INT         buffer [1];
42
#define INSN_VALUE(buf) (*(buf))
43
#else
44
  unsigned char         buffer [CGEN_MAX_INSN_SIZE];
45
#define INSN_VALUE(buf) (buf)
46
#endif
47
  char *                addr;
48
  fragS *               frag;
49
  int                   num_fixups;
50
  fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
51
  int                   indices [MAX_OPERAND_INSTANCES];
52
}
53
m32c_insn;
54
 
55
#define rl_for(_insn) (CGEN_ATTR_CGEN_INSN_RL_TYPE_VALUE (&((_insn).insn->base->attrs)))
56
#define relaxable(_insn) (CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE (&((_insn).insn->base->attrs)))
57
 
58
const char comment_chars[]        = ";";
59
const char line_comment_chars[]   = "#";
60
const char line_separator_chars[] = "|";
61
const char EXP_CHARS[]            = "eE";
62
const char FLT_CHARS[]            = "dD";
63
 
64
#define M32C_SHORTOPTS ""
65
const char * md_shortopts = M32C_SHORTOPTS;
66
 
67
/* assembler options */
68
#define OPTION_CPU_M16C        (OPTION_MD_BASE)
69
#define OPTION_CPU_M32C        (OPTION_MD_BASE + 1)
70
#define OPTION_LINKRELAX       (OPTION_MD_BASE + 2)
71
#define OPTION_H_TICK_HEX      (OPTION_MD_BASE + 3)
72
 
73
struct option md_longopts[] =
74
{
75
  { "m16c",       no_argument,        NULL, OPTION_CPU_M16C   },
76
  { "m32c",       no_argument,        NULL, OPTION_CPU_M32C   },
77
  { "relax",      no_argument,        NULL, OPTION_LINKRELAX   },
78
  { "h-tick-hex", no_argument,        NULL, OPTION_H_TICK_HEX  },
79
  {NULL, no_argument, NULL, 0}
80
};
81
size_t md_longopts_size = sizeof (md_longopts);
82
 
83
/* Default machine */
84
 
85
#define DEFAULT_MACHINE bfd_mach_m16c
86
#define DEFAULT_FLAGS   EF_M32C_CPU_M16C
87
 
88
static unsigned long m32c_mach = bfd_mach_m16c;
89
static int cpu_mach = (1 << MACH_M16C);
90
static int insn_size;
91
static int m32c_relax = 0;
92
 
93
/* Flags to set in the elf header */
94
static flagword m32c_flags = DEFAULT_FLAGS;
95
 
96
static char default_isa = 1 << (7 - ISA_M16C);
97
static CGEN_BITSET m32c_isa = {1, & default_isa};
98
 
99
static void
100
set_isa (enum isa_attr isa_num)
101
{
102
  cgen_bitset_set (& m32c_isa, isa_num);
103
}
104
 
105
static void s_bss (int);
106
 
107
int
108
md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
109
{
110
  switch (c)
111
    {
112
    case OPTION_CPU_M16C:
113
      m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M16C;
114
      m32c_mach = bfd_mach_m16c;
115
      cpu_mach = (1 << MACH_M16C);
116
      set_isa (ISA_M16C);
117
      break;
118
 
119
    case OPTION_CPU_M32C:
120
      m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M32C;
121
      m32c_mach = bfd_mach_m32c;
122
      cpu_mach = (1 << MACH_M32C);
123
      set_isa (ISA_M32C);
124
      break;
125
 
126
    case OPTION_LINKRELAX:
127
      m32c_relax = 1;
128
      break;
129
 
130
    case OPTION_H_TICK_HEX:
131
      enable_h_tick_hex = 1;
132
      break;
133
 
134
    default:
135
      return 0;
136
    }
137
  return 1;
138
}
139
 
140
void
141
md_show_usage (FILE * stream)
142
{
143
  fprintf (stream, _(" M32C specific command line options:\n"));
144
}
145
 
146
static void
147
s_bss (int ignore ATTRIBUTE_UNUSED)
148
{
149
  int temp;
150
 
151
  temp = get_absolute_expression ();
152
  subseg_set (bss_section, (subsegT) temp);
153
  demand_empty_rest_of_line ();
154
}
155
 
156
/* The target specific pseudo-ops which we support.  */
157
const pseudo_typeS md_pseudo_table[] =
158
{
159
  { "bss",      s_bss,          0},
160
  { "3byte",    cons,           3 },
161
  { "word",     cons,           4 },
162
  {"file",      (void (*) (int)) dwarf2_directive_file, 0},
163
  {"loc",       dwarf2_directive_loc, 0},
164
  {"loc_mark_labels", dwarf2_directive_loc_mark_labels, 0},
165
  { NULL,       NULL,           0 }
166
};
167
 
168
 
169
void
170
md_begin (void)
171
{
172
  /* Initialize the `cgen' interface.  */
173
 
174
  /* Set the machine number and endian.  */
175
  gas_cgen_cpu_desc = m32c_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach,
176
                                          CGEN_CPU_OPEN_ENDIAN,
177
                                          CGEN_ENDIAN_BIG,
178
                                          CGEN_CPU_OPEN_ISAS, & m32c_isa,
179
                                          CGEN_CPU_OPEN_END);
180
 
181
  m32c_cgen_init_asm (gas_cgen_cpu_desc);
182
 
183
  /* This is a callback from cgen to gas to parse operands.  */
184
  cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
185
 
186
  /* Set the ELF flags if desired. */
187
  if (m32c_flags)
188
    bfd_set_private_flags (stdoutput, m32c_flags);
189
 
190
  /* Set the machine type */
191
  bfd_default_set_arch_mach (stdoutput, bfd_arch_m32c, m32c_mach);
192
 
193
  insn_size = 0;
194
}
195
 
196
void
197
m32c_md_end (void)
198
{
199
  int i, n_nops;
200
 
201
  if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
202
    {
203
      /* Pad with nops for objdump.  */
204
      n_nops = (32 - ((insn_size) % 32)) / 8;
205
      for (i = 1; i <= n_nops; i++)
206
        md_assemble ("nop");
207
    }
208
}
209
 
210
void
211
m32c_start_line_hook (void)
212
{
213
#if 0 /* not necessary....handled in the .cpu file */
214
  char *s = input_line_pointer;
215
  char *sg;
216
 
217
  for (s = input_line_pointer ; s && s[0] != '\n'; s++)
218
    {
219
      if (s[0] == ':')
220
        {
221
          /* Remove :g suffix.  Squeeze out blanks.  */
222
          if (s[1] == 'g')
223
            {
224
              for (sg = s - 1; sg && sg >= input_line_pointer; sg--)
225
                {
226
                  sg[2] = sg[0];
227
                }
228
              sg[1] = ' ';
229
              sg[2] = ' ';
230
              input_line_pointer += 2;
231
            }
232
        }
233
    }
234
#endif
235
}
236
 
237
/* Process [[indirect-operands]] in instruction str.  */
238
 
239
static bfd_boolean
240
m32c_indirect_operand (char *str)
241
{
242
  char *new_str;
243
  char *s;
244
  char *ns;
245
  int ns_len;
246
  char *ns_end;
247
  enum indirect_type {none, relative, absolute} ;
248
  enum indirect_type indirection [3] = { none, none, none };
249
  int brace_n [3] = { 0, 0, 0 };
250
  int operand;
251
 
252
  s = str;
253
  operand = 1;
254
  for (s = str; *s; s++)
255
    {
256
      if (s[0] == ',')
257
        operand = 2;
258
      /* [abs] where abs is not a0 or a1  */
259
      if (s[1] == '[' && ! (s[2] == 'a' && (s[3] == '0' || s[3] == '1'))
260
          && (ISBLANK (s[0]) || s[0] == ','))
261
        indirection[operand] = absolute;
262
      if (s[0] == ']' && s[1] == ']')
263
        indirection[operand] = relative;
264
      if (s[0] == '[' && s[1] == '[')
265
        indirection[operand] = relative;
266
    }
267
 
268
  if (indirection[1] == none && indirection[2] == none)
269
    return FALSE;
270
 
271
  operand = 1;
272
  ns_len = strlen (str);
273
  new_str = (char*) xmalloc (ns_len);
274
  ns = new_str;
275
  ns_end = ns + ns_len;
276
 
277
  for (s = str; *s; s++)
278
    {
279
      if (s[0] == ',')
280
        operand = 2;
281
 
282
      if (s[0] == '[' && ! brace_n[operand])
283
        {
284
          brace_n[operand] += 1;
285
          /* Squeeze [[ to [ if this is an indirect operand.  */
286
          if (indirection[operand] != none)
287
            continue;
288
        }
289
 
290
      else if (s[0] == '[' && brace_n[operand])
291
        {
292
          brace_n[operand] += 1;
293
        }
294
      else if (s[0] == ']' && s[1] == ']' && indirection[operand] == relative)
295
        {
296
          s += 1;               /* skip one ].  */
297
          brace_n[operand] -= 2; /* allow for 2 [.  */
298
        }
299
      else if (s[0] == ']' && indirection[operand] == absolute)
300
        {
301
          brace_n[operand] -= 1;
302
          continue;             /* skip closing ].  */
303
        }
304
      else if (s[0] == ']')
305
        {
306
          brace_n[operand] -= 1;
307
        }
308
      *ns = s[0];
309
      ns += 1;
310
      if (ns >= ns_end)
311
        return FALSE;
312
      if (s[0] == 0)
313
        break;
314
    }
315
  *ns = '\0';
316
  for (operand = 1; operand <= 2; operand++)
317
    if (brace_n[operand])
318
      {
319
        fprintf (stderr, "Unmatched [[operand-%d]] %d\n", operand, brace_n[operand]);
320
      }
321
 
322
  if (indirection[1] != none && indirection[2] != none)
323
    md_assemble ("src-dest-indirect");
324
  else if (indirection[1] != none)
325
    md_assemble ("src-indirect");
326
  else if (indirection[2] != none)
327
    md_assemble ("dest-indirect");
328
 
329
  md_assemble (new_str);
330
  free (new_str);
331
  return TRUE;
332
}
333
 
334
void
335
md_assemble (char * str)
336
{
337
  static int last_insn_had_delay_slot = 0;
338
  m32c_insn insn;
339
  char *    errmsg;
340
  finished_insnS results;
341
  int rl_type;
342
 
343
  if (m32c_mach == bfd_mach_m32c && m32c_indirect_operand (str))
344
    return;
345
 
346
  /* Initialize GAS's cgen interface for a new instruction.  */
347
  gas_cgen_init_parse ();
348
 
349
  insn.insn = m32c_cgen_assemble_insn
350
    (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
351
 
352
  if (!insn.insn)
353
    {
354
      as_bad ("%s", errmsg);
355
      return;
356
    }
357
 
358
  results.num_fixups = 0;
359
  /* Doesn't really matter what we pass for RELAX_P here.  */
360
  gas_cgen_finish_insn (insn.insn, insn.buffer,
361
                        CGEN_FIELDS_BITSIZE (& insn.fields), 1, &results);
362
 
363
  last_insn_had_delay_slot
364
    = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
365
  insn_size = CGEN_INSN_BITSIZE(insn.insn);
366
 
367
  rl_type = rl_for (insn);
368
 
369
  /* We have to mark all the jumps, because we need to adjust them
370
     when we delete bytes, but we only need to mark the displacements
371
     if they're symbolic - if they're not, we've already picked the
372
     shortest opcode by now.  The linker, however, will still have to
373
     check any operands to see if they're the displacement type, since
374
     we don't know (nor record) *which* operands are relaxable.  */
375
  if (m32c_relax
376
      && rl_type != RL_TYPE_NONE
377
      && (rl_type == RL_TYPE_JUMP || results.num_fixups)
378
      && !relaxable (insn))
379
    {
380
      int reloc = 0;
381
      int addend = results.num_fixups + 16 * insn_size/8;
382
 
383
      switch (rl_for (insn))
384
        {
385
        case RL_TYPE_JUMP:  reloc = BFD_RELOC_M32C_RL_JUMP;  break;
386
        case RL_TYPE_1ADDR: reloc = BFD_RELOC_M32C_RL_1ADDR; break;
387
        case RL_TYPE_2ADDR: reloc = BFD_RELOC_M32C_RL_2ADDR; break;
388
        }
389
      if (insn.insn->base->num == M32C_INSN_JMP16_S
390
          || insn.insn->base->num == M32C_INSN_JMP32_S)
391
        addend = 0x10;
392
 
393
      fix_new (results.frag,
394
               results.addr - results.frag->fr_literal,
395
               0, abs_section_sym, addend, 0,
396
               reloc);
397
    }
398
}
399
 
400
/* The syntax in the manual says constants begin with '#'.
401
   We just ignore it.  */
402
 
403
void
404
md_operand (expressionS * exp)
405
{
406
  /* In case of a syntax error, escape back to try next syntax combo. */
407
  if (exp->X_op == O_absent)
408
    gas_cgen_md_operand (exp);
409
}
410
 
411
valueT
412
md_section_align (segT segment, valueT size)
413
{
414
  int align = bfd_get_section_alignment (stdoutput, segment);
415
  return ((size + (1 << align) - 1) & (-1 << align));
416
}
417
 
418
symbolS *
419
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
420
{
421
  return 0;
422
}
423
 
424
const relax_typeS md_relax_table[] =
425
{
426
  /* The fields are:
427
     1) most positive reach of this state,
428
     2) most negative reach of this state,
429
     3) how many bytes this mode will have in the variable part of the frag
430
     4) which index into the table to try if we can't fit into this one.  */
431
 
432
  /* 0 */ {     0,      0, 0,  0 }, /* unused */
433
  /* 1 */ {     0,      0, 0,  0 }, /* marker for "don't know yet" */
434
 
435
  /* 2 */ {   127,   -128, 2,  3 }, /* jcnd16_5.b */
436
  /* 3 */ { 32767, -32768, 5,  4 }, /* jcnd16_5.w */
437
  /* 4 */ {     0,      0, 6,  0 }, /* jcnd16_5.a */
438
 
439
  /* 5 */ {   127,   -128, 2,  6 }, /* jcnd16.b */
440
  /* 6 */ { 32767, -32768, 5,  7 }, /* jcnd16.w */
441
  /* 7 */ {     0,      0, 6,  0 }, /* jcnd16.a */
442
 
443
  /* 8 */ {     8,      1, 1,  9 }, /* jmp16.s */
444
  /* 9 */ {   127,   -128, 2, 10 }, /* jmp16.b */
445
 /* 10 */ { 32767, -32768, 3, 11 }, /* jmp16.w */
446
 /* 11 */ {     0,      0, 4,  0 }, /* jmp16.a */
447
 
448
 /* 12 */ {   127,   -128, 2, 13 }, /* jcnd32.b */
449
 /* 13 */ { 32767, -32768, 5, 14 }, /* jcnd32.w */
450
 /* 14 */ {     0,      0, 6,  0 }, /* jcnd32.a */
451
 
452
 /* 15 */ {     8,      1, 1, 16 }, /* jmp32.s */
453
 /* 16 */ {   127,   -128, 2, 17 }, /* jmp32.b */
454
 /* 17 */ { 32767, -32768, 3, 18 }, /* jmp32.w */
455
 /* 18 */ {     0,      0, 4,  0 }, /* jmp32.a */
456
 
457
 /* 19 */ { 32767, -32768, 3, 20 }, /* jsr16.w */
458
 /* 20 */ {     0,      0, 4,  0 }, /* jsr16.a */
459
 /* 21 */ { 32767, -32768, 3, 11 }, /* jsr32.w */
460
 /* 22 */ {     0,      0, 4,  0 }, /* jsr32.a */
461
 
462
 /* 23 */ {     0,      0, 3,  0 }, /* adjnz pc8 */
463
 /* 24 */ {     0,      0, 4,  0 }, /* adjnz disp8 pc8 */
464
 /* 25 */ {     0,      0, 5,  0 }, /* adjnz disp16 pc8 */
465
 /* 26 */ {     0,      0, 6,  0 }  /* adjnz disp24 pc8 */
466
};
467
 
468
enum {
469
  M32C_MACRO_JCND16_5_W,
470
  M32C_MACRO_JCND16_5_A,
471
  M32C_MACRO_JCND16_W,
472
  M32C_MACRO_JCND16_A,
473
  M32C_MACRO_JCND32_W,
474
  M32C_MACRO_JCND32_A,
475
  /* the digit is the array index of the pcrel byte */
476
  M32C_MACRO_ADJNZ_2,
477
  M32C_MACRO_ADJNZ_3,
478
  M32C_MACRO_ADJNZ_4,
479
  M32C_MACRO_ADJNZ_5,
480
} M32C_Macros;
481
 
482
static struct {
483
  int insn;
484
  int bytes;
485
  int insn_for_extern;
486
  int pcrel_aim_offset;
487
} subtype_mappings[] = {
488
  /* 0 */ { 0, 0, 0, 0 },
489
  /* 1 */ { 0, 0, 0, 0 },
490
 
491
  /* 2 */ {  M32C_INSN_JCND16_5,    2, -M32C_MACRO_JCND16_5_A, 1 },
492
  /* 3 */ { -M32C_MACRO_JCND16_5_W, 5, -M32C_MACRO_JCND16_5_A, 4 },
493
  /* 4 */ { -M32C_MACRO_JCND16_5_A, 6, -M32C_MACRO_JCND16_5_A, 0 },
494
 
495
  /* 5 */ {  M32C_INSN_JCND16,      3, -M32C_MACRO_JCND16_A,   1 },
496
  /* 6 */ { -M32C_MACRO_JCND16_W,   6, -M32C_MACRO_JCND16_A,   4 },
497
  /* 7 */ { -M32C_MACRO_JCND16_A,   7, -M32C_MACRO_JCND16_A,   0 },
498
 
499
  /* 8 */ {  M32C_INSN_JMP16_S,     1, M32C_INSN_JMP16_A,     0 },
500
  /* 9 */ {  M32C_INSN_JMP16_B,     2, M32C_INSN_JMP16_A,     1 },
501
 /* 10 */ {  M32C_INSN_JMP16_W,     3, M32C_INSN_JMP16_A,     2 },
502
 /* 11 */ {  M32C_INSN_JMP16_A,     4, M32C_INSN_JMP16_A,     0 },
503
 
504
 /* 12 */ {  M32C_INSN_JCND32,      2, -M32C_MACRO_JCND32_A,   1 },
505
 /* 13 */ { -M32C_MACRO_JCND32_W,   5, -M32C_MACRO_JCND32_A,   4 },
506
 /* 14 */ { -M32C_MACRO_JCND32_A,   6, -M32C_MACRO_JCND32_A,   0 },
507
 
508
 /* 15 */ {  M32C_INSN_JMP32_S,     1, M32C_INSN_JMP32_A,     0 },
509
 /* 16 */ {  M32C_INSN_JMP32_B,     2, M32C_INSN_JMP32_A,     1 },
510
 /* 17 */ {  M32C_INSN_JMP32_W,     3, M32C_INSN_JMP32_A,     2 },
511
 /* 18 */ {  M32C_INSN_JMP32_A,     4, M32C_INSN_JMP32_A,     0 },
512
 
513
 /* 19 */ {  M32C_INSN_JSR16_W,     3, M32C_INSN_JSR16_A,     2 },
514
 /* 20 */ {  M32C_INSN_JSR16_A,     4, M32C_INSN_JSR16_A,     0 },
515
 /* 21 */ {  M32C_INSN_JSR32_W,     3, M32C_INSN_JSR32_A,     2 },
516
 /* 22 */ {  M32C_INSN_JSR32_A,     4, M32C_INSN_JSR32_A,     0 },
517
 
518
 /* 23 */ { -M32C_MACRO_ADJNZ_2,    3, -M32C_MACRO_ADJNZ_2,    0 },
519
 /* 24 */ { -M32C_MACRO_ADJNZ_3,    4, -M32C_MACRO_ADJNZ_3,    0 },
520
 /* 25 */ { -M32C_MACRO_ADJNZ_4,    5, -M32C_MACRO_ADJNZ_4,    0 },
521
 /* 26 */ { -M32C_MACRO_ADJNZ_5,    6, -M32C_MACRO_ADJNZ_5,    0 }
522
};
523
#define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
524
 
525
void
526
m32c_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state)
527
{
528
  symbolS *symbolP = fragP->fr_symbol;
529
  if (symbolP && !S_IS_DEFINED (symbolP))
530
    *aim = 0;
531
  /* Adjust for m32c pcrel not being relative to the next opcode.  */
532
  *aim += subtype_mappings[this_state].pcrel_aim_offset;
533
}
534
 
535
static int
536
insn_to_subtype (int inum, const CGEN_INSN *insn)
537
{
538
  unsigned int i;
539
 
540
  if (insn
541
      && (strncmp (insn->base->mnemonic, "adjnz", 5) == 0
542
          || strncmp (insn->base->mnemonic, "sbjnz", 5) == 0))
543
    {
544
      i = 23 + insn->base->bitsize/8 - 3;
545
      /*printf("mapping %d used for %s\n", i, insn->base->mnemonic);*/
546
      return i;
547
    }
548
 
549
  for (i=0; i<NUM_MAPPINGS; i++)
550
    if (inum == subtype_mappings[i].insn)
551
      {
552
        /*printf("mapping %d used\n", i);*/
553
        return i;
554
      }
555
  abort ();
556
}
557
 
558
/* Return an initial guess of the length by which a fragment must grow to
559
   hold a branch to reach its destination.
560
   Also updates fr_type/fr_subtype as necessary.
561
 
562
   Called just before doing relaxation.
563
   Any symbol that is now undefined will not become defined.
564
   The guess for fr_var is ACTUALLY the growth beyond fr_fix.
565
   Whatever we do to grow fr_fix or fr_var contributes to our returned value.
566
   Although it may not be explicit in the frag, pretend fr_var starts with a
567
 
568
 
569
int
570
md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
571
{
572
  int where = fragP->fr_opcode - fragP->fr_literal;
573
 
574
  if (fragP->fr_subtype == 1)
575
    fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num, fragP->fr_cgen.insn);
576
 
577
  if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
578
    {
579
      int new_insn;
580
 
581
      new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern;
582
      fragP->fr_subtype = insn_to_subtype (new_insn, 0);
583
    }
584
 
585
  if (fragP->fr_cgen.insn->base
586
      && fragP->fr_cgen.insn->base->num
587
         != subtype_mappings[fragP->fr_subtype].insn
588
      && subtype_mappings[fragP->fr_subtype].insn > 0)
589
    {
590
      int new_insn= subtype_mappings[fragP->fr_subtype].insn;
591
      if (new_insn >= 0)
592
        {
593
          fragP->fr_cgen.insn = (fragP->fr_cgen.insn
594
                                 - fragP->fr_cgen.insn->base->num
595
                                 + new_insn);
596
        }
597
    }
598
 
599
  return subtype_mappings[fragP->fr_subtype].bytes - (fragP->fr_fix - where);
600
}
601
 
602
/* *fragP has been relaxed to its final size, and now needs to have
603
   the bytes inside it modified to conform to the new size.
604
 
605
   Called after relaxation is finished.
606
   fragP->fr_type == rs_machine_dependent.
607
   fragP->fr_subtype is the subtype of what the address relaxed to.  */
608
 
609
static int
610
target_address_for (fragS *frag)
611
{
612
  int rv = frag->fr_offset;
613
  symbolS *sym = frag->fr_symbol;
614
 
615
  if (sym)
616
    rv += S_GET_VALUE (sym);
617
 
618
  /*printf("target_address_for returns %d\n", rv);*/
619
  return rv;
620
}
621
 
622
void
623
md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
624
                 segT    sec ATTRIBUTE_UNUSED,
625
                 fragS * fragP ATTRIBUTE_UNUSED)
626
{
627
  int addend;
628
  int operand;
629
  int new_insn;
630
  int where = fragP->fr_opcode - fragP->fr_literal;
631
  int rl_where = fragP->fr_opcode - fragP->fr_literal;
632
  unsigned char *op = (unsigned char *)fragP->fr_opcode;
633
  int op_base = 0;
634
  int op_op = 0;
635
  int rl_addend = 0;
636
 
637
  addend = target_address_for (fragP) - (fragP->fr_address + where);
638
  new_insn = subtype_mappings[fragP->fr_subtype].insn;
639
 
640
  fragP->fr_fix = where + subtype_mappings[fragP->fr_subtype].bytes;
641
 
642
  op_base = 0;
643
 
644
  switch (subtype_mappings[fragP->fr_subtype].insn)
645
    {
646
    case M32C_INSN_JCND16_5:
647
      op[1] = addend - 1;
648
      operand = M32C_OPERAND_LAB_8_8;
649
      op_op = 1;
650
      rl_addend = 0x21;
651
      break;
652
 
653
    case -M32C_MACRO_JCND16_5_W:
654
      op[0] ^= 0x04;
655
      op[1] = 4;
656
      op[2] = 0xf4;
657
      op[3] = addend - 3;
658
      op[4] = (addend - 3) >> 8;
659
      operand = M32C_OPERAND_LAB_8_16;
660
      where += 2;
661
      new_insn = M32C_INSN_JMP16_W;
662
      op_base = 2;
663
      op_op = 3;
664
      rl_addend = 0x51;
665
      break;
666
 
667
    case -M32C_MACRO_JCND16_5_A:
668
      op[0] ^= 0x04;
669
      op[1] = 5;
670
      op[2] = 0xfc;
671
      operand = M32C_OPERAND_LAB_8_24;
672
      where += 2;
673
      new_insn = M32C_INSN_JMP16_A;
674
      op_base = 2;
675
      op_op = 3;
676
      rl_addend = 0x61;
677
      break;
678
 
679
 
680
    case M32C_INSN_JCND16:
681
      op[2] = addend - 2;
682
      operand = M32C_OPERAND_LAB_16_8;
683
      op_base = 0;
684
      op_op = 2;
685
      rl_addend = 0x31;
686
      break;
687
 
688
    case -M32C_MACRO_JCND16_W:
689
      op[1] ^= 0x04;
690
      op[2] = 4;
691
      op[3] = 0xf4;
692
      op[4] = addend - 4;
693
      op[5] = (addend - 4) >> 8;
694
      operand = M32C_OPERAND_LAB_8_16;
695
      where += 3;
696
      new_insn = M32C_INSN_JMP16_W;
697
      op_base = 3;
698
      op_op = 4;
699
      rl_addend = 0x61;
700
      break;
701
 
702
    case -M32C_MACRO_JCND16_A:
703
      op[1] ^= 0x04;
704
      op[2] = 5;
705
      op[3] = 0xfc;
706
      operand = M32C_OPERAND_LAB_8_24;
707
      where += 3;
708
      new_insn = M32C_INSN_JMP16_A;
709
      op_base = 3;
710
      op_op = 4;
711
      rl_addend = 0x71;
712
      break;
713
 
714
    case M32C_INSN_JMP16_S:
715
      op[0] = 0x60 | ((addend-2) & 0x07);
716
      operand = M32C_OPERAND_LAB_5_3;
717
      op_base = 0;
718
      op_op = 0;
719
      rl_addend = 0x10;
720
      break;
721
 
722
    case M32C_INSN_JMP16_B:
723
      op[0] = 0xfe;
724
      op[1] = addend - 1;
725
      operand = M32C_OPERAND_LAB_8_8;
726
      op_base = 0;
727
      op_op = 1;
728
      rl_addend = 0x21;
729
      break;
730
 
731
    case M32C_INSN_JMP16_W:
732
      op[0] = 0xf4;
733
      op[1] = addend - 1;
734
      op[2] = (addend - 1) >> 8;
735
      operand = M32C_OPERAND_LAB_8_16;
736
      op_base = 0;
737
      op_op = 1;
738
      rl_addend = 0x31;
739
      break;
740
 
741
    case M32C_INSN_JMP16_A:
742
      op[0] = 0xfc;
743
      op[1] = 0;
744
      op[2] = 0;
745
      op[3] = 0;
746
      operand = M32C_OPERAND_LAB_8_24;
747
      op_base = 0;
748
      op_op = 1;
749
      rl_addend = 0x41;
750
      break;
751
 
752
    case M32C_INSN_JCND32:
753
      op[1] = addend - 1;
754
      operand = M32C_OPERAND_LAB_8_8;
755
      op_base = 0;
756
      op_op = 1;
757
      rl_addend = 0x21;
758
      break;
759
 
760
    case -M32C_MACRO_JCND32_W:
761
      op[0] ^= 0x40;
762
      op[1] = 4;
763
      op[2] = 0xce;
764
      op[3] = addend - 3;
765
      op[4] = (addend - 3) >> 8;
766
      operand = M32C_OPERAND_LAB_8_16;
767
      where += 2;
768
      new_insn = M32C_INSN_JMP32_W;
769
      op_base = 2;
770
      op_op = 3;
771
      rl_addend = 0x51;
772
      break;
773
 
774
    case -M32C_MACRO_JCND32_A:
775
      op[0] ^= 0x40;
776
      op[1] = 5;
777
      op[2] = 0xcc;
778
      operand = M32C_OPERAND_LAB_8_24;
779
      where += 2;
780
      new_insn = M32C_INSN_JMP32_A;
781
      op_base = 2;
782
      op_op = 3;
783
      rl_addend = 0x61;
784
      break;
785
 
786
 
787
 
788
    case M32C_INSN_JMP32_S:
789
      addend = ((addend-2) & 0x07);
790
      op[0] = 0x4a | (addend & 0x01) | ((addend << 3) & 0x30);
791
      operand = M32C_OPERAND_LAB32_JMP_S;
792
      op_base = 0;
793
      op_op = 0;
794
      rl_addend = 0x10;
795
      break;
796
 
797
    case M32C_INSN_JMP32_B:
798
      op[0] = 0xbb;
799
      op[1] = addend - 1;
800
      operand = M32C_OPERAND_LAB_8_8;
801
      op_base = 0;
802
      op_op = 1;
803
      rl_addend = 0x21;
804
      break;
805
 
806
    case M32C_INSN_JMP32_W:
807
      op[0] = 0xce;
808
      op[1] = addend - 1;
809
      op[2] = (addend - 1) >> 8;
810
      operand = M32C_OPERAND_LAB_8_16;
811
      op_base = 0;
812
      op_op = 1;
813
      rl_addend = 0x31;
814
      break;
815
 
816
    case M32C_INSN_JMP32_A:
817
      op[0] = 0xcc;
818
      op[1] = 0;
819
      op[2] = 0;
820
      op[3] = 0;
821
      operand = M32C_OPERAND_LAB_8_24;
822
      op_base = 0;
823
      op_op = 1;
824
      rl_addend = 0x41;
825
      break;
826
 
827
 
828
    case M32C_INSN_JSR16_W:
829
      op[0] = 0xf5;
830
      op[1] = addend - 1;
831
      op[2] = (addend - 1) >> 8;
832
      operand = M32C_OPERAND_LAB_8_16;
833
      op_base = 0;
834
      op_op = 1;
835
      rl_addend = 0x31;
836
      break;
837
 
838
    case M32C_INSN_JSR16_A:
839
      op[0] = 0xfd;
840
      op[1] = 0;
841
      op[2] = 0;
842
      op[3] = 0;
843
      operand = M32C_OPERAND_LAB_8_24;
844
      op_base = 0;
845
      op_op = 1;
846
      rl_addend = 0x41;
847
      break;
848
 
849
    case M32C_INSN_JSR32_W:
850
      op[0] = 0xcf;
851
      op[1] = addend - 1;
852
      op[2] = (addend - 1) >> 8;
853
      operand = M32C_OPERAND_LAB_8_16;
854
      op_base = 0;
855
      op_op = 1;
856
      rl_addend = 0x31;
857
      break;
858
 
859
    case M32C_INSN_JSR32_A:
860
      op[0] = 0xcd;
861
      op[1] = 0;
862
      op[2] = 0;
863
      op[3] = 0;
864
      operand = M32C_OPERAND_LAB_8_24;
865
      op_base = 0;
866
      op_op = 1;
867
      rl_addend = 0x41;
868
      break;
869
 
870
    case -M32C_MACRO_ADJNZ_2:
871
      rl_addend = 0x31;
872
      op[2] = addend - 2;
873
      operand = M32C_OPERAND_LAB_16_8;
874
      break;
875
    case -M32C_MACRO_ADJNZ_3:
876
      rl_addend = 0x41;
877
      op[3] = addend - 2;
878
      operand = M32C_OPERAND_LAB_24_8;
879
      break;
880
    case -M32C_MACRO_ADJNZ_4:
881
      rl_addend = 0x51;
882
      op[4] = addend - 2;
883
      operand = M32C_OPERAND_LAB_32_8;
884
      break;
885
    case -M32C_MACRO_ADJNZ_5:
886
      rl_addend = 0x61;
887
      op[5] = addend - 2;
888
      operand = M32C_OPERAND_LAB_40_8;
889
      break;
890
 
891
 
892
    default:
893
      printf("\nHey!  Need more opcode converters! missing: %d %s\n\n",
894
             fragP->fr_subtype,
895
             fragP->fr_cgen.insn->base->name);
896
      abort();
897
    }
898
 
899
  if (m32c_relax)
900
    {
901
      if (operand != M32C_OPERAND_LAB_8_24)
902
        fragP->fr_offset = (fragP->fr_address + where);
903
 
904
      fix_new (fragP,
905
               rl_where,
906
               0, abs_section_sym, rl_addend, 0,
907
               BFD_RELOC_M32C_RL_JUMP);
908
    }
909
 
910
  if (S_GET_SEGMENT (fragP->fr_symbol) != sec
911
      || operand == M32C_OPERAND_LAB_8_24
912
      || (m32c_relax && (operand != M32C_OPERAND_LAB_5_3
913
                         && operand != M32C_OPERAND_LAB32_JMP_S)))
914
    {
915
      fixS *fixP;
916
      gas_assert (fragP->fr_cgen.insn != 0);
917
      fixP = gas_cgen_record_fixup (fragP,
918
                                    where,
919
                                    fragP->fr_cgen.insn,
920
                                    (fragP->fr_fix - where) * 8,
921
                                    cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
922
                                                                operand),
923
                                    fragP->fr_cgen.opinfo,
924
                                    fragP->fr_symbol, fragP->fr_offset);
925
    }
926
}
927
 
928
/* Functions concerning relocs.  */
929
 
930
/* The location from which a PC relative jump should be calculated,
931
   given a PC relative reloc.  */
932
 
933
long
934
md_pcrel_from_section (fixS * fixP, segT sec)
935
{
936
  if (fixP->fx_addsy != (symbolS *) NULL
937
      && (! S_IS_DEFINED (fixP->fx_addsy)
938
          || S_GET_SEGMENT (fixP->fx_addsy) != sec))
939
    /* The symbol is undefined (or is defined but not in this section).
940
       Let the linker figure it out.  */
941
    return 0;
942
 
943
  return (fixP->fx_frag->fr_address + fixP->fx_where);
944
}
945
 
946
/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
947
   Returns BFD_RELOC_NONE if no reloc type can be found.
948
   *FIXP may be modified if desired.  */
949
 
950
bfd_reloc_code_real_type
951
md_cgen_lookup_reloc (const CGEN_INSN *    insn ATTRIBUTE_UNUSED,
952
                      const CGEN_OPERAND * operand,
953
                      fixS *               fixP ATTRIBUTE_UNUSED)
954
{
955
  static const struct op_reloc {
956
    /* A CGEN operand type that can be a relocatable expression.  */
957
    CGEN_OPERAND_TYPE operand;
958
 
959
    /* The appropriate BFD reloc type to use for that.  */
960
    bfd_reloc_code_real_type reloc;
961
 
962
    /* The offset from the start of the instruction to the field to be
963
       relocated, in bytes.  */
964
    int offset;
965
  } op_reloc_table[] = {
966
 
967
    /* PC-REL relocs for 8-bit fields.  */
968
    { M32C_OPERAND_LAB_8_8,    BFD_RELOC_8_PCREL, 1 },
969
    { M32C_OPERAND_LAB_16_8,   BFD_RELOC_8_PCREL, 2 },
970
    { M32C_OPERAND_LAB_24_8,   BFD_RELOC_8_PCREL, 3 },
971
    { M32C_OPERAND_LAB_32_8,   BFD_RELOC_8_PCREL, 4 },
972
    { M32C_OPERAND_LAB_40_8,   BFD_RELOC_8_PCREL, 5 },
973
 
974
    /* PC-REL relocs for 16-bit fields.  */
975
    { M32C_OPERAND_LAB_8_16,   BFD_RELOC_16_PCREL, 1 },
976
 
977
    /* Absolute relocs for 8-bit fields.  */
978
    { M32C_OPERAND_IMM_8_QI,   BFD_RELOC_8, 1 },
979
    { M32C_OPERAND_IMM_16_QI,  BFD_RELOC_8, 2 },
980
    { M32C_OPERAND_IMM_24_QI,  BFD_RELOC_8, 3 },
981
    { M32C_OPERAND_IMM_32_QI,  BFD_RELOC_8, 4 },
982
    { M32C_OPERAND_IMM_40_QI,  BFD_RELOC_8, 5 },
983
    { M32C_OPERAND_IMM_48_QI,  BFD_RELOC_8, 6 },
984
    { M32C_OPERAND_IMM_56_QI,  BFD_RELOC_8, 7 },
985
    { M32C_OPERAND_DSP_8_S8,   BFD_RELOC_8, 1 },
986
    { M32C_OPERAND_DSP_16_S8,  BFD_RELOC_8, 2 },
987
    { M32C_OPERAND_DSP_24_S8,  BFD_RELOC_8, 3 },
988
    { M32C_OPERAND_DSP_32_S8,  BFD_RELOC_8, 4 },
989
    { M32C_OPERAND_DSP_40_S8,  BFD_RELOC_8, 5 },
990
    { M32C_OPERAND_DSP_48_S8,  BFD_RELOC_8, 6 },
991
    { M32C_OPERAND_DSP_8_U8,   BFD_RELOC_8, 1 },
992
    { M32C_OPERAND_DSP_16_U8,  BFD_RELOC_8, 2 },
993
    { M32C_OPERAND_DSP_24_U8,  BFD_RELOC_8, 3 },
994
    { M32C_OPERAND_DSP_32_U8,  BFD_RELOC_8, 4 },
995
    { M32C_OPERAND_DSP_40_U8,  BFD_RELOC_8, 5 },
996
    { M32C_OPERAND_DSP_48_U8,  BFD_RELOC_8, 6 },
997
    { M32C_OPERAND_BITBASE32_16_S11_UNPREFIXED, BFD_RELOC_8, 2 },
998
    { M32C_OPERAND_BITBASE32_16_U11_UNPREFIXED, BFD_RELOC_8, 2 },
999
    { M32C_OPERAND_BITBASE32_24_S11_PREFIXED, BFD_RELOC_8, 3 },
1000
    { M32C_OPERAND_BITBASE32_24_U11_PREFIXED, BFD_RELOC_8, 3 },
1001
 
1002
    /* Absolute relocs for 16-bit fields.  */
1003
    { M32C_OPERAND_IMM_8_HI,   BFD_RELOC_16, 1 },
1004
    { M32C_OPERAND_IMM_16_HI,  BFD_RELOC_16, 2 },
1005
    { M32C_OPERAND_IMM_24_HI,  BFD_RELOC_16, 3 },
1006
    { M32C_OPERAND_IMM_32_HI,  BFD_RELOC_16, 4 },
1007
    { M32C_OPERAND_IMM_40_HI,  BFD_RELOC_16, 5 },
1008
    { M32C_OPERAND_IMM_48_HI,  BFD_RELOC_16, 6 },
1009
    { M32C_OPERAND_IMM_56_HI,  BFD_RELOC_16, 7 },
1010
    { M32C_OPERAND_IMM_64_HI,  BFD_RELOC_16, 8 },
1011
    { M32C_OPERAND_DSP_16_S16, BFD_RELOC_16, 2 },
1012
    { M32C_OPERAND_DSP_24_S16, BFD_RELOC_16, 3 },
1013
    { M32C_OPERAND_DSP_32_S16, BFD_RELOC_16, 4 },
1014
    { M32C_OPERAND_DSP_40_S16, BFD_RELOC_16, 5 },
1015
    { M32C_OPERAND_DSP_8_U16,  BFD_RELOC_16, 1 },
1016
    { M32C_OPERAND_DSP_16_U16, BFD_RELOC_16, 2 },
1017
    { M32C_OPERAND_DSP_24_U16, BFD_RELOC_16, 3 },
1018
    { M32C_OPERAND_DSP_32_U16, BFD_RELOC_16, 4 },
1019
    { M32C_OPERAND_DSP_40_U16, BFD_RELOC_16, 5 },
1020
    { M32C_OPERAND_DSP_48_U16, BFD_RELOC_16, 6 },
1021
    { M32C_OPERAND_BITBASE32_16_S19_UNPREFIXED, BFD_RELOC_16, 2 },
1022
    { M32C_OPERAND_BITBASE32_16_U19_UNPREFIXED, BFD_RELOC_16, 2 },
1023
    { M32C_OPERAND_BITBASE32_24_S19_PREFIXED, BFD_RELOC_16, 3 },
1024
    { M32C_OPERAND_BITBASE32_24_U19_PREFIXED, BFD_RELOC_16, 3 },
1025
 
1026
    /* Absolute relocs for 24-bit fields.  */
1027
    { M32C_OPERAND_LAB_8_24,   BFD_RELOC_24, 1 },
1028
    { M32C_OPERAND_DSP_8_S24,  BFD_RELOC_24, 1 },
1029
    { M32C_OPERAND_DSP_8_U24,  BFD_RELOC_24, 1 },
1030
    { M32C_OPERAND_DSP_16_U24, BFD_RELOC_24, 2 },
1031
    { M32C_OPERAND_DSP_24_U24, BFD_RELOC_24, 3 },
1032
    { M32C_OPERAND_DSP_32_U24, BFD_RELOC_24, 4 },
1033
    { M32C_OPERAND_DSP_40_U24, BFD_RELOC_24, 5 },
1034
    { M32C_OPERAND_DSP_48_U24, BFD_RELOC_24, 6 },
1035
    { M32C_OPERAND_DSP_16_U20, BFD_RELOC_24, 2 },
1036
    { M32C_OPERAND_DSP_24_U20, BFD_RELOC_24, 3 },
1037
    { M32C_OPERAND_DSP_32_U20, BFD_RELOC_24, 4 },
1038
    { M32C_OPERAND_BITBASE32_16_U27_UNPREFIXED, BFD_RELOC_24, 2 },
1039
    { M32C_OPERAND_BITBASE32_24_U27_PREFIXED, BFD_RELOC_24, 3 },
1040
 
1041
    /* Absolute relocs for 32-bit fields.  */
1042
    { M32C_OPERAND_IMM_16_SI,  BFD_RELOC_32, 2 },
1043
    { M32C_OPERAND_IMM_24_SI,  BFD_RELOC_32, 3 },
1044
    { M32C_OPERAND_IMM_32_SI,  BFD_RELOC_32, 4 },
1045
    { M32C_OPERAND_IMM_40_SI,  BFD_RELOC_32, 5 },
1046
 
1047
  };
1048
 
1049
  int i;
1050
 
1051
  for (i = ARRAY_SIZE (op_reloc_table); --i >= 0; )
1052
    {
1053
      const struct op_reloc *or = &op_reloc_table[i];
1054
 
1055
      if (or->operand == operand->type)
1056
        {
1057
          fixP->fx_where += or->offset;
1058
          fixP->fx_size -= or->offset;
1059
 
1060
          if (fixP->fx_cgen.opinfo
1061
              && fixP->fx_cgen.opinfo != BFD_RELOC_NONE)
1062
            return fixP->fx_cgen.opinfo;
1063
 
1064
          return or->reloc;
1065
        }
1066
    }
1067
 
1068
  fprintf
1069
    (stderr,
1070
     "Error: tc-m32c.c:md_cgen_lookup_reloc Unimplemented relocation for operand %s\n",
1071
     operand->name);
1072
 
1073
  return BFD_RELOC_NONE;
1074
}
1075
 
1076
void
1077
m32c_cons_fix_new (fragS *      frag,
1078
                   int          where,
1079
                   int          size,
1080
                   expressionS *exp)
1081
{
1082
  bfd_reloc_code_real_type type;
1083
 
1084
  switch (size)
1085
    {
1086
    case 1:
1087
      type = BFD_RELOC_8;
1088
      break;
1089
    case 2:
1090
      type = BFD_RELOC_16;
1091
      break;
1092
    case 3:
1093
      type = BFD_RELOC_24;
1094
      break;
1095
    case 4:
1096
    default:
1097
      type = BFD_RELOC_32;
1098
      break;
1099
    case 8:
1100
      type = BFD_RELOC_64;
1101
      break;
1102
    }
1103
 
1104
  fix_new_exp (frag, where, (int) size, exp, 0, type);
1105
}
1106
 
1107
void
1108
m32c_apply_fix (struct fix *f, valueT *t, segT s)
1109
{
1110
  if (f->fx_r_type == BFD_RELOC_M32C_RL_JUMP
1111
      || f->fx_r_type == BFD_RELOC_M32C_RL_1ADDR
1112
      || f->fx_r_type == BFD_RELOC_M32C_RL_2ADDR)
1113
    return;
1114
  gas_cgen_md_apply_fix (f, t, s);
1115
}
1116
 
1117
arelent *
1118
tc_gen_reloc (asection *sec, fixS *fx)
1119
{
1120
  if (fx->fx_r_type == BFD_RELOC_M32C_RL_JUMP
1121
      || fx->fx_r_type == BFD_RELOC_M32C_RL_1ADDR
1122
      || fx->fx_r_type == BFD_RELOC_M32C_RL_2ADDR)
1123
    {
1124
      arelent * reloc;
1125
 
1126
      reloc = xmalloc (sizeof (* reloc));
1127
 
1128
      reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1129
      *reloc->sym_ptr_ptr = symbol_get_bfdsym (fx->fx_addsy);
1130
      reloc->address = fx->fx_frag->fr_address + fx->fx_where;
1131
      reloc->howto = bfd_reloc_type_lookup (stdoutput, fx->fx_r_type);
1132
      reloc->addend = fx->fx_offset;
1133
      return reloc;
1134
 
1135
    }
1136
  return gas_cgen_tc_gen_reloc (sec, fx);
1137
}
1138
 
1139
/* See whether we need to force a relocation into the output file.
1140
   This is used to force out switch and PC relative relocations when
1141
   relaxing.  */
1142
 
1143
int
1144
m32c_force_relocation (fixS * fixp)
1145
{
1146
  int reloc = fixp->fx_r_type;
1147
 
1148
  if (reloc > (int)BFD_RELOC_UNUSED)
1149
    {
1150
      reloc -= (int)BFD_RELOC_UNUSED;
1151
      switch (reloc)
1152
        {
1153
        case M32C_OPERAND_DSP_32_S16:
1154
        case M32C_OPERAND_DSP_32_U16:
1155
        case M32C_OPERAND_IMM_32_HI:
1156
        case M32C_OPERAND_DSP_16_S16:
1157
        case M32C_OPERAND_DSP_16_U16:
1158
        case M32C_OPERAND_IMM_16_HI:
1159
        case M32C_OPERAND_DSP_24_S16:
1160
        case M32C_OPERAND_DSP_24_U16:
1161
        case M32C_OPERAND_IMM_24_HI:
1162
          return 1;
1163
 
1164
        /* If we're doing linker relaxing, we need to keep all the
1165
           pc-relative jumps in case we need to fix them due to
1166
           deleted bytes between the jump and its destination.  */
1167
        case M32C_OPERAND_LAB_8_8:
1168
        case M32C_OPERAND_LAB_8_16:
1169
        case M32C_OPERAND_LAB_8_24:
1170
        case M32C_OPERAND_LAB_16_8:
1171
        case M32C_OPERAND_LAB_24_8:
1172
        case M32C_OPERAND_LAB_32_8:
1173
        case M32C_OPERAND_LAB_40_8:
1174
          if (m32c_relax)
1175
            return 1;
1176
        default:
1177
          break;
1178
        }
1179
    }
1180
  else
1181
    {
1182
      switch (fixp->fx_r_type)
1183
        {
1184
        case BFD_RELOC_16:
1185
          return 1;
1186
 
1187
        case BFD_RELOC_M32C_RL_JUMP:
1188
        case BFD_RELOC_M32C_RL_1ADDR:
1189
        case BFD_RELOC_M32C_RL_2ADDR:
1190
        case BFD_RELOC_8_PCREL:
1191
        case BFD_RELOC_16_PCREL:
1192
          if (m32c_relax)
1193
            return 1;
1194
        default:
1195
          break;
1196
        }
1197
    }
1198
 
1199
  return generic_force_reloc (fixp);
1200
}
1201
 
1202
/* Write a value out to the object file, using the appropriate endianness.  */
1203
 
1204
void
1205
md_number_to_chars (char * buf, valueT val, int n)
1206
{
1207
  number_to_chars_littleendian (buf, val, n);
1208
}
1209
 
1210
/* Turn a string in input_line_pointer into a floating point constant of type
1211
   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
1212
   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.  */
1213
 
1214
/* Equal to MAX_PRECISION in atof-ieee.c.  */
1215
#define MAX_LITTLENUMS 6
1216
 
1217
char *
1218
md_atof (int type, char * litP, int * sizeP)
1219
{
1220
  return ieee_md_atof (type, litP, sizeP, TRUE);
1221
}
1222
 
1223
bfd_boolean
1224
m32c_fix_adjustable (fixS * fixP)
1225
{
1226
  int reloc;
1227
  if (fixP->fx_addsy == NULL)
1228
    return 1;
1229
 
1230
  /* We need the symbol name for the VTABLE entries.  */
1231
  reloc = fixP->fx_r_type;
1232
  if (reloc > (int)BFD_RELOC_UNUSED)
1233
    {
1234
      reloc -= (int)BFD_RELOC_UNUSED;
1235
      switch (reloc)
1236
        {
1237
        case M32C_OPERAND_DSP_32_S16:
1238
        case M32C_OPERAND_DSP_32_U16:
1239
        case M32C_OPERAND_IMM_32_HI:
1240
        case M32C_OPERAND_DSP_16_S16:
1241
        case M32C_OPERAND_DSP_16_U16:
1242
        case M32C_OPERAND_IMM_16_HI:
1243
        case M32C_OPERAND_DSP_24_S16:
1244
        case M32C_OPERAND_DSP_24_U16:
1245
        case M32C_OPERAND_IMM_24_HI:
1246
          return 0;
1247
        }
1248
    }
1249
  else
1250
    {
1251
      if (fixP->fx_r_type == BFD_RELOC_16)
1252
        return 0;
1253
    }
1254
 
1255
  /* Do not adjust relocations involving symbols in merged sections.
1256
 
1257
     A reloc patching in the value of some symbol S plus some addend A
1258
     can be produced in different ways:
1259
 
1260
     1) It might simply be a reference to the data at S + A.  Clearly,
1261
        if linker merging shift that data around, the value patched in
1262
        by the reloc needs to be adjusted accordingly.
1263
 
1264
     2) Or, it might be a reference to S, with A added in as a constant
1265
        bias.  For example, given code like this:
1266
 
1267
          static int S[100];
1268
 
1269
          ... S[i - 8] ...
1270
 
1271
        it would be reasonable for the compiler to rearrange the array
1272
        reference to something like:
1273
 
1274
          ... (S-8)[i] ...
1275
 
1276
        and emit assembly code that refers to S - (8 * sizeof (int)),
1277
        so the subtraction is done entirely at compile-time.  In this
1278
        case, the reloc's addend A would be -(8 * sizeof (int)), and
1279
        shifting around code or data at S + A should not affect the
1280
        reloc: the reloc isn't referring to that code or data at all.
1281
 
1282
     The linker has no way of knowing which case it has in hand.  So,
1283
     to disambiguate, we have the linker always treat reloc addends as
1284
     in case 2): they're constants that should be simply added to the
1285
     symbol value, just like the reloc says.  And we express case 1)
1286
     in different way: we have the compiler place a label at the real
1287
     target, and reference that label with an addend of zero.  (The
1288
     compiler is unlikely to reference code using a label plus an
1289
     offset anyway, since it doesn't know the sizes of the
1290
     instructions.)
1291
 
1292
     The simplification being done by gas/write.c:adjust_reloc_syms,
1293
     however, turns the explicit-label usage into the label-plus-
1294
     offset usage, re-introducing the ambiguity the compiler avoided.
1295
     So we need to disable that simplification for symbols referring
1296
     to merged data.
1297
 
1298
     This only affects object size a little bit.  */
1299
  if (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE)
1300
    return 0;
1301
 
1302
  if (m32c_relax)
1303
    return 0;
1304
 
1305
  return 1;
1306
}
1307
 
1308
/* Worker function for m32c_is_colon_insn().  */
1309
static char
1310
restore_colon (int advance_i_l_p_by)
1311
{
1312
  char c;
1313
 
1314
  /* Restore the colon, and advance input_line_pointer to
1315
     the end of the new symbol.  */
1316
  * input_line_pointer = ':';
1317
  input_line_pointer += advance_i_l_p_by;
1318
  c = * input_line_pointer;
1319
  * input_line_pointer = 0;
1320
 
1321
  return c;
1322
}
1323
 
1324
/* Determines if the symbol starting at START and ending in
1325
   a colon that was at the location pointed to by INPUT_LINE_POINTER
1326
   (but which has now been replaced bu a NUL) is in fact an
1327
   :Z, :S, :Q, or :G suffix.
1328
   If it is, then it restores the colon, advances INPUT_LINE_POINTER
1329
   to the real end of the instruction/symbol, and returns the character
1330
   that really terminated the symbol.  Otherwise it returns 0.  */
1331
char
1332
m32c_is_colon_insn (char *start ATTRIBUTE_UNUSED)
1333
{
1334
  char * i_l_p = input_line_pointer;
1335
 
1336
  /* Check to see if the text following the colon is 'G' */
1337
  if (TOLOWER (i_l_p[1]) == 'g' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1338
    return restore_colon (2);
1339
 
1340
  /* Check to see if the text following the colon is 'Q' */
1341
  if (TOLOWER (i_l_p[1]) == 'q' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1342
    return restore_colon (2);
1343
 
1344
  /* Check to see if the text following the colon is 'S' */
1345
  if (TOLOWER (i_l_p[1]) == 's' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1346
    return restore_colon (2);
1347
 
1348
  /* Check to see if the text following the colon is 'Z' */
1349
  if (TOLOWER (i_l_p[1]) == 'z' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1350
    return restore_colon (2);
1351
 
1352
  return 0;
1353
}

powered by: WebSVN 2.1.0

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