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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [gas/] [config/] [tc-sh64.c] - Blame information for rev 308

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

Line No. Rev Author Line
1 38 julius
/* tc-sh64.c -- Assemble code for the SuperH SH SHcompact and SHmedia.
2
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3
   Free Software Foundation.
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, 51 Franklin Street - Fifth Floor,
20
   Boston, MA 02110-1301, USA.  */
21
 
22
/* This file defines SHmedia ISA-specific functions and includes tc-sh.c.
23
   The SHcompact ISA is in all useful aspects the "old" sh4 as implemented
24
   in tc-sh.c.  Not making this file part of tc-sh.c makes it easier to
25
   keep a leaner sh[1-4]-only implementation.  */
26
 
27
#define HAVE_SH64
28
 
29
#include "as.h"
30
#include "safe-ctype.h"
31
#include "opcodes/sh64-opc.h"
32
 
33
#ifndef OBJ_ELF
34
#error This file assumes object output is in the ELF format
35
#endif
36
 
37
/* Suffix used when we make "datalabel" symbol copies.  It must not
38
   collide with anything that can normally appear in a symbol, "faked
39
   symbol" or local symbol.  */
40
#define DATALABEL_SUFFIX " DL"
41
 
42
/* See shmedia_md_apply_fix and shmedia_md_pcrel_from_section for usage.  */
43
#define SHMEDIA_MD_PCREL_FROM_FIX(FIXP) \
44
 ((FIXP)->fx_size + (FIXP)->fx_where + (FIXP)->fx_frag->fr_address - 4)
45
 
46
/* We use this internally to see which one is PT and which is a PTA/PTB
47
   that should be error-checked.  We give it a better name here (but not
48
   one that looks official).  Adding it to reloc.c would make it look too
49
   much of a real reloc; it is just used temporarily as a fixup-type.  */
50
#define SHMEDIA_BFD_RELOC_PT BFD_RELOC_12_PCREL
51
 
52
typedef struct
53
 {
54
   shmedia_arg_type type;
55
 
56
   /* These could go into a union, but that would uglify the code.  */
57
   int reg;
58
   expressionS immediate;
59
 
60
   /* If IMMEDIATE was a shift-expression, like "(S >> N) & 65535", where
61
      N = 0, 16, 32, 48, used to extract a certain 16-bit-field to make up
62
      a MOVI or SHORI relocation for a symbol, then we put the
63
      corresponding reloc-type here and modify the "immediate" expression
64
      to S.  Otherwise, this is just BFD_RELOC_NONE.  */
65
   bfd_reloc_code_real_type reloctype;
66
 } shmedia_operand_info;
67
 
68
/* Frag containing last base instruction.  This is put in the TC field in
69
   a frag, so we can emit fixups for fr_opcode without needing to make
70
   sure that the opcode is in the same frag as any variant operand.  */
71
fragS *sh64_last_insn_frag = NULL;
72
 
73
typedef struct
74
 {
75
   shmedia_operand_info operands[3];
76
   unsigned long ops_val;
77
 } shmedia_operands_info;
78
 
79
enum sh64_abi_values
80
 { sh64_abi_unspecified, sh64_abi_32, sh64_abi_64 };
81
 
82
/* What ISA are we assembling code for?  */
83
enum sh64_isa_values sh64_isa_mode = sh64_isa_unspecified;
84
 
85
/* What ABI was specified, if any (implicitly or explicitly)?  */
86
static enum sh64_abi_values sh64_abi = sh64_abi_unspecified;
87
 
88
/* A note that says if we're in a sequence of insns without label
89
   settings, segment or ISA mode changes or emitted data.  */
90
static bfd_boolean seen_insn = FALSE;
91
 
92
/* This is set to TRUE in shmedia_md_end, so that we don't emit any
93
   .cranges entries when the assembler calls output functions while
94
   grinding along after all input is seen.  */
95
static bfd_boolean sh64_end_of_assembly = FALSE;
96
 
97
/* Controlled by the option -no-mix, this invalidates mixing SHcompact and
98
   SHmedia code in the same section, and also invalidates mixing data and
99
   SHmedia code in the same section.  No .cranges will therefore be
100
   emitted, unless -shcompact-const-crange is specified and there is a
101
   constant pool in SHcompact code.  */
102
static bfd_boolean sh64_mix = TRUE;
103
 
104
static bfd_boolean sh64_shcompact_const_crange = FALSE;
105
 
106
/* Controlled by the option -no-expand, this says whether or not we expand
107
   MOVI and PT/PTA/PTB.  When we do not expand these insns to fit an
108
   operand, we will emit errors for operands out of range and generate the
109
   basic instruction and reloc for an external symbol.  */
110
static bfd_boolean sh64_expand = TRUE;
111
 
112
/* Controlled by the option -expand-pt32, this says whether we expand
113
   PT/PTA/PTB of an external symbol to (only) 32 or (the full) 64 bits
114
   when -abi=64 is in effect.  */
115
static bfd_boolean sh64_pt32 = FALSE;
116
 
117
/* When emitting a .cranges descriptor, we want to avoid getting recursive
118
   calls through emit_expr.  */
119
static bfd_boolean emitting_crange = FALSE;
120
 
121
/* SHmedia mnemonics.  */
122
static struct hash_control *shmedia_opcode_hash_control = NULL;
123
 
124
static const unsigned char shmedia_big_nop_pattern[4] =
125
 {
126
   (SHMEDIA_NOP_OPC >> 24) & 255, (SHMEDIA_NOP_OPC >> 16) & 255,
127
   (SHMEDIA_NOP_OPC >> 8) & 255, SHMEDIA_NOP_OPC & 255
128
 };
129
 
130
static const unsigned char shmedia_little_nop_pattern[4] =
131
 {
132
   SHMEDIA_NOP_OPC & 255, (SHMEDIA_NOP_OPC >> 8) & 255,
133
   (SHMEDIA_NOP_OPC >> 16) & 255, (SHMEDIA_NOP_OPC >> 24) & 255
134
 };
135
 
136
static void shmedia_md_begin (void);
137
static int shmedia_parse_reg (char *, int *, int *, shmedia_arg_type);
138
static void shmedia_md_assemble (char *);
139
static void shmedia_md_apply_fix (fixS *, valueT *);
140
static int shmedia_md_estimate_size_before_relax (fragS *, segT);
141
static int shmedia_init_reloc (arelent *, fixS *);
142
static char *shmedia_get_operands (shmedia_opcode_info *, char *,
143
                                   shmedia_operands_info *);
144
static void s_sh64_mode (int);
145
static void s_sh64_abi (int);
146
static void shmedia_md_convert_frag (bfd *, segT, fragS *, bfd_boolean);
147
static void shmedia_check_limits  (offsetT *, bfd_reloc_code_real_type,
148
                                   fixS *);
149
static void sh64_set_contents_type (enum sh64_elf_cr_type);
150
static void shmedia_get_operand (char **, shmedia_operand_info *,
151
                                 shmedia_arg_type);
152
static unsigned long shmedia_immediate_op (char *, shmedia_operand_info *,
153
                                           int, bfd_reloc_code_real_type);
154
static char *shmedia_parse_exp (char *, shmedia_operand_info *);
155
static void shmedia_frob_file_before_adjust (void);
156
static void sh64_emit_crange (symbolS *, symbolS *, enum sh64_elf_cr_type);
157
static void sh64_flush_last_crange (bfd *, asection *, void *);
158
static void sh64_flag_output (void);
159
static void sh64_update_contents_mark (bfd_boolean);
160
static void sh64_vtable_entry (int);
161
static void sh64_vtable_inherit (int);
162
static char *strip_datalabels (void);
163
static int shmedia_build_Mytes (shmedia_opcode_info *,
164
                                shmedia_operands_info *);
165
static shmedia_opcode_info *shmedia_find_cooked_opcode (char **);
166
static unsigned long shmedia_mask_number (unsigned long,
167
                                          bfd_reloc_code_real_type);
168
 
169
#include "tc-sh.c"
170
 
171
void
172
shmedia_md_end (void)
173
{
174
  symbolS *symp;
175
 
176
  /* First, update the last range to include whatever data was last
177
     emitted.  */
178
  sh64_update_contents_mark (TRUE);
179
 
180
  /* Make sure frags generated after this point are not marked with the
181
     wrong ISA; make them easily spottable.  We still want to distinguish
182
     it from sh64_isa_unspecified when we compile for SHcompact or
183
     SHmedia.  */
184
  if (sh64_isa_mode != sh64_isa_unspecified)
185
    sh64_isa_mode = sh64_isa_sh5_guard;
186
 
187
  sh64_end_of_assembly = TRUE;
188
 
189
  bfd_map_over_sections (stdoutput, sh64_flush_last_crange, NULL);
190
 
191
  /* Iterate over segments and emit the last .cranges descriptor.  */
192
  for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
193
    {
194
      symbolS *mainsym = *symbol_get_tc (symp);
195
 
196
      /* Is this a datalabel symbol; does it have a pointer to the main
197
         symbol?  */
198
      if (mainsym != NULL)
199
        {
200
          /* If the datalabel symbol is undefined, check if the main
201
             symbol has changed in that respect.  */
202
          if (S_GET_SEGMENT (symp) == undefined_section)
203
            {
204
              segT symseg;
205
 
206
              symseg = S_GET_SEGMENT (mainsym);
207
 
208
              /* If the symbol is now defined to something that is not
209
                 global and without STO_SH5_ISA32, we just equate the
210
                 datalabel symbol to the main symbol, and the lack of
211
                 STO_SH5_ISA32 will handle the datalabelness.  */
212
              if (symseg != undefined_section)
213
                {
214
                  if (S_GET_OTHER (mainsym) != STO_SH5_ISA32)
215
                    {
216
                      symp->sy_value.X_op = O_symbol;
217
                      symp->sy_value.X_add_symbol = mainsym;
218
                      symp->sy_value.X_op_symbol = NULL;
219
                      symp->sy_value.X_add_number = 0;
220
                      S_SET_SEGMENT (symp, S_GET_SEGMENT (mainsym));
221
                      symbol_set_frag (symp, &zero_address_frag);
222
                      copy_symbol_attributes (symp, mainsym);
223
                    }
224
                  else
225
                    {
226
                      /* An undefined symbol has since we saw it at
227
                         "datalabel", been defined to a BranchTarget
228
                         symbol.  What we need to do here is very similar
229
                         to when we find the "datalabel" for a defined
230
                         symbol.  FIXME: Break out to common function.  */
231
                      symbol_set_value_expression (symp,
232
                                                   symbol_get_value_expression
233
                                                   (mainsym));
234
                      S_SET_SEGMENT (symp, symseg);
235
                      symbol_set_frag (symp, symbol_get_frag (mainsym));
236
                      copy_symbol_attributes (symp, mainsym);
237
 
238
                      /* Unset the BranchTarget mark that can be set at
239
                         attribute-copying.  */
240
                      S_SET_OTHER (symp,
241
                                   S_GET_OTHER (symp) & ~STO_SH5_ISA32);
242
 
243
                      /* The GLOBAL and WEAK attributes are not copied
244
                         over by copy_symbol_attributes.  Do it here.  */
245
                      if (S_IS_WEAK (mainsym))
246
                        S_SET_WEAK (symp);
247
                      else if (S_IS_EXTERNAL (mainsym))
248
                        S_SET_EXTERNAL (symp);
249
                    }
250
                }
251
              else
252
                {
253
                  /* A symbol that was defined at the time we saw
254
                     "datalabel" can since have been attributed with being
255
                     weak or global.  */
256
                  if (S_IS_WEAK (mainsym))
257
                    S_SET_WEAK (symp);
258
                  else if (S_IS_EXTERNAL (mainsym))
259
                    S_SET_EXTERNAL (symp);
260
                }
261
            }
262
        }
263
    }
264
 
265
  for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
266
    if (S_GET_OTHER (symp) & STO_SH5_ISA32)
267
      symp->sy_value.X_add_number++;
268
}
269
 
270
/* When resolving symbols, the main assembler has done us a misfavour.  It
271
   has removed the equation to the main symbol for a datalabel reference
272
   that should be equal to the main symbol, e.g. when it's a global or
273
   weak symbol and is a non-BranchTarget symbol anyway.  We change that
274
   back, so that relocs are against the main symbol, not the local "section
275
   + offset" value.  */
276
 
277
static void
278
shmedia_frob_file_before_adjust (void)
279
{
280
  symbolS *symp;
281
  for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
282
    {
283
      symbolS *mainsym = *symbol_get_tc (symp);
284
 
285
      if (mainsym != NULL
286
          && S_GET_OTHER (mainsym) != STO_SH5_ISA32
287
          && (S_IS_EXTERNAL (mainsym) || S_IS_WEAK (mainsym)))
288
        {
289
          symp->sy_value.X_op = O_symbol;
290
          symp->sy_value.X_add_symbol = mainsym;
291
          symp->sy_value.X_op_symbol = NULL;
292
          symp->sy_value.X_add_number = 0;
293
 
294
          /* For the "equation trick" to work, we have to set the section
295
             to undefined.  */
296
          S_SET_SEGMENT (symp, undefined_section);
297
          symbol_set_frag (symp, &zero_address_frag);
298
          copy_symbol_attributes (symp, mainsym);
299
 
300
          /* Don't forget to remove the STO_SH5_ISA32 attribute after
301
             copying the other attributes.  */
302
          S_SET_OTHER (symp, S_GET_OTHER (symp) & ~STO_SH5_ISA32);
303
        }
304
    }
305
}
306
 
307
/* We need to mark the current location after the alignment.  This is
308
   copied code the caller, do_align.  We mark the frag location before and
309
   after as we need and arrange to skip the same code in do_align.
310
 
311
   An alternative to code duplication is to call the do_align recursively,
312
   arranging to fall through into do_align if we're already here.  That
313
   would require do_align as an incoming function parameter, since it's
314
   static in read.c.  That solution was discarded a too kludgy.  */
315
 
316
void
317
sh64_do_align (int n, const char *fill, int len, int max)
318
{
319
  /* Update region, or put a data region in front.  */
320
  sh64_update_contents_mark (TRUE);
321
 
322
  /* Only make a frag if we HAVE to...  */
323
  if (n != 0 && !need_pass_2)
324
    {
325
      if (fill == NULL)
326
        {
327
          if (subseg_text_p (now_seg))
328
            frag_align_code (n, max);
329
          else
330
            frag_align (n, 0, max);
331
        }
332
      else if (len <= 1)
333
        frag_align (n, *fill, max);
334
      else
335
        frag_align_pattern (n, fill, len, max);
336
    }
337
 
338
  /* Update mark for current region with current type.  */
339
  sh64_update_contents_mark (FALSE);
340
}
341
 
342
/* The MAX_MEM_FOR_RS_ALIGN_CODE worker.  We have to find out the ISA of
343
   the current segment at this position.  We can't look just at
344
   sh64_isa_shmedia, and we can't look at frag_now.  This is brittle:
345
   callers are currently frag_align_code from subsegs_finish in write.c
346
   (end of assembly) and frag_align_code from do_align in read.c (during
347
   assembly).  */
348
 
349
int
350
sh64_max_mem_for_rs_align_code (void)
351
{
352
  segment_info_type *seginfo;
353
  fragS *mode_start_frag;
354
  seginfo = seg_info (now_seg);
355
 
356
  /* We don't use the contents type we find at the tc_segment_info_data,
357
     since that does not give us absolute information about the ISA; the
358
     contents type can presumably be CRT_DATA and we'd be none the wiser.
359
     Instead we use the information stored at the frag of the symbol at
360
     the start of this range.  If any information is missing or NULL,
361
     assume SHcompact.  */
362
  return
363
    /* If the current ISA mode is SHmedia, that's the mode that we're
364
       going to assign to the new frag, so request enough memory for
365
       it, even if we switch modes afterwards, otherwise we may
366
       allocate too little memory and end up overflowing our buffer.  */
367
    (sh64_isa_mode == sh64_isa_shmedia
368
     || (sh64_isa_mode != sh64_isa_unspecified
369
         && seginfo != NULL
370
         && seginfo->tc_segment_info_data.mode_start_symbol != NULL
371
         && ((mode_start_frag
372
              = (symbol_get_frag
373
                 (seginfo->tc_segment_info_data.mode_start_symbol)))
374
             != NULL)
375
         && mode_start_frag->tc_frag_data.isa == sh64_isa_shmedia))
376
    ? (3 + 4) : (2 + 1);
377
}
378
 
379
/* Put in SHmedia NOP:s if the alignment was created when in SHmedia mode.  */
380
 
381
void
382
sh64_handle_align (fragS * frag)
383
{
384
  int bytes = frag->fr_next->fr_address - frag->fr_address - frag->fr_fix;
385
  char * p  = frag->fr_literal + frag->fr_fix;
386
 
387
  if (frag->tc_frag_data.isa == sh64_isa_shmedia
388
      && frag->fr_type == rs_align_code)
389
    {
390
      while (bytes & 3)
391
        {
392
          *p++ = 0;
393
          bytes--;
394
          frag->fr_fix += 1;
395
        }
396
 
397
      if (target_big_endian)
398
        {
399
          memcpy (p, shmedia_big_nop_pattern,
400
                  sizeof shmedia_big_nop_pattern);
401
          frag->fr_var = sizeof shmedia_big_nop_pattern;
402
        }
403
      else
404
        {
405
          memcpy (p, shmedia_little_nop_pattern,
406
                  sizeof shmedia_little_nop_pattern);
407
          frag->fr_var = sizeof shmedia_little_nop_pattern;
408
        }
409
    }
410
  else
411
    /* Punt to SHcompact function.  */
412
    sh_handle_align (frag);
413
}
414
 
415
/* Set SEC_SH64_ISA32 for SHmedia sections.  */
416
 
417
void
418
shmedia_frob_section_type (asection *sec)
419
{
420
  segment_info_type *seginfo;
421
  seginfo = seg_info (sec);
422
 
423
  /* This and elf32-sh64.c:sh64_elf_fake_sections are the only places
424
     where we use anything else than ELF header flags to communicate the
425
     section as containing SHmedia or other contents.  BFD SEC_* section
426
     flags are running out and should not be overloaded with
427
     target-specific semantics.  This target is ELF only (semantics not
428
     defined for other formats), so we use the target-specific pointer
429
     field of the ELF section data.  */
430
  if (seginfo && sh64_abi == sh64_abi_32)
431
    {
432
      struct sh64_section_data *sec_elf_data;
433
      flagword sec_type = 0;
434
 
435
      if (seginfo->tc_segment_info_data.emitted_ranges != 0)
436
        sec_type = SHF_SH5_ISA32_MIXED;
437
      else if (seginfo->tc_segment_info_data.contents_type == CRT_SH5_ISA32)
438
        sec_type = SHF_SH5_ISA32;
439
 
440
      sec_elf_data = sh64_elf_section_data (sec)->sh64_info;
441
      if (sec_elf_data == NULL)
442
        {
443
          sec_elf_data = xcalloc (1, sizeof (*sec_elf_data));
444
          sh64_elf_section_data (sec)->sh64_info = sec_elf_data;
445
        }
446
 
447
      sec_elf_data->contents_flags = sec_type;
448
    }
449
}
450
 
451
/* This function is called by write_object_file right before the symbol
452
   table is written.  We subtract 1 from all symbols marked STO_SH5_ISA32,
453
   as their values are temporarily incremented in shmedia_md_end, before
454
   symbols values are used by relocs and fixups.
455
 
456
   To increment all symbols and then decrement here is admittedly a
457
   hackish solution.  The alternative is to add infrastructure and hooks
458
   to symbol evaluation that evaluates symbols differently internally to
459
   the value output into the object file, but at the moment that just
460
   seems too much for little benefit.  */
461
 
462
void
463
sh64_adjust_symtab (void)
464
{
465
  symbolS *symp;
466
 
467
  for (symp = symbol_rootP; symp; symp = symbol_next (symp))
468
    {
469
      symbolS *main_symbol = *symbol_get_tc (symp);
470
 
471
      if (main_symbol)
472
        {
473
          char *sym_name = (char *) S_GET_NAME (symp);
474
 
475
          /* All datalabels not used in relocs should be gone by now.
476
 
477
             We change those remaining to have the name of the main
478
             symbol, and we set the ELF type of the symbol of the reloc to
479
             STT_DATALABEL.  */
480
          sym_name[strlen (sym_name) - strlen (DATALABEL_SUFFIX)] = 0;
481
          elf_symbol (symbol_get_bfdsym (symp))->internal_elf_sym.st_info
482
            = STT_DATALABEL;
483
 
484
          /* Also set this symbol to "undefined", so we'll have only one
485
             definition.  */
486
          S_SET_SEGMENT (symp, undefined_section);
487
        }
488
      else if (S_GET_OTHER (symp) & STO_SH5_ISA32)
489
        {
490
          /* It's important to change the BFD symbol value, since it is now
491
             set to the GAS symbolS value.  */
492
          symp->bsym->value--;
493
 
494
          /* Note that we do *not* adjust symp->sy_value.X_add_number.  If
495
             you do this, the test case in sh/sh64/immexpr2.s will fail.
496
             This is because *after* symbols have been output but before
497
             relocs are output, fixups are inspected one more time, and
498
             some leftover expressions are resolved.  To resolve to the
499
             same values, those expressions must have the same GAS symbol
500
             values before as after symbols have been output.  We could
501
             "symp->sy_value.X_add_number++" on the STO_SH5_ISA32 symbols
502
             through tc_frob_file after symbols have been output, but that
503
             would be too gross.  */
504
        }
505
    }
506
}
507
 
508
/* Fill-in an allocated arelent.  */
509
 
510
static int
511
shmedia_init_reloc (arelent *rel, fixS *fixP)
512
{
513
  /* Adjust parts of *relp according to *fixp, and tell that it has been
514
     done, so default initializations will not happen.   */
515
  switch (fixP->fx_r_type)
516
    {
517
    case BFD_RELOC_64:
518
    case BFD_RELOC_64_PCREL:
519
    case BFD_RELOC_SH_IMM_LOW16:
520
    case BFD_RELOC_SH_IMM_MEDLOW16:
521
    case BFD_RELOC_SH_IMM_MEDHI16:
522
    case BFD_RELOC_SH_IMM_HI16:
523
    case BFD_RELOC_SH_IMM_LOW16_PCREL:
524
    case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
525
    case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
526
    case BFD_RELOC_SH_IMM_HI16_PCREL:
527
    case BFD_RELOC_SH_IMMU5:
528
    case BFD_RELOC_SH_IMMU6:
529
    case BFD_RELOC_SH_IMMS6:
530
    case BFD_RELOC_SH_IMMS10:
531
    case BFD_RELOC_SH_IMMS10BY2:
532
    case BFD_RELOC_SH_IMMS10BY4:
533
    case BFD_RELOC_SH_IMMS10BY8:
534
    case BFD_RELOC_SH_IMMS16:
535
    case BFD_RELOC_SH_IMMU16:
536
    case BFD_RELOC_SH_PT_16:
537
    case BFD_RELOC_SH_GOT_LOW16:
538
    case BFD_RELOC_SH_GOT_MEDLOW16:
539
    case BFD_RELOC_SH_GOT_MEDHI16:
540
    case BFD_RELOC_SH_GOT_HI16:
541
    case BFD_RELOC_SH_GOT10BY4:
542
    case BFD_RELOC_SH_GOT10BY8:
543
    case BFD_RELOC_SH_GOTPLT_LOW16:
544
    case BFD_RELOC_SH_GOTPLT_MEDLOW16:
545
    case BFD_RELOC_SH_GOTPLT_MEDHI16:
546
    case BFD_RELOC_SH_GOTPLT_HI16:
547
    case BFD_RELOC_SH_GOTPLT10BY4:
548
    case BFD_RELOC_SH_GOTPLT10BY8:
549
    case BFD_RELOC_SH_GOTOFF_LOW16:
550
    case BFD_RELOC_SH_GOTOFF_MEDLOW16:
551
    case BFD_RELOC_SH_GOTOFF_MEDHI16:
552
    case BFD_RELOC_SH_GOTOFF_HI16:
553
    case BFD_RELOC_SH_GOTPC_LOW16:
554
    case BFD_RELOC_SH_GOTPC_MEDLOW16:
555
    case BFD_RELOC_SH_GOTPC_MEDHI16:
556
    case BFD_RELOC_SH_GOTPC_HI16:
557
    case BFD_RELOC_SH_PLT_LOW16:
558
    case BFD_RELOC_SH_PLT_MEDLOW16:
559
    case BFD_RELOC_SH_PLT_MEDHI16:
560
    case BFD_RELOC_SH_PLT_HI16:
561
      rel->addend = fixP->fx_addnumber + fixP->fx_offset;
562
      return 1;
563
 
564
    case BFD_RELOC_SH_IMMS6BY32:
565
      /* This must be resolved in assembly; we do not support it as a
566
         reloc in an object file.  */
567
      as_bad_where (fixP->fx_file, fixP->fx_line,
568
                    _("This operand must be constant at assembly time"));
569
      break;
570
 
571
      /* There are valid cases where we get here for other than SHmedia
572
         relocs, so don't make a BAD_CASE out of this.  */
573
    default:
574
      ;
575
    }
576
 
577
  return 0;
578
}
579
 
580
/* Hook called from md_apply_fix in tc-sh.c.  */
581
 
582
static void
583
shmedia_md_apply_fix (fixS *fixP, valueT *valp)
584
{
585
  offsetT val = *valp;
586
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
587
  unsigned long insn
588
    = target_big_endian ? bfd_getb32 (buf) : bfd_getl32 (buf);
589
  bfd_reloc_code_real_type orig_fx_r_type = fixP->fx_r_type;
590
 
591
  /* Change a 64-bit pc-relative reloc into the correct type, just like
592
     tc-sh.c:md_apply_fix.  */
593
  if (fixP->fx_pcrel)
594
    {
595
      switch (orig_fx_r_type)
596
        {
597
        case BFD_RELOC_64:
598
        case BFD_RELOC_SH_IMM_LOW16:
599
        case BFD_RELOC_SH_IMM_MEDLOW16:
600
        case BFD_RELOC_SH_IMM_MEDHI16:
601
        case BFD_RELOC_SH_IMM_HI16:
602
          /* Because write.c calls MD_PCREL_FROM_SECTION twice, we need to
603
             undo one of the adjustments, if the relocation is not
604
             actually for a symbol within the same segment (which we
605
             cannot check, because we're not called from md_apply_fix, so
606
             we have to keep the reloc).  FIXME: This is a bug in
607
             write.c:fixup_segment affecting most targets that change
608
             ordinary relocs to pcrel relocs in md_apply_fix.  */
609
          fixP->fx_offset
610
            = *valp + SHMEDIA_MD_PCREL_FROM_FIX (fixP);
611
          break;
612
 
613
        case BFD_RELOC_SH_PLT_LOW16:
614
        case BFD_RELOC_SH_PLT_MEDLOW16:
615
        case BFD_RELOC_SH_PLT_MEDHI16:
616
        case BFD_RELOC_SH_PLT_HI16:
617
        case BFD_RELOC_SH_GOTPC_LOW16:
618
        case BFD_RELOC_SH_GOTPC_MEDLOW16:
619
        case BFD_RELOC_SH_GOTPC_MEDHI16:
620
        case BFD_RELOC_SH_GOTPC_HI16:
621
          *valp = 0;
622
          return;
623
 
624
        default:
625
          ;
626
        }
627
 
628
      /* We might need to change some relocs into the corresponding
629
         PC-relative one.  */
630
      switch (orig_fx_r_type)
631
        {
632
        case BFD_RELOC_64:
633
          fixP->fx_r_type = BFD_RELOC_64_PCREL;
634
          break;
635
 
636
        case BFD_RELOC_SH_IMM_LOW16:
637
          fixP->fx_r_type = BFD_RELOC_SH_IMM_LOW16_PCREL;
638
          break;
639
 
640
        case BFD_RELOC_SH_IMM_MEDLOW16:
641
          fixP->fx_r_type = BFD_RELOC_SH_IMM_MEDLOW16_PCREL;
642
          break;
643
 
644
        case BFD_RELOC_SH_IMM_MEDHI16:
645
          fixP->fx_r_type = BFD_RELOC_SH_IMM_MEDHI16_PCREL;
646
          break;
647
 
648
        case BFD_RELOC_SH_IMM_HI16:
649
          fixP->fx_r_type = BFD_RELOC_SH_IMM_HI16_PCREL;
650
          break;
651
 
652
        case SHMEDIA_BFD_RELOC_PT:
653
          /* This is how we see a difference between PT and PTA when not
654
             expanding (in which case we handle it in
655
             shmedia_md_convert_frag).  Note that we don't see a
656
             difference after the reloc is emitted.  */
657
          fixP->fx_r_type = BFD_RELOC_SH_PT_16;
658
          break;
659
 
660
        case BFD_RELOC_SH_PT_16:
661
          /* This tells us there was a PTA or PTB insn explicitly
662
             expressed as such (not as PT).  We "or" in a 1 into the
663
             lowest bit in the (unused) destination field to tell the
664
             linker that it should check the right ISA type of the
665
             destination and not just change a PTA to PTB (if necessary).  */
666
          md_number_to_chars (buf, insn | (1 << 10), 4);
667
          break;
668
 
669
        case BFD_RELOC_64_PCREL:
670
        case BFD_RELOC_SH_IMM_LOW16_PCREL:
671
        case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
672
        case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
673
        case BFD_RELOC_SH_IMM_HI16_PCREL:
674
          /* Already handled.  */
675
          break;
676
 
677
        default:
678
          /* Everything else that changes into a pc-relative relocation is
679
             an error.  */
680
          as_bad_where (fixP->fx_file, fixP->fx_line,
681
                        _("Invalid operand expression"));
682
          break;
683
        }
684
 
685
      return;
686
    }
687
 
688
  /* If an expression looked like it was PC-relative, but was completely
689
     resolvable, we end up here with the result only in *VALP, and no
690
     relocation will be emitted.  */
691
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
692
    {
693
      /* Emit error for an out-of-range value.  */
694
      shmedia_check_limits ((offsetT *) valp, fixP->fx_r_type, fixP);
695
 
696
      switch (fixP->fx_r_type)
697
        {
698
        case BFD_RELOC_SH_IMM_LOW16:
699
          md_number_to_chars (buf, insn | ((val & 65535) << 10), 4);
700
          break;
701
 
702
        case BFD_RELOC_SH_IMM_MEDLOW16:
703
          md_number_to_chars (buf,
704
                              insn
705
                              | ((valueT) (val & ((valueT) 65535 << 16))
706
                                 >> (16 - 10)), 4);
707
          break;
708
 
709
        case BFD_RELOC_SH_IMM_MEDHI16:
710
          md_number_to_chars (buf,
711
                              insn
712
                              | ((valueT) (val & ((valueT) 65535 << 32))
713
                                 >> (32 - 10)), 4);
714
          break;
715
 
716
        case BFD_RELOC_SH_IMM_HI16:
717
          md_number_to_chars (buf,
718
                              insn
719
                              | ((valueT) (val & ((valueT) 65535 << 48))
720
                                 >> (48 - 10)), 4);
721
          break;
722
 
723
        case BFD_RELOC_SH_IMMS16:
724
        case BFD_RELOC_SH_IMMU16:
725
          md_number_to_chars (buf, insn | ((val & 65535) << 10), 4);
726
          break;
727
 
728
        case BFD_RELOC_SH_IMMS10:
729
          md_number_to_chars (buf, insn | ((val & 0x3ff) << 10), 4);
730
          break;
731
 
732
        case BFD_RELOC_SH_IMMS10BY2:
733
          md_number_to_chars (buf,
734
                              insn | ((val & (0x3ff << 1)) << (10 - 1)), 4);
735
          break;
736
 
737
        case BFD_RELOC_SH_IMMS10BY4:
738
          md_number_to_chars (buf,
739
                              insn | ((val & (0x3ff << 2)) << (10 - 2)), 4);
740
          break;
741
 
742
        case BFD_RELOC_SH_IMMS10BY8:
743
          md_number_to_chars (buf,
744
                              insn | ((val & (0x3ff << 3)) << (10 - 3)), 4);
745
          break;
746
 
747
        case BFD_RELOC_SH_SHMEDIA_CODE:
748
          /* We just ignore and remove this one for the moment.  FIXME:
749
             Use it when implementing relaxing.  */
750
          break;
751
 
752
        case BFD_RELOC_64:
753
          md_number_to_chars (buf, val, 8);
754
          break;
755
 
756
        case SHMEDIA_BFD_RELOC_PT:
757
          /* Change a PT to PTB if the operand turned out to be SHcompact.
758
             The basic opcode specified with PT is equivalent to PTA.  */
759
          if ((val & 1) == 0)
760
            insn |= SHMEDIA_PTB_BIT;
761
          /* Fall through.  */
762
 
763
        case BFD_RELOC_SH_PT_16:
764
          if (! sh64_expand || sh_relax)
765
            {
766
              /* Check if the operand of a PTA or PTB was for the "wrong"
767
                 ISA.  A PT had an incoming fixup of SHMEDIA_BFD_RELOC_PT,
768
                 which we have changed to the right type above.  */
769
              if (orig_fx_r_type != SHMEDIA_BFD_RELOC_PT)
770
                {
771
                  if ((insn & SHMEDIA_PTB_BIT) != 0 && (val & 1) != 0)
772
                    as_bad_where (fixP->fx_file, fixP->fx_line,
773
                                  _("PTB operand is a SHmedia symbol"));
774
                  else if ((insn & SHMEDIA_PTB_BIT) == 0 && (val & 1) == 0)
775
                    as_bad_where (fixP->fx_file, fixP->fx_line,
776
                                  _("PTA operand is a SHcompact symbol"));
777
                }
778
 
779
              md_number_to_chars (buf,
780
                                  insn | ((val & (0xffff << 2))
781
                                          << (10 - 2)),
782
                                  4);
783
              break;
784
            }
785
          /* Fall through.  */
786
 
787
        default:
788
          /* This isn't a BAD_CASE, because presumably we can get here
789
             from unexpected operands.  Since we don't handle them, make
790
             them syntax errors.  */
791
          as_bad_where (fixP->fx_file, fixP->fx_line,
792
                        _("invalid expression in operand"));
793
        }
794
      fixP->fx_done = 1;
795
    }
796
}
797
 
798
/* Hook called from md_convert_frag in tc-sh.c.  */
799
 
800
static void
801
shmedia_md_convert_frag (bfd *output_bfd ATTRIBUTE_UNUSED,
802
                         segT seg ATTRIBUTE_UNUSED, fragS *fragP,
803
                         bfd_boolean final)
804
{
805
  /* Pointer to first byte in variable-sized part of the frag.  */
806
  char *var_partp;
807
 
808
  /* Pointer to first opcode byte in frag.  */
809
  char *opcodep;
810
 
811
  /* Pointer to frag of opcode.  */
812
  fragS *opc_fragP = fragP->tc_frag_data.opc_frag;
813
 
814
  /* Size in bytes of variable-sized part of frag.  */
815
  int var_part_size = 0;
816
 
817
  /* This is part of *fragP.  It contains all information about addresses
818
     and offsets to varying parts.  */
819
  symbolS *symbolP = fragP->fr_symbol;
820
 
821
  bfd_boolean reloc_needed
822
    = (! final
823
       || sh_relax
824
       || symbolP == NULL
825
       || ! S_IS_DEFINED (symbolP)
826
       || S_IS_EXTERNAL (symbolP)
827
       || S_IS_WEAK (symbolP)
828
       || (S_GET_SEGMENT (fragP->fr_symbol) != absolute_section
829
           && S_GET_SEGMENT (fragP->fr_symbol) != seg));
830
 
831
  bfd_reloc_code_real_type reloctype = BFD_RELOC_NONE;
832
 
833
  unsigned long var_part_offset;
834
 
835
  /* Where, in file space, does addr point?  */
836
  bfd_vma target_address;
837
  bfd_vma opcode_address;
838
 
839
  /* What was the insn?  */
840
  unsigned long insn;
841
  know (fragP->fr_type == rs_machine_dependent);
842
 
843
  var_part_offset = fragP->fr_fix;
844
  var_partp = fragP->fr_literal + var_part_offset;
845
  opcodep = fragP->fr_opcode;
846
 
847
  insn = target_big_endian ? bfd_getb32 (opcodep) : bfd_getl32 (opcodep);
848
 
849
  target_address
850
    = ((symbolP && final && ! sh_relax ? S_GET_VALUE (symbolP) : 0)
851
       + fragP->fr_offset);
852
 
853
  /* The opcode that would be extended is the last four "fixed" bytes.  */
854
  opcode_address = fragP->fr_address + fragP->fr_fix - 4;
855
 
856
  switch (fragP->fr_subtype)
857
    {
858
    case C (SH64PCREL16PT_64, SH64PCREL16):
859
    case C (SH64PCREL16PT_32, SH64PCREL16):
860
      /* We can get a PT to a relaxed SHcompact address if it is in the
861
         same section; a mixed-ISA section.  Change the opcode to PTB if
862
         so.  */
863
      if ((target_address & 1) == 0)
864
        insn |= SHMEDIA_PTB_BIT;
865
      /* Fall through.  */
866
 
867
    case C (SH64PCREL16_32, SH64PCREL16):
868
    case C (SH64PCREL16_64, SH64PCREL16):
869
      /* Check that a PTA or PTB points to the right type of target.  We
870
         can get here for a SHcompact target if we are in a mixed-ISA
871
         section.  */
872
      if (((target_address & 1) == 0) && ((insn & SHMEDIA_PTB_BIT) == 0))
873
        as_bad_where (fragP->fr_file, fragP->fr_line,
874
                      _("PTA operand is a SHcompact symbol"));
875
      if (((target_address & 1) != 0) && ((insn & SHMEDIA_PTB_BIT) != 0))
876
        as_bad_where (fragP->fr_file, fragP->fr_line,
877
                      _("PTB operand is a SHmedia symbol"));
878
 
879
      /* When relaxing, we do not output the address in the insn, but
880
         instead a 1 into the low bit.  This matches what the linker
881
         expects to find for a BFD_RELOC_SH_PT_16 reloc, when it checks
882
         correctness for PTA/PTB insn; used when the target address is
883
         unknown (which is not the case here).  */
884
      md_number_to_chars (opcodep,
885
                          insn
886
                          | (((sh_relax
887
                               ? 1 : ((target_address - opcode_address) / 4))
888
                              & ((1 << 16) - 1)) << 10),
889
                          4);
890
 
891
      /* Note that we do not emit info that this was originally a PT since
892
         we have resolved to which one of PTA or PTB it will be.  */
893
      if (sh_relax)
894
        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
895
                 fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_SH_PT_16);
896
      var_part_size = 0;
897
      break;
898
 
899
    case C (SH64PCREL16_32, SH64PCRELPLT):
900
    case C (SH64PCREL16PT_32, SH64PCRELPLT):
901
      reloctype = BFD_RELOC_32_PLT_PCREL;
902
      reloc_needed = 1;
903
      /* Fall through */
904
 
905
    case C (SH64PCREL16_32, SH64PCREL32):
906
    case C (SH64PCREL16_64, SH64PCREL32):
907
    case C (SH64PCREL16PT_32, SH64PCREL32):
908
    case C (SH64PCREL16PT_64, SH64PCREL32):
909
      /* In the fixed bit, put in a MOVI.  */
910
      md_number_to_chars (opcodep,
911
                          SHMEDIA_MOVI_OPC
912
                          | (SHMEDIA_TEMP_REG << 4)
913
                          | ((((reloc_needed
914
                                ? 0 : (target_address - (opcode_address + 8))
915
                                ) >> 16) & 65535) << 10),
916
                          4);
917
 
918
      /* Fill in a SHORI for the low part.  */
919
      md_number_to_chars (var_partp,
920
                          SHMEDIA_SHORI_OPC
921
                          | (SHMEDIA_TEMP_REG << 4)
922
                          | (((reloc_needed
923
                               ? 0 : (target_address - (opcode_address + 8)))
924
                              & 65535) << 10),
925
                          4);
926
 
927
      /* End with a "PTREL R25,TRd".  */
928
      md_number_to_chars (var_partp + 4,
929
                          SHMEDIA_PTREL_OPC | (insn & SHMEDIA_LIKELY_BIT)
930
                          | (SHMEDIA_TEMP_REG << 10)
931
                          | (insn & (7 << 4)),
932
                          4);
933
 
934
      /* We need relocs only if the target symbol was undefined or if
935
         we're relaxing.  */
936
      if (reloc_needed)
937
        {
938
          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
939
                   fragP->fr_symbol, fragP->fr_offset - 8, 1,
940
                   reloctype == BFD_RELOC_32_PLT_PCREL
941
                   ? BFD_RELOC_SH_PLT_MEDLOW16
942
                   : BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
943
          fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
944
                   fragP->fr_offset - 4, 1,
945
                   reloctype == BFD_RELOC_32_PLT_PCREL
946
                   ? BFD_RELOC_SH_PLT_LOW16
947
                   : BFD_RELOC_SH_IMM_LOW16_PCREL);
948
        }
949
 
950
      var_part_size = 8;
951
      break;
952
 
953
    case C (SH64PCREL16_64, SH64PCREL48):
954
    case C (SH64PCREL16PT_64, SH64PCREL48):
955
      /* In the fixed bit, put in a MOVI.  */
956
      md_number_to_chars (opcodep,
957
                          SHMEDIA_MOVI_OPC
958
                          | (SHMEDIA_TEMP_REG << 4)
959
                          | ((((reloc_needed
960
                                ? 0 : (target_address - (opcode_address + 12))
961
                                ) >> 32) & 65535) << 10),
962
                          4);
963
 
964
      /* The first SHORI, for the medium part.  */
965
      md_number_to_chars (var_partp,
966
                          SHMEDIA_SHORI_OPC
967
                          | (SHMEDIA_TEMP_REG << 4)
968
                          | ((((reloc_needed
969
                                ? 0 : (target_address - (opcode_address + 12))
970
                                ) >> 16) & 65535) << 10),
971
                          4);
972
 
973
      /* Fill in a SHORI for the low part.  */
974
      md_number_to_chars (var_partp + 4,
975
                          SHMEDIA_SHORI_OPC
976
                          | (SHMEDIA_TEMP_REG << 4)
977
                          | (((reloc_needed
978
                               ? 0 : (target_address - (opcode_address + 12)))
979
                              & 65535) << 10),
980
                          4);
981
 
982
      /* End with a "PTREL R25,TRd".  */
983
      md_number_to_chars (var_partp + 8,
984
                          SHMEDIA_PTREL_OPC | (insn & SHMEDIA_LIKELY_BIT)
985
                          | (SHMEDIA_TEMP_REG << 10)
986
                          | (insn & (7 << 4)),
987
                          4);
988
 
989
      /* We need relocs only if the target symbol was undefined or if
990
         we're relaxing.  */
991
      if (reloc_needed)
992
        {
993
          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
994
                   fragP->fr_symbol, fragP->fr_offset - 12, 1,
995
                   reloctype == BFD_RELOC_32_PLT_PCREL
996
                   ? BFD_RELOC_SH_PLT_MEDHI16
997
                   : BFD_RELOC_SH_IMM_MEDHI16_PCREL);
998
          fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
999
                   fragP->fr_offset - 8, 1,
1000
                   reloctype == BFD_RELOC_32_PLT_PCREL
1001
                   ? BFD_RELOC_SH_PLT_MEDLOW16
1002
                   : BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
1003
          fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
1004
                   fragP->fr_offset - 4, 1,
1005
                   reloctype == BFD_RELOC_32_PLT_PCREL
1006
                   ? BFD_RELOC_SH_PLT_LOW16
1007
                   : BFD_RELOC_SH_IMM_LOW16_PCREL);
1008
        }
1009
 
1010
      var_part_size = 12;
1011
      break;
1012
 
1013
    case C (SH64PCREL16_64, SH64PCRELPLT):
1014
    case C (SH64PCREL16PT_64, SH64PCRELPLT):
1015
      reloctype = BFD_RELOC_32_PLT_PCREL;
1016
      reloc_needed = 1;
1017
      /* Fall through */
1018
 
1019
    case C (SH64PCREL16_64, SH64PCREL64):
1020
    case C (SH64PCREL16PT_64, SH64PCREL64):
1021
      /* In the fixed bit, put in a MOVI.  */
1022
      md_number_to_chars (opcodep,
1023
                          SHMEDIA_MOVI_OPC
1024
                          | (SHMEDIA_TEMP_REG << 4)
1025
                          | ((((reloc_needed
1026
                                ? 0 : (target_address - (opcode_address + 16))
1027
                                ) >> 48) & 65535) << 10),
1028
                          4);
1029
 
1030
      /* The first SHORI, for the medium-high part.  */
1031
      md_number_to_chars (var_partp,
1032
                          SHMEDIA_SHORI_OPC
1033
                          | (SHMEDIA_TEMP_REG << 4)
1034
                          | ((((reloc_needed
1035
                                ? 0 : (target_address - (opcode_address + 16))
1036
                                ) >> 32) & 65535) << 10),
1037
                          4);
1038
 
1039
      /* A SHORI, for the medium-low part.  */
1040
      md_number_to_chars (var_partp + 4,
1041
                          SHMEDIA_SHORI_OPC
1042
                          | (SHMEDIA_TEMP_REG << 4)
1043
                          | ((((reloc_needed
1044
                                ? 0 : (target_address - (opcode_address + 16))
1045
                                ) >> 16) & 65535) << 10),
1046
                          4);
1047
 
1048
      /* Fill in a SHORI for the low part.  */
1049
      md_number_to_chars (var_partp + 8,
1050
                          SHMEDIA_SHORI_OPC
1051
                          | (SHMEDIA_TEMP_REG << 4)
1052
                          | (((reloc_needed
1053
                               ? 0 : (target_address - (opcode_address + 16)))
1054
                              & 65535) << 10),
1055
                          4);
1056
 
1057
      /* End with a "PTREL R25,TRd".  */
1058
      md_number_to_chars (var_partp + 12,
1059
                          SHMEDIA_PTREL_OPC | (insn & SHMEDIA_LIKELY_BIT)
1060
                          | (SHMEDIA_TEMP_REG << 10)
1061
                          | (insn & (7 << 4)),
1062
                          4);
1063
 
1064
      /* We need relocs only if the target symbol was undefined or if
1065
         we're relaxing.  */
1066
      if (reloc_needed)
1067
        {
1068
          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1069
                   fragP->fr_symbol, fragP->fr_offset - 16, 1,
1070
                   reloctype == BFD_RELOC_32_PLT_PCREL
1071
                   ? BFD_RELOC_SH_PLT_HI16
1072
                   : BFD_RELOC_SH_IMM_HI16_PCREL);
1073
          fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
1074
                   fragP->fr_offset - 12, 1,
1075
                   reloctype == BFD_RELOC_32_PLT_PCREL
1076
                   ? BFD_RELOC_SH_PLT_MEDHI16
1077
                   : BFD_RELOC_SH_IMM_MEDHI16_PCREL);
1078
          fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
1079
                   fragP->fr_offset - 8, 1,
1080
                   reloctype == BFD_RELOC_32_PLT_PCREL
1081
                   ? BFD_RELOC_SH_PLT_MEDLOW16
1082
                   : BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
1083
          fix_new (fragP, var_partp - fragP->fr_literal + 8, 4, fragP->fr_symbol,
1084
                   fragP->fr_offset - 4, 1,
1085
                   reloctype == BFD_RELOC_32_PLT_PCREL
1086
                   ? BFD_RELOC_SH_PLT_LOW16
1087
                   : BFD_RELOC_SH_IMM_LOW16_PCREL);
1088
        }
1089
 
1090
      var_part_size = 16;
1091
      break;
1092
 
1093
    case C (MOVI_IMM_64, MOVI_GOTOFF):
1094
      reloctype = BFD_RELOC_32_GOTOFF;
1095
      reloc_needed = 1;
1096
      /* Fall through.  */
1097
 
1098
    case C (MOVI_IMM_64, UNDEF_MOVI):
1099
    case C (MOVI_IMM_64, MOVI_64):
1100
      {
1101
        /* We only get here for undefined symbols, so we can simplify
1102
           handling compared to those above; we have 0 in the parts that
1103
           will be filled with the symbol parts.  */
1104
 
1105
        int reg = (insn >> 4) & 0x3f;
1106
 
1107
        /* In the fixed bit, put in a MOVI.  */
1108
        md_number_to_chars (opcodep, SHMEDIA_MOVI_OPC | (reg << 4), 4);
1109
        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1110
                 fragP->fr_symbol, fragP->fr_offset, 0,
1111
                 reloctype == BFD_RELOC_NONE
1112
                 ? BFD_RELOC_SH_IMM_HI16
1113
                 : reloctype == BFD_RELOC_32_GOTOFF
1114
                 ? BFD_RELOC_SH_GOTOFF_HI16
1115
                 : (abort (), BFD_RELOC_SH_IMM_HI16));
1116
 
1117
        /* The first SHORI, for the medium-high part.  */
1118
        md_number_to_chars (var_partp, SHMEDIA_SHORI_OPC | (reg << 4), 4);
1119
        fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
1120
                 fragP->fr_offset, 0,
1121
                 reloctype == BFD_RELOC_NONE
1122
                 ? BFD_RELOC_SH_IMM_MEDHI16
1123
                 : reloctype == BFD_RELOC_32_GOTOFF
1124
                 ? BFD_RELOC_SH_GOTOFF_MEDHI16
1125
                 : (abort (), BFD_RELOC_SH_IMM_MEDHI16));
1126
 
1127
        /* A SHORI, for the medium-low part.  */
1128
        md_number_to_chars (var_partp + 4,
1129
                            SHMEDIA_SHORI_OPC | (reg << 4), 4);
1130
        fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
1131
                 fragP->fr_offset, 0,
1132
                 reloctype == BFD_RELOC_NONE
1133
                 ? BFD_RELOC_SH_IMM_MEDLOW16
1134
                 : reloctype == BFD_RELOC_32_GOTOFF
1135
                 ? BFD_RELOC_SH_GOTOFF_MEDLOW16
1136
                 : (abort (), BFD_RELOC_SH_IMM_MEDLOW16));
1137
 
1138
        /* Fill in a SHORI for the low part.  */
1139
        md_number_to_chars (var_partp + 8,
1140
                            SHMEDIA_SHORI_OPC | (reg << 4), 4);
1141
        fix_new (fragP, var_partp - fragP->fr_literal + 8, 4, fragP->fr_symbol,
1142
                 fragP->fr_offset, 0,
1143
                 reloctype == BFD_RELOC_NONE
1144
                 ? BFD_RELOC_SH_IMM_LOW16
1145
                 : reloctype == BFD_RELOC_32_GOTOFF
1146
                 ? BFD_RELOC_SH_GOTOFF_LOW16
1147
                 : (abort (), BFD_RELOC_SH_IMM_LOW16));
1148
 
1149
        var_part_size = 12;
1150
        break;
1151
      }
1152
 
1153
    case C (MOVI_IMM_32, MOVI_GOTOFF):
1154
      reloctype = BFD_RELOC_32_GOTOFF;
1155
      reloc_needed = 1;
1156
      /* Fall through.  */
1157
 
1158
    case C (MOVI_IMM_32, UNDEF_MOVI):
1159
    case C (MOVI_IMM_32, MOVI_32):
1160
      {
1161
        /* Note that we only get here for undefined symbols.  */
1162
 
1163
        int reg = (insn >> 4) & 0x3f;
1164
 
1165
        /* A MOVI, for the high part.  */
1166
        md_number_to_chars (opcodep, SHMEDIA_MOVI_OPC | (reg << 4), 4);
1167
        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1168
                 fragP->fr_symbol, fragP->fr_offset, 0,
1169
                 reloctype == BFD_RELOC_NONE
1170
                 ? BFD_RELOC_SH_IMM_MEDLOW16
1171
                 : reloctype == BFD_RELOC_32_GOTOFF
1172
                 ? BFD_RELOC_SH_GOTOFF_MEDLOW16
1173
                 : reloctype == BFD_RELOC_SH_GOTPC
1174
                 ? BFD_RELOC_SH_GOTPC_MEDLOW16
1175
                 : reloctype == BFD_RELOC_32_PLT_PCREL
1176
                 ? BFD_RELOC_SH_PLT_MEDLOW16
1177
                 : (abort (), BFD_RELOC_SH_IMM_MEDLOW16));
1178
 
1179
        /* Fill in a SHORI for the low part.  */
1180
        md_number_to_chars (var_partp,
1181
                            SHMEDIA_SHORI_OPC | (reg << 4), 4);
1182
        fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
1183
                 fragP->fr_offset, 0,
1184
                 reloctype == BFD_RELOC_NONE
1185
                 ? BFD_RELOC_SH_IMM_LOW16
1186
                 : reloctype == BFD_RELOC_32_GOTOFF
1187
                 ? BFD_RELOC_SH_GOTOFF_LOW16
1188
                 : reloctype == BFD_RELOC_SH_GOTPC
1189
                 ? BFD_RELOC_SH_GOTPC_LOW16
1190
                 : reloctype == BFD_RELOC_32_PLT_PCREL
1191
                 ? BFD_RELOC_SH_PLT_LOW16
1192
                 : (abort (), BFD_RELOC_SH_IMM_LOW16));
1193
 
1194
        var_part_size = 4;
1195
        break;
1196
      }
1197
 
1198
    case C (MOVI_IMM_32_PCREL, MOVI_16):
1199
    case C (MOVI_IMM_64_PCREL, MOVI_16):
1200
      md_number_to_chars (opcodep,
1201
                          insn
1202
                          | (((reloc_needed
1203
                               ? 0 : (target_address - opcode_address))
1204
                              & 65535) << 10),
1205
                          4);
1206
      if (reloc_needed)
1207
        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1208
                 fragP->fr_symbol, fragP->fr_offset, 1,
1209
                 BFD_RELOC_SH_IMM_LOW16_PCREL);
1210
      var_part_size = 0;
1211
      break;
1212
 
1213
    case C (MOVI_IMM_32, MOVI_16):
1214
    case C (MOVI_IMM_64, MOVI_16):
1215
      md_number_to_chars (opcodep,
1216
                          insn
1217
                          | (((reloc_needed ? 0 : target_address)
1218
                              & 65535) << 10),
1219
                          4);
1220
      if (reloc_needed)
1221
        abort ();
1222
      var_part_size = 0;
1223
      break;
1224
 
1225
    case C (MOVI_IMM_32_PCREL, MOVI_PLT):
1226
      reloctype = BFD_RELOC_32_PLT_PCREL;
1227
      goto movi_imm_32_pcrel_reloc_needed;
1228
 
1229
    case C (MOVI_IMM_32_PCREL, MOVI_GOTPC):
1230
      reloctype = BFD_RELOC_SH_GOTPC;
1231
      /* Fall through.  */
1232
 
1233
    movi_imm_32_pcrel_reloc_needed:
1234
      reloc_needed = 1;
1235
      /* Fall through.  */
1236
 
1237
    case C (MOVI_IMM_32_PCREL, MOVI_32):
1238
    case C (MOVI_IMM_64_PCREL, MOVI_32):
1239
      {
1240
        int reg = (insn >> 4) & 0x3f;
1241
 
1242
        md_number_to_chars (opcodep,
1243
                            insn
1244
                            | (((((reloc_needed
1245
                                   ? 0 : (target_address - opcode_address)))
1246
                                >> 16) & 65535) << 10), 4);
1247
 
1248
        /* A SHORI, for the low part.  */
1249
        md_number_to_chars (var_partp,
1250
                            SHMEDIA_SHORI_OPC
1251
                            | (reg << 4)
1252
                            | (((reloc_needed
1253
                                 ? 0 : (target_address - opcode_address))
1254
                                & 65535) << 10), 4);
1255
        if (reloc_needed)
1256
          {
1257
            fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1258
                     fragP->fr_symbol, fragP->fr_offset, 1,
1259
                     reloctype == BFD_RELOC_NONE
1260
                     ? BFD_RELOC_SH_IMM_MEDLOW16_PCREL
1261
                     : reloctype == BFD_RELOC_SH_GOTPC
1262
                     ? BFD_RELOC_SH_GOTPC_MEDLOW16
1263
                     : reloctype == BFD_RELOC_32_PLT_PCREL
1264
                     ? BFD_RELOC_SH_PLT_MEDLOW16
1265
                     : (abort (), BFD_RELOC_SH_IMM_MEDLOW16_PCREL));
1266
            fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
1267
                     fragP->fr_offset + 4, 1,
1268
                     reloctype == BFD_RELOC_NONE
1269
                     ? BFD_RELOC_SH_IMM_LOW16_PCREL
1270
                     : reloctype == BFD_RELOC_SH_GOTPC
1271
                     ? BFD_RELOC_SH_GOTPC_LOW16
1272
                     : reloctype == BFD_RELOC_32_PLT_PCREL
1273
                     ? BFD_RELOC_SH_PLT_LOW16
1274
                     : (abort (), BFD_RELOC_SH_IMM_LOW16_PCREL));
1275
          }
1276
        var_part_size = 4;
1277
      }
1278
      break;
1279
 
1280
    case C (MOVI_IMM_32_PCREL, MOVI_48):
1281
    case C (MOVI_IMM_64_PCREL, MOVI_48):
1282
      {
1283
        int reg = (insn >> 4) & 0x3f;
1284
 
1285
        md_number_to_chars (opcodep,
1286
                            insn
1287
                            | (((((reloc_needed
1288
                                   ? 0 : (target_address - opcode_address)))
1289
                                >> 32) & 65535) << 10), 4);
1290
 
1291
        /* A SHORI, for the medium part.  */
1292
        md_number_to_chars (var_partp,
1293
                            SHMEDIA_SHORI_OPC
1294
                            | (reg << 4)
1295
                            | ((((reloc_needed
1296
                                  ? 0 : (target_address - opcode_address))
1297
                                 >> 16) & 65535) << 10), 4);
1298
 
1299
        /* A SHORI, for the low part.  */
1300
        md_number_to_chars (var_partp + 4,
1301
                            SHMEDIA_SHORI_OPC
1302
                            | (reg << 4)
1303
                            | (((reloc_needed
1304
                                 ? 0 : (target_address - opcode_address))
1305
                                & 65535) << 10), 4);
1306
        if (reloc_needed)
1307
          {
1308
            fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1309
                     fragP->fr_symbol, fragP->fr_offset, 1,
1310
                     BFD_RELOC_SH_IMM_MEDHI16_PCREL);
1311
            fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
1312
                     fragP->fr_offset + 4, 1, BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
1313
            fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
1314
                     fragP->fr_offset + 8, 1, BFD_RELOC_SH_IMM_LOW16_PCREL);
1315
          }
1316
        var_part_size = 8;
1317
      }
1318
      break;
1319
 
1320
    case C (MOVI_IMM_64_PCREL, MOVI_PLT):
1321
      reloctype = BFD_RELOC_32_PLT_PCREL;
1322
      goto movi_imm_64_pcrel_reloc_needed;
1323
 
1324
    case C (MOVI_IMM_64_PCREL, MOVI_GOTPC):
1325
      reloctype = BFD_RELOC_SH_GOTPC;
1326
      /* Fall through.  */
1327
 
1328
    movi_imm_64_pcrel_reloc_needed:
1329
      reloc_needed = 1;
1330
      /* Fall through.  */
1331
 
1332
    case C (MOVI_IMM_32_PCREL, MOVI_64):
1333
    case C (MOVI_IMM_64_PCREL, MOVI_64):
1334
      {
1335
        int reg = (insn >> 4) & 0x3f;
1336
 
1337
        md_number_to_chars (opcodep,
1338
                            insn
1339
                            | (((((reloc_needed
1340
                                   ? 0 : (target_address - opcode_address)))
1341
                                >> 48) & 65535) << 10), 4);
1342
 
1343
        /* A SHORI, for the medium-high part.  */
1344
        md_number_to_chars (var_partp,
1345
                            SHMEDIA_SHORI_OPC
1346
                            | (reg << 4)
1347
                            | ((((reloc_needed
1348
                                  ? 0 : (target_address - opcode_address))
1349
                                 >> 32) & 65535) << 10), 4);
1350
 
1351
        /* A SHORI, for the medium-low part.  */
1352
        md_number_to_chars (var_partp + 4,
1353
                            SHMEDIA_SHORI_OPC
1354
                            | (reg << 4)
1355
                            | ((((reloc_needed
1356
                                  ? 0 : (target_address - opcode_address))
1357
                                 >> 16) & 65535) << 10), 4);
1358
 
1359
        /* A SHORI, for the low part.  */
1360
        md_number_to_chars (var_partp + 8,
1361
                            SHMEDIA_SHORI_OPC
1362
                            | (reg << 4)
1363
                            | (((reloc_needed
1364
                                 ? 0 : (target_address - opcode_address))
1365
                                & 65535) << 10), 4);
1366
        if (reloc_needed)
1367
          {
1368
            fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
1369
                     fragP->fr_symbol, fragP->fr_offset, 1,
1370
                     reloctype == BFD_RELOC_NONE
1371
                     ? BFD_RELOC_SH_IMM_HI16_PCREL
1372
                     : reloctype == BFD_RELOC_SH_GOTPC
1373
                     ? BFD_RELOC_SH_GOTPC_HI16
1374
                     : reloctype == BFD_RELOC_32_PLT_PCREL
1375
                     ? BFD_RELOC_SH_PLT_HI16
1376
                     : (abort (), BFD_RELOC_SH_IMM_HI16_PCREL));
1377
            fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
1378
                     fragP->fr_offset + 4, 1,
1379
                     reloctype == BFD_RELOC_NONE
1380
                     ? BFD_RELOC_SH_IMM_MEDHI16_PCREL
1381
                     : reloctype == BFD_RELOC_SH_GOTPC
1382
                     ? BFD_RELOC_SH_GOTPC_MEDHI16
1383
                     : reloctype == BFD_RELOC_32_PLT_PCREL
1384
                     ? BFD_RELOC_SH_PLT_MEDHI16
1385
                     : (abort (), BFD_RELOC_SH_IMM_MEDHI16_PCREL));
1386
            fix_new (fragP, var_partp - fragP->fr_literal + 4, 4,
1387
                     fragP->fr_symbol,
1388
                     fragP->fr_offset + 8, 1,
1389
                     reloctype == BFD_RELOC_NONE
1390
                     ? BFD_RELOC_SH_IMM_MEDLOW16_PCREL
1391
                     : reloctype == BFD_RELOC_SH_GOTPC
1392
                     ? BFD_RELOC_SH_GOTPC_MEDLOW16
1393
                     : reloctype == BFD_RELOC_32_PLT_PCREL
1394
                     ? BFD_RELOC_SH_PLT_MEDLOW16
1395
                     : (abort (), BFD_RELOC_SH_IMM_MEDLOW16_PCREL));
1396
            fix_new (fragP, var_partp - fragP->fr_literal + 8, 4,
1397
                     fragP->fr_symbol,
1398
                     fragP->fr_offset + 12, 1,
1399
                     reloctype == BFD_RELOC_NONE
1400
                     ? BFD_RELOC_SH_IMM_LOW16_PCREL
1401
                     : reloctype == BFD_RELOC_SH_GOTPC
1402
                     ? BFD_RELOC_SH_GOTPC_LOW16
1403
                     : reloctype == BFD_RELOC_32_PLT_PCREL
1404
                     ? BFD_RELOC_SH_PLT_LOW16
1405
                     : (abort (), BFD_RELOC_SH_IMM_LOW16_PCREL));
1406
          }
1407
        var_part_size = 12;
1408
      }
1409
      break;
1410
 
1411
    default:
1412
      BAD_CASE (fragP->fr_subtype);
1413
    }
1414
 
1415
  fragP->fr_fix += var_part_size;
1416
  fragP->fr_var = 0;
1417
}
1418
 
1419
/* Mask NUMBER (originating from a signed number) corresponding to the HOW
1420
   reloc.  */
1421
 
1422
static unsigned long
1423
shmedia_mask_number (unsigned long number, bfd_reloc_code_real_type how)
1424
{
1425
  switch (how)
1426
    {
1427
    case BFD_RELOC_SH_IMMU5:
1428
      number &= (1 << 5) - 1;
1429
      break;
1430
 
1431
    case BFD_RELOC_SH_IMMS6:
1432
    case BFD_RELOC_SH_IMMU6:
1433
      number &= (1 << 6) - 1;
1434
      break;
1435
 
1436
    case BFD_RELOC_SH_IMMS6BY32:
1437
      number = (number & ((1 << (6 + 5)) - 1)) >> 5;
1438
      break;
1439
 
1440
    case BFD_RELOC_SH_IMMS10:
1441
      number &= (1 << 10) - 1;
1442
      break;
1443
 
1444
    case BFD_RELOC_SH_IMMS10BY2:
1445
      number = (number & ((1 << (10 + 1)) - 1)) >> 1;
1446
      break;
1447
 
1448
    case BFD_RELOC_SH_IMMS10BY4:
1449
      number = (number & ((1 << (10 + 2)) - 1)) >> 2;
1450
      break;
1451
 
1452
    case BFD_RELOC_SH_IMMS10BY8:
1453
      number = (number & ((1 << (10 + 3)) - 1)) >> 3;
1454
      break;
1455
 
1456
    case BFD_RELOC_SH_IMMS16:
1457
    case BFD_RELOC_SH_IMMU16:
1458
      number &= (1 << 16) - 1;
1459
      break;
1460
 
1461
    default:
1462
      BAD_CASE (how);
1463
    }
1464
 
1465
  return number;
1466
}
1467
 
1468
/* Emit errors for values out-of-range, using as_bad_where if FRAGP is
1469
   non-NULL, as_bad otherwise.  */
1470
 
1471
static void
1472
shmedia_check_limits (offsetT *valp, bfd_reloc_code_real_type reloc,
1473
                      fixS *fixp)
1474
{
1475
  offsetT val = *valp;
1476
 
1477
  char *msg = NULL;
1478
 
1479
  switch (reloc)
1480
    {
1481
    case BFD_RELOC_SH_IMMU5:
1482
      if (val < 0 || val > (1 << 5) - 1)
1483
        msg = _("invalid operand, not a 5-bit unsigned value: %d");
1484
      break;
1485
 
1486
    case BFD_RELOC_SH_IMMS6:
1487
      if (val < -(1 << 5) || val > (1 << 5) - 1)
1488
        msg = _("invalid operand, not a 6-bit signed value: %d");
1489
      break;
1490
 
1491
    case BFD_RELOC_SH_IMMU6:
1492
      if (val < 0 || val > (1 << 6) - 1)
1493
        msg = _("invalid operand, not a 6-bit unsigned value: %d");
1494
      break;
1495
 
1496
    case BFD_RELOC_SH_IMMS6BY32:
1497
      if (val < -(1 << 10) || val > (1 << 10) - 1)
1498
        msg = _("invalid operand, not a 11-bit signed value: %d");
1499
      else if (val & 31)
1500
        msg = _("invalid operand, not a multiple of 32: %d");
1501
      break;
1502
 
1503
    case BFD_RELOC_SH_IMMS10:
1504
      if (val < -(1 << 9) || val > (1 << 9) - 1)
1505
        msg = _("invalid operand, not a 10-bit signed value: %d");
1506
      break;
1507
 
1508
    case BFD_RELOC_SH_IMMS10BY2:
1509
      if (val < -(1 << 10) || val > (1 << 10) - 1)
1510
        msg = _("invalid operand, not a 11-bit signed value: %d");
1511
      else if (val & 1)
1512
        msg = _("invalid operand, not an even value: %d");
1513
      break;
1514
 
1515
    case BFD_RELOC_SH_IMMS10BY4:
1516
      if (val < -(1 << 11) || val > (1 << 11) - 1)
1517
        msg = _("invalid operand, not a 12-bit signed value: %d");
1518
      else if (val & 3)
1519
        msg = _("invalid operand, not a multiple of 4: %d");
1520
      break;
1521
 
1522
    case BFD_RELOC_SH_IMMS10BY8:
1523
      if (val < -(1 << 12) || val > (1 << 12) - 1)
1524
        msg = _("invalid operand, not a 13-bit signed value: %d");
1525
      else if (val & 7)
1526
        msg = _("invalid operand, not a multiple of 8: %d");
1527
      break;
1528
 
1529
    case BFD_RELOC_SH_IMMS16:
1530
      if (val < -(1 << 15) || val > (1 << 15) - 1)
1531
        msg = _("invalid operand, not a 16-bit signed value: %d");
1532
      break;
1533
 
1534
    case BFD_RELOC_SH_IMMU16:
1535
      if (val < 0 || val > (1 << 16) - 1)
1536
        msg = _("invalid operand, not a 16-bit unsigned value: %d");
1537
      break;
1538
 
1539
    case BFD_RELOC_SH_PT_16:
1540
    case SHMEDIA_BFD_RELOC_PT:
1541
      if (val < -(1 << 15) * 4 || val > ((1 << 15) - 1) * 4 + 1)
1542
        msg = _("operand out of range for PT, PTA and PTB");
1543
      else if ((val % 4) != 0 && ((val - 1) % 4) != 0)
1544
        msg = _("operand not a multiple of 4 for PT, PTA or PTB: %d");
1545
      break;
1546
 
1547
      /* These have no limits; they take a 16-bit slice of a 32- or 64-bit
1548
         number.  */
1549
    case BFD_RELOC_SH_IMM_HI16:
1550
    case BFD_RELOC_SH_IMM_MEDHI16:
1551
    case BFD_RELOC_SH_IMM_MEDLOW16:
1552
    case BFD_RELOC_SH_IMM_LOW16:
1553
    case BFD_RELOC_SH_IMM_HI16_PCREL:
1554
    case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
1555
    case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
1556
    case BFD_RELOC_SH_IMM_LOW16_PCREL:
1557
 
1558
    case BFD_RELOC_SH_SHMEDIA_CODE:
1559
      break;
1560
 
1561
      /* This one has limits out of our reach.  */
1562
    case BFD_RELOC_64:
1563
      break;
1564
 
1565
    default:
1566
      BAD_CASE (reloc);
1567
    }
1568
 
1569
  if (msg)
1570
    {
1571
      if (fixp)
1572
        as_bad_where (fixp->fx_file, fixp->fx_line, msg, val);
1573
      else
1574
        as_bad (msg, val);
1575
    }
1576
}
1577
 
1578
/* Handle an immediate operand by checking limits and noting it for later
1579
   evaluation if not computable yet, and return a bitfield suitable to
1580
   "or" into the opcode (non-zero if the value was a constant number).  */
1581
 
1582
static unsigned long
1583
shmedia_immediate_op (char *where, shmedia_operand_info *op, int pcrel,
1584
                      bfd_reloc_code_real_type how)
1585
{
1586
  unsigned long retval = 0;
1587
 
1588
  /* If this is not an absolute number, make it a fixup.  A constant in
1589
     place of a pc-relative operand also needs a fixup.  */
1590
  if (op->immediate.X_op != O_constant || pcrel)
1591
    fix_new_exp (frag_now,
1592
                 where - frag_now->fr_literal,
1593
                 4,
1594
                 &op->immediate,
1595
                 pcrel,
1596
                 how);
1597
  else
1598
    {
1599
      /* Check that the number is within limits as represented by the
1600
         reloc, and return the number.  */
1601
      shmedia_check_limits (&op->immediate.X_add_number, how, NULL);
1602
 
1603
      retval
1604
        = shmedia_mask_number ((unsigned long) op->immediate.X_add_number,
1605
                               how);
1606
    }
1607
 
1608
  return retval << 10;
1609
}
1610
 
1611
/* Try and parse a register name case-insensitively, return the number of
1612
   chars consumed.  */
1613
 
1614
static int
1615
shmedia_parse_reg (char *src, int *mode, int *reg, shmedia_arg_type argtype)
1616
{
1617
  int l0 = TOLOWER (src[0]);
1618
  int l1 = l0 ? TOLOWER (src[1]) : 0;
1619
 
1620
  if (l0 == 'r')
1621
    {
1622
      if (src[1] >= '1' && src[1] <= '5')
1623
        {
1624
          if (src[2] >= '0' && src[2] <= '9'
1625
              && ! IDENT_CHAR ((unsigned char) src[3]))
1626
            {
1627
              *mode = A_GREG_M;
1628
              *reg = 10 * (src[1] - '0') + src[2] - '0';
1629
              return 3;
1630
            }
1631
        }
1632
 
1633
      if (src[1] == '6')
1634
        {
1635
          if (src[2] >= '0' && src[2] <= '3'
1636
              && ! IDENT_CHAR ((unsigned char) src[3]))
1637
            {
1638
              *mode = A_GREG_M;
1639
              *reg = 60 + src[2] - '0';
1640
              return 3;
1641
            }
1642
        }
1643
 
1644
      if (src[1] >= '0' && src[1] <= '9'
1645
          && ! IDENT_CHAR ((unsigned char) src[2]))
1646
        {
1647
          *mode = A_GREG_M;
1648
          *reg = (src[1] - '0');
1649
          return 2;
1650
        }
1651
    }
1652
 
1653
  if (l0 == 't' && l1 == 'r')
1654
    {
1655
      if (src[2] >= '0' && src[2] <= '7'
1656
          && ! IDENT_CHAR ((unsigned char) src[3]))
1657
        {
1658
          *mode = A_TREG_B;
1659
          *reg = (src[2] - '0');
1660
          return 3;
1661
        }
1662
    }
1663
 
1664
  if (l0 == 'f' && l1 == 'r')
1665
    {
1666
      if (src[2] >= '1' && src[2] <= '5')
1667
        {
1668
          if (src[3] >= '0' && src[3] <= '9'
1669
              && ! IDENT_CHAR ((unsigned char) src[4]))
1670
            {
1671
              *mode = A_FREG_G;
1672
              *reg = 10 * (src[2] - '0') + src[3] - '0';
1673
              return 4;
1674
            }
1675
        }
1676
      if (src[2] == '6')
1677
        {
1678
          if (src[3] >= '0' && src[3] <= '3'
1679
              && ! IDENT_CHAR ((unsigned char) src[4]))
1680
            {
1681
              *mode = A_FREG_G;
1682
              *reg = 60 + src[3] - '0';
1683
              return 4;
1684
            }
1685
        }
1686
      if (src[2] >= '0' && src[2] <= '9'
1687
          && ! IDENT_CHAR ((unsigned char) src[3]))
1688
        {
1689
          *mode = A_FREG_G;
1690
          *reg = (src[2] - '0');
1691
          return 3;
1692
        }
1693
    }
1694
 
1695
  if (l0 == 'f' && l1 == 'v')
1696
    {
1697
      if (src[2] >= '1' && src[2] <= '5')
1698
        {
1699
          if (src[3] >= '0' && src[3] <= '9'
1700
              && ((10 * (src[2] - '0') + src[3] - '0') % 4) == 0
1701
              && ! IDENT_CHAR ((unsigned char) src[4]))
1702
            {
1703
              *mode = A_FVREG_G;
1704
              *reg = 10 * (src[2] - '0') + src[3] - '0';
1705
              return 4;
1706
            }
1707
        }
1708
      if (src[2] == '6')
1709
        {
1710
          if (src[3] == '0'
1711
              && ! IDENT_CHAR ((unsigned char) src[4]))
1712
            {
1713
              *mode = A_FVREG_G;
1714
              *reg = 60 + src[3] - '0';
1715
              return 4;
1716
            }
1717
        }
1718
      if (src[2] >= '0' && src[2] <= '9'
1719
          && ((src[2] - '0') % 4) == 0
1720
          && ! IDENT_CHAR ((unsigned char) src[3]))
1721
        {
1722
          *mode = A_FVREG_G;
1723
          *reg = (src[2] - '0');
1724
          return 3;
1725
        }
1726
    }
1727
 
1728
  if (l0 == 'd' && l1 == 'r')
1729
    {
1730
      if (src[2] >= '1' && src[2] <= '5')
1731
        {
1732
          if (src[3] >= '0' && src[3] <= '9'
1733
              && ((src[3] - '0') % 2) == 0
1734
              && ! IDENT_CHAR ((unsigned char) src[4]))
1735
            {
1736
              *mode = A_DREG_G;
1737
              *reg = 10 * (src[2] - '0') + src[3] - '0';
1738
              return 4;
1739
            }
1740
        }
1741
 
1742
      if (src[2] == '6')
1743
        {
1744
          if ((src[3] == '0' || src[3] == '2')
1745
              && ! IDENT_CHAR ((unsigned char) src[4]))
1746
            {
1747
              *mode = A_DREG_G;
1748
              *reg = 60 + src[3] - '0';
1749
              return 4;
1750
            }
1751
        }
1752
 
1753
      if (src[2] >= '0' && src[2] <= '9'
1754
          && ((src[2] - '0') % 2) == 0
1755
          && ! IDENT_CHAR ((unsigned char) src[3]))
1756
        {
1757
          *mode = A_DREG_G;
1758
          *reg = (src[2] - '0');
1759
          return 3;
1760
        }
1761
    }
1762
 
1763
  if (l0 == 'f' && l1 == 'p')
1764
    {
1765
      if (src[2] >= '1' && src[2] <= '5')
1766
        {
1767
          if (src[3] >= '0' && src[3] <= '9'
1768
              && ((src[3] - '0') % 2) == 0
1769
              && ! IDENT_CHAR ((unsigned char) src[4]))
1770
            {
1771
              *mode = A_FPREG_G;
1772
              *reg = 10 * (src[2] - '0') + src[3] - '0';
1773
              return 4;
1774
            }
1775
        }
1776
 
1777
      if (src[2] == '6')
1778
        {
1779
          if ((src[3] == '0' || src[3] == '2')
1780
              && ! IDENT_CHAR ((unsigned char) src[4]))
1781
            {
1782
              *mode = A_FPREG_G;
1783
              *reg = 60 + src[3] - '0';
1784
              return 4;
1785
            }
1786
        }
1787
 
1788
      if (src[2] >= '0' && src[2] <= '9'
1789
          && ((src[2] - '0') % 2) == 0
1790
          && ! IDENT_CHAR ((unsigned char) src[3]))
1791
        {
1792
          *mode = A_FPREG_G;
1793
          *reg = (src[2] - '0');
1794
          return 3;
1795
        }
1796
    }
1797
 
1798
  if (l0 == 'm' && strncasecmp (src, "mtrx", 4) == 0)
1799
    {
1800
      if (src[4] == '0' && ! IDENT_CHAR ((unsigned char) src[5]))
1801
        {
1802
          *mode = A_FMREG_G;
1803
          *reg = 0;
1804
          return 5;
1805
        }
1806
 
1807
      if (src[4] == '1' && src[5] == '6'
1808
          && ! IDENT_CHAR ((unsigned char) src[6]))
1809
        {
1810
          *mode = A_FMREG_G;
1811
          *reg = 16;
1812
          return 6;
1813
        }
1814
 
1815
      if (src[4] == '3' && src[5] == '2'
1816
          && ! IDENT_CHAR ((unsigned char) src[6]))
1817
        {
1818
          *mode = A_FMREG_G;
1819
          *reg = 32;
1820
          return 6;
1821
        }
1822
 
1823
      if (src[4] == '4' && src[5] == '8'
1824
          && ! IDENT_CHAR ((unsigned char) src[6]))
1825
        {
1826
          *mode = A_FMREG_G;
1827
          *reg = 48;
1828
          return 6;
1829
        }
1830
    }
1831
 
1832
  if (l0 == 'c' && l1 == 'r')
1833
    {
1834
      if (src[2] >= '1' && src[2] <= '5')
1835
        {
1836
          if (src[3] >= '0' && src[3] <= '9'
1837
              && ! IDENT_CHAR ((unsigned char) src[4]))
1838
            {
1839
              *mode = A_CREG_K;
1840
              *reg = 10 * (src[2] - '0') + src[3] - '0';
1841
              return 4;
1842
            }
1843
        }
1844
      if (src[2] == '6')
1845
        {
1846
          if (src[3] >= '0' && src[3] <= '3'
1847
              && ! IDENT_CHAR ((unsigned char) src[4]))
1848
            {
1849
              *mode = A_CREG_K;
1850
              *reg = 60 + src[3] - '0';
1851
              return 4;
1852
            }
1853
        }
1854
      if (src[2] >= '0' && src[2] <= '9'
1855
          && ! IDENT_CHAR ((unsigned char) src[3]))
1856
        {
1857
          *mode = A_CREG_K;
1858
          *reg = (src[2] - '0');
1859
          return 3;
1860
        }
1861
    }
1862
 
1863
  /* We either have an error, a symbol or a control register by predefined
1864
     name.  To keep things simple but still fast for normal cases, we do
1865
     linear search in the (not to big) table of predefined control
1866
     registers.  We only do this when we *expect* a control register.
1867
     Those instructions should be rare enough that linear searching is ok.
1868
     Or just read them into a hash-table in shmedia_md_begin.  Since they
1869
     cannot be specified in the same place of symbol operands, don't add
1870
     them there to the *main* symbol table as being in "reg_section".  */
1871
  if (argtype == A_CREG_J || argtype == A_CREG_K)
1872
    {
1873
      const shmedia_creg_info *cregp;
1874
      int len = 0;
1875
 
1876
      for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++)
1877
        {
1878
          len = strlen (cregp->name);
1879
          if (strncasecmp (cregp->name, src, len) == 0
1880
              && ! IDENT_CHAR (src[len]))
1881
            break;
1882
        }
1883
 
1884
      if (cregp->name != NULL)
1885
        {
1886
          *mode = A_CREG_K;
1887
          *reg = cregp->cregno;
1888
          return len;
1889
        }
1890
    }
1891
 
1892
  return 0;
1893
}
1894
 
1895
/* Called from md_estimate_size_before_relax in tc-sh.c  */
1896
 
1897
static int
1898
shmedia_md_estimate_size_before_relax (fragS *fragP,
1899
                                       segT segment_type ATTRIBUTE_UNUSED)
1900
{
1901
  int old_fr_fix;
1902
  expressionS *exp;
1903
 
1904
  /* For ELF, we can't relax externally visible symbols; see tc-i386.c.  */
1905
  bfd_boolean sym_relaxable
1906
    = (fragP->fr_symbol
1907
       && S_GET_SEGMENT (fragP->fr_symbol) == segment_type
1908
       && ! S_IS_EXTERNAL (fragP->fr_symbol)
1909
       && ! S_IS_WEAK (fragP->fr_symbol));
1910
 
1911
  old_fr_fix = fragP->fr_fix;
1912
 
1913
  switch (fragP->fr_subtype)
1914
    {
1915
    case C (SH64PCREL16_32, UNDEF_SH64PCREL):
1916
    case C (SH64PCREL16PT_32, UNDEF_SH64PCREL):
1917
      /* Used to be to somewhere which was unknown.  */
1918
      if (sym_relaxable)
1919
        {
1920
          int what = GET_WHAT (fragP->fr_subtype);
1921
 
1922
          /* In this segment, so head for shortest.  */
1923
          fragP->fr_subtype = C (what, SH64PCREL16);
1924
        }
1925
      else
1926
        {
1927
          int what = GET_WHAT (fragP->fr_subtype);
1928
          /* We know the abs value, but we don't know where we will be
1929
             linked, so we must make it the longest.  Presumably we could
1930
             switch to a non-pcrel representation, but having absolute
1931
             values in PT operands should be rare enough not to be worth
1932
             adding that code.  */
1933
          fragP->fr_subtype = C (what, SH64PCREL32);
1934
        }
1935
      fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
1936
      break;
1937
 
1938
    case C (SH64PCREL16_64, UNDEF_SH64PCREL):
1939
    case C (SH64PCREL16PT_64, UNDEF_SH64PCREL):
1940
      /* Used to be to somewhere which was unknown.  */
1941
      if (sym_relaxable)
1942
        {
1943
          int what = GET_WHAT (fragP->fr_subtype);
1944
 
1945
          /* In this segment, so head for shortest.  */
1946
          fragP->fr_subtype = C (what, SH64PCREL16);
1947
        }
1948
      else
1949
        {
1950
          int what = GET_WHAT (fragP->fr_subtype);
1951
          /* We know the abs value, but we don't know where we will be
1952
             linked, so we must make it the longest.  Presumably we could
1953
             switch to a non-pcrel representation, but having absolute
1954
             values in PT operands should be rare enough not to be worth
1955
             adding that code.  */
1956
          fragP->fr_subtype = C (what, SH64PCREL64);
1957
        }
1958
      fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
1959
      break;
1960
 
1961
    case C (MOVI_IMM_64, UNDEF_MOVI):
1962
    case C (MOVI_IMM_32, UNDEF_MOVI):
1963
      exp = NULL;
1964
 
1965
      /* Look inside the "symbol".  If we find a PC-relative expression,
1966
         change this to a PC-relative, relaxable expression.  */
1967
      if (fragP->fr_symbol != NULL
1968
          && (exp = symbol_get_value_expression (fragP->fr_symbol)) != NULL
1969
          && exp->X_op == O_subtract
1970
          && exp->X_op_symbol != NULL
1971
          && S_GET_SEGMENT (exp->X_op_symbol) == segment_type)
1972
        {
1973
          int what = GET_WHAT (fragP->fr_subtype);
1974
          int what_high = what == MOVI_IMM_32 ? MOVI_32 : MOVI_64;
1975
          expressionS *opexp
1976
            = symbol_get_value_expression (exp->X_op_symbol);
1977
          expressionS *addexp
1978
            = symbol_get_value_expression (exp->X_add_symbol);
1979
 
1980
          /* Change the MOVI expression to the "X" in "X - Y" and subtract
1981
             Y:s offset to this location from X.  Note that we can only
1982
             allow an Y which is offset from this frag.  */
1983
          if (opexp != NULL
1984
              && addexp != NULL
1985
              && opexp->X_op == O_constant
1986
              && fragP == symbol_get_frag (exp->X_op_symbol))
1987
            {
1988
              /* At this point, before relaxing, the add-number of opexp
1989
                 is the offset from the fr_fix part.  */
1990
              fragP->fr_offset
1991
                = (exp->X_add_number
1992
                   - (opexp->X_add_number - (fragP->fr_fix - 4)));
1993
              fragP->fr_symbol = exp->X_add_symbol;
1994
 
1995
              what = what == MOVI_IMM_32
1996
                ? MOVI_IMM_32_PCREL : MOVI_IMM_64_PCREL;
1997
 
1998
              /* Check the "X" symbol to estimate the size of this
1999
                 PC-relative expression.  */
2000
              if (S_GET_SEGMENT (exp->X_add_symbol) == segment_type
2001
                  && ! S_IS_EXTERNAL (exp->X_add_symbol)
2002
                  && ! S_IS_WEAK (exp->X_add_symbol))
2003
                fragP->fr_subtype = C (what, MOVI_16);
2004
              else
2005
                fragP->fr_subtype = C (what, what_high);
2006
 
2007
              /* This is now a PC-relative expression, fit to be relaxed.  */
2008
            }
2009
          else
2010
            fragP->fr_subtype = C (what, what_high);
2011
        }
2012
      else if (fragP->fr_symbol == NULL
2013
               || (S_GET_SEGMENT (fragP->fr_symbol) == absolute_section
2014
                   && exp->X_op == O_constant))
2015
        {
2016
          unsigned long insn
2017
            = (target_big_endian
2018
               ? bfd_getb32 (fragP->fr_opcode)
2019
               : bfd_getl32 (fragP->fr_opcode));
2020
          offsetT one = (offsetT) 1;
2021
          offsetT value = fragP->fr_offset
2022
            + (fragP->fr_symbol == NULL ? 0 : S_GET_VALUE (fragP->fr_symbol));
2023
 
2024
          if (value >= ((offsetT) -1 << 15) && value < ((offsetT) 1 << 15))
2025
            {
2026
              /* Fits in 16-bit signed number.  */
2027
              int what = GET_WHAT (fragP->fr_subtype);
2028
              fragP->fr_subtype = C (what, MOVI_16);
2029
 
2030
              /* Just "or" in the value.  */
2031
              md_number_to_chars (fragP->fr_opcode,
2032
                                  insn | ((value & ((1 << 16) - 1)) << 10),
2033
                                  4);
2034
            }
2035
          else if (value >= -(one << 31)
2036
                   && (value < (one << 31)
2037
                       || (sh64_abi == sh64_abi_32 && value < (one << 32))))
2038
            {
2039
              /* The value fits in a 32-bit signed number.  */
2040
              int reg = (insn >> 4) & 0x3f;
2041
 
2042
              /* Just "or" in the high bits of the value, making the first
2043
                 MOVI.  */
2044
              md_number_to_chars (fragP->fr_opcode,
2045
                                  insn
2046
                                  | (((value >> 16) & ((1 << 16) - 1)) << 10),
2047
                                  4);
2048
 
2049
              /* Add a SHORI with the low bits.  Note that this insn lives
2050
                 in the variable fragment part.  */
2051
              md_number_to_chars (fragP->fr_literal + old_fr_fix,
2052
                                  SHMEDIA_SHORI_OPC
2053
                                  | (reg << 4)
2054
                                  | ((value & ((1 << 16) - 1)) << 10),
2055
                                  4);
2056
 
2057
              /* We took a piece of the variable part.  */
2058
              fragP->fr_fix += 4;
2059
            }
2060
          else if (GET_WHAT (fragP->fr_subtype) == MOVI_IMM_32)
2061
            {
2062
              /* Value out of range.  */
2063
              as_bad_where (fragP->fr_file, fragP->fr_line,
2064
                            _("MOVI operand is not a 32-bit signed value: 0x%8x%08x"),
2065
                            ((unsigned int) (value >> 32)
2066
                             & (unsigned int) 0xffffffff),
2067
                            (unsigned int) value & (unsigned int) 0xffffffff);
2068
 
2069
              /* Must advance size, or we will get internal inconsistency
2070
                 and fall into an assert.  */
2071
              fragP->fr_fix += 4;
2072
            }
2073
          /* Now we know we are allowed to expand to 48- and 64-bit values.  */
2074
          else if (value >= -(one << 47) && value < (one << 47))
2075
            {
2076
              /* The value fits in a 48-bit signed number.  */
2077
              int reg = (insn >> 4) & 0x3f;
2078
 
2079
              /* Just "or" in the high bits of the value, making the first
2080
                 MOVI.  */
2081
              md_number_to_chars (fragP->fr_opcode,
2082
                                  insn
2083
                                  | (((value >> 32) & ((1 << 16) - 1)) << 10),
2084
                                  4);
2085
 
2086
              /* Add a SHORI with the middle bits.  Note that this insn lives
2087
                 in the variable fragment part.  */
2088
              md_number_to_chars (fragP->fr_literal + old_fr_fix,
2089
                                  SHMEDIA_SHORI_OPC
2090
                                  | (reg << 4)
2091
                                  | (((value >> 16) & ((1 << 16) - 1)) << 10),
2092
                                  4);
2093
 
2094
              /* Add a SHORI with the low bits.  */
2095
              md_number_to_chars (fragP->fr_literal + old_fr_fix + 4,
2096
                                  SHMEDIA_SHORI_OPC
2097
                                  | (reg << 4)
2098
                                  | ((value & ((1 << 16) - 1)) << 10),
2099
                                  4);
2100
 
2101
              /* We took a piece of the variable part.  */
2102
              fragP->fr_fix += 8;
2103
            }
2104
          else
2105
            {
2106
              /* A 64-bit number.  */
2107
              int reg = (insn >> 4) & 0x3f;
2108
 
2109
              /* Just "or" in the high bits of the value, making the first
2110
                 MOVI.  */
2111
              md_number_to_chars (fragP->fr_opcode,
2112
                                  insn
2113
                                  | (((value >> 48) & ((1 << 16) - 1)) << 10),
2114
                                  4);
2115
 
2116
              /* Add a SHORI with the midhigh bits.  Note that this insn lives
2117
                 in the variable fragment part.  */
2118
              md_number_to_chars (fragP->fr_literal + old_fr_fix,
2119
                                  SHMEDIA_SHORI_OPC
2120
                                  | (reg << 4)
2121
                                  | (((value >> 32) & ((1 << 16) - 1)) << 10),
2122
                                  4);
2123
 
2124
              /* Add a SHORI with the midlow bits.  */
2125
              md_number_to_chars (fragP->fr_literal + old_fr_fix + 4,
2126
                                  SHMEDIA_SHORI_OPC
2127
                                  | (reg << 4)
2128
                                  | (((value >> 16) & ((1 << 16) - 1)) << 10),
2129
                                  4);
2130
 
2131
              /* Add a SHORI with the low bits.  */
2132
              md_number_to_chars (fragP->fr_literal + old_fr_fix + 8,
2133
                                  SHMEDIA_SHORI_OPC
2134
                                  | (reg << 4)
2135
                                  | ((value & ((1 << 16) - 1)) << 10), 4);
2136
              /* We took all of the variable part.  */
2137
              fragP->fr_fix += 12;
2138
            }
2139
 
2140
          /* MOVI expansions that get here have not been converted to
2141
             PC-relative frags, but instead expanded by
2142
             md_number_to_chars or by calling shmedia_md_convert_frag
2143
             with final == FALSE.  We must not have them around as
2144
             frags anymore; symbols would be prematurely evaluated
2145
             when relaxing.  We will not need to have md_convert_frag
2146
             called again with them; any further handling is through
2147
             the already emitted fixups.  */
2148
          frag_wane (fragP);
2149
          break;
2150
        }
2151
      fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
2152
      break;
2153
 
2154
      /* For relaxation states that remain unchanged, report the
2155
         estimated length.  */
2156
    case C (SH64PCREL16_32, SH64PCREL16):
2157
    case C (SH64PCREL16PT_32, SH64PCREL16):
2158
    case C (SH64PCREL16_32, SH64PCREL32):
2159
    case C (SH64PCREL16PT_32, SH64PCREL32):
2160
    case C (SH64PCREL16_32, SH64PCRELPLT):
2161
    case C (SH64PCREL16PT_32, SH64PCRELPLT):
2162
    case C (SH64PCREL16_64, SH64PCREL16):
2163
    case C (SH64PCREL16PT_64, SH64PCREL16):
2164
    case C (SH64PCREL16_64, SH64PCREL32):
2165
    case C (SH64PCREL16PT_64, SH64PCREL32):
2166
    case C (SH64PCREL16_64, SH64PCREL48):
2167
    case C (SH64PCREL16PT_64, SH64PCREL48):
2168
    case C (SH64PCREL16_64, SH64PCREL64):
2169
    case C (SH64PCREL16PT_64, SH64PCREL64):
2170
    case C (SH64PCREL16_64, SH64PCRELPLT):
2171
    case C (SH64PCREL16PT_64, SH64PCRELPLT):
2172
    case C (MOVI_IMM_32, MOVI_16):
2173
    case C (MOVI_IMM_32, MOVI_32):
2174
    case C (MOVI_IMM_32, MOVI_GOTOFF):
2175
    case C (MOVI_IMM_32_PCREL, MOVI_16):
2176
    case C (MOVI_IMM_32_PCREL, MOVI_32):
2177
    case C (MOVI_IMM_32_PCREL, MOVI_PLT):
2178
    case C (MOVI_IMM_32_PCREL, MOVI_GOTPC):
2179
    case C (MOVI_IMM_64, MOVI_16):
2180
    case C (MOVI_IMM_64, MOVI_32):
2181
    case C (MOVI_IMM_64, MOVI_48):
2182
    case C (MOVI_IMM_64, MOVI_64):
2183
    case C (MOVI_IMM_64, MOVI_GOTOFF):
2184
    case C (MOVI_IMM_64_PCREL, MOVI_16):
2185
    case C (MOVI_IMM_64_PCREL, MOVI_32):
2186
    case C (MOVI_IMM_64_PCREL, MOVI_48):
2187
    case C (MOVI_IMM_64_PCREL, MOVI_64):
2188
    case C (MOVI_IMM_64_PCREL, MOVI_PLT):
2189
    case C (MOVI_IMM_64_PCREL, MOVI_GOTPC):
2190
      fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
2191
      break;
2192
 
2193
    default:
2194
      abort ();
2195
    }
2196
 
2197
  return fragP->fr_var + (fragP->fr_fix - old_fr_fix);
2198
}
2199
 
2200
/* Parse an expression, SH64-style.  Copied from tc-sh.c, but with
2201
   datatypes adjusted.  */
2202
 
2203
static char *
2204
shmedia_parse_exp (char *s, shmedia_operand_info *op)
2205
{
2206
  char *save;
2207
  char *new;
2208
 
2209
  save = input_line_pointer;
2210
  input_line_pointer = s;
2211
  expression (&op->immediate);
2212
  if (op->immediate.X_op == O_absent)
2213
    as_bad (_("missing operand"));
2214
  new = input_line_pointer;
2215
  input_line_pointer = save;
2216
  return new;
2217
}
2218
 
2219
/* Parse an operand.  Store pointer to next character in *PTR.  */
2220
 
2221
static void
2222
shmedia_get_operand (char **ptr, shmedia_operand_info *op,
2223
                     shmedia_arg_type argtype)
2224
{
2225
  char *src = *ptr;
2226
  int mode = -1;
2227
  unsigned int len;
2228
 
2229
  len = shmedia_parse_reg (src, &mode, &(op->reg), argtype);
2230
  if (len)
2231
    {
2232
      *ptr = src + len;
2233
      op->type = mode;
2234
    }
2235
  else
2236
    {
2237
      /* Not a reg, so it must be a displacement.  */
2238
      *ptr = shmedia_parse_exp (src, op);
2239
      op->type = A_IMMM;
2240
 
2241
      /* This is just an initialization; shmedia_get_operands will change
2242
         as needed.  */
2243
      op->reloctype = BFD_RELOC_NONE;
2244
    }
2245
}
2246
 
2247
/* Parse the operands for this insn; return NULL if invalid, else return
2248
   how much text was consumed.  */
2249
 
2250
static char *
2251
shmedia_get_operands (shmedia_opcode_info *info, char *args,
2252
                      shmedia_operands_info *operands)
2253
{
2254
  char *ptr = args;
2255
  int i;
2256
 
2257
  if (*ptr == ' ')
2258
    ptr++;
2259
 
2260
  for (i = 0; info->arg[i] != 0; i++)
2261
    {
2262
      memset (operands->operands + i, 0, sizeof (operands->operands[0]));
2263
 
2264
      /* No operand to get for these fields.  */
2265
      if (info->arg[i] == A_REUSE_PREV)
2266
        continue;
2267
 
2268
      shmedia_get_operand (&ptr, &operands->operands[i], info->arg[i]);
2269
 
2270
      /* Check operands type match.  */
2271
      switch (info->arg[i])
2272
        {
2273
        case A_GREG_M:
2274
        case A_GREG_N:
2275
        case A_GREG_D:
2276
          if (operands->operands[i].type != A_GREG_M)
2277
            return NULL;
2278
          break;
2279
 
2280
        case A_FREG_G:
2281
        case A_FREG_H:
2282
        case A_FREG_F:
2283
          if (operands->operands[i].type != A_FREG_G)
2284
            return NULL;
2285
          break;
2286
 
2287
        case A_FVREG_G:
2288
        case A_FVREG_H:
2289
        case A_FVREG_F:
2290
          if (operands->operands[i].type != A_FVREG_G)
2291
            return NULL;
2292
          break;
2293
 
2294
        case A_FMREG_G:
2295
        case A_FMREG_H:
2296
        case A_FMREG_F:
2297
          if (operands->operands[i].type != A_FMREG_G)
2298
            return NULL;
2299
          break;
2300
 
2301
        case A_FPREG_G:
2302
        case A_FPREG_H:
2303
        case A_FPREG_F:
2304
          if (operands->operands[i].type != A_FPREG_G)
2305
            return NULL;
2306
          break;
2307
 
2308
        case A_DREG_G:
2309
        case A_DREG_H:
2310
        case A_DREG_F:
2311
          if (operands->operands[i].type != A_DREG_G)
2312
            return NULL;
2313
          break;
2314
 
2315
        case A_TREG_A:
2316
        case A_TREG_B:
2317
          if (operands->operands[i].type != A_TREG_B)
2318
            return NULL;
2319
          break;
2320
 
2321
        case A_CREG_J:
2322
        case A_CREG_K:
2323
          if (operands->operands[i].type != A_CREG_K)
2324
            return NULL;
2325
          break;
2326
 
2327
        case A_IMMS16:
2328
        case A_IMMU16:
2329
          /* Check for an expression that looks like S & 65535 or
2330
             (S >> N) & 65535, where N = 0, 16, 32, 48.
2331
 
2332
             Get the S and put at operands->operands[i].immediate, and
2333
             adjust operands->operands[i].reloctype.  */
2334
          {
2335
            expressionS *imm_expr = &operands->operands[i].immediate;
2336
            expressionS *right_expr;
2337
 
2338
            if (operands->operands[i].type == A_IMMM
2339
                && imm_expr->X_op == O_bit_and
2340
                && imm_expr->X_op_symbol != NULL
2341
                && ((right_expr
2342
                     = symbol_get_value_expression (imm_expr->X_op_symbol))
2343
                    ->X_op == O_constant)
2344
                && right_expr->X_add_number == 0xffff)
2345
              {
2346
                symbolS *inner = imm_expr->X_add_symbol;
2347
                bfd_reloc_code_real_type reloctype = BFD_RELOC_SH_IMM_LOW16;
2348
                expressionS *inner_expr
2349
                  = symbol_get_value_expression (inner);
2350
 
2351
                if (inner_expr->X_op == O_right_shift)
2352
                  {
2353
                    expressionS *inner_right;
2354
 
2355
                    if (inner_expr->X_op_symbol != NULL
2356
                      && ((inner_right
2357
                           = symbol_get_value_expression (inner_expr
2358
                                                          ->X_op_symbol))
2359
                          ->X_op == O_constant))
2360
                      {
2361
                        offsetT addnum
2362
                          = inner_right->X_add_number;
2363
 
2364
                        if (addnum == 0 || addnum == 16 || addnum == 32
2365
                            || addnum == 48)
2366
                          {
2367
                            reloctype
2368
                              = (addnum == 0
2369
                                 ? BFD_RELOC_SH_IMM_LOW16
2370
                                 : (addnum == 16
2371
                                    ? BFD_RELOC_SH_IMM_MEDLOW16
2372
                                    : (addnum == 32
2373
                                       ? BFD_RELOC_SH_IMM_MEDHI16
2374
                                       : BFD_RELOC_SH_IMM_HI16)));
2375
 
2376
                            inner = inner_expr->X_add_symbol;
2377
                            inner_expr = symbol_get_value_expression (inner);
2378
                          }
2379
                      }
2380
                  }
2381
 
2382
                /* I'm not sure I understand the logic, but evidently the
2383
                   inner expression of a lone symbol is O_constant, with
2384
                   the actual symbol in expr_section.  For a constant, the
2385
                   section would be absolute_section.  For sym+offset,
2386
                   it's O_symbol as always.  See expr.c:make_expr_symbol,
2387
                   first statements.  */
2388
 
2389
                if (inner_expr->X_op == O_constant
2390
                    && S_GET_SEGMENT (inner) != absolute_section)
2391
                  {
2392
                    operands->operands[i].immediate.X_op = O_symbol;
2393
                    operands->operands[i].immediate.X_add_symbol = inner;
2394
                    operands->operands[i].immediate.X_add_number = 0;
2395
                  }
2396
                else
2397
                  operands->operands[i].immediate
2398
                    = *symbol_get_value_expression (inner);
2399
 
2400
                operands->operands[i].reloctype = reloctype;
2401
              }
2402
          }
2403
          /* Fall through.  */
2404
        case A_IMMS6:
2405
        case A_IMMS6BY32:
2406
        case A_IMMS10:
2407
        case A_IMMS10BY1:
2408
        case A_IMMS10BY2:
2409
        case A_IMMS10BY4:
2410
        case A_IMMS10BY8:
2411
        case A_PCIMMS16BY4:
2412
        case A_PCIMMS16BY4_PT:
2413
        case A_IMMU5:
2414
        case A_IMMU6:
2415
          if (operands->operands[i].type != A_IMMM)
2416
            return NULL;
2417
 
2418
          if (sh_check_fixup (&operands->operands[i].immediate,
2419
                              &operands->operands[i].reloctype))
2420
            {
2421
              as_bad (_("invalid PIC reference"));
2422
              return NULL;
2423
            }
2424
 
2425
          break;
2426
 
2427
        default:
2428
          BAD_CASE (info->arg[i]);
2429
        }
2430
 
2431
      if (*ptr == ',' && info->arg[i + 1])
2432
        ptr++;
2433
    }
2434
  return ptr;
2435
}
2436
 
2437
 
2438
/* Find an opcode at the start of *STR_P in the hash table, and set
2439
   *STR_P to the first character after the last one read.  */
2440
 
2441
static shmedia_opcode_info *
2442
shmedia_find_cooked_opcode (char **str_p)
2443
{
2444
  char *str = *str_p;
2445
  char *op_start;
2446
  char *op_end;
2447
  char name[20];
2448
  unsigned int nlen = 0;
2449
 
2450
  /* Drop leading whitespace.  */
2451
  while (*str == ' ')
2452
    str++;
2453
 
2454
  /* Find the op code end.  */
2455
  for (op_start = op_end = str;
2456
       *op_end
2457
       && nlen < sizeof (name) - 1
2458
       && ! is_end_of_line[(unsigned char) *op_end]
2459
       && ! ISSPACE ((unsigned char) *op_end);
2460
       op_end++)
2461
    {
2462
      unsigned char c = op_start[nlen];
2463
 
2464
      /* The machine independent code will convert CMP/EQ into cmp/EQ
2465
         because it thinks the '/' is the end of the symbol.  Moreover,
2466
         all but the first sub-insn is a parallel processing insn won't
2467
         be capitalized.  Instead of hacking up the machine independent
2468
         code, we just deal with it here.  */
2469
      c = TOLOWER (c);
2470
      name[nlen] = c;
2471
      nlen++;
2472
    }
2473
 
2474
  name[nlen] = 0;
2475
  *str_p = op_end;
2476
 
2477
  if (nlen == 0)
2478
    as_bad (_("can't find opcode"));
2479
 
2480
  return
2481
    (shmedia_opcode_info *) hash_find (shmedia_opcode_hash_control, name);
2482
}
2483
 
2484
/* Build up an instruction, including allocating the frag.  */
2485
 
2486
static int
2487
shmedia_build_Mytes (shmedia_opcode_info *opcode,
2488
                     shmedia_operands_info *operands)
2489
{
2490
  unsigned long insn = opcode->opcode_base;
2491
  int i, j;
2492
  char *insn_loc = frag_more (4);
2493
 
2494
  /* The parameter to dwarf2_emit_insn is actually the offset to the start
2495
     of the insn from the fix piece of instruction that was emitted.
2496
     Since we want .debug_line addresses to record (address | 1) for
2497
     SHmedia insns, we get the wanted effect by taking one off the size,
2498
     knowing it's a multiple of 4.  We count from the first fix piece of
2499
     the insn.  There must be no frags changes (frag_more or frag_var)
2500
     calls in-between the frag_more call we account for, and this
2501
     dwarf2_emit_insn call.  */
2502
  dwarf2_emit_insn (3);
2503
 
2504
  /* This is stored into any frag_var operand.  */
2505
  sh64_last_insn_frag = frag_now;
2506
 
2507
  /* Loop over opcode info, emit an instruction.  */
2508
  for (i = 0, j = 0; opcode->arg[i]; i++)
2509
    {
2510
      shmedia_arg_type argtype = opcode->arg[i];
2511
      shmedia_operand_info *opjp = &operands->operands[j];
2512
      switch (argtype)
2513
        {
2514
        case A_TREG_A:
2515
        case A_TREG_B:
2516
        case A_GREG_M:
2517
        case A_GREG_N:
2518
        case A_GREG_D:
2519
        case A_FREG_G:
2520
        case A_FREG_H:
2521
        case A_FREG_F:
2522
        case A_FVREG_G:
2523
        case A_FVREG_H:
2524
        case A_FVREG_F:
2525
        case A_FMREG_G:
2526
        case A_FMREG_H:
2527
        case A_FMREG_F:
2528
        case A_FPREG_G:
2529
        case A_FPREG_H:
2530
        case A_FPREG_F:
2531
        case A_DREG_G:
2532
        case A_DREG_H:
2533
        case A_DREG_F:
2534
        case A_CREG_J:
2535
        case A_CREG_K:
2536
          /* Six-bit register fields.  They just get filled with the
2537
             parsed register number.  */
2538
          insn |= (opjp->reg << opcode->nibbles[i]);
2539
          j++;
2540
          break;
2541
 
2542
        case A_REUSE_PREV:
2543
          /* Copy the register for the previous operand to this position.  */
2544
          insn |= (operands->operands[j - 1].reg << opcode->nibbles[i]);
2545
          j++;
2546
          break;
2547
 
2548
        case A_IMMS6:
2549
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2550
                                        BFD_RELOC_SH_IMMS6);
2551
          j++;
2552
          break;
2553
 
2554
        case A_IMMS6BY32:
2555
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2556
                                        BFD_RELOC_SH_IMMS6BY32);
2557
          j++;
2558
          break;
2559
 
2560
        case A_IMMS10BY1:
2561
        case A_IMMS10:
2562
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2563
                                        BFD_RELOC_SH_IMMS10);
2564
          j++;
2565
          break;
2566
 
2567
        case A_IMMS10BY2:
2568
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2569
                                        BFD_RELOC_SH_IMMS10BY2);
2570
          j++;
2571
          break;
2572
 
2573
        case A_IMMS10BY4:
2574
          if (opjp->reloctype == BFD_RELOC_NONE)
2575
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2576
                                          BFD_RELOC_SH_IMMS10BY4);
2577
          else if (opjp->reloctype == BFD_RELOC_SH_GOTPLT32)
2578
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2579
                                          BFD_RELOC_SH_GOTPLT10BY4);
2580
          else if (opjp->reloctype == BFD_RELOC_32_GOT_PCREL)
2581
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2582
                                          BFD_RELOC_SH_GOT10BY4);
2583
          else
2584
            as_bad (_("invalid PIC reference"));
2585
          j++;
2586
          break;
2587
 
2588
        case A_IMMS10BY8:
2589
          if (opjp->reloctype == BFD_RELOC_NONE)
2590
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2591
                                          BFD_RELOC_SH_IMMS10BY8);
2592
          else if (opjp->reloctype == BFD_RELOC_SH_GOTPLT32)
2593
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2594
                                          BFD_RELOC_SH_GOTPLT10BY8);
2595
          else if (opjp->reloctype == BFD_RELOC_32_GOT_PCREL)
2596
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2597
                                          BFD_RELOC_SH_GOT10BY8);
2598
          else
2599
            as_bad (_("invalid PIC reference"));
2600
          j++;
2601
          break;
2602
 
2603
        case A_IMMS16:
2604
          /* Sneak a peek if this is the MOVI insn.  If so, check if we
2605
             should expand it.  */
2606
          if (opjp->reloctype == BFD_RELOC_32_GOT_PCREL)
2607
            opjp->reloctype = BFD_RELOC_SH_GOT_LOW16;
2608
          else if (opjp->reloctype == BFD_RELOC_SH_GOTPLT32)
2609
            opjp->reloctype = BFD_RELOC_SH_GOTPLT_LOW16;
2610
 
2611
          if ((opjp->reloctype == BFD_RELOC_NONE
2612
               || opjp->reloctype == BFD_RELOC_32_GOTOFF
2613
               || opjp->reloctype == BFD_RELOC_32_PLT_PCREL
2614
               || opjp->reloctype == BFD_RELOC_SH_GOTPC)
2615
              && opcode->opcode_base == SHMEDIA_MOVI_OPC
2616
              && (opjp->immediate.X_op != O_constant
2617
                  || opjp->immediate.X_add_number < -32768
2618
                  || opjp->immediate.X_add_number > 32767)
2619
              && (sh64_expand
2620
                  || opjp->reloctype == BFD_RELOC_32_GOTOFF
2621
                  || opjp->reloctype == BFD_RELOC_32_PLT_PCREL
2622
                  || opjp->reloctype == BFD_RELOC_SH_GOTPC))
2623
            {
2624
              int what = sh64_abi == sh64_abi_64 ? MOVI_IMM_64 : MOVI_IMM_32;
2625
              offsetT max = sh64_abi == sh64_abi_64 ? MOVI_64 : MOVI_32;
2626
              offsetT min = MOVI_16;
2627
              offsetT init = UNDEF_MOVI;
2628
              valueT addvalue
2629
                = opjp->immediate.X_op_symbol != NULL
2630
                ? 0 : opjp->immediate.X_add_number;
2631
              symbolS *sym
2632
                = opjp->immediate.X_op_symbol != NULL
2633
                ? make_expr_symbol (&opjp->immediate)
2634
                : opjp->immediate.X_add_symbol;
2635
 
2636
              if (opjp->reloctype == BFD_RELOC_32_GOTOFF)
2637
                init = max = min = MOVI_GOTOFF;
2638
              else if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
2639
                {
2640
                  init = max = min = MOVI_PLT;
2641
                  what = (sh64_abi == sh64_abi_64
2642
                          ? MOVI_IMM_64_PCREL
2643
                          : MOVI_IMM_32_PCREL);
2644
                }
2645
              else if (opjp->reloctype == BFD_RELOC_SH_GOTPC)
2646
                {
2647
                  init = max = min = MOVI_GOTPC;
2648
                  what = (sh64_abi == sh64_abi_64
2649
                          ? MOVI_IMM_64_PCREL
2650
                          : MOVI_IMM_32_PCREL);
2651
                }
2652
 
2653
              frag_var (rs_machine_dependent,
2654
                        md_relax_table[C (what, max)].rlx_length,
2655
                        md_relax_table[C (what, min)].rlx_length,
2656
                        C (what, init), sym, addvalue, insn_loc);
2657
            }
2658
          else
2659
            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2660
                                          (opjp->reloctype
2661
                                           == BFD_RELOC_NONE)
2662
                                          ? BFD_RELOC_SH_IMMS16
2663
                                          : opjp->reloctype);
2664
          j++;
2665
          break;
2666
 
2667
        case A_PCIMMS16BY4:
2668
          {
2669
            int what
2670
              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
2671
                 ? SH64PCREL16_64 : SH64PCREL16_32);
2672
            offsetT max
2673
              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
2674
                 ? SH64PCREL64 : SH64PCREL32);
2675
            offsetT min = SH64PCREL16;
2676
            offsetT init = UNDEF_SH64PCREL;
2677
 
2678
            /* Don't allow complex expressions here.  */
2679
            if (opjp->immediate.X_op_symbol != NULL)
2680
              {
2681
                as_bad(_("invalid operand: expression in PT target"));
2682
                return 0;
2683
              }
2684
 
2685
            if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
2686
              init = max = min = SH64PCRELPLT;
2687
 
2688
            /* If we're not expanding, then just emit a fixup.  */
2689
            if (sh64_expand || opjp->reloctype != BFD_RELOC_NONE)
2690
              frag_var (rs_machine_dependent,
2691
                        md_relax_table[C (what, max)].rlx_length,
2692
                        md_relax_table[C (what, min)].rlx_length,
2693
                        C (what, init),
2694
                        opjp->immediate.X_add_symbol,
2695
                        opjp->immediate.X_add_number,
2696
                        insn_loc);
2697
            else
2698
              insn |= shmedia_immediate_op (insn_loc, opjp, 1,
2699
                                            opjp->reloctype == BFD_RELOC_NONE
2700
                                            ? BFD_RELOC_SH_PT_16
2701
                                            : opjp->reloctype);
2702
 
2703
            j++;
2704
            break;
2705
          }
2706
 
2707
        case A_PCIMMS16BY4_PT:
2708
          {
2709
            int what
2710
              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
2711
                 ? SH64PCREL16PT_64 : SH64PCREL16PT_32);
2712
            offsetT max
2713
              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
2714
                 ? SH64PCREL64 : SH64PCREL32);
2715
            offsetT min = SH64PCREL16;
2716
            offsetT init = UNDEF_SH64PCREL;
2717
 
2718
            /* Don't allow complex expressions here.  */
2719
            if (opjp->immediate.X_op_symbol != NULL)
2720
              {
2721
                as_bad(_("invalid operand: expression in PT target"));
2722
                return 0;
2723
              }
2724
 
2725
            if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
2726
              init = max = min = SH64PCRELPLT;
2727
 
2728
            /* If we're not expanding, then just emit a fixup.  */
2729
            if (sh64_expand || opjp->reloctype != BFD_RELOC_NONE)
2730
              frag_var (rs_machine_dependent,
2731
                        md_relax_table[C (what, max)].rlx_length,
2732
                        md_relax_table[C (what, min)].rlx_length,
2733
                        C (what, init),
2734
                        opjp->immediate.X_add_symbol,
2735
                        opjp->immediate.X_add_number,
2736
                        insn_loc);
2737
            else
2738
              /* This reloc-type is just temporary, so we can distinguish
2739
                 PTA from PT.  It is changed in shmedia_md_apply_fix to
2740
                 BFD_RELOC_SH_PT_16.  */
2741
              insn |= shmedia_immediate_op (insn_loc, opjp, 1,
2742
                                            opjp->reloctype == BFD_RELOC_NONE
2743
                                            ? SHMEDIA_BFD_RELOC_PT
2744
                                            : opjp->reloctype);
2745
 
2746
            j++;
2747
            break;
2748
          }
2749
 
2750
        case A_IMMU5:
2751
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2752
                                        BFD_RELOC_SH_IMMU5);
2753
          j++;
2754
          break;
2755
 
2756
        case A_IMMU6:
2757
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2758
                                        BFD_RELOC_SH_IMMU6);
2759
          j++;
2760
          break;
2761
 
2762
        case A_IMMU16:
2763
          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
2764
                                        (opjp->reloctype
2765
                                         == BFD_RELOC_NONE)
2766
                                        ? BFD_RELOC_SH_IMMU16
2767
                                        : opjp->reloctype);
2768
          j++;
2769
          break;
2770
 
2771
        default:
2772
          BAD_CASE (argtype);
2773
        }
2774
    }
2775
 
2776
  md_number_to_chars (insn_loc, insn, 4);
2777
  return 4;
2778
}
2779
 
2780
/* Assemble a SHmedia instruction.  */
2781
 
2782
static void
2783
shmedia_md_assemble (char *str)
2784
{
2785
  char *op_end;
2786
  shmedia_opcode_info *opcode;
2787
  shmedia_operands_info operands;
2788
  int size;
2789
 
2790
  opcode = shmedia_find_cooked_opcode (&str);
2791
  op_end = str;
2792
 
2793
  if (opcode == NULL)
2794
    {
2795
      as_bad (_("unknown opcode"));
2796
      return;
2797
    }
2798
 
2799
  /* Start a SHmedia code region, if there has been pseudoinsns or similar
2800
     seen since the last one.  */
2801
  if (!seen_insn)
2802
    {
2803
      sh64_update_contents_mark (TRUE);
2804
      sh64_set_contents_type (CRT_SH5_ISA32);
2805
      seen_insn = TRUE;
2806
    }
2807
 
2808
  op_end = shmedia_get_operands (opcode, op_end, &operands);
2809
 
2810
  if (op_end == NULL)
2811
    {
2812
      as_bad (_("invalid operands to %s"), opcode->name);
2813
      return;
2814
    }
2815
 
2816
  if (*op_end)
2817
    {
2818
      as_bad (_("excess operands to %s"), opcode->name);
2819
      return;
2820
    }
2821
 
2822
  size = shmedia_build_Mytes (opcode, &operands);
2823
  if (size == 0)
2824
    return;
2825
}
2826
 
2827
/* Hook called from md_begin in tc-sh.c.  */
2828
 
2829
void
2830
shmedia_md_begin (void)
2831
{
2832
  const shmedia_opcode_info *shmedia_opcode;
2833
  shmedia_opcode_hash_control = hash_new ();
2834
 
2835
  /* Create opcode table for SHmedia mnemonics.  */
2836
  for (shmedia_opcode = shmedia_table;
2837
       shmedia_opcode->name;
2838
       shmedia_opcode++)
2839
    hash_insert (shmedia_opcode_hash_control, shmedia_opcode->name,
2840
                 (char *) shmedia_opcode);
2841
}
2842
 
2843
/* Switch instruction set.  Only valid if one of the --isa or --abi
2844
   options was specified.  */
2845
 
2846
static void
2847
s_sh64_mode (int ignore ATTRIBUTE_UNUSED)
2848
{
2849
  char *name = input_line_pointer, ch;
2850
 
2851
  /* Make sure data up to this location is handled according to the
2852
     previous ISA.  */
2853
  sh64_update_contents_mark (TRUE);
2854
 
2855
  while (!is_end_of_line[(unsigned char) *input_line_pointer])
2856
    input_line_pointer++;
2857
  ch = *input_line_pointer;
2858
  *input_line_pointer = '\0';
2859
 
2860
  /* If the mode was not set before, explicitly or implicitly, then we're
2861
     not emitting SH64 code, so this pseudo is invalid.  */
2862
  if (sh64_isa_mode == sh64_isa_unspecified)
2863
    as_bad (_("The `.mode %s' directive is not valid with this architecture"),
2864
            name);
2865
 
2866
  if (strcasecmp (name, "shcompact") == 0)
2867
    sh64_isa_mode = sh64_isa_shcompact;
2868
  else if (strcasecmp (name, "shmedia") == 0)
2869
    sh64_isa_mode = sh64_isa_shmedia;
2870
  else
2871
    as_bad (_("Invalid argument to .mode: %s"), name);
2872
 
2873
  /* Make a new frag, marking it with the supposedly-changed ISA.  */
2874
  frag_wane (frag_now);
2875
  frag_new (0);
2876
 
2877
  /* Contents type up to this new point is the same as before; don't add a
2878
     data region just because the new frag we created.  */
2879
  sh64_update_contents_mark (FALSE);
2880
 
2881
  *input_line_pointer = ch;
2882
  demand_empty_rest_of_line ();
2883
}
2884
 
2885
/* Check that the right ABI is used.  Only valid if one of the --isa or
2886
   --abi options was specified.  */
2887
 
2888
static void
2889
s_sh64_abi (int ignore ATTRIBUTE_UNUSED)
2890
{
2891
  char *name = input_line_pointer, ch;
2892
 
2893
  while (!is_end_of_line[(unsigned char) *input_line_pointer])
2894
    input_line_pointer++;
2895
  ch = *input_line_pointer;
2896
  *input_line_pointer = '\0';
2897
 
2898
  /* If the mode was not set before, explicitly or implicitly, then we're
2899
     not emitting SH64 code, so this pseudo is invalid.  */
2900
  if (sh64_abi == sh64_abi_unspecified)
2901
    as_bad (_("The `.abi %s' directive is not valid with this architecture"),
2902
            name);
2903
 
2904
  if (strcmp (name, "64") == 0)
2905
    {
2906
      if (sh64_abi != sh64_abi_64)
2907
        as_bad (_("`.abi 64' but command-line options do not specify 64-bit ABI"));
2908
    }
2909
  else if (strcmp (name, "32") == 0)
2910
    {
2911
      if (sh64_abi != sh64_abi_32)
2912
        as_bad (_("`.abi 32' but command-line options do not specify 32-bit ABI"));
2913
    }
2914
  else
2915
    as_bad (_("Invalid argument to .abi: %s"), name);
2916
 
2917
  *input_line_pointer = ch;
2918
  demand_empty_rest_of_line ();
2919
}
2920
 
2921
/* This function is the first target-specific function called after
2922
   parsing command-line options.  Therefore we set default values from
2923
   command-line options here and do some sanity checking we couldn't do
2924
   when options were being parsed.  */
2925
 
2926
const char *
2927
sh64_target_format (void)
2928
{
2929
#ifdef TE_NetBSD
2930
  /* For NetBSD, if the ISA is unspecified, always use SHmedia.  */
2931
  if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
2932
    sh64_isa_mode = sh64_isa_shmedia;
2933
 
2934
  /* If the ABI is unspecified, select a default: based on how
2935
     we were configured: sh64 == sh64_abi_64, else sh64_abi_32.  */
2936
  if (sh64_abi == sh64_abi_unspecified)
2937
    {
2938
      if (preset_target_arch != 0 || sh64_isa_mode == sh64_isa_shcompact)
2939
        sh64_abi = sh64_abi_32;
2940
      else if (strncmp (TARGET_CPU, "sh64", 4) == 0)
2941
        sh64_abi = sh64_abi_64;
2942
      else
2943
        sh64_abi = sh64_abi_32;
2944
    }
2945
#endif
2946
 
2947
#ifdef TE_LINUX
2948
  if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
2949
    sh64_isa_mode = sh64_isa_shmedia;
2950
 
2951
  if (sh64_abi == sh64_abi_unspecified)
2952
    sh64_abi = sh64_abi_32;
2953
#endif
2954
 
2955
  if (sh64_abi == sh64_abi_64 && sh64_isa_mode == sh64_isa_unspecified)
2956
    sh64_isa_mode = sh64_isa_shmedia;
2957
 
2958
  if (sh64_abi == sh64_abi_32 && sh64_isa_mode == sh64_isa_unspecified)
2959
    sh64_isa_mode = sh64_isa_shcompact;
2960
 
2961
  if (sh64_isa_mode == sh64_isa_shcompact
2962
      && sh64_abi == sh64_abi_unspecified)
2963
    sh64_abi = sh64_abi_32;
2964
 
2965
  if (sh64_isa_mode == sh64_isa_shmedia
2966
      && sh64_abi == sh64_abi_unspecified)
2967
    sh64_abi = sh64_abi_64;
2968
 
2969
  if (sh64_isa_mode == sh64_isa_unspecified && ! sh64_mix)
2970
    as_bad (_("-no-mix is invalid without specifying SHcompact or SHmedia"));
2971
 
2972
  if ((sh64_isa_mode == sh64_isa_unspecified
2973
       || sh64_isa_mode == sh64_isa_shmedia)
2974
      && sh64_shcompact_const_crange)
2975
    as_bad (_("-shcompact-const-crange is invalid without SHcompact"));
2976
 
2977
  if (sh64_pt32 && sh64_abi != sh64_abi_64)
2978
    as_bad (_("-expand-pt32 only valid with -abi=64"));
2979
 
2980
  if (! sh64_expand && sh64_isa_mode == sh64_isa_unspecified)
2981
    as_bad (_("-no-expand only valid with SHcompact or SHmedia"));
2982
 
2983
  if (sh64_pt32 && ! sh64_expand)
2984
    as_bad (_("-expand-pt32 invalid together with -no-expand"));
2985
 
2986
#ifdef TE_NetBSD
2987
  if (sh64_abi == sh64_abi_64)
2988
    return (target_big_endian ? "elf64-sh64-nbsd" : "elf64-sh64l-nbsd");
2989
  else
2990
    return (target_big_endian ? "elf32-sh64-nbsd" : "elf32-sh64l-nbsd");
2991
#elif defined (TE_LINUX)
2992
  if (sh64_abi == sh64_abi_64)
2993
    return (target_big_endian ? "elf64-sh64big-linux" : "elf64-sh64-linux");
2994
  else
2995
    return (target_big_endian ? "elf32-sh64big-linux" : "elf32-sh64-linux");
2996
#else
2997
  /* When the ISA is not one of SHmedia or SHcompact, use the old SH
2998
     object format.  */
2999
  if (sh64_isa_mode == sh64_isa_unspecified)
3000
    return (target_big_endian ? "elf32-sh" : "elf32-shl");
3001
  else if (sh64_abi == sh64_abi_64)
3002
    return (target_big_endian ? "elf64-sh64" : "elf64-sh64l");
3003
  else
3004
    return (target_big_endian ? "elf32-sh64" : "elf32-sh64l");
3005
#endif
3006
}
3007
 
3008
/* The worker function of TARGET_MACH.  */
3009
 
3010
int
3011
sh64_target_mach (void)
3012
{
3013
  /* We need to explicitly set bfd_mach_sh5 instead of the default 0.  But
3014
     we only do this for the 64-bit ABI: if we do it for the 32-bit ABI,
3015
     the SH5 info in the bfd_arch_info structure will be selected.
3016
     However correct, as the machine has 64-bit addresses, functions
3017
     expected to emit 32-bit data for addresses will start failing.  For
3018
     example, the dwarf2dbg.c functions will emit 64-bit debugging format,
3019
     and we don't want that in the 32-bit ABI.
3020
 
3021
     We could have two bfd_arch_info structures for SH64; one for the
3022
     32-bit ABI and one for the rest (64-bit ABI).  But that would be a
3023
     bigger kludge: it's a flaw in the BFD design, and we need to just
3024
     work around it by having the default machine set here in the
3025
     assembler.  For everything else but the assembler, the various bfd
3026
     functions will set the machine type right to bfd_mach_sh5 from object
3027
     file header flags regardless of the 0 here.  */
3028
 
3029
  return (sh64_abi == sh64_abi_64) ? bfd_mach_sh5 : 0;
3030
}
3031
 
3032
/* This is MD_PCREL_FROM_SECTION, we we define so it is called instead of
3033
   md_pcrel_from (in tc-sh.c).  */
3034
 
3035
valueT
3036
shmedia_md_pcrel_from_section (struct fix *fixP, segT sec ATTRIBUTE_UNUSED)
3037
{
3038
  /* Use the ISA for the instruction to decide which offset to use.  We
3039
     can glean it from the fisup type.  */
3040
  switch (fixP->fx_r_type)
3041
    {
3042
    case BFD_RELOC_SH_IMM_LOW16:
3043
    case BFD_RELOC_SH_IMM_MEDLOW16:
3044
    case BFD_RELOC_SH_IMM_MEDHI16:
3045
    case BFD_RELOC_SH_IMM_HI16:
3046
    case BFD_RELOC_SH_IMM_LOW16_PCREL:
3047
    case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
3048
    case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
3049
    case BFD_RELOC_SH_IMM_HI16_PCREL:
3050
    case BFD_RELOC_SH_IMMU5:
3051
    case BFD_RELOC_SH_IMMU6:
3052
    case BFD_RELOC_SH_IMMS6:
3053
    case BFD_RELOC_SH_IMMS10:
3054
    case BFD_RELOC_SH_IMMS10BY2:
3055
    case BFD_RELOC_SH_IMMS10BY4:
3056
    case BFD_RELOC_SH_IMMS10BY8:
3057
    case BFD_RELOC_SH_IMMS16:
3058
    case BFD_RELOC_SH_IMMU16:
3059
    case BFD_RELOC_SH_PT_16:
3060
    case SHMEDIA_BFD_RELOC_PT:
3061
      /* PC-relative relocs are relative to the address of the last generated
3062
         instruction, i.e. fx_size - 4.  */
3063
      return SHMEDIA_MD_PCREL_FROM_FIX (fixP);
3064
 
3065
    case BFD_RELOC_64:
3066
    case BFD_RELOC_64_PCREL:
3067
      /* Fall through.  */
3068
 
3069
    default:
3070
      /* If section was SHcompact, use its function.  */
3071
      return (valueT) md_pcrel_from_section (fixP, sec);
3072
    }
3073
 
3074
  know (0 /* Shouldn't get here.  */);
3075
  return 0;
3076
}
3077
 
3078
/* Create one .cranges descriptor from two symbols, STARTSYM marking begin
3079
   and ENDSYM marking end, and CR_TYPE specifying the type.  */
3080
 
3081
static void
3082
sh64_emit_crange (symbolS *startsym, symbolS *endsym,
3083
                  enum sh64_elf_cr_type cr_type)
3084
{
3085
  expressionS exp;
3086
  segT current_seg = now_seg;
3087
  subsegT current_subseg = now_subseg;
3088
 
3089
  asection *cranges
3090
    = bfd_make_section_old_way (stdoutput,
3091
                                SH64_CRANGES_SECTION_NAME);
3092
 
3093
  /* Temporarily change to the .cranges section.  */
3094
  subseg_set (cranges, 0);
3095
 
3096
  /* Emit the cr_addr part.  */
3097
  exp.X_op = O_symbol;
3098
  exp.X_add_number = 0;
3099
  exp.X_op_symbol = NULL;
3100
  exp.X_add_symbol = startsym;
3101
  emit_expr (&exp, 4);
3102
 
3103
  /* Emit the cr_size part.  */
3104
  exp.X_op = O_subtract;
3105
  exp.X_add_number = 0;
3106
  exp.X_add_symbol = endsym;
3107
  exp.X_op_symbol = startsym;
3108
  emit_expr (&exp, 4);
3109
 
3110
  /* Emit the cr_size part.  */
3111
  exp.X_op = O_constant;
3112
  exp.X_add_number = cr_type;
3113
  exp.X_add_symbol = NULL;
3114
  exp.X_op_symbol = NULL;
3115
  emit_expr (&exp, 2);
3116
 
3117
  /* Now back to our regular program.  */
3118
  subseg_set (current_seg, current_subseg);
3119
}
3120
 
3121
/* Called when the assembler is about to emit contents of some type into
3122
   SEG, so it is *known* that the type of that new contents is in
3123
   NEW_CONTENTS_TYPE.  If just switching back and forth between different
3124
   contents types (for example, with consecutive .mode pseudos), then this
3125
   function isn't called.  */
3126
 
3127
static void
3128
sh64_set_contents_type (enum sh64_elf_cr_type new_contents_type)
3129
{
3130
  segment_info_type *seginfo;
3131
 
3132
  /* We will not be called when emitting .cranges output, since callers
3133
     stop that.  Validize that assumption.  */
3134
  know (!emitting_crange);
3135
 
3136
  seginfo = seg_info (now_seg);
3137
 
3138
  if (seginfo)
3139
    {
3140
      symbolS *symp = seginfo->tc_segment_info_data.last_contents_mark;
3141
 
3142
      enum sh64_elf_cr_type contents_type
3143
        = seginfo->tc_segment_info_data.contents_type;
3144
 
3145
      /* If it was just SHcompact switching between code and constant
3146
         pool, don't change contents type.  Just make sure we don't set
3147
         the contents type to data, as that would join with a data-region
3148
         in SHmedia mode.  */
3149
      if (sh64_isa_mode == sh64_isa_shcompact
3150
          && ! sh64_shcompact_const_crange)
3151
        new_contents_type = CRT_SH5_ISA16;
3152
 
3153
      /* If nothing changed, stop here.  */
3154
      if (contents_type == new_contents_type)
3155
        return;
3156
 
3157
      /* If we're in 64-bit ABI mode, we do not emit .cranges, as it is
3158
         only specified for 32-bit addresses.  It could presumably be
3159
         extended, but in 64-bit ABI mode we don't have SHcompact code, so
3160
         we would only use it to mark code and data.  */
3161
      if (sh64_abi == sh64_abi_64)
3162
        {
3163
          /* Make the code type "sticky".  We don't want to set the
3164
             sections contents type to data if there's any code in it as
3165
             we don't have .cranges in 64-bit mode to notice the
3166
             difference.  */
3167
          seginfo->tc_segment_info_data.contents_type
3168
            = (new_contents_type == CRT_SH5_ISA32
3169
               || contents_type == CRT_SH5_ISA32)
3170
            ? CRT_SH5_ISA32 : new_contents_type;
3171
          return;
3172
        }
3173
 
3174
      /* If none was marked, create a start symbol for this range and
3175
         perhaps as a closing symbol for the old one.  */
3176
      if (symp == NULL)
3177
        symp = symbol_new (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (),
3178
                           frag_now);
3179
 
3180
      /* We will use this symbol, so don't leave a pointer behind.  */
3181
      seginfo->tc_segment_info_data.last_contents_mark = NULL;
3182
 
3183
      /* We'll be making only datalabel references to it, if we emit a
3184
         .cranges descriptor, so remove any code flag.  */
3185
      S_SET_OTHER (symp, S_GET_OTHER (symp) & ~STO_SH5_ISA32);
3186
 
3187
      /* If we have already marked the start of a range, we need to close
3188
         and emit it before marking a new one, so emit a new .cranges
3189
         descriptor into the .cranges section.  */
3190
      if (seginfo->tc_segment_info_data.mode_start_symbol)
3191
        {
3192
          /* If we're not supposed to emit mixed-mode sections, make it an
3193
             error, but continue processing.  */
3194
          if (! sh64_mix
3195
              && (new_contents_type == CRT_SH5_ISA32
3196
                  || contents_type == CRT_SH5_ISA32))
3197
            as_bad (
3198
_("SHmedia code not allowed in same section as constants and SHcompact code"));
3199
 
3200
          emitting_crange = TRUE;
3201
          sh64_emit_crange (seginfo->tc_segment_info_data.mode_start_symbol,
3202
                            symp, contents_type);
3203
          emitting_crange = FALSE;
3204
          seginfo->tc_segment_info_data.emitted_ranges++;
3205
        }
3206
 
3207
      seginfo->tc_segment_info_data.mode_start_symbol = symp;
3208
      seginfo->tc_segment_info_data.mode_start_subseg = now_subseg;
3209
      seginfo->tc_segment_info_data.contents_type = new_contents_type;
3210
 
3211
      /* Always reset this, so the SHcompact code will emit a reloc when
3212
         it prepares to relax.  */
3213
      seginfo->tc_segment_info_data.in_code = 0;
3214
    }
3215
  else
3216
    as_bad (_("No segment info for current section"));
3217
}
3218
 
3219
/* Hook when defining symbols and labels.  We set the ST_OTHER field if
3220
   the symbol is "shmedia" (with "bitor 1" automatically applied).  Simple
3221
   semantics for a label being "shmedia" : It was defined when .mode
3222
   SHmedia was in effect, and it was defined in a code section.  It
3223
   doesn't matter whether or not an assembled opcode is nearby.  */
3224
 
3225
void
3226
sh64_frob_label (symbolS *symp)
3227
{
3228
  segT seg = S_GET_SEGMENT (symp);
3229
  static const symbolS *null = NULL;
3230
 
3231
  /* Reset the tc marker for all newly created symbols.  */
3232
  symbol_set_tc (symp, (symbolS **) &null);
3233
 
3234
  if (seg != NULL && sh64_isa_mode == sh64_isa_shmedia && subseg_text_p (seg))
3235
    S_SET_OTHER (symp, S_GET_OTHER (symp) | STO_SH5_ISA32);
3236
}
3237
 
3238
/* Handle the "datalabel" qualifier.  We need to call "operand", but it's
3239
   static, so a function pointer is passed here instead.  FIXME: A target
3240
   hook for qualifiers is needed; we currently use the md_parse_name
3241
   symbol hook.  */
3242
 
3243
int
3244
sh64_consume_datalabel (const char *name, expressionS *exp,
3245
                        enum expr_mode mode, char *cp,
3246
                        segT (*operandf) (expressionS *, enum expr_mode))
3247
{
3248
  static int parsing_datalabel = 0;
3249
 
3250
  if (strcasecmp (name, "datalabel") == 0)
3251
    {
3252
      int save_parsing_datalabel = parsing_datalabel;
3253
 
3254
      if (parsing_datalabel)
3255
        as_bad (_("duplicate datalabel operator ignored"));
3256
 
3257
      *input_line_pointer = *cp;
3258
      parsing_datalabel = 1;
3259
      (*operandf) (exp, expr_normal);
3260
      parsing_datalabel = save_parsing_datalabel;
3261
 
3262
      if (exp->X_op == O_symbol || exp->X_op == O_PIC_reloc)
3263
        {
3264
          symbolS *symp = exp->X_add_symbol;
3265
          segT symseg = S_GET_SEGMENT (symp);
3266
 
3267
          /* If the symbol is defined to something that is already a
3268
             datalabel, we don't need to bother with any special handling.  */
3269
          if (symseg != undefined_section
3270
              && S_GET_OTHER (symp) != STO_SH5_ISA32)
3271
            /* Do nothing.  */
3272
            ;
3273
          else
3274
            {
3275
              symbolS *dl_symp;
3276
              const char *name = S_GET_NAME (symp);
3277
              char *dl_name
3278
                = xmalloc (strlen (name) + sizeof (DATALABEL_SUFFIX));
3279
 
3280
              /* Now we copy the datalabel-qualified symbol into a symbol
3281
                 with the same name, but with " DL" appended.  We mark the
3282
                 symbol using the TC_SYMFIELD_TYPE field with a pointer to
3283
                 the main symbol, so we don't have to inspect all symbol
3284
                 names.  Note that use of "datalabel" is not expected to
3285
                 be a common case.  */
3286
              strcpy (dl_name, name);
3287
              strcat (dl_name, DATALABEL_SUFFIX);
3288
 
3289
              /* A FAKE_LABEL_NAME marks "$" or ".".  There can be any
3290
                 number of them and all have the same (faked) name; we
3291
                 must make a new one each time.  */
3292
              if (strcmp (name, FAKE_LABEL_NAME) == 0)
3293
                dl_symp = symbol_make (dl_name);
3294
              else
3295
                dl_symp = symbol_find_or_make (dl_name);
3296
 
3297
              free (dl_name);
3298
              symbol_set_value_expression (dl_symp,
3299
                                           symbol_get_value_expression (symp));
3300
              S_SET_SEGMENT (dl_symp, symseg);
3301
              symbol_set_frag (dl_symp, symbol_get_frag (symp));
3302
              symbol_set_tc (dl_symp, &symp);
3303
              copy_symbol_attributes (dl_symp, symp);
3304
              exp->X_add_symbol = dl_symp;
3305
 
3306
              /* Unset the BranchTarget mark that can be set at symbol
3307
                 creation or attributes copying.  */
3308
              S_SET_OTHER (dl_symp, S_GET_OTHER (dl_symp) & ~STO_SH5_ISA32);
3309
 
3310
              /* The GLOBAL and WEAK attributes are not copied over by
3311
                 copy_symbol_attributes.  Do it here.  */
3312
              if (S_IS_WEAK (symp))
3313
                S_SET_WEAK (dl_symp);
3314
              else if (S_IS_EXTERNAL (symp))
3315
                S_SET_EXTERNAL (dl_symp);
3316
            }
3317
        }
3318
      /* Complain about other types of operands than symbol, unless they
3319
         have already been complained about.  A constant is always a
3320
         datalabel.  Removing the low bit would therefore be wrong.
3321
         Complaining about it would also be wrong.  */
3322
      else if (exp->X_op != O_illegal
3323
               && exp->X_op != O_absent
3324
               && exp->X_op != O_constant)
3325
        as_bad (_("Invalid DataLabel expression"));
3326
 
3327
      *cp = *input_line_pointer;
3328
 
3329
      return 1;
3330
    }
3331
 
3332
  return sh_parse_name (name, exp, mode, cp);
3333
}
3334
 
3335
/* This function is called just before symbols are being output.  It
3336
   returns zero when a symbol must be output, non-zero otherwise.
3337
   Datalabel references that were fully resolved to local symbols are not
3338
   necessary to output.  We also do not want to output undefined symbols
3339
   that are not used in relocs.  For symbols that are used in a reloc, it
3340
   does not matter what we set here.  If it is *not* used in a reloc, then
3341
   it was probably the datalabel counterpart that was used in a reloc;
3342
   then we need not output the main symbol.  */
3343
 
3344
int
3345
sh64_exclude_symbol (symbolS *symp)
3346
{
3347
  symbolS *main_symbol = *symbol_get_tc (symp);
3348
 
3349
  return main_symbol != NULL || ! S_IS_DEFINED (symp);
3350
}
3351
 
3352
/* If we haven't seen an insn since the last update, and location
3353
   indicators have moved (a new frag, new location within frag) we have
3354
   emitted data, so change contents type to data.  Forget that we have
3355
   seen a sequence of insns and store the current location so we can mark
3356
   a new region if needed.  */
3357
 
3358
static void
3359
sh64_update_contents_mark (bfd_boolean update_type)
3360
{
3361
  segment_info_type *seginfo;
3362
  seginfo = seg_info (now_seg);
3363
 
3364
  if (seginfo != NULL)
3365
    {
3366
      symbolS *symp = seginfo->tc_segment_info_data.last_contents_mark;
3367
 
3368
      if (symp == NULL)
3369
        {
3370
          symp = symbol_new (FAKE_LABEL_NAME, now_seg,
3371
                             (valueT) frag_now_fix (), frag_now);
3372
          seginfo->tc_segment_info_data.last_contents_mark = symp;
3373
        }
3374
      else
3375
        {
3376
          /* If we have moved location since last flush, we need to emit a
3377
             data range.  The previous contents type ended at the location
3378
             of the last update.  */
3379
          if ((S_GET_VALUE (symp) != frag_now_fix ()
3380
               || symbol_get_frag (symp) != frag_now))
3381
            {
3382
              enum sh64_elf_cr_type contents_type
3383
                = seginfo->tc_segment_info_data.contents_type;
3384
 
3385
              if (update_type
3386
                  && contents_type != CRT_DATA
3387
                  && contents_type != CRT_NONE
3388
                  && ! seen_insn)
3389
                {
3390
                  sh64_set_contents_type (CRT_DATA);
3391
                  symp = seginfo->tc_segment_info_data.last_contents_mark;
3392
                }
3393
 
3394
              /* If the symbol wasn't used up to make up a new range
3395
                 descriptor, update it to this new location.  */
3396
              if (symp)
3397
                {
3398
                  S_SET_VALUE (symp, (valueT) frag_now_fix ());
3399
                  symbol_set_frag (symp, frag_now);
3400
                }
3401
            }
3402
        }
3403
    }
3404
 
3405
  seen_insn = FALSE;
3406
}
3407
 
3408
/* Called when the assembler is about to output some data, or maybe it's
3409
   just switching segments.  */
3410
 
3411
void
3412
sh64_flush_pending_output (void)
3413
{
3414
  sh64_update_contents_mark (TRUE);
3415
  sh_flush_pending_output ();
3416
}
3417
 
3418
/* Flush out the last crange descriptor after all insns have been emitted.  */
3419
 
3420
static void
3421
sh64_flush_last_crange (bfd *abfd ATTRIBUTE_UNUSED, asection *seg,
3422
                        void *countparg ATTRIBUTE_UNUSED)
3423
{
3424
  segment_info_type *seginfo;
3425
 
3426
  seginfo = seg_info (seg);
3427
 
3428
  if (seginfo
3429
      /* Only emit .cranges descriptors if we would make it more than one.  */
3430
      && seginfo->tc_segment_info_data.emitted_ranges != 0)
3431
    {
3432
      symbolS *symp;
3433
 
3434
      /* We need a closing symbol, so switch to the indicated section and
3435
         emit it.  */
3436
 
3437
      /* Change to the section we're about to handle.  */
3438
      subseg_set (seg, seginfo->tc_segment_info_data.mode_start_subseg);
3439
 
3440
      symp = symbol_new (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (),
3441
                         frag_now);
3442
 
3443
      /* We'll be making a datalabel reference to it, so remove any code
3444
         flag.  */
3445
      S_SET_OTHER (symp, S_GET_OTHER (symp) & ~STO_SH5_ISA32);
3446
 
3447
      sh64_emit_crange (seginfo->tc_segment_info_data.mode_start_symbol,
3448
                        symp,
3449
                        seginfo->tc_segment_info_data.contents_type);
3450
    }
3451
}
3452
 
3453
/* If and only if we see a call to md_number_to_chars without flagging the
3454
   start of an insn, we set the contents type to CRT_DATA, and only when
3455
   in SHmedia mode.  Note that by default we don't bother changing when
3456
   going from SHcompact to data, as the constant pools in GCC-generated
3457
   SHcompact code would create an inordinate amount of .cranges
3458
   descriptors.  */
3459
 
3460
static void
3461
sh64_flag_output (void)
3462
{
3463
  if (sh64_isa_mode != sh64_isa_unspecified
3464
      && !seen_insn
3465
      && !sh64_end_of_assembly
3466
      && !emitting_crange)
3467
    {
3468
      md_flush_pending_output ();
3469
      sh64_set_contents_type (CRT_DATA);
3470
    }
3471
}
3472
 
3473
/* Vtables don't need "datalabel" but we allow it by simply deleting
3474
   any we find.  */
3475
 
3476
static char *
3477
strip_datalabels (void)
3478
{
3479
  char *src, *dest, *start=input_line_pointer;
3480
 
3481
  for (src=input_line_pointer, dest=input_line_pointer; *src != '\n'; )
3482
    {
3483
      if (strncasecmp (src, "datalabel", 9) == 0
3484
          && ISSPACE (src[9])
3485
          && (src == start || !(ISALNUM (src[-1])) || src[-1] == '_'))
3486
        src += 10;
3487
      else
3488
        *dest++ = *src++;
3489
    }
3490
 
3491
  if (dest < src)
3492
    *dest = '\n';
3493
  return src + 1;
3494
}
3495
 
3496
static void
3497
sh64_vtable_entry (int ignore ATTRIBUTE_UNUSED)
3498
{
3499
  char *eol = strip_datalabels ();
3500
 
3501
  obj_elf_vtable_entry (0);
3502
  input_line_pointer = eol;
3503
}
3504
 
3505
static void
3506
sh64_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
3507
{
3508
  char *eol = strip_datalabels ();
3509
 
3510
  obj_elf_vtable_inherit (0);
3511
  input_line_pointer = eol;
3512
}
3513
 
3514
int
3515
sh64_fake_label (const char *name)
3516
{
3517
  size_t len;
3518
 
3519
  if (strcmp (name, FAKE_LABEL_NAME) == 0)
3520
    return 1;
3521
 
3522
  len = strlen (name);
3523
  if (len >= (sizeof (DATALABEL_SUFFIX) - 1))
3524
    return strcmp (&name [len - sizeof (DATALABEL_SUFFIX) + 1],
3525
                   DATALABEL_SUFFIX) == 0;
3526
 
3527
  return 0;
3528
}

powered by: WebSVN 2.1.0

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