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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [gas/] [config/] [tc-m32c.c] - Blame information for rev 6

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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