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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [config/] [tc-m32c.c] - Blame information for rev 824

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

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

powered by: WebSVN 2.1.0

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