Back to index

cell-binutils  2.17cvs20070401
tc-sh64.c
Go to the documentation of this file.
00001 /* tc-sh64.c -- Assemble code for the SuperH SH SHcompact and SHmedia.
00002    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
00003    Free Software Foundation.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    GAS is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to
00019    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
00020    Boston, MA 02110-1301, USA.  */
00021 
00022 /* This file defines SHmedia ISA-specific functions and includes tc-sh.c.
00023    The SHcompact ISA is in all useful aspects the "old" sh4 as implemented
00024    in tc-sh.c.  Not making this file part of tc-sh.c makes it easier to
00025    keep a leaner sh[1-4]-only implementation.  */
00026 
00027 #define HAVE_SH64
00028 
00029 #include "as.h"
00030 #include "safe-ctype.h"
00031 #include "opcodes/sh64-opc.h"
00032 
00033 #ifndef OBJ_ELF
00034 #error This file assumes object output is in the ELF format
00035 #endif
00036 
00037 /* Suffix used when we make "datalabel" symbol copies.  It must not
00038    collide with anything that can normally appear in a symbol, "faked
00039    symbol" or local symbol.  */
00040 #define DATALABEL_SUFFIX " DL"
00041 
00042 /* See shmedia_md_apply_fix and shmedia_md_pcrel_from_section for usage.  */
00043 #define SHMEDIA_MD_PCREL_FROM_FIX(FIXP) \
00044  ((FIXP)->fx_size + (FIXP)->fx_where + (FIXP)->fx_frag->fr_address - 4)
00045 
00046 /* We use this internally to see which one is PT and which is a PTA/PTB
00047    that should be error-checked.  We give it a better name here (but not
00048    one that looks official).  Adding it to reloc.c would make it look too
00049    much of a real reloc; it is just used temporarily as a fixup-type.  */
00050 #define SHMEDIA_BFD_RELOC_PT BFD_RELOC_12_PCREL
00051 
00052 typedef struct
00053  {
00054    shmedia_arg_type type;
00055 
00056    /* These could go into a union, but that would uglify the code.  */
00057    int reg;
00058    expressionS immediate;
00059 
00060    /* If IMMEDIATE was a shift-expression, like "(S >> N) & 65535", where
00061       N = 0, 16, 32, 48, used to extract a certain 16-bit-field to make up
00062       a MOVI or SHORI relocation for a symbol, then we put the
00063       corresponding reloc-type here and modify the "immediate" expression
00064       to S.  Otherwise, this is just BFD_RELOC_NONE.  */
00065    bfd_reloc_code_real_type reloctype;
00066  } shmedia_operand_info;
00067 
00068 /* Frag containing last base instruction.  This is put in the TC field in
00069    a frag, so we can emit fixups for fr_opcode without needing to make
00070    sure that the opcode is in the same frag as any variant operand.  */
00071 fragS *sh64_last_insn_frag = NULL;
00072 
00073 typedef struct
00074  {
00075    shmedia_operand_info operands[3];
00076    unsigned long ops_val;
00077  } shmedia_operands_info;
00078 
00079 enum sh64_abi_values
00080  { sh64_abi_unspecified, sh64_abi_32, sh64_abi_64 };
00081 
00082 /* What ISA are we assembling code for?  */
00083 enum sh64_isa_values sh64_isa_mode = sh64_isa_unspecified;
00084 
00085 /* What ABI was specified, if any (implicitly or explicitly)?  */
00086 static enum sh64_abi_values sh64_abi = sh64_abi_unspecified;
00087 
00088 /* A note that says if we're in a sequence of insns without label
00089    settings, segment or ISA mode changes or emitted data.  */
00090 static bfd_boolean seen_insn = FALSE;
00091 
00092 /* This is set to TRUE in shmedia_md_end, so that we don't emit any
00093    .cranges entries when the assembler calls output functions while
00094    grinding along after all input is seen.  */
00095 static bfd_boolean sh64_end_of_assembly = FALSE;
00096 
00097 /* Controlled by the option -no-mix, this invalidates mixing SHcompact and
00098    SHmedia code in the same section, and also invalidates mixing data and
00099    SHmedia code in the same section.  No .cranges will therefore be
00100    emitted, unless -shcompact-const-crange is specified and there is a
00101    constant pool in SHcompact code.  */
00102 static bfd_boolean sh64_mix = TRUE;
00103 
00104 static bfd_boolean sh64_shcompact_const_crange = FALSE;
00105 
00106 /* Controlled by the option -no-expand, this says whether or not we expand
00107    MOVI and PT/PTA/PTB.  When we do not expand these insns to fit an
00108    operand, we will emit errors for operands out of range and generate the
00109    basic instruction and reloc for an external symbol.  */
00110 static bfd_boolean sh64_expand = TRUE;
00111 
00112 /* Controlled by the option -expand-pt32, this says whether we expand
00113    PT/PTA/PTB of an external symbol to (only) 32 or (the full) 64 bits
00114    when -abi=64 is in effect.  */
00115 static bfd_boolean sh64_pt32 = FALSE;
00116 
00117 /* When emitting a .cranges descriptor, we want to avoid getting recursive
00118    calls through emit_expr.  */
00119 static bfd_boolean emitting_crange = FALSE;
00120 
00121 /* SHmedia mnemonics.  */
00122 static struct hash_control *shmedia_opcode_hash_control = NULL;
00123 
00124 static const unsigned char shmedia_big_nop_pattern[4] =
00125  {
00126    (SHMEDIA_NOP_OPC >> 24) & 255, (SHMEDIA_NOP_OPC >> 16) & 255,
00127    (SHMEDIA_NOP_OPC >> 8) & 255, SHMEDIA_NOP_OPC & 255
00128  };
00129 
00130 static const unsigned char shmedia_little_nop_pattern[4] =
00131  {
00132    SHMEDIA_NOP_OPC & 255, (SHMEDIA_NOP_OPC >> 8) & 255,
00133    (SHMEDIA_NOP_OPC >> 16) & 255, (SHMEDIA_NOP_OPC >> 24) & 255
00134  };
00135 
00136 static void shmedia_md_begin (void);
00137 static int shmedia_parse_reg (char *, int *, int *, shmedia_arg_type);
00138 static void shmedia_md_assemble (char *);
00139 static void shmedia_md_apply_fix (fixS *, valueT *);
00140 static int shmedia_md_estimate_size_before_relax (fragS *, segT);
00141 static int shmedia_init_reloc (arelent *, fixS *);
00142 static char *shmedia_get_operands (shmedia_opcode_info *, char *,
00143                                shmedia_operands_info *);
00144 static void s_sh64_mode (int);
00145 static void s_sh64_abi (int);
00146 static void shmedia_md_convert_frag (bfd *, segT, fragS *, bfd_boolean);
00147 static void shmedia_check_limits  (offsetT *, bfd_reloc_code_real_type,
00148                                fixS *);
00149 static void sh64_set_contents_type (enum sh64_elf_cr_type);
00150 static void shmedia_get_operand (char **, shmedia_operand_info *,
00151                              shmedia_arg_type);
00152 static unsigned long shmedia_immediate_op (char *, shmedia_operand_info *,
00153                                       int, bfd_reloc_code_real_type);
00154 static char *shmedia_parse_exp (char *, shmedia_operand_info *);
00155 static void shmedia_frob_file_before_adjust (void);
00156 static void sh64_emit_crange (symbolS *, symbolS *, enum sh64_elf_cr_type);
00157 static void sh64_flush_last_crange (bfd *, asection *, void *);
00158 static void sh64_flag_output (void);
00159 static void sh64_update_contents_mark (bfd_boolean);
00160 static void sh64_vtable_entry (int);
00161 static void sh64_vtable_inherit (int);
00162 static char *strip_datalabels (void);
00163 static int shmedia_build_Mytes (shmedia_opcode_info *,
00164                             shmedia_operands_info *);
00165 static shmedia_opcode_info *shmedia_find_cooked_opcode (char **);
00166 static unsigned long shmedia_mask_number (unsigned long,
00167                                      bfd_reloc_code_real_type);
00168 
00169 #include "tc-sh.c"
00170 
00171 void
00172 shmedia_md_end (void)
00173 {
00174   symbolS *symp;
00175 
00176   /* First, update the last range to include whatever data was last
00177      emitted.  */
00178   sh64_update_contents_mark (TRUE);
00179 
00180   /* Make sure frags generated after this point are not marked with the
00181      wrong ISA; make them easily spottable.  We still want to distinguish
00182      it from sh64_isa_unspecified when we compile for SHcompact or
00183      SHmedia.  */
00184   if (sh64_isa_mode != sh64_isa_unspecified)
00185     sh64_isa_mode = sh64_isa_sh5_guard;
00186 
00187   sh64_end_of_assembly = TRUE;
00188 
00189   bfd_map_over_sections (stdoutput, sh64_flush_last_crange, NULL);
00190 
00191   /* Iterate over segments and emit the last .cranges descriptor.  */
00192   for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
00193     {
00194       symbolS *mainsym = *symbol_get_tc (symp);
00195 
00196       /* Is this a datalabel symbol; does it have a pointer to the main
00197         symbol?  */
00198       if (mainsym != NULL)
00199        {
00200          /* If the datalabel symbol is undefined, check if the main
00201             symbol has changed in that respect.  */
00202          if (S_GET_SEGMENT (symp) == undefined_section)
00203            {
00204              segT symseg;
00205 
00206              symseg = S_GET_SEGMENT (mainsym);
00207 
00208              /* If the symbol is now defined to something that is not
00209                global and without STO_SH5_ISA32, we just equate the
00210                datalabel symbol to the main symbol, and the lack of
00211                STO_SH5_ISA32 will handle the datalabelness.  */
00212              if (symseg != undefined_section)
00213               {
00214                 if (S_GET_OTHER (mainsym) != STO_SH5_ISA32)
00215                   {
00216                     symp->sy_value.X_op = O_symbol;
00217                     symp->sy_value.X_add_symbol = mainsym;
00218                     symp->sy_value.X_op_symbol = NULL;
00219                     symp->sy_value.X_add_number = 0;
00220                     S_SET_SEGMENT (symp, S_GET_SEGMENT (mainsym));
00221                     symbol_set_frag (symp, &zero_address_frag);
00222                     copy_symbol_attributes (symp, mainsym);
00223                   }
00224                 else
00225                   {
00226                     /* An undefined symbol has since we saw it at
00227                       "datalabel", been defined to a BranchTarget
00228                       symbol.  What we need to do here is very similar
00229                       to when we find the "datalabel" for a defined
00230                       symbol.  FIXME: Break out to common function.  */
00231                     symbol_set_value_expression (symp,
00232                                              symbol_get_value_expression
00233                                              (mainsym));
00234                     S_SET_SEGMENT (symp, symseg);
00235                     symbol_set_frag (symp, symbol_get_frag (mainsym));
00236                     copy_symbol_attributes (symp, mainsym);
00237 
00238                     /* Unset the BranchTarget mark that can be set at
00239                       attribute-copying.  */
00240                     S_SET_OTHER (symp,
00241                                S_GET_OTHER (symp) & ~STO_SH5_ISA32);
00242 
00243                     /* The GLOBAL and WEAK attributes are not copied
00244                       over by copy_symbol_attributes.  Do it here.  */
00245                     if (S_IS_WEAK (mainsym))
00246                      S_SET_WEAK (symp);
00247                     else if (S_IS_EXTERNAL (mainsym))
00248                      S_SET_EXTERNAL (symp);
00249                   }
00250               }
00251              else
00252               {
00253                 /* A symbol that was defined at the time we saw
00254                    "datalabel" can since have been attributed with being
00255                    weak or global.  */
00256                 if (S_IS_WEAK (mainsym))
00257                   S_SET_WEAK (symp);
00258                 else if (S_IS_EXTERNAL (mainsym))
00259                   S_SET_EXTERNAL (symp);
00260               }
00261            }
00262        }
00263     }
00264 
00265   for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
00266     if (S_GET_OTHER (symp) & STO_SH5_ISA32)
00267       symp->sy_value.X_add_number++;
00268 }
00269 
00270 /* When resolving symbols, the main assembler has done us a misfavour.  It
00271    has removed the equation to the main symbol for a datalabel reference
00272    that should be equal to the main symbol, e.g. when it's a global or
00273    weak symbol and is a non-BranchTarget symbol anyway.  We change that
00274    back, so that relocs are against the main symbol, not the local "section
00275    + offset" value.  */
00276 
00277 static void
00278 shmedia_frob_file_before_adjust (void)
00279 {
00280   symbolS *symp;
00281   for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
00282     {
00283       symbolS *mainsym = *symbol_get_tc (symp);
00284 
00285       if (mainsym != NULL
00286          && S_GET_OTHER (mainsym) != STO_SH5_ISA32
00287          && (S_IS_EXTERNAL (mainsym) || S_IS_WEAK (mainsym)))
00288        {
00289          symp->sy_value.X_op = O_symbol;
00290          symp->sy_value.X_add_symbol = mainsym;
00291          symp->sy_value.X_op_symbol = NULL;
00292          symp->sy_value.X_add_number = 0;
00293 
00294          /* For the "equation trick" to work, we have to set the section
00295             to undefined.  */
00296          S_SET_SEGMENT (symp, undefined_section);
00297          symbol_set_frag (symp, &zero_address_frag);
00298          copy_symbol_attributes (symp, mainsym);
00299 
00300          /* Don't forget to remove the STO_SH5_ISA32 attribute after
00301             copying the other attributes.  */
00302          S_SET_OTHER (symp, S_GET_OTHER (symp) & ~STO_SH5_ISA32);
00303        }
00304     }
00305 }
00306 
00307 /* We need to mark the current location after the alignment.  This is
00308    copied code the caller, do_align.  We mark the frag location before and
00309    after as we need and arrange to skip the same code in do_align.
00310 
00311    An alternative to code duplication is to call the do_align recursively,
00312    arranging to fall through into do_align if we're already here.  That
00313    would require do_align as an incoming function parameter, since it's
00314    static in read.c.  That solution was discarded a too kludgy.  */
00315 
00316 void
00317 sh64_do_align (int n, const char *fill, int len, int max)
00318 {
00319   /* Update region, or put a data region in front.  */
00320   sh64_update_contents_mark (TRUE);
00321 
00322   /* Only make a frag if we HAVE to...  */
00323   if (n != 0 && !need_pass_2)
00324     {
00325       if (fill == NULL)
00326        {
00327          if (subseg_text_p (now_seg))
00328            frag_align_code (n, max);
00329          else
00330            frag_align (n, 0, max);
00331        }
00332       else if (len <= 1)
00333        frag_align (n, *fill, max);
00334       else
00335        frag_align_pattern (n, fill, len, max);
00336     }
00337 
00338   /* Update mark for current region with current type.  */
00339   sh64_update_contents_mark (FALSE);
00340 }
00341 
00342 /* The MAX_MEM_FOR_RS_ALIGN_CODE worker.  We have to find out the ISA of
00343    the current segment at this position.  We can't look just at
00344    sh64_isa_shmedia, and we can't look at frag_now.  This is brittle:
00345    callers are currently frag_align_code from subsegs_finish in write.c
00346    (end of assembly) and frag_align_code from do_align in read.c (during
00347    assembly).  */
00348 
00349 int
00350 sh64_max_mem_for_rs_align_code (void)
00351 {
00352   segment_info_type *seginfo;
00353   fragS *mode_start_frag;
00354   seginfo = seg_info (now_seg);
00355 
00356   /* We don't use the contents type we find at the tc_segment_info_data,
00357      since that does not give us absolute information about the ISA; the
00358      contents type can presumably be CRT_DATA and we'd be none the wiser.
00359      Instead we use the information stored at the frag of the symbol at
00360      the start of this range.  If any information is missing or NULL,
00361      assume SHcompact.  */
00362   return
00363     /* If the current ISA mode is SHmedia, that's the mode that we're
00364        going to assign to the new frag, so request enough memory for
00365        it, even if we switch modes afterwards, otherwise we may
00366        allocate too little memory and end up overflowing our buffer.  */
00367     (sh64_isa_mode == sh64_isa_shmedia
00368      || (sh64_isa_mode != sh64_isa_unspecified
00369         && seginfo != NULL
00370         && seginfo->tc_segment_info_data.mode_start_symbol != NULL
00371         && ((mode_start_frag
00372              = (symbol_get_frag
00373                (seginfo->tc_segment_info_data.mode_start_symbol)))
00374             != NULL)
00375         && mode_start_frag->tc_frag_data.isa == sh64_isa_shmedia))
00376     ? (3 + 4) : (2 + 1);
00377 }
00378 
00379 /* Put in SHmedia NOP:s if the alignment was created when in SHmedia mode.  */
00380 
00381 void
00382 sh64_handle_align (fragS * frag)
00383 {
00384   int bytes = frag->fr_next->fr_address - frag->fr_address - frag->fr_fix;
00385   char * p  = frag->fr_literal + frag->fr_fix;
00386 
00387   if (frag->tc_frag_data.isa == sh64_isa_shmedia
00388       && frag->fr_type == rs_align_code)
00389     {
00390       while (bytes & 3)
00391        {
00392          *p++ = 0;
00393          bytes--;
00394          frag->fr_fix += 1;
00395        }
00396 
00397       if (target_big_endian)
00398        {
00399          memcpy (p, shmedia_big_nop_pattern,
00400                 sizeof shmedia_big_nop_pattern);
00401          frag->fr_var = sizeof shmedia_big_nop_pattern;
00402        }
00403       else
00404        {
00405          memcpy (p, shmedia_little_nop_pattern,
00406                 sizeof shmedia_little_nop_pattern);
00407          frag->fr_var = sizeof shmedia_little_nop_pattern;
00408        }
00409     }
00410   else
00411     /* Punt to SHcompact function.  */
00412     sh_handle_align (frag);
00413 }
00414 
00415 /* Set SEC_SH64_ISA32 for SHmedia sections.  */
00416 
00417 void
00418 shmedia_frob_section_type (asection *sec)
00419 {
00420   segment_info_type *seginfo;
00421   seginfo = seg_info (sec);
00422 
00423   /* This and elf32-sh64.c:sh64_elf_fake_sections are the only places
00424      where we use anything else than ELF header flags to communicate the
00425      section as containing SHmedia or other contents.  BFD SEC_* section
00426      flags are running out and should not be overloaded with
00427      target-specific semantics.  This target is ELF only (semantics not
00428      defined for other formats), so we use the target-specific pointer
00429      field of the ELF section data.  */
00430   if (seginfo && sh64_abi == sh64_abi_32)
00431     {
00432       struct sh64_section_data *sec_elf_data;
00433       flagword sec_type = 0;
00434 
00435       if (seginfo->tc_segment_info_data.emitted_ranges != 0)
00436        sec_type = SHF_SH5_ISA32_MIXED;
00437       else if (seginfo->tc_segment_info_data.contents_type == CRT_SH5_ISA32)
00438        sec_type = SHF_SH5_ISA32;
00439 
00440       sec_elf_data = sh64_elf_section_data (sec)->sh64_info;
00441       if (sec_elf_data == NULL)
00442        {
00443          sec_elf_data = xcalloc (1, sizeof (*sec_elf_data));
00444          sh64_elf_section_data (sec)->sh64_info = sec_elf_data;
00445        }
00446 
00447       sec_elf_data->contents_flags = sec_type;
00448     }
00449 }
00450 
00451 /* This function is called by write_object_file right before the symbol
00452    table is written.  We subtract 1 from all symbols marked STO_SH5_ISA32,
00453    as their values are temporarily incremented in shmedia_md_end, before
00454    symbols values are used by relocs and fixups.
00455 
00456    To increment all symbols and then decrement here is admittedly a
00457    hackish solution.  The alternative is to add infrastructure and hooks
00458    to symbol evaluation that evaluates symbols differently internally to
00459    the value output into the object file, but at the moment that just
00460    seems too much for little benefit.  */
00461 
00462 void
00463 sh64_adjust_symtab (void)
00464 {
00465   symbolS *symp;
00466 
00467   for (symp = symbol_rootP; symp; symp = symbol_next (symp))
00468     {
00469       symbolS *main_symbol = *symbol_get_tc (symp);
00470 
00471       if (main_symbol)
00472        {
00473          char *sym_name = (char *) S_GET_NAME (symp);
00474 
00475          /* All datalabels not used in relocs should be gone by now.
00476 
00477             We change those remaining to have the name of the main
00478             symbol, and we set the ELF type of the symbol of the reloc to
00479             STT_DATALABEL.  */
00480          sym_name[strlen (sym_name) - strlen (DATALABEL_SUFFIX)] = 0;
00481          elf_symbol (symbol_get_bfdsym (symp))->internal_elf_sym.st_info
00482            = STT_DATALABEL;
00483 
00484          /* Also set this symbol to "undefined", so we'll have only one
00485             definition.  */
00486          S_SET_SEGMENT (symp, undefined_section);
00487        }
00488       else if (S_GET_OTHER (symp) & STO_SH5_ISA32)
00489        {
00490          /* It's important to change the BFD symbol value, since it is now
00491             set to the GAS symbolS value.  */
00492          symp->bsym->value--;
00493 
00494          /* Note that we do *not* adjust symp->sy_value.X_add_number.  If
00495             you do this, the test case in sh/sh64/immexpr2.s will fail.
00496             This is because *after* symbols have been output but before
00497             relocs are output, fixups are inspected one more time, and
00498             some leftover expressions are resolved.  To resolve to the
00499             same values, those expressions must have the same GAS symbol
00500             values before as after symbols have been output.  We could
00501             "symp->sy_value.X_add_number++" on the STO_SH5_ISA32 symbols
00502             through tc_frob_file after symbols have been output, but that
00503             would be too gross.  */
00504        }
00505     }
00506 }
00507 
00508 /* Fill-in an allocated arelent.  */
00509 
00510 static int
00511 shmedia_init_reloc (arelent *rel, fixS *fixP)
00512 {
00513   /* Adjust parts of *relp according to *fixp, and tell that it has been
00514      done, so default initializations will not happen.   */
00515   switch (fixP->fx_r_type)
00516     {
00517     case BFD_RELOC_64:
00518     case BFD_RELOC_64_PCREL:
00519     case BFD_RELOC_SH_IMM_LOW16:
00520     case BFD_RELOC_SH_IMM_MEDLOW16:
00521     case BFD_RELOC_SH_IMM_MEDHI16:
00522     case BFD_RELOC_SH_IMM_HI16:
00523     case BFD_RELOC_SH_IMM_LOW16_PCREL:
00524     case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
00525     case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
00526     case BFD_RELOC_SH_IMM_HI16_PCREL:
00527     case BFD_RELOC_SH_IMMU5:
00528     case BFD_RELOC_SH_IMMU6:
00529     case BFD_RELOC_SH_IMMS6:
00530     case BFD_RELOC_SH_IMMS10:
00531     case BFD_RELOC_SH_IMMS10BY2:
00532     case BFD_RELOC_SH_IMMS10BY4:
00533     case BFD_RELOC_SH_IMMS10BY8:
00534     case BFD_RELOC_SH_IMMS16:
00535     case BFD_RELOC_SH_IMMU16:
00536     case BFD_RELOC_SH_PT_16:
00537     case BFD_RELOC_SH_GOT_LOW16:
00538     case BFD_RELOC_SH_GOT_MEDLOW16:
00539     case BFD_RELOC_SH_GOT_MEDHI16:
00540     case BFD_RELOC_SH_GOT_HI16:
00541     case BFD_RELOC_SH_GOT10BY4:
00542     case BFD_RELOC_SH_GOT10BY8:
00543     case BFD_RELOC_SH_GOTPLT_LOW16:
00544     case BFD_RELOC_SH_GOTPLT_MEDLOW16:
00545     case BFD_RELOC_SH_GOTPLT_MEDHI16:
00546     case BFD_RELOC_SH_GOTPLT_HI16:
00547     case BFD_RELOC_SH_GOTPLT10BY4:
00548     case BFD_RELOC_SH_GOTPLT10BY8:
00549     case BFD_RELOC_SH_GOTOFF_LOW16:
00550     case BFD_RELOC_SH_GOTOFF_MEDLOW16:
00551     case BFD_RELOC_SH_GOTOFF_MEDHI16:
00552     case BFD_RELOC_SH_GOTOFF_HI16:
00553     case BFD_RELOC_SH_GOTPC_LOW16:
00554     case BFD_RELOC_SH_GOTPC_MEDLOW16:
00555     case BFD_RELOC_SH_GOTPC_MEDHI16:
00556     case BFD_RELOC_SH_GOTPC_HI16:
00557     case BFD_RELOC_SH_PLT_LOW16:
00558     case BFD_RELOC_SH_PLT_MEDLOW16:
00559     case BFD_RELOC_SH_PLT_MEDHI16:
00560     case BFD_RELOC_SH_PLT_HI16:
00561       rel->addend = fixP->fx_addnumber + fixP->fx_offset;
00562       return 1;
00563 
00564     case BFD_RELOC_SH_IMMS6BY32:
00565       /* This must be resolved in assembly; we do not support it as a
00566         reloc in an object file.  */
00567       as_bad_where (fixP->fx_file, fixP->fx_line,
00568                   _("This operand must be constant at assembly time"));
00569       break;
00570 
00571       /* There are valid cases where we get here for other than SHmedia
00572         relocs, so don't make a BAD_CASE out of this.  */
00573     default:
00574       ;
00575     }
00576 
00577   return 0;
00578 }
00579 
00580 /* Hook called from md_apply_fix in tc-sh.c.  */
00581 
00582 static void
00583 shmedia_md_apply_fix (fixS *fixP, valueT *valp)
00584 {
00585   offsetT val = *valp;
00586   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
00587   unsigned long insn
00588     = target_big_endian ? bfd_getb32 (buf) : bfd_getl32 (buf);
00589   bfd_reloc_code_real_type orig_fx_r_type = fixP->fx_r_type;
00590 
00591   /* Change a 64-bit pc-relative reloc into the correct type, just like
00592      tc-sh.c:md_apply_fix.  */
00593   if (fixP->fx_pcrel)
00594     {
00595       switch (orig_fx_r_type)
00596        {
00597        case BFD_RELOC_64:
00598        case BFD_RELOC_SH_IMM_LOW16:
00599        case BFD_RELOC_SH_IMM_MEDLOW16:
00600        case BFD_RELOC_SH_IMM_MEDHI16:
00601        case BFD_RELOC_SH_IMM_HI16:
00602          /* Because write.c calls MD_PCREL_FROM_SECTION twice, we need to
00603             undo one of the adjustments, if the relocation is not
00604             actually for a symbol within the same segment (which we
00605             cannot check, because we're not called from md_apply_fix, so
00606             we have to keep the reloc).  FIXME: This is a bug in
00607             write.c:fixup_segment affecting most targets that change
00608             ordinary relocs to pcrel relocs in md_apply_fix.  */
00609          fixP->fx_offset
00610            = *valp + SHMEDIA_MD_PCREL_FROM_FIX (fixP);
00611          break;
00612 
00613        case BFD_RELOC_SH_PLT_LOW16:
00614        case BFD_RELOC_SH_PLT_MEDLOW16:
00615        case BFD_RELOC_SH_PLT_MEDHI16:
00616        case BFD_RELOC_SH_PLT_HI16:
00617        case BFD_RELOC_SH_GOTPC_LOW16:
00618        case BFD_RELOC_SH_GOTPC_MEDLOW16:
00619        case BFD_RELOC_SH_GOTPC_MEDHI16:
00620        case BFD_RELOC_SH_GOTPC_HI16:
00621          *valp = 0;
00622          return;
00623 
00624        default:
00625          ;
00626        }
00627 
00628       /* We might need to change some relocs into the corresponding
00629         PC-relative one.  */
00630       switch (orig_fx_r_type)
00631        {
00632        case BFD_RELOC_64:
00633          fixP->fx_r_type = BFD_RELOC_64_PCREL;
00634          break;
00635 
00636        case BFD_RELOC_SH_IMM_LOW16:
00637          fixP->fx_r_type = BFD_RELOC_SH_IMM_LOW16_PCREL;
00638          break;
00639 
00640        case BFD_RELOC_SH_IMM_MEDLOW16:
00641          fixP->fx_r_type = BFD_RELOC_SH_IMM_MEDLOW16_PCREL;
00642          break;
00643 
00644        case BFD_RELOC_SH_IMM_MEDHI16:
00645          fixP->fx_r_type = BFD_RELOC_SH_IMM_MEDHI16_PCREL;
00646          break;
00647 
00648        case BFD_RELOC_SH_IMM_HI16:
00649          fixP->fx_r_type = BFD_RELOC_SH_IMM_HI16_PCREL;
00650          break;
00651 
00652        case SHMEDIA_BFD_RELOC_PT:
00653          /* This is how we see a difference between PT and PTA when not
00654             expanding (in which case we handle it in
00655             shmedia_md_convert_frag).  Note that we don't see a
00656             difference after the reloc is emitted.  */
00657          fixP->fx_r_type = BFD_RELOC_SH_PT_16;
00658          break;
00659 
00660        case BFD_RELOC_SH_PT_16:
00661          /* This tells us there was a PTA or PTB insn explicitly
00662             expressed as such (not as PT).  We "or" in a 1 into the
00663             lowest bit in the (unused) destination field to tell the
00664             linker that it should check the right ISA type of the
00665             destination and not just change a PTA to PTB (if necessary).  */
00666          md_number_to_chars (buf, insn | (1 << 10), 4);
00667          break;
00668 
00669        case BFD_RELOC_64_PCREL:
00670        case BFD_RELOC_SH_IMM_LOW16_PCREL:
00671        case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
00672        case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
00673        case BFD_RELOC_SH_IMM_HI16_PCREL:
00674          /* Already handled.  */
00675          break;
00676 
00677        default:
00678          /* Everything else that changes into a pc-relative relocation is
00679             an error.  */
00680          as_bad_where (fixP->fx_file, fixP->fx_line,
00681                      _("Invalid operand expression"));
00682          break;
00683        }
00684 
00685       return;
00686     }
00687 
00688   /* If an expression looked like it was PC-relative, but was completely
00689      resolvable, we end up here with the result only in *VALP, and no
00690      relocation will be emitted.  */
00691   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
00692     {
00693       /* Emit error for an out-of-range value.  */
00694       shmedia_check_limits ((offsetT *) valp, fixP->fx_r_type, fixP);
00695 
00696       switch (fixP->fx_r_type)
00697        {
00698        case BFD_RELOC_SH_IMM_LOW16:
00699          md_number_to_chars (buf, insn | ((val & 65535) << 10), 4);
00700          break;
00701 
00702        case BFD_RELOC_SH_IMM_MEDLOW16:
00703          md_number_to_chars (buf,
00704                            insn
00705                            | ((valueT) (val & ((valueT) 65535 << 16))
00706                              >> (16 - 10)), 4);
00707          break;
00708 
00709        case BFD_RELOC_SH_IMM_MEDHI16:
00710          md_number_to_chars (buf,
00711                            insn
00712                            | ((valueT) (val & ((valueT) 65535 << 32))
00713                              >> (32 - 10)), 4);
00714          break;
00715 
00716        case BFD_RELOC_SH_IMM_HI16:
00717          md_number_to_chars (buf,
00718                            insn
00719                            | ((valueT) (val & ((valueT) 65535 << 48))
00720                              >> (48 - 10)), 4);
00721          break;
00722 
00723        case BFD_RELOC_SH_IMMS16:
00724        case BFD_RELOC_SH_IMMU16:
00725          md_number_to_chars (buf, insn | ((val & 65535) << 10), 4);
00726          break;
00727 
00728        case BFD_RELOC_SH_IMMS10:
00729          md_number_to_chars (buf, insn | ((val & 0x3ff) << 10), 4);
00730          break;
00731 
00732        case BFD_RELOC_SH_IMMS10BY2:
00733          md_number_to_chars (buf,
00734                            insn | ((val & (0x3ff << 1)) << (10 - 1)), 4);
00735          break;
00736 
00737        case BFD_RELOC_SH_IMMS10BY4:
00738          md_number_to_chars (buf,
00739                            insn | ((val & (0x3ff << 2)) << (10 - 2)), 4);
00740          break;
00741 
00742        case BFD_RELOC_SH_IMMS10BY8:
00743          md_number_to_chars (buf,
00744                            insn | ((val & (0x3ff << 3)) << (10 - 3)), 4);
00745          break;
00746 
00747        case BFD_RELOC_SH_SHMEDIA_CODE:
00748          /* We just ignore and remove this one for the moment.  FIXME:
00749             Use it when implementing relaxing.  */
00750          break;
00751 
00752        case BFD_RELOC_64:
00753          md_number_to_chars (buf, val, 8);
00754          break;
00755 
00756        case SHMEDIA_BFD_RELOC_PT:
00757          /* Change a PT to PTB if the operand turned out to be SHcompact.
00758             The basic opcode specified with PT is equivalent to PTA.  */
00759          if ((val & 1) == 0)
00760            insn |= SHMEDIA_PTB_BIT;
00761          /* Fall through.  */
00762 
00763        case BFD_RELOC_SH_PT_16:
00764          if (! sh64_expand || sh_relax)
00765            {
00766              /* Check if the operand of a PTA or PTB was for the "wrong"
00767                ISA.  A PT had an incoming fixup of SHMEDIA_BFD_RELOC_PT,
00768                which we have changed to the right type above.  */
00769              if (orig_fx_r_type != SHMEDIA_BFD_RELOC_PT)
00770               {
00771                 if ((insn & SHMEDIA_PTB_BIT) != 0 && (val & 1) != 0)
00772                   as_bad_where (fixP->fx_file, fixP->fx_line,
00773                               _("PTB operand is a SHmedia symbol"));
00774                 else if ((insn & SHMEDIA_PTB_BIT) == 0 && (val & 1) == 0)
00775                   as_bad_where (fixP->fx_file, fixP->fx_line,
00776                               _("PTA operand is a SHcompact symbol"));
00777               }
00778 
00779              md_number_to_chars (buf,
00780                               insn | ((val & (0xffff << 2))
00781                                      << (10 - 2)),
00782                               4);
00783              break;
00784            }
00785          /* Fall through.  */
00786 
00787        default:
00788          /* This isn't a BAD_CASE, because presumably we can get here
00789             from unexpected operands.  Since we don't handle them, make
00790             them syntax errors.  */
00791          as_bad_where (fixP->fx_file, fixP->fx_line,
00792                      _("invalid expression in operand"));
00793        }
00794       fixP->fx_done = 1;
00795     }
00796 }
00797 
00798 /* Hook called from md_convert_frag in tc-sh.c.  */
00799 
00800 static void
00801 shmedia_md_convert_frag (bfd *output_bfd ATTRIBUTE_UNUSED,
00802                       segT seg ATTRIBUTE_UNUSED, fragS *fragP,
00803                       bfd_boolean final)
00804 {
00805   /* Pointer to first byte in variable-sized part of the frag. */
00806   char *var_partp;
00807 
00808   /* Pointer to first opcode byte in frag.  */
00809   char *opcodep;
00810 
00811   /* Pointer to frag of opcode.  */
00812   fragS *opc_fragP = fragP->tc_frag_data.opc_frag;
00813 
00814   /* Size in bytes of variable-sized part of frag.  */
00815   int var_part_size = 0;
00816 
00817   /* This is part of *fragP.  It contains all information about addresses
00818      and offsets to varying parts.  */
00819   symbolS *symbolP = fragP->fr_symbol;
00820 
00821   bfd_boolean reloc_needed
00822     = (! final
00823        || sh_relax
00824        || symbolP == NULL
00825        || ! S_IS_DEFINED (symbolP)
00826        || S_IS_EXTERNAL (symbolP)
00827        || S_IS_WEAK (symbolP)
00828        || (S_GET_SEGMENT (fragP->fr_symbol) != absolute_section
00829           && S_GET_SEGMENT (fragP->fr_symbol) != seg));
00830 
00831   bfd_reloc_code_real_type reloctype = BFD_RELOC_NONE;
00832 
00833   unsigned long var_part_offset;
00834 
00835   /* Where, in file space, does addr point?  */
00836   bfd_vma target_address;
00837   bfd_vma opcode_address;
00838 
00839   /* What was the insn?  */
00840   unsigned long insn;
00841   know (fragP->fr_type == rs_machine_dependent);
00842 
00843   var_part_offset = fragP->fr_fix;
00844   var_partp = fragP->fr_literal + var_part_offset;
00845   opcodep = fragP->fr_opcode;
00846 
00847   insn = target_big_endian ? bfd_getb32 (opcodep) : bfd_getl32 (opcodep);
00848 
00849   target_address
00850     = ((symbolP && final && ! sh_relax ? S_GET_VALUE (symbolP) : 0)
00851        + fragP->fr_offset);
00852 
00853   /* The opcode that would be extended is the last four "fixed" bytes.  */
00854   opcode_address = fragP->fr_address + fragP->fr_fix - 4;
00855 
00856   switch (fragP->fr_subtype)
00857     {
00858     case C (SH64PCREL16PT_64, SH64PCREL16):
00859     case C (SH64PCREL16PT_32, SH64PCREL16):
00860       /* We can get a PT to a relaxed SHcompact address if it is in the
00861         same section; a mixed-ISA section.  Change the opcode to PTB if
00862         so.  */
00863       if ((target_address & 1) == 0)
00864        insn |= SHMEDIA_PTB_BIT;
00865       /* Fall through.  */
00866 
00867     case C (SH64PCREL16_32, SH64PCREL16):
00868     case C (SH64PCREL16_64, SH64PCREL16):
00869       /* Check that a PTA or PTB points to the right type of target.  We
00870         can get here for a SHcompact target if we are in a mixed-ISA
00871         section.  */
00872       if (((target_address & 1) == 0) && ((insn & SHMEDIA_PTB_BIT) == 0))
00873        as_bad_where (fragP->fr_file, fragP->fr_line,
00874                     _("PTA operand is a SHcompact symbol"));
00875       if (((target_address & 1) != 0) && ((insn & SHMEDIA_PTB_BIT) != 0))
00876        as_bad_where (fragP->fr_file, fragP->fr_line,
00877                     _("PTB operand is a SHmedia symbol"));
00878 
00879       /* When relaxing, we do not output the address in the insn, but
00880         instead a 1 into the low bit.  This matches what the linker
00881         expects to find for a BFD_RELOC_SH_PT_16 reloc, when it checks
00882         correctness for PTA/PTB insn; used when the target address is
00883         unknown (which is not the case here).  */
00884       md_number_to_chars (opcodep,
00885                        insn
00886                        | (((sh_relax
00887                             ? 1 : ((target_address - opcode_address) / 4))
00888                            & ((1 << 16) - 1)) << 10),
00889                        4);
00890 
00891       /* Note that we do not emit info that this was originally a PT since
00892         we have resolved to which one of PTA or PTB it will be.  */
00893       if (sh_relax)
00894        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
00895                fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_SH_PT_16);
00896       var_part_size = 0;
00897       break;
00898 
00899     case C (SH64PCREL16_32, SH64PCRELPLT):
00900     case C (SH64PCREL16PT_32, SH64PCRELPLT):
00901       reloctype = BFD_RELOC_32_PLT_PCREL;
00902       reloc_needed = 1;
00903       /* Fall through */
00904 
00905     case C (SH64PCREL16_32, SH64PCREL32):
00906     case C (SH64PCREL16_64, SH64PCREL32):
00907     case C (SH64PCREL16PT_32, SH64PCREL32):
00908     case C (SH64PCREL16PT_64, SH64PCREL32):
00909       /* In the fixed bit, put in a MOVI.  */
00910       md_number_to_chars (opcodep,
00911                        SHMEDIA_MOVI_OPC
00912                        | (SHMEDIA_TEMP_REG << 4)
00913                        | ((((reloc_needed
00914                             ? 0 : (target_address - (opcode_address + 8))
00915                             ) >> 16) & 65535) << 10),
00916                        4);
00917 
00918       /* Fill in a SHORI for the low part.  */
00919       md_number_to_chars (var_partp,
00920                        SHMEDIA_SHORI_OPC
00921                        | (SHMEDIA_TEMP_REG << 4)
00922                        | (((reloc_needed
00923                             ? 0 : (target_address - (opcode_address + 8)))
00924                            & 65535) << 10),
00925                        4);
00926 
00927       /* End with a "PTREL R25,TRd".  */
00928       md_number_to_chars (var_partp + 4,
00929                        SHMEDIA_PTREL_OPC | (insn & SHMEDIA_LIKELY_BIT)
00930                        | (SHMEDIA_TEMP_REG << 10)
00931                        | (insn & (7 << 4)),
00932                        4);
00933 
00934       /* We need relocs only if the target symbol was undefined or if
00935         we're relaxing.  */
00936       if (reloc_needed)
00937        {
00938          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
00939                  fragP->fr_symbol, fragP->fr_offset - 8, 1,
00940                  reloctype == BFD_RELOC_32_PLT_PCREL
00941                  ? BFD_RELOC_SH_PLT_MEDLOW16
00942                  : BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
00943          fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
00944                  fragP->fr_offset - 4, 1,
00945                  reloctype == BFD_RELOC_32_PLT_PCREL
00946                  ? BFD_RELOC_SH_PLT_LOW16
00947                  : BFD_RELOC_SH_IMM_LOW16_PCREL);
00948        }
00949 
00950       var_part_size = 8;
00951       break;
00952 
00953     case C (SH64PCREL16_64, SH64PCREL48):
00954     case C (SH64PCREL16PT_64, SH64PCREL48):
00955       /* In the fixed bit, put in a MOVI.  */
00956       md_number_to_chars (opcodep,
00957                        SHMEDIA_MOVI_OPC
00958                        | (SHMEDIA_TEMP_REG << 4)
00959                        | ((((reloc_needed
00960                             ? 0 : (target_address - (opcode_address + 12))
00961                             ) >> 32) & 65535) << 10),
00962                        4);
00963 
00964       /* The first SHORI, for the medium part.  */
00965       md_number_to_chars (var_partp,
00966                        SHMEDIA_SHORI_OPC
00967                        | (SHMEDIA_TEMP_REG << 4)
00968                        | ((((reloc_needed
00969                             ? 0 : (target_address - (opcode_address + 12))
00970                             ) >> 16) & 65535) << 10),
00971                        4);
00972 
00973       /* Fill in a SHORI for the low part.  */
00974       md_number_to_chars (var_partp + 4,
00975                        SHMEDIA_SHORI_OPC
00976                        | (SHMEDIA_TEMP_REG << 4)
00977                        | (((reloc_needed
00978                             ? 0 : (target_address - (opcode_address + 12)))
00979                            & 65535) << 10),
00980                        4);
00981 
00982       /* End with a "PTREL R25,TRd".  */
00983       md_number_to_chars (var_partp + 8,
00984                        SHMEDIA_PTREL_OPC | (insn & SHMEDIA_LIKELY_BIT)
00985                        | (SHMEDIA_TEMP_REG << 10)
00986                        | (insn & (7 << 4)),
00987                        4);
00988 
00989       /* We need relocs only if the target symbol was undefined or if
00990         we're relaxing.  */
00991       if (reloc_needed)
00992        {
00993          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
00994                  fragP->fr_symbol, fragP->fr_offset - 12, 1,
00995                  reloctype == BFD_RELOC_32_PLT_PCREL
00996                  ? BFD_RELOC_SH_PLT_MEDHI16
00997                  : BFD_RELOC_SH_IMM_MEDHI16_PCREL);
00998          fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
00999                  fragP->fr_offset - 8, 1,
01000                  reloctype == BFD_RELOC_32_PLT_PCREL
01001                  ? BFD_RELOC_SH_PLT_MEDLOW16
01002                  : BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
01003          fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
01004                  fragP->fr_offset - 4, 1,
01005                  reloctype == BFD_RELOC_32_PLT_PCREL
01006                  ? BFD_RELOC_SH_PLT_LOW16
01007                  : BFD_RELOC_SH_IMM_LOW16_PCREL);
01008        }
01009 
01010       var_part_size = 12;
01011       break;
01012 
01013     case C (SH64PCREL16_64, SH64PCRELPLT):
01014     case C (SH64PCREL16PT_64, SH64PCRELPLT):
01015       reloctype = BFD_RELOC_32_PLT_PCREL;
01016       reloc_needed = 1;
01017       /* Fall through */
01018 
01019     case C (SH64PCREL16_64, SH64PCREL64):
01020     case C (SH64PCREL16PT_64, SH64PCREL64):
01021       /* In the fixed bit, put in a MOVI.  */
01022       md_number_to_chars (opcodep,
01023                        SHMEDIA_MOVI_OPC
01024                        | (SHMEDIA_TEMP_REG << 4)
01025                        | ((((reloc_needed
01026                             ? 0 : (target_address - (opcode_address + 16))
01027                             ) >> 48) & 65535) << 10),
01028                        4);
01029 
01030       /* The first SHORI, for the medium-high part.  */
01031       md_number_to_chars (var_partp,
01032                        SHMEDIA_SHORI_OPC
01033                        | (SHMEDIA_TEMP_REG << 4)
01034                        | ((((reloc_needed
01035                             ? 0 : (target_address - (opcode_address + 16))
01036                             ) >> 32) & 65535) << 10),
01037                        4);
01038 
01039       /* A SHORI, for the medium-low part.  */
01040       md_number_to_chars (var_partp + 4,
01041                        SHMEDIA_SHORI_OPC
01042                        | (SHMEDIA_TEMP_REG << 4)
01043                        | ((((reloc_needed
01044                             ? 0 : (target_address - (opcode_address + 16))
01045                             ) >> 16) & 65535) << 10),
01046                        4);
01047 
01048       /* Fill in a SHORI for the low part.  */
01049       md_number_to_chars (var_partp + 8,
01050                        SHMEDIA_SHORI_OPC
01051                        | (SHMEDIA_TEMP_REG << 4)
01052                        | (((reloc_needed
01053                             ? 0 : (target_address - (opcode_address + 16)))
01054                            & 65535) << 10),
01055                        4);
01056 
01057       /* End with a "PTREL R25,TRd".  */
01058       md_number_to_chars (var_partp + 12,
01059                        SHMEDIA_PTREL_OPC | (insn & SHMEDIA_LIKELY_BIT)
01060                        | (SHMEDIA_TEMP_REG << 10)
01061                        | (insn & (7 << 4)),
01062                        4);
01063 
01064       /* We need relocs only if the target symbol was undefined or if
01065         we're relaxing.  */
01066       if (reloc_needed)
01067        {
01068          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01069                  fragP->fr_symbol, fragP->fr_offset - 16, 1,
01070                  reloctype == BFD_RELOC_32_PLT_PCREL
01071                  ? BFD_RELOC_SH_PLT_HI16
01072                  : BFD_RELOC_SH_IMM_HI16_PCREL);
01073          fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
01074                  fragP->fr_offset - 12, 1,
01075                  reloctype == BFD_RELOC_32_PLT_PCREL
01076                  ? BFD_RELOC_SH_PLT_MEDHI16
01077                  : BFD_RELOC_SH_IMM_MEDHI16_PCREL);
01078          fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
01079                  fragP->fr_offset - 8, 1,
01080                  reloctype == BFD_RELOC_32_PLT_PCREL
01081                  ? BFD_RELOC_SH_PLT_MEDLOW16
01082                  : BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
01083          fix_new (fragP, var_partp - fragP->fr_literal + 8, 4, fragP->fr_symbol,
01084                  fragP->fr_offset - 4, 1,
01085                  reloctype == BFD_RELOC_32_PLT_PCREL
01086                  ? BFD_RELOC_SH_PLT_LOW16
01087                  : BFD_RELOC_SH_IMM_LOW16_PCREL);
01088        }
01089 
01090       var_part_size = 16;
01091       break;
01092 
01093     case C (MOVI_IMM_64, MOVI_GOTOFF):
01094       reloctype = BFD_RELOC_32_GOTOFF;
01095       reloc_needed = 1;
01096       /* Fall through.  */
01097 
01098     case C (MOVI_IMM_64, UNDEF_MOVI):
01099     case C (MOVI_IMM_64, MOVI_64):
01100       {
01101        /* We only get here for undefined symbols, so we can simplify
01102           handling compared to those above; we have 0 in the parts that
01103           will be filled with the symbol parts.  */
01104 
01105        int reg = (insn >> 4) & 0x3f;
01106 
01107        /* In the fixed bit, put in a MOVI.  */
01108        md_number_to_chars (opcodep, SHMEDIA_MOVI_OPC | (reg << 4), 4);
01109        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01110                fragP->fr_symbol, fragP->fr_offset, 0,
01111                reloctype == BFD_RELOC_NONE
01112                ? BFD_RELOC_SH_IMM_HI16
01113                : reloctype == BFD_RELOC_32_GOTOFF
01114                ? BFD_RELOC_SH_GOTOFF_HI16
01115                : (abort (), BFD_RELOC_SH_IMM_HI16));
01116 
01117        /* The first SHORI, for the medium-high part.  */
01118        md_number_to_chars (var_partp, SHMEDIA_SHORI_OPC | (reg << 4), 4);
01119        fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
01120                fragP->fr_offset, 0,
01121                reloctype == BFD_RELOC_NONE
01122                ? BFD_RELOC_SH_IMM_MEDHI16
01123                : reloctype == BFD_RELOC_32_GOTOFF
01124                ? BFD_RELOC_SH_GOTOFF_MEDHI16
01125                : (abort (), BFD_RELOC_SH_IMM_MEDHI16));
01126 
01127        /* A SHORI, for the medium-low part.  */
01128        md_number_to_chars (var_partp + 4,
01129                          SHMEDIA_SHORI_OPC | (reg << 4), 4);
01130        fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
01131                fragP->fr_offset, 0,
01132                reloctype == BFD_RELOC_NONE
01133                ? BFD_RELOC_SH_IMM_MEDLOW16
01134                : reloctype == BFD_RELOC_32_GOTOFF
01135                ? BFD_RELOC_SH_GOTOFF_MEDLOW16
01136                : (abort (), BFD_RELOC_SH_IMM_MEDLOW16));
01137 
01138        /* Fill in a SHORI for the low part.  */
01139        md_number_to_chars (var_partp + 8,
01140                          SHMEDIA_SHORI_OPC | (reg << 4), 4);
01141        fix_new (fragP, var_partp - fragP->fr_literal + 8, 4, fragP->fr_symbol,
01142                fragP->fr_offset, 0,
01143                reloctype == BFD_RELOC_NONE
01144                ? BFD_RELOC_SH_IMM_LOW16
01145                : reloctype == BFD_RELOC_32_GOTOFF
01146                ? BFD_RELOC_SH_GOTOFF_LOW16
01147                : (abort (), BFD_RELOC_SH_IMM_LOW16));
01148 
01149        var_part_size = 12;
01150        break;
01151       }
01152 
01153     case C (MOVI_IMM_32, MOVI_GOTOFF):
01154       reloctype = BFD_RELOC_32_GOTOFF;
01155       reloc_needed = 1;
01156       /* Fall through.  */
01157 
01158     case C (MOVI_IMM_32, UNDEF_MOVI):
01159     case C (MOVI_IMM_32, MOVI_32):
01160       {
01161        /* Note that we only get here for undefined symbols.  */
01162 
01163        int reg = (insn >> 4) & 0x3f;
01164 
01165        /* A MOVI, for the high part.  */
01166        md_number_to_chars (opcodep, SHMEDIA_MOVI_OPC | (reg << 4), 4);
01167        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01168                fragP->fr_symbol, fragP->fr_offset, 0,
01169                reloctype == BFD_RELOC_NONE
01170                ? BFD_RELOC_SH_IMM_MEDLOW16
01171                : reloctype == BFD_RELOC_32_GOTOFF
01172                ? BFD_RELOC_SH_GOTOFF_MEDLOW16
01173                : reloctype == BFD_RELOC_SH_GOTPC
01174                ? BFD_RELOC_SH_GOTPC_MEDLOW16
01175                : reloctype == BFD_RELOC_32_PLT_PCREL
01176                ? BFD_RELOC_SH_PLT_MEDLOW16
01177                : (abort (), BFD_RELOC_SH_IMM_MEDLOW16));
01178 
01179        /* Fill in a SHORI for the low part.  */
01180        md_number_to_chars (var_partp,
01181                          SHMEDIA_SHORI_OPC | (reg << 4), 4);
01182        fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
01183                fragP->fr_offset, 0,
01184                reloctype == BFD_RELOC_NONE
01185                ? BFD_RELOC_SH_IMM_LOW16
01186                : reloctype == BFD_RELOC_32_GOTOFF
01187                ? BFD_RELOC_SH_GOTOFF_LOW16
01188                : reloctype == BFD_RELOC_SH_GOTPC
01189                ? BFD_RELOC_SH_GOTPC_LOW16
01190                : reloctype == BFD_RELOC_32_PLT_PCREL
01191                ? BFD_RELOC_SH_PLT_LOW16
01192                : (abort (), BFD_RELOC_SH_IMM_LOW16));
01193 
01194        var_part_size = 4;
01195        break;
01196       }
01197 
01198     case C (MOVI_IMM_32_PCREL, MOVI_16):
01199     case C (MOVI_IMM_64_PCREL, MOVI_16):
01200       md_number_to_chars (opcodep,
01201                        insn
01202                        | (((reloc_needed
01203                             ? 0 : (target_address - opcode_address))
01204                            & 65535) << 10),
01205                        4);
01206       if (reloc_needed)
01207        fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01208                fragP->fr_symbol, fragP->fr_offset, 1,
01209                BFD_RELOC_SH_IMM_LOW16_PCREL);
01210       var_part_size = 0;
01211       break;
01212 
01213     case C (MOVI_IMM_32, MOVI_16):
01214     case C (MOVI_IMM_64, MOVI_16):
01215       md_number_to_chars (opcodep,
01216                        insn
01217                        | (((reloc_needed ? 0 : target_address)
01218                            & 65535) << 10),
01219                        4);
01220       if (reloc_needed)
01221        abort ();
01222       var_part_size = 0;
01223       break;
01224 
01225     case C (MOVI_IMM_32_PCREL, MOVI_PLT):
01226       reloctype = BFD_RELOC_32_PLT_PCREL;
01227       goto movi_imm_32_pcrel_reloc_needed;
01228 
01229     case C (MOVI_IMM_32_PCREL, MOVI_GOTPC):
01230       reloctype = BFD_RELOC_SH_GOTPC;
01231       /* Fall through.  */
01232 
01233     movi_imm_32_pcrel_reloc_needed:
01234       reloc_needed = 1;
01235       /* Fall through.  */
01236 
01237     case C (MOVI_IMM_32_PCREL, MOVI_32):
01238     case C (MOVI_IMM_64_PCREL, MOVI_32):
01239       {
01240        int reg = (insn >> 4) & 0x3f;
01241 
01242        md_number_to_chars (opcodep,
01243                          insn
01244                          | (((((reloc_needed
01245                                ? 0 : (target_address - opcode_address)))
01246                             >> 16) & 65535) << 10), 4);
01247 
01248        /* A SHORI, for the low part.  */
01249        md_number_to_chars (var_partp,
01250                          SHMEDIA_SHORI_OPC
01251                          | (reg << 4)
01252                          | (((reloc_needed
01253                              ? 0 : (target_address - opcode_address))
01254                             & 65535) << 10), 4);
01255        if (reloc_needed)
01256          {
01257            fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01258                    fragP->fr_symbol, fragP->fr_offset, 1,
01259                    reloctype == BFD_RELOC_NONE
01260                    ? BFD_RELOC_SH_IMM_MEDLOW16_PCREL
01261                    : reloctype == BFD_RELOC_SH_GOTPC
01262                    ? BFD_RELOC_SH_GOTPC_MEDLOW16
01263                    : reloctype == BFD_RELOC_32_PLT_PCREL
01264                    ? BFD_RELOC_SH_PLT_MEDLOW16
01265                    : (abort (), BFD_RELOC_SH_IMM_MEDLOW16_PCREL));
01266            fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
01267                    fragP->fr_offset + 4, 1,
01268                    reloctype == BFD_RELOC_NONE
01269                    ? BFD_RELOC_SH_IMM_LOW16_PCREL
01270                    : reloctype == BFD_RELOC_SH_GOTPC
01271                    ? BFD_RELOC_SH_GOTPC_LOW16
01272                    : reloctype == BFD_RELOC_32_PLT_PCREL
01273                    ? BFD_RELOC_SH_PLT_LOW16
01274                    : (abort (), BFD_RELOC_SH_IMM_LOW16_PCREL));
01275          }
01276        var_part_size = 4;
01277       }
01278       break;
01279 
01280     case C (MOVI_IMM_32_PCREL, MOVI_48):
01281     case C (MOVI_IMM_64_PCREL, MOVI_48):
01282       {
01283        int reg = (insn >> 4) & 0x3f;
01284 
01285        md_number_to_chars (opcodep,
01286                          insn
01287                          | (((((reloc_needed
01288                                ? 0 : (target_address - opcode_address)))
01289                             >> 32) & 65535) << 10), 4);
01290 
01291        /* A SHORI, for the medium part.  */
01292        md_number_to_chars (var_partp,
01293                          SHMEDIA_SHORI_OPC
01294                          | (reg << 4)
01295                          | ((((reloc_needed
01296                               ? 0 : (target_address - opcode_address))
01297                              >> 16) & 65535) << 10), 4);
01298 
01299        /* A SHORI, for the low part.  */
01300        md_number_to_chars (var_partp + 4,
01301                          SHMEDIA_SHORI_OPC
01302                          | (reg << 4)
01303                          | (((reloc_needed
01304                              ? 0 : (target_address - opcode_address))
01305                             & 65535) << 10), 4);
01306        if (reloc_needed)
01307          {
01308            fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01309                    fragP->fr_symbol, fragP->fr_offset, 1,
01310                    BFD_RELOC_SH_IMM_MEDHI16_PCREL);
01311            fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
01312                    fragP->fr_offset + 4, 1, BFD_RELOC_SH_IMM_MEDLOW16_PCREL);
01313            fix_new (fragP, var_partp - fragP->fr_literal + 4, 4, fragP->fr_symbol,
01314                    fragP->fr_offset + 8, 1, BFD_RELOC_SH_IMM_LOW16_PCREL);
01315          }
01316        var_part_size = 8;
01317       }
01318       break;
01319 
01320     case C (MOVI_IMM_64_PCREL, MOVI_PLT):
01321       reloctype = BFD_RELOC_32_PLT_PCREL;
01322       goto movi_imm_64_pcrel_reloc_needed;
01323 
01324     case C (MOVI_IMM_64_PCREL, MOVI_GOTPC):
01325       reloctype = BFD_RELOC_SH_GOTPC;
01326       /* Fall through.  */
01327 
01328     movi_imm_64_pcrel_reloc_needed:
01329       reloc_needed = 1;
01330       /* Fall through.  */
01331 
01332     case C (MOVI_IMM_32_PCREL, MOVI_64):
01333     case C (MOVI_IMM_64_PCREL, MOVI_64):
01334       {
01335        int reg = (insn >> 4) & 0x3f;
01336 
01337        md_number_to_chars (opcodep,
01338                          insn
01339                          | (((((reloc_needed
01340                                ? 0 : (target_address - opcode_address)))
01341                             >> 48) & 65535) << 10), 4);
01342 
01343        /* A SHORI, for the medium-high part.  */
01344        md_number_to_chars (var_partp,
01345                          SHMEDIA_SHORI_OPC
01346                          | (reg << 4)
01347                          | ((((reloc_needed
01348                               ? 0 : (target_address - opcode_address))
01349                              >> 32) & 65535) << 10), 4);
01350 
01351        /* A SHORI, for the medium-low part.  */
01352        md_number_to_chars (var_partp + 4,
01353                          SHMEDIA_SHORI_OPC
01354                          | (reg << 4)
01355                          | ((((reloc_needed
01356                               ? 0 : (target_address - opcode_address))
01357                              >> 16) & 65535) << 10), 4);
01358 
01359        /* A SHORI, for the low part.  */
01360        md_number_to_chars (var_partp + 8,
01361                          SHMEDIA_SHORI_OPC
01362                          | (reg << 4)
01363                          | (((reloc_needed
01364                              ? 0 : (target_address - opcode_address))
01365                             & 65535) << 10), 4);
01366        if (reloc_needed)
01367          {
01368            fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01369                    fragP->fr_symbol, fragP->fr_offset, 1,
01370                    reloctype == BFD_RELOC_NONE
01371                    ? BFD_RELOC_SH_IMM_HI16_PCREL
01372                    : reloctype == BFD_RELOC_SH_GOTPC
01373                    ? BFD_RELOC_SH_GOTPC_HI16
01374                    : reloctype == BFD_RELOC_32_PLT_PCREL
01375                    ? BFD_RELOC_SH_PLT_HI16
01376                    : (abort (), BFD_RELOC_SH_IMM_HI16_PCREL));
01377            fix_new (fragP, var_partp - fragP->fr_literal, 4, fragP->fr_symbol,
01378                    fragP->fr_offset + 4, 1,
01379                    reloctype == BFD_RELOC_NONE
01380                    ? BFD_RELOC_SH_IMM_MEDHI16_PCREL
01381                    : reloctype == BFD_RELOC_SH_GOTPC
01382                    ? BFD_RELOC_SH_GOTPC_MEDHI16
01383                    : reloctype == BFD_RELOC_32_PLT_PCREL
01384                    ? BFD_RELOC_SH_PLT_MEDHI16
01385                    : (abort (), BFD_RELOC_SH_IMM_MEDHI16_PCREL));
01386            fix_new (fragP, var_partp - fragP->fr_literal + 4, 4,
01387                    fragP->fr_symbol,
01388                    fragP->fr_offset + 8, 1,
01389                    reloctype == BFD_RELOC_NONE
01390                    ? BFD_RELOC_SH_IMM_MEDLOW16_PCREL
01391                    : reloctype == BFD_RELOC_SH_GOTPC
01392                    ? BFD_RELOC_SH_GOTPC_MEDLOW16
01393                    : reloctype == BFD_RELOC_32_PLT_PCREL
01394                    ? BFD_RELOC_SH_PLT_MEDLOW16
01395                    : (abort (), BFD_RELOC_SH_IMM_MEDLOW16_PCREL));
01396            fix_new (fragP, var_partp - fragP->fr_literal + 8, 4,
01397                    fragP->fr_symbol,
01398                    fragP->fr_offset + 12, 1,
01399                    reloctype == BFD_RELOC_NONE
01400                    ? BFD_RELOC_SH_IMM_LOW16_PCREL
01401                    : reloctype == BFD_RELOC_SH_GOTPC
01402                    ? BFD_RELOC_SH_GOTPC_LOW16
01403                    : reloctype == BFD_RELOC_32_PLT_PCREL
01404                    ? BFD_RELOC_SH_PLT_LOW16
01405                    : (abort (), BFD_RELOC_SH_IMM_LOW16_PCREL));
01406          }
01407        var_part_size = 12;
01408       }
01409       break;
01410 
01411     default:
01412       BAD_CASE (fragP->fr_subtype);
01413     }
01414 
01415   fragP->fr_fix += var_part_size;
01416   fragP->fr_var = 0;
01417 }
01418 
01419 /* Mask NUMBER (originating from a signed number) corresponding to the HOW
01420    reloc.  */
01421 
01422 static unsigned long
01423 shmedia_mask_number (unsigned long number, bfd_reloc_code_real_type how)
01424 {
01425   switch (how)
01426     {
01427     case BFD_RELOC_SH_IMMU5:
01428       number &= (1 << 5) - 1;
01429       break;
01430 
01431     case BFD_RELOC_SH_IMMS6:
01432     case BFD_RELOC_SH_IMMU6:
01433       number &= (1 << 6) - 1;
01434       break;
01435 
01436     case BFD_RELOC_SH_IMMS6BY32:
01437       number = (number & ((1 << (6 + 5)) - 1)) >> 5;
01438       break;
01439 
01440     case BFD_RELOC_SH_IMMS10:
01441       number &= (1 << 10) - 1;
01442       break;
01443 
01444     case BFD_RELOC_SH_IMMS10BY2:
01445       number = (number & ((1 << (10 + 1)) - 1)) >> 1;
01446       break;
01447 
01448     case BFD_RELOC_SH_IMMS10BY4:
01449       number = (number & ((1 << (10 + 2)) - 1)) >> 2;
01450       break;
01451 
01452     case BFD_RELOC_SH_IMMS10BY8:
01453       number = (number & ((1 << (10 + 3)) - 1)) >> 3;
01454       break;
01455 
01456     case BFD_RELOC_SH_IMMS16:
01457     case BFD_RELOC_SH_IMMU16:
01458       number &= (1 << 16) - 1;
01459       break;
01460 
01461     default:
01462       BAD_CASE (how);
01463     }
01464 
01465   return number;
01466 }
01467 
01468 /* Emit errors for values out-of-range, using as_bad_where if FRAGP is
01469    non-NULL, as_bad otherwise.  */
01470 
01471 static void
01472 shmedia_check_limits (offsetT *valp, bfd_reloc_code_real_type reloc,
01473                     fixS *fixp)
01474 {
01475   offsetT val = *valp;
01476 
01477   char *msg = NULL;
01478 
01479   switch (reloc)
01480     {
01481     case BFD_RELOC_SH_IMMU5:
01482       if (val < 0 || val > (1 << 5) - 1)
01483        msg = _("invalid operand, not a 5-bit unsigned value: %d");
01484       break;
01485 
01486     case BFD_RELOC_SH_IMMS6:
01487       if (val < -(1 << 5) || val > (1 << 5) - 1)
01488        msg = _("invalid operand, not a 6-bit signed value: %d");
01489       break;
01490 
01491     case BFD_RELOC_SH_IMMU6:
01492       if (val < 0 || val > (1 << 6) - 1)
01493        msg = _("invalid operand, not a 6-bit unsigned value: %d");
01494       break;
01495 
01496     case BFD_RELOC_SH_IMMS6BY32:
01497       if (val < -(1 << 10) || val > (1 << 10) - 1)
01498        msg = _("invalid operand, not a 11-bit signed value: %d");
01499       else if (val & 31)
01500        msg = _("invalid operand, not a multiple of 32: %d");
01501       break;
01502 
01503     case BFD_RELOC_SH_IMMS10:
01504       if (val < -(1 << 9) || val > (1 << 9) - 1)
01505        msg = _("invalid operand, not a 10-bit signed value: %d");
01506       break;
01507 
01508     case BFD_RELOC_SH_IMMS10BY2:
01509       if (val < -(1 << 10) || val > (1 << 10) - 1)
01510        msg = _("invalid operand, not a 11-bit signed value: %d");
01511       else if (val & 1)
01512        msg = _("invalid operand, not an even value: %d");
01513       break;
01514 
01515     case BFD_RELOC_SH_IMMS10BY4:
01516       if (val < -(1 << 11) || val > (1 << 11) - 1)
01517        msg = _("invalid operand, not a 12-bit signed value: %d");
01518       else if (val & 3)
01519        msg = _("invalid operand, not a multiple of 4: %d");
01520       break;
01521 
01522     case BFD_RELOC_SH_IMMS10BY8:
01523       if (val < -(1 << 12) || val > (1 << 12) - 1)
01524        msg = _("invalid operand, not a 13-bit signed value: %d");
01525       else if (val & 7)
01526        msg = _("invalid operand, not a multiple of 8: %d");
01527       break;
01528 
01529     case BFD_RELOC_SH_IMMS16:
01530       if (val < -(1 << 15) || val > (1 << 15) - 1)
01531        msg = _("invalid operand, not a 16-bit signed value: %d");
01532       break;
01533 
01534     case BFD_RELOC_SH_IMMU16:
01535       if (val < 0 || val > (1 << 16) - 1)
01536        msg = _("invalid operand, not a 16-bit unsigned value: %d");
01537       break;
01538 
01539     case BFD_RELOC_SH_PT_16:
01540     case SHMEDIA_BFD_RELOC_PT:
01541       if (val < -(1 << 15) * 4 || val > ((1 << 15) - 1) * 4 + 1)
01542        msg = _("operand out of range for PT, PTA and PTB");
01543       else if ((val % 4) != 0 && ((val - 1) % 4) != 0)
01544        msg = _("operand not a multiple of 4 for PT, PTA or PTB: %d");
01545       break;
01546 
01547       /* These have no limits; they take a 16-bit slice of a 32- or 64-bit
01548         number.  */
01549     case BFD_RELOC_SH_IMM_HI16:
01550     case BFD_RELOC_SH_IMM_MEDHI16:
01551     case BFD_RELOC_SH_IMM_MEDLOW16:
01552     case BFD_RELOC_SH_IMM_LOW16:
01553     case BFD_RELOC_SH_IMM_HI16_PCREL:
01554     case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
01555     case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
01556     case BFD_RELOC_SH_IMM_LOW16_PCREL:
01557 
01558     case BFD_RELOC_SH_SHMEDIA_CODE:
01559       break;
01560 
01561       /* This one has limits out of our reach.  */
01562     case BFD_RELOC_64:
01563       break;
01564 
01565     default:
01566       BAD_CASE (reloc);
01567     }
01568 
01569   if (msg)
01570     {
01571       if (fixp)
01572        as_bad_where (fixp->fx_file, fixp->fx_line, msg, val);
01573       else
01574        as_bad (msg, val);
01575     }
01576 }
01577 
01578 /* Handle an immediate operand by checking limits and noting it for later
01579    evaluation if not computable yet, and return a bitfield suitable to
01580    "or" into the opcode (non-zero if the value was a constant number).  */
01581 
01582 static unsigned long
01583 shmedia_immediate_op (char *where, shmedia_operand_info *op, int pcrel,
01584                     bfd_reloc_code_real_type how)
01585 {
01586   unsigned long retval = 0;
01587 
01588   /* If this is not an absolute number, make it a fixup.  A constant in
01589      place of a pc-relative operand also needs a fixup.  */
01590   if (op->immediate.X_op != O_constant || pcrel)
01591     fix_new_exp (frag_now,
01592                where - frag_now->fr_literal,
01593                4,
01594                &op->immediate,
01595                pcrel,
01596                how);
01597   else
01598     {
01599       /* Check that the number is within limits as represented by the
01600         reloc, and return the number.  */
01601       shmedia_check_limits (&op->immediate.X_add_number, how, NULL);
01602 
01603       retval
01604        = shmedia_mask_number ((unsigned long) op->immediate.X_add_number,
01605                             how);
01606     }
01607 
01608   return retval << 10;
01609 }
01610 
01611 /* Try and parse a register name case-insensitively, return the number of
01612    chars consumed.  */
01613 
01614 static int
01615 shmedia_parse_reg (char *src, int *mode, int *reg, shmedia_arg_type argtype)
01616 {
01617   int l0 = TOLOWER (src[0]);
01618   int l1 = l0 ? TOLOWER (src[1]) : 0;
01619 
01620   if (l0 == 'r')
01621     {
01622       if (src[1] >= '1' && src[1] <= '5')
01623        {
01624          if (src[2] >= '0' && src[2] <= '9'
01625              && ! IDENT_CHAR ((unsigned char) src[3]))
01626            {
01627              *mode = A_GREG_M;
01628              *reg = 10 * (src[1] - '0') + src[2] - '0';
01629              return 3;
01630            }
01631        }
01632 
01633       if (src[1] == '6')
01634        {
01635          if (src[2] >= '0' && src[2] <= '3'
01636              && ! IDENT_CHAR ((unsigned char) src[3]))
01637            {
01638              *mode = A_GREG_M;
01639              *reg = 60 + src[2] - '0';
01640              return 3;
01641            }
01642        }
01643 
01644       if (src[1] >= '0' && src[1] <= '9'
01645          && ! IDENT_CHAR ((unsigned char) src[2]))
01646        {
01647          *mode = A_GREG_M;
01648          *reg = (src[1] - '0');
01649          return 2;
01650        }
01651     }
01652 
01653   if (l0 == 't' && l1 == 'r')
01654     {
01655       if (src[2] >= '0' && src[2] <= '7'
01656          && ! IDENT_CHAR ((unsigned char) src[3]))
01657        {
01658          *mode = A_TREG_B;
01659          *reg = (src[2] - '0');
01660          return 3;
01661        }
01662     }
01663 
01664   if (l0 == 'f' && l1 == 'r')
01665     {
01666       if (src[2] >= '1' && src[2] <= '5')
01667        {
01668          if (src[3] >= '0' && src[3] <= '9'
01669              && ! IDENT_CHAR ((unsigned char) src[4]))
01670            {
01671              *mode = A_FREG_G;
01672              *reg = 10 * (src[2] - '0') + src[3] - '0';
01673              return 4;
01674            }
01675        }
01676       if (src[2] == '6')
01677        {
01678          if (src[3] >= '0' && src[3] <= '3'
01679              && ! IDENT_CHAR ((unsigned char) src[4]))
01680            {
01681              *mode = A_FREG_G;
01682              *reg = 60 + src[3] - '0';
01683              return 4;
01684            }
01685        }
01686       if (src[2] >= '0' && src[2] <= '9'
01687          && ! IDENT_CHAR ((unsigned char) src[3]))
01688        {
01689          *mode = A_FREG_G;
01690          *reg = (src[2] - '0');
01691          return 3;
01692        }
01693     }
01694 
01695   if (l0 == 'f' && l1 == 'v')
01696     {
01697       if (src[2] >= '1' && src[2] <= '5')
01698        {
01699          if (src[3] >= '0' && src[3] <= '9'
01700              && ((10 * (src[2] - '0') + src[3] - '0') % 4) == 0
01701              && ! IDENT_CHAR ((unsigned char) src[4]))
01702            {
01703              *mode = A_FVREG_G;
01704              *reg = 10 * (src[2] - '0') + src[3] - '0';
01705              return 4;
01706            }
01707        }
01708       if (src[2] == '6')
01709        {
01710          if (src[3] == '0'
01711              && ! IDENT_CHAR ((unsigned char) src[4]))
01712            {
01713              *mode = A_FVREG_G;
01714              *reg = 60 + src[3] - '0';
01715              return 4;
01716            }
01717        }
01718       if (src[2] >= '0' && src[2] <= '9'
01719          && ((src[2] - '0') % 4) == 0
01720          && ! IDENT_CHAR ((unsigned char) src[3]))
01721        {
01722          *mode = A_FVREG_G;
01723          *reg = (src[2] - '0');
01724          return 3;
01725        }
01726     }
01727 
01728   if (l0 == 'd' && l1 == 'r')
01729     {
01730       if (src[2] >= '1' && src[2] <= '5')
01731        {
01732          if (src[3] >= '0' && src[3] <= '9'
01733              && ((src[3] - '0') % 2) == 0
01734              && ! IDENT_CHAR ((unsigned char) src[4]))
01735            {
01736              *mode = A_DREG_G;
01737              *reg = 10 * (src[2] - '0') + src[3] - '0';
01738              return 4;
01739            }
01740        }
01741 
01742       if (src[2] == '6')
01743        {
01744          if ((src[3] == '0' || src[3] == '2')
01745              && ! IDENT_CHAR ((unsigned char) src[4]))
01746            {
01747              *mode = A_DREG_G;
01748              *reg = 60 + src[3] - '0';
01749              return 4;
01750            }
01751        }
01752 
01753       if (src[2] >= '0' && src[2] <= '9'
01754          && ((src[2] - '0') % 2) == 0
01755          && ! IDENT_CHAR ((unsigned char) src[3]))
01756        {
01757          *mode = A_DREG_G;
01758          *reg = (src[2] - '0');
01759          return 3;
01760        }
01761     }
01762 
01763   if (l0 == 'f' && l1 == 'p')
01764     {
01765       if (src[2] >= '1' && src[2] <= '5')
01766        {
01767          if (src[3] >= '0' && src[3] <= '9'
01768              && ((src[3] - '0') % 2) == 0
01769              && ! IDENT_CHAR ((unsigned char) src[4]))
01770            {
01771              *mode = A_FPREG_G;
01772              *reg = 10 * (src[2] - '0') + src[3] - '0';
01773              return 4;
01774            }
01775        }
01776 
01777       if (src[2] == '6')
01778        {
01779          if ((src[3] == '0' || src[3] == '2')
01780              && ! IDENT_CHAR ((unsigned char) src[4]))
01781            {
01782              *mode = A_FPREG_G;
01783              *reg = 60 + src[3] - '0';
01784              return 4;
01785            }
01786        }
01787 
01788       if (src[2] >= '0' && src[2] <= '9'
01789          && ((src[2] - '0') % 2) == 0
01790          && ! IDENT_CHAR ((unsigned char) src[3]))
01791        {
01792          *mode = A_FPREG_G;
01793          *reg = (src[2] - '0');
01794          return 3;
01795        }
01796     }
01797 
01798   if (l0 == 'm' && strncasecmp (src, "mtrx", 4) == 0)
01799     {
01800       if (src[4] == '0' && ! IDENT_CHAR ((unsigned char) src[5]))
01801        {
01802          *mode = A_FMREG_G;
01803          *reg = 0;
01804          return 5;
01805        }
01806 
01807       if (src[4] == '1' && src[5] == '6'
01808          && ! IDENT_CHAR ((unsigned char) src[6]))
01809        {
01810          *mode = A_FMREG_G;
01811          *reg = 16;
01812          return 6;
01813        }
01814 
01815       if (src[4] == '3' && src[5] == '2'
01816          && ! IDENT_CHAR ((unsigned char) src[6]))
01817        {
01818          *mode = A_FMREG_G;
01819          *reg = 32;
01820          return 6;
01821        }
01822 
01823       if (src[4] == '4' && src[5] == '8'
01824          && ! IDENT_CHAR ((unsigned char) src[6]))
01825        {
01826          *mode = A_FMREG_G;
01827          *reg = 48;
01828          return 6;
01829        }
01830     }
01831 
01832   if (l0 == 'c' && l1 == 'r')
01833     {
01834       if (src[2] >= '1' && src[2] <= '5')
01835        {
01836          if (src[3] >= '0' && src[3] <= '9'
01837              && ! IDENT_CHAR ((unsigned char) src[4]))
01838            {
01839              *mode = A_CREG_K;
01840              *reg = 10 * (src[2] - '0') + src[3] - '0';
01841              return 4;
01842            }
01843        }
01844       if (src[2] == '6')
01845        {
01846          if (src[3] >= '0' && src[3] <= '3'
01847              && ! IDENT_CHAR ((unsigned char) src[4]))
01848            {
01849              *mode = A_CREG_K;
01850              *reg = 60 + src[3] - '0';
01851              return 4;
01852            }
01853        }
01854       if (src[2] >= '0' && src[2] <= '9'
01855          && ! IDENT_CHAR ((unsigned char) src[3]))
01856        {
01857          *mode = A_CREG_K;
01858          *reg = (src[2] - '0');
01859          return 3;
01860        }
01861     }
01862 
01863   /* We either have an error, a symbol or a control register by predefined
01864      name.  To keep things simple but still fast for normal cases, we do
01865      linear search in the (not to big) table of predefined control
01866      registers.  We only do this when we *expect* a control register.
01867      Those instructions should be rare enough that linear searching is ok.
01868      Or just read them into a hash-table in shmedia_md_begin.  Since they
01869      cannot be specified in the same place of symbol operands, don't add
01870      them there to the *main* symbol table as being in "reg_section".  */
01871   if (argtype == A_CREG_J || argtype == A_CREG_K)
01872     {
01873       const shmedia_creg_info *cregp;
01874       int len = 0;
01875 
01876       for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++)
01877        {
01878          len = strlen (cregp->name);
01879          if (strncasecmp (cregp->name, src, len) == 0
01880              && ! IDENT_CHAR (src[len]))
01881            break;
01882        }
01883 
01884       if (cregp->name != NULL)
01885        {
01886          *mode = A_CREG_K;
01887          *reg = cregp->cregno;
01888          return len;
01889        }
01890     }
01891 
01892   return 0;
01893 }
01894 
01895 /* Called from md_estimate_size_before_relax in tc-sh.c  */
01896 
01897 static int
01898 shmedia_md_estimate_size_before_relax (fragS *fragP,
01899                                    segT segment_type ATTRIBUTE_UNUSED)
01900 {
01901   int old_fr_fix;
01902   expressionS *exp;
01903 
01904   /* For ELF, we can't relax externally visible symbols; see tc-i386.c.  */
01905   bfd_boolean sym_relaxable
01906     = (fragP->fr_symbol
01907        && S_GET_SEGMENT (fragP->fr_symbol) == segment_type
01908        && ! S_IS_EXTERNAL (fragP->fr_symbol)
01909        && ! S_IS_WEAK (fragP->fr_symbol));
01910 
01911   old_fr_fix = fragP->fr_fix;
01912 
01913   switch (fragP->fr_subtype)
01914     {
01915     case C (SH64PCREL16_32, UNDEF_SH64PCREL):
01916     case C (SH64PCREL16PT_32, UNDEF_SH64PCREL):
01917       /* Used to be to somewhere which was unknown.  */
01918       if (sym_relaxable)
01919        {
01920          int what = GET_WHAT (fragP->fr_subtype);
01921 
01922          /* In this segment, so head for shortest.  */
01923          fragP->fr_subtype = C (what, SH64PCREL16);
01924        }
01925       else
01926        {
01927          int what = GET_WHAT (fragP->fr_subtype);
01928          /* We know the abs value, but we don't know where we will be
01929             linked, so we must make it the longest.  Presumably we could
01930             switch to a non-pcrel representation, but having absolute
01931             values in PT operands should be rare enough not to be worth
01932             adding that code.  */
01933          fragP->fr_subtype = C (what, SH64PCREL32);
01934        }
01935       fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
01936       break;
01937 
01938     case C (SH64PCREL16_64, UNDEF_SH64PCREL):
01939     case C (SH64PCREL16PT_64, UNDEF_SH64PCREL):
01940       /* Used to be to somewhere which was unknown.  */
01941       if (sym_relaxable)
01942        {
01943          int what = GET_WHAT (fragP->fr_subtype);
01944 
01945          /* In this segment, so head for shortest.  */
01946          fragP->fr_subtype = C (what, SH64PCREL16);
01947        }
01948       else
01949        {
01950          int what = GET_WHAT (fragP->fr_subtype);
01951          /* We know the abs value, but we don't know where we will be
01952             linked, so we must make it the longest.  Presumably we could
01953             switch to a non-pcrel representation, but having absolute
01954             values in PT operands should be rare enough not to be worth
01955             adding that code.  */
01956          fragP->fr_subtype = C (what, SH64PCREL64);
01957        }
01958       fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
01959       break;
01960 
01961     case C (MOVI_IMM_64, UNDEF_MOVI):
01962     case C (MOVI_IMM_32, UNDEF_MOVI):
01963       exp = NULL;
01964 
01965       /* Look inside the "symbol".  If we find a PC-relative expression,
01966         change this to a PC-relative, relaxable expression.  */
01967       if (fragP->fr_symbol != NULL
01968          && (exp = symbol_get_value_expression (fragP->fr_symbol)) != NULL
01969          && exp->X_op == O_subtract
01970          && exp->X_op_symbol != NULL
01971          && S_GET_SEGMENT (exp->X_op_symbol) == segment_type)
01972        {
01973          int what = GET_WHAT (fragP->fr_subtype);
01974          int what_high = what == MOVI_IMM_32 ? MOVI_32 : MOVI_64;
01975          expressionS *opexp
01976            = symbol_get_value_expression (exp->X_op_symbol);
01977          expressionS *addexp
01978            = symbol_get_value_expression (exp->X_add_symbol);
01979 
01980          /* Change the MOVI expression to the "X" in "X - Y" and subtract
01981             Y:s offset to this location from X.  Note that we can only
01982             allow an Y which is offset from this frag.  */
01983          if (opexp != NULL
01984              && addexp != NULL
01985              && opexp->X_op == O_constant
01986              && fragP == symbol_get_frag (exp->X_op_symbol))
01987            {
01988              /* At this point, before relaxing, the add-number of opexp
01989                is the offset from the fr_fix part.  */
01990              fragP->fr_offset
01991               = (exp->X_add_number
01992                  - (opexp->X_add_number - (fragP->fr_fix - 4)));
01993              fragP->fr_symbol = exp->X_add_symbol;
01994 
01995              what = what == MOVI_IMM_32
01996               ? MOVI_IMM_32_PCREL : MOVI_IMM_64_PCREL;
01997 
01998              /* Check the "X" symbol to estimate the size of this
01999                PC-relative expression.  */
02000              if (S_GET_SEGMENT (exp->X_add_symbol) == segment_type
02001                 && ! S_IS_EXTERNAL (exp->X_add_symbol)
02002                 && ! S_IS_WEAK (exp->X_add_symbol))
02003               fragP->fr_subtype = C (what, MOVI_16);
02004              else
02005               fragP->fr_subtype = C (what, what_high);
02006 
02007              /* This is now a PC-relative expression, fit to be relaxed.  */
02008            }
02009          else
02010            fragP->fr_subtype = C (what, what_high);
02011        }
02012       else if (fragP->fr_symbol == NULL
02013               || (S_GET_SEGMENT (fragP->fr_symbol) == absolute_section
02014                  && exp->X_op == O_constant))
02015        {
02016          unsigned long insn
02017            = (target_big_endian
02018               ? bfd_getb32 (fragP->fr_opcode)
02019               : bfd_getl32 (fragP->fr_opcode));
02020          offsetT one = (offsetT) 1;
02021          offsetT value = fragP->fr_offset
02022            + (fragP->fr_symbol == NULL ? 0 : S_GET_VALUE (fragP->fr_symbol));
02023 
02024          if (value >= ((offsetT) -1 << 15) && value < ((offsetT) 1 << 15))
02025            {
02026              /* Fits in 16-bit signed number.  */
02027              int what = GET_WHAT (fragP->fr_subtype);
02028              fragP->fr_subtype = C (what, MOVI_16);
02029 
02030              /* Just "or" in the value.  */
02031              md_number_to_chars (fragP->fr_opcode,
02032                               insn | ((value & ((1 << 16) - 1)) << 10),
02033                               4);
02034            }
02035          else if (value >= -(one << 31)
02036                  && (value < (one << 31)
02037                      || (sh64_abi == sh64_abi_32 && value < (one << 32))))
02038            {
02039              /* The value fits in a 32-bit signed number.  */
02040              int reg = (insn >> 4) & 0x3f;
02041 
02042              /* Just "or" in the high bits of the value, making the first
02043                MOVI.  */
02044              md_number_to_chars (fragP->fr_opcode,
02045                               insn
02046                               | (((value >> 16) & ((1 << 16) - 1)) << 10),
02047                               4);
02048 
02049              /* Add a SHORI with the low bits.  Note that this insn lives
02050                in the variable fragment part.  */
02051              md_number_to_chars (fragP->fr_literal + old_fr_fix,
02052                               SHMEDIA_SHORI_OPC
02053                               | (reg << 4)
02054                               | ((value & ((1 << 16) - 1)) << 10),
02055                               4);
02056 
02057              /* We took a piece of the variable part.  */
02058              fragP->fr_fix += 4;
02059            }
02060          else if (GET_WHAT (fragP->fr_subtype) == MOVI_IMM_32)
02061            {
02062              /* Value out of range.  */
02063              as_bad_where (fragP->fr_file, fragP->fr_line,
02064                          _("MOVI operand is not a 32-bit signed value: 0x%8x%08x"),
02065                          ((unsigned int) (value >> 32)
02066                           & (unsigned int) 0xffffffff),
02067                          (unsigned int) value & (unsigned int) 0xffffffff);
02068 
02069              /* Must advance size, or we will get internal inconsistency
02070                and fall into an assert.  */
02071              fragP->fr_fix += 4;
02072            }
02073          /* Now we know we are allowed to expand to 48- and 64-bit values.  */
02074          else if (value >= -(one << 47) && value < (one << 47))
02075            {
02076              /* The value fits in a 48-bit signed number.  */
02077              int reg = (insn >> 4) & 0x3f;
02078 
02079              /* Just "or" in the high bits of the value, making the first
02080                MOVI.  */
02081              md_number_to_chars (fragP->fr_opcode,
02082                               insn
02083                               | (((value >> 32) & ((1 << 16) - 1)) << 10),
02084                               4);
02085 
02086              /* Add a SHORI with the middle bits.  Note that this insn lives
02087                in the variable fragment part.  */
02088              md_number_to_chars (fragP->fr_literal + old_fr_fix,
02089                               SHMEDIA_SHORI_OPC
02090                               | (reg << 4)
02091                               | (((value >> 16) & ((1 << 16) - 1)) << 10),
02092                               4);
02093 
02094              /* Add a SHORI with the low bits.  */
02095              md_number_to_chars (fragP->fr_literal + old_fr_fix + 4,
02096                               SHMEDIA_SHORI_OPC
02097                               | (reg << 4)
02098                               | ((value & ((1 << 16) - 1)) << 10),
02099                               4);
02100 
02101              /* We took a piece of the variable part.  */
02102              fragP->fr_fix += 8;
02103            }
02104          else
02105            {
02106              /* A 64-bit number.  */
02107              int reg = (insn >> 4) & 0x3f;
02108 
02109              /* Just "or" in the high bits of the value, making the first
02110                MOVI.  */
02111              md_number_to_chars (fragP->fr_opcode,
02112                               insn
02113                               | (((value >> 48) & ((1 << 16) - 1)) << 10),
02114                               4);
02115 
02116              /* Add a SHORI with the midhigh bits.  Note that this insn lives
02117                in the variable fragment part.  */
02118              md_number_to_chars (fragP->fr_literal + old_fr_fix,
02119                               SHMEDIA_SHORI_OPC
02120                               | (reg << 4)
02121                               | (((value >> 32) & ((1 << 16) - 1)) << 10),
02122                               4);
02123 
02124              /* Add a SHORI with the midlow bits.  */
02125              md_number_to_chars (fragP->fr_literal + old_fr_fix + 4,
02126                               SHMEDIA_SHORI_OPC
02127                               | (reg << 4)
02128                               | (((value >> 16) & ((1 << 16) - 1)) << 10),
02129                               4);
02130 
02131              /* Add a SHORI with the low bits.  */
02132              md_number_to_chars (fragP->fr_literal + old_fr_fix + 8,
02133                               SHMEDIA_SHORI_OPC
02134                               | (reg << 4)
02135                               | ((value & ((1 << 16) - 1)) << 10), 4);
02136              /* We took all of the variable part.  */
02137              fragP->fr_fix += 12;
02138            }
02139 
02140          /* MOVI expansions that get here have not been converted to
02141             PC-relative frags, but instead expanded by
02142             md_number_to_chars or by calling shmedia_md_convert_frag
02143             with final == FALSE.  We must not have them around as
02144             frags anymore; symbols would be prematurely evaluated
02145             when relaxing.  We will not need to have md_convert_frag
02146             called again with them; any further handling is through
02147             the already emitted fixups.  */
02148          frag_wane (fragP);
02149          break;
02150        }
02151       fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
02152       break;
02153 
02154       /* For relaxation states that remain unchanged, report the
02155          estimated length.  */
02156     case C (SH64PCREL16_32, SH64PCREL16):
02157     case C (SH64PCREL16PT_32, SH64PCREL16):
02158     case C (SH64PCREL16_32, SH64PCREL32):
02159     case C (SH64PCREL16PT_32, SH64PCREL32):
02160     case C (SH64PCREL16_32, SH64PCRELPLT):
02161     case C (SH64PCREL16PT_32, SH64PCRELPLT):
02162     case C (SH64PCREL16_64, SH64PCREL16):
02163     case C (SH64PCREL16PT_64, SH64PCREL16):
02164     case C (SH64PCREL16_64, SH64PCREL32):
02165     case C (SH64PCREL16PT_64, SH64PCREL32):
02166     case C (SH64PCREL16_64, SH64PCREL48):
02167     case C (SH64PCREL16PT_64, SH64PCREL48):
02168     case C (SH64PCREL16_64, SH64PCREL64):
02169     case C (SH64PCREL16PT_64, SH64PCREL64):
02170     case C (SH64PCREL16_64, SH64PCRELPLT):
02171     case C (SH64PCREL16PT_64, SH64PCRELPLT):
02172     case C (MOVI_IMM_32, MOVI_16):
02173     case C (MOVI_IMM_32, MOVI_32):
02174     case C (MOVI_IMM_32, MOVI_GOTOFF):
02175     case C (MOVI_IMM_32_PCREL, MOVI_16):
02176     case C (MOVI_IMM_32_PCREL, MOVI_32):
02177     case C (MOVI_IMM_32_PCREL, MOVI_PLT):
02178     case C (MOVI_IMM_32_PCREL, MOVI_GOTPC):
02179     case C (MOVI_IMM_64, MOVI_16):
02180     case C (MOVI_IMM_64, MOVI_32):
02181     case C (MOVI_IMM_64, MOVI_48):
02182     case C (MOVI_IMM_64, MOVI_64):
02183     case C (MOVI_IMM_64, MOVI_GOTOFF):
02184     case C (MOVI_IMM_64_PCREL, MOVI_16):
02185     case C (MOVI_IMM_64_PCREL, MOVI_32):
02186     case C (MOVI_IMM_64_PCREL, MOVI_48):
02187     case C (MOVI_IMM_64_PCREL, MOVI_64):
02188     case C (MOVI_IMM_64_PCREL, MOVI_PLT):
02189     case C (MOVI_IMM_64_PCREL, MOVI_GOTPC):
02190       fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
02191       break;
02192 
02193     default:
02194       abort ();
02195     }
02196 
02197   return fragP->fr_var + (fragP->fr_fix - old_fr_fix);
02198 }
02199 
02200 /* Parse an expression, SH64-style.  Copied from tc-sh.c, but with
02201    datatypes adjusted.  */
02202 
02203 static char *
02204 shmedia_parse_exp (char *s, shmedia_operand_info *op)
02205 {
02206   char *save;
02207   char *new;
02208 
02209   save = input_line_pointer;
02210   input_line_pointer = s;
02211   expression (&op->immediate);
02212   if (op->immediate.X_op == O_absent)
02213     as_bad (_("missing operand"));
02214   new = input_line_pointer;
02215   input_line_pointer = save;
02216   return new;
02217 }
02218 
02219 /* Parse an operand.  Store pointer to next character in *PTR.  */
02220 
02221 static void
02222 shmedia_get_operand (char **ptr, shmedia_operand_info *op,
02223                    shmedia_arg_type argtype)
02224 {
02225   char *src = *ptr;
02226   int mode = -1;
02227   unsigned int len;
02228 
02229   len = shmedia_parse_reg (src, &mode, &(op->reg), argtype);
02230   if (len)
02231     {
02232       *ptr = src + len;
02233       op->type = mode;
02234     }
02235   else
02236     {
02237       /* Not a reg, so it must be a displacement.  */
02238       *ptr = shmedia_parse_exp (src, op);
02239       op->type = A_IMMM;
02240 
02241       /* This is just an initialization; shmedia_get_operands will change
02242         as needed.  */
02243       op->reloctype = BFD_RELOC_NONE;
02244     }
02245 }
02246 
02247 /* Parse the operands for this insn; return NULL if invalid, else return
02248    how much text was consumed.  */
02249 
02250 static char *
02251 shmedia_get_operands (shmedia_opcode_info *info, char *args,
02252                     shmedia_operands_info *operands)
02253 {
02254   char *ptr = args;
02255   int i;
02256 
02257   if (*ptr == ' ')
02258     ptr++;
02259 
02260   for (i = 0; info->arg[i] != 0; i++)
02261     {
02262       memset (operands->operands + i, 0, sizeof (operands->operands[0]));
02263 
02264       /* No operand to get for these fields.  */
02265       if (info->arg[i] == A_REUSE_PREV)
02266        continue;
02267 
02268       shmedia_get_operand (&ptr, &operands->operands[i], info->arg[i]);
02269 
02270       /* Check operands type match.  */
02271       switch (info->arg[i])
02272        {
02273        case A_GREG_M:
02274        case A_GREG_N:
02275        case A_GREG_D:
02276          if (operands->operands[i].type != A_GREG_M)
02277            return NULL;
02278          break;
02279 
02280        case A_FREG_G:
02281        case A_FREG_H:
02282        case A_FREG_F:
02283          if (operands->operands[i].type != A_FREG_G)
02284            return NULL;
02285          break;
02286 
02287        case A_FVREG_G:
02288        case A_FVREG_H:
02289        case A_FVREG_F:
02290          if (operands->operands[i].type != A_FVREG_G)
02291            return NULL;
02292          break;
02293 
02294        case A_FMREG_G:
02295        case A_FMREG_H:
02296        case A_FMREG_F:
02297          if (operands->operands[i].type != A_FMREG_G)
02298            return NULL;
02299          break;
02300 
02301        case A_FPREG_G:
02302        case A_FPREG_H:
02303        case A_FPREG_F:
02304          if (operands->operands[i].type != A_FPREG_G)
02305            return NULL;
02306          break;
02307 
02308        case A_DREG_G:
02309        case A_DREG_H:
02310        case A_DREG_F:
02311          if (operands->operands[i].type != A_DREG_G)
02312            return NULL;
02313          break;
02314 
02315        case A_TREG_A:
02316        case A_TREG_B:
02317          if (operands->operands[i].type != A_TREG_B)
02318            return NULL;
02319          break;
02320 
02321        case A_CREG_J:
02322        case A_CREG_K:
02323          if (operands->operands[i].type != A_CREG_K)
02324            return NULL;
02325          break;
02326 
02327        case A_IMMS16:
02328        case A_IMMU16:
02329          /* Check for an expression that looks like S & 65535 or
02330             (S >> N) & 65535, where N = 0, 16, 32, 48.
02331 
02332             Get the S and put at operands->operands[i].immediate, and
02333             adjust operands->operands[i].reloctype.  */
02334          {
02335            expressionS *imm_expr = &operands->operands[i].immediate;
02336            expressionS *right_expr;
02337 
02338            if (operands->operands[i].type == A_IMMM
02339               && imm_expr->X_op == O_bit_and
02340               && imm_expr->X_op_symbol != NULL
02341               && ((right_expr
02342                    = symbol_get_value_expression (imm_expr->X_op_symbol))
02343                   ->X_op == O_constant)
02344               && right_expr->X_add_number == 0xffff)
02345              {
02346               symbolS *inner = imm_expr->X_add_symbol;
02347               bfd_reloc_code_real_type reloctype = BFD_RELOC_SH_IMM_LOW16;
02348               expressionS *inner_expr
02349                 = symbol_get_value_expression (inner);
02350 
02351               if (inner_expr->X_op == O_right_shift)
02352                 {
02353                   expressionS *inner_right;
02354 
02355                   if (inner_expr->X_op_symbol != NULL
02356                     && ((inner_right
02357                         = symbol_get_value_expression (inner_expr
02358                                                    ->X_op_symbol))
02359                        ->X_op == O_constant))
02360                     {
02361                      offsetT addnum
02362                        = inner_right->X_add_number;
02363 
02364                      if (addnum == 0 || addnum == 16 || addnum == 32
02365                          || addnum == 48)
02366                        {
02367                          reloctype
02368                            = (addnum == 0
02369                              ? BFD_RELOC_SH_IMM_LOW16
02370                              : (addnum == 16
02371                                 ? BFD_RELOC_SH_IMM_MEDLOW16
02372                                 : (addnum == 32
02373                                    ? BFD_RELOC_SH_IMM_MEDHI16
02374                                    : BFD_RELOC_SH_IMM_HI16)));
02375 
02376                          inner = inner_expr->X_add_symbol;
02377                          inner_expr = symbol_get_value_expression (inner);
02378                        }
02379                     }
02380                 }
02381 
02382               /* I'm not sure I understand the logic, but evidently the
02383                  inner expression of a lone symbol is O_constant, with
02384                  the actual symbol in expr_section.  For a constant, the
02385                  section would be absolute_section.  For sym+offset,
02386                  it's O_symbol as always.  See expr.c:make_expr_symbol,
02387                  first statements.  */
02388 
02389               if (inner_expr->X_op == O_constant
02390                   && S_GET_SEGMENT (inner) != absolute_section)
02391                 {
02392                   operands->operands[i].immediate.X_op = O_symbol;
02393                   operands->operands[i].immediate.X_add_symbol = inner;
02394                   operands->operands[i].immediate.X_add_number = 0;
02395                 }
02396               else
02397                 operands->operands[i].immediate
02398                   = *symbol_get_value_expression (inner);
02399 
02400               operands->operands[i].reloctype = reloctype;
02401              }
02402          }
02403          /* Fall through.  */
02404        case A_IMMS6:
02405        case A_IMMS6BY32:
02406        case A_IMMS10:
02407        case A_IMMS10BY1:
02408        case A_IMMS10BY2:
02409        case A_IMMS10BY4:
02410        case A_IMMS10BY8:
02411        case A_PCIMMS16BY4:
02412        case A_PCIMMS16BY4_PT:
02413        case A_IMMU5:
02414        case A_IMMU6:
02415          if (operands->operands[i].type != A_IMMM)
02416            return NULL;
02417 
02418          if (sh_check_fixup (&operands->operands[i].immediate,
02419                            &operands->operands[i].reloctype))
02420            {
02421              as_bad (_("invalid PIC reference"));
02422              return NULL;
02423            }
02424 
02425          break;
02426 
02427        default:
02428          BAD_CASE (info->arg[i]);
02429        }
02430 
02431       if (*ptr == ',' && info->arg[i + 1])
02432        ptr++;
02433     }
02434   return ptr;
02435 }
02436 
02437 
02438 /* Find an opcode at the start of *STR_P in the hash table, and set
02439    *STR_P to the first character after the last one read.  */
02440 
02441 static shmedia_opcode_info *
02442 shmedia_find_cooked_opcode (char **str_p)
02443 {
02444   char *str = *str_p;
02445   char *op_start;
02446   char *op_end;
02447   char name[20];
02448   unsigned int nlen = 0;
02449 
02450   /* Drop leading whitespace.  */
02451   while (*str == ' ')
02452     str++;
02453 
02454   /* Find the op code end.  */
02455   for (op_start = op_end = str;
02456        *op_end
02457        && nlen < sizeof (name) - 1
02458        && ! is_end_of_line[(unsigned char) *op_end]
02459        && ! ISSPACE ((unsigned char) *op_end);
02460        op_end++)
02461     {
02462       unsigned char c = op_start[nlen];
02463 
02464       /* The machine independent code will convert CMP/EQ into cmp/EQ
02465         because it thinks the '/' is the end of the symbol.  Moreover,
02466         all but the first sub-insn is a parallel processing insn won't
02467         be capitalized.  Instead of hacking up the machine independent
02468         code, we just deal with it here.  */
02469       c = TOLOWER (c);
02470       name[nlen] = c;
02471       nlen++;
02472     }
02473 
02474   name[nlen] = 0;
02475   *str_p = op_end;
02476 
02477   if (nlen == 0)
02478     as_bad (_("can't find opcode"));
02479 
02480   return
02481     (shmedia_opcode_info *) hash_find (shmedia_opcode_hash_control, name);
02482 }
02483 
02484 /* Build up an instruction, including allocating the frag.  */
02485 
02486 static int
02487 shmedia_build_Mytes (shmedia_opcode_info *opcode,
02488                    shmedia_operands_info *operands)
02489 {
02490   unsigned long insn = opcode->opcode_base;
02491   int i, j;
02492   char *insn_loc = frag_more (4);
02493 
02494   /* The parameter to dwarf2_emit_insn is actually the offset to the start
02495      of the insn from the fix piece of instruction that was emitted.
02496      Since we want .debug_line addresses to record (address | 1) for
02497      SHmedia insns, we get the wanted effect by taking one off the size,
02498      knowing it's a multiple of 4.  We count from the first fix piece of
02499      the insn.  There must be no frags changes (frag_more or frag_var)
02500      calls in-between the frag_more call we account for, and this
02501      dwarf2_emit_insn call.  */
02502   dwarf2_emit_insn (3);
02503 
02504   /* This is stored into any frag_var operand.  */
02505   sh64_last_insn_frag = frag_now;
02506 
02507   /* Loop over opcode info, emit an instruction.  */
02508   for (i = 0, j = 0; opcode->arg[i]; i++)
02509     {
02510       shmedia_arg_type argtype = opcode->arg[i];
02511       shmedia_operand_info *opjp = &operands->operands[j];
02512       switch (argtype)
02513        {
02514        case A_TREG_A:
02515        case A_TREG_B:
02516        case A_GREG_M:
02517        case A_GREG_N:
02518        case A_GREG_D:
02519        case A_FREG_G:
02520        case A_FREG_H:
02521        case A_FREG_F:
02522        case A_FVREG_G:
02523        case A_FVREG_H:
02524        case A_FVREG_F:
02525        case A_FMREG_G:
02526        case A_FMREG_H:
02527        case A_FMREG_F:
02528        case A_FPREG_G:
02529        case A_FPREG_H:
02530        case A_FPREG_F:
02531        case A_DREG_G:
02532        case A_DREG_H:
02533        case A_DREG_F:
02534        case A_CREG_J:
02535        case A_CREG_K:
02536          /* Six-bit register fields.  They just get filled with the
02537             parsed register number.  */
02538          insn |= (opjp->reg << opcode->nibbles[i]);
02539          j++;
02540          break;
02541 
02542        case A_REUSE_PREV:
02543          /* Copy the register for the previous operand to this position.  */
02544          insn |= (operands->operands[j - 1].reg << opcode->nibbles[i]);
02545          j++;
02546          break;
02547 
02548        case A_IMMS6:
02549          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02550                                    BFD_RELOC_SH_IMMS6);
02551          j++;
02552          break;
02553 
02554        case A_IMMS6BY32:
02555          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02556                                    BFD_RELOC_SH_IMMS6BY32);
02557          j++;
02558          break;
02559 
02560        case A_IMMS10BY1:
02561        case A_IMMS10:
02562          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02563                                    BFD_RELOC_SH_IMMS10);
02564          j++;
02565          break;
02566 
02567        case A_IMMS10BY2:
02568          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02569                                    BFD_RELOC_SH_IMMS10BY2);
02570          j++;
02571          break;
02572 
02573        case A_IMMS10BY4:
02574          if (opjp->reloctype == BFD_RELOC_NONE)
02575            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02576                                      BFD_RELOC_SH_IMMS10BY4);
02577          else if (opjp->reloctype == BFD_RELOC_SH_GOTPLT32)
02578            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02579                                      BFD_RELOC_SH_GOTPLT10BY4);
02580          else if (opjp->reloctype == BFD_RELOC_32_GOT_PCREL)
02581            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02582                                      BFD_RELOC_SH_GOT10BY4);
02583          else
02584            as_bad (_("invalid PIC reference"));
02585          j++;
02586          break;
02587 
02588        case A_IMMS10BY8:
02589          if (opjp->reloctype == BFD_RELOC_NONE)
02590            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02591                                      BFD_RELOC_SH_IMMS10BY8);
02592          else if (opjp->reloctype == BFD_RELOC_SH_GOTPLT32)
02593            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02594                                      BFD_RELOC_SH_GOTPLT10BY8);
02595          else if (opjp->reloctype == BFD_RELOC_32_GOT_PCREL)
02596            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02597                                      BFD_RELOC_SH_GOT10BY8);
02598          else
02599            as_bad (_("invalid PIC reference"));
02600          j++;
02601          break;
02602 
02603        case A_IMMS16:
02604          /* Sneak a peek if this is the MOVI insn.  If so, check if we
02605             should expand it.  */
02606          if (opjp->reloctype == BFD_RELOC_32_GOT_PCREL)
02607            opjp->reloctype = BFD_RELOC_SH_GOT_LOW16;
02608          else if (opjp->reloctype == BFD_RELOC_SH_GOTPLT32)
02609            opjp->reloctype = BFD_RELOC_SH_GOTPLT_LOW16;
02610 
02611          if ((opjp->reloctype == BFD_RELOC_NONE
02612               || opjp->reloctype == BFD_RELOC_32_GOTOFF
02613               || opjp->reloctype == BFD_RELOC_32_PLT_PCREL
02614               || opjp->reloctype == BFD_RELOC_SH_GOTPC)
02615              && opcode->opcode_base == SHMEDIA_MOVI_OPC
02616              && (opjp->immediate.X_op != O_constant
02617                 || opjp->immediate.X_add_number < -32768
02618                 || opjp->immediate.X_add_number > 32767)
02619              && (sh64_expand
02620                 || opjp->reloctype == BFD_RELOC_32_GOTOFF
02621                 || opjp->reloctype == BFD_RELOC_32_PLT_PCREL
02622                 || opjp->reloctype == BFD_RELOC_SH_GOTPC))
02623            {
02624              int what = sh64_abi == sh64_abi_64 ? MOVI_IMM_64 : MOVI_IMM_32;
02625              offsetT max = sh64_abi == sh64_abi_64 ? MOVI_64 : MOVI_32;
02626              offsetT min = MOVI_16;
02627              offsetT init = UNDEF_MOVI;
02628              valueT addvalue
02629               = opjp->immediate.X_op_symbol != NULL
02630               ? 0 : opjp->immediate.X_add_number;
02631              symbolS *sym
02632               = opjp->immediate.X_op_symbol != NULL
02633               ? make_expr_symbol (&opjp->immediate)
02634               : opjp->immediate.X_add_symbol;
02635 
02636              if (opjp->reloctype == BFD_RELOC_32_GOTOFF)
02637               init = max = min = MOVI_GOTOFF;
02638              else if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
02639               {
02640                 init = max = min = MOVI_PLT;
02641                 what = (sh64_abi == sh64_abi_64
02642                        ? MOVI_IMM_64_PCREL
02643                        : MOVI_IMM_32_PCREL);
02644               }
02645              else if (opjp->reloctype == BFD_RELOC_SH_GOTPC)
02646               {
02647                 init = max = min = MOVI_GOTPC;
02648                 what = (sh64_abi == sh64_abi_64
02649                        ? MOVI_IMM_64_PCREL
02650                        : MOVI_IMM_32_PCREL);
02651               }
02652 
02653              frag_var (rs_machine_dependent,
02654                      md_relax_table[C (what, max)].rlx_length,
02655                      md_relax_table[C (what, min)].rlx_length,
02656                      C (what, init), sym, addvalue, insn_loc);
02657            }
02658          else
02659            insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02660                                      (opjp->reloctype
02661                                       == BFD_RELOC_NONE)
02662                                      ? BFD_RELOC_SH_IMMS16
02663                                      : opjp->reloctype);
02664          j++;
02665          break;
02666 
02667        case A_PCIMMS16BY4:
02668          {
02669            int what
02670              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
02671                ? SH64PCREL16_64 : SH64PCREL16_32);
02672            offsetT max
02673              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
02674                ? SH64PCREL64 : SH64PCREL32);
02675            offsetT min = SH64PCREL16;
02676            offsetT init = UNDEF_SH64PCREL;
02677 
02678            /* Don't allow complex expressions here.  */
02679            if (opjp->immediate.X_op_symbol != NULL)
02680              {
02681               as_bad(_("invalid operand: expression in PT target"));
02682               return 0;
02683              }
02684 
02685            if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
02686              init = max = min = SH64PCRELPLT;
02687 
02688            /* If we're not expanding, then just emit a fixup.  */
02689            if (sh64_expand || opjp->reloctype != BFD_RELOC_NONE)
02690              frag_var (rs_machine_dependent,
02691                      md_relax_table[C (what, max)].rlx_length,
02692                      md_relax_table[C (what, min)].rlx_length,
02693                      C (what, init),
02694                      opjp->immediate.X_add_symbol,
02695                      opjp->immediate.X_add_number,
02696                      insn_loc);
02697            else
02698              insn |= shmedia_immediate_op (insn_loc, opjp, 1,
02699                                        opjp->reloctype == BFD_RELOC_NONE
02700                                        ? BFD_RELOC_SH_PT_16
02701                                        : opjp->reloctype);
02702 
02703            j++;
02704            break;
02705          }
02706 
02707        case A_PCIMMS16BY4_PT:
02708          {
02709            int what
02710              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
02711                ? SH64PCREL16PT_64 : SH64PCREL16PT_32);
02712            offsetT max
02713              = ((sh64_abi == sh64_abi_64 && ! sh64_pt32)
02714                ? SH64PCREL64 : SH64PCREL32);
02715            offsetT min = SH64PCREL16;
02716            offsetT init = UNDEF_SH64PCREL;
02717 
02718            /* Don't allow complex expressions here.  */
02719            if (opjp->immediate.X_op_symbol != NULL)
02720              {
02721               as_bad(_("invalid operand: expression in PT target"));
02722               return 0;
02723              }
02724 
02725            if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
02726              init = max = min = SH64PCRELPLT;
02727 
02728            /* If we're not expanding, then just emit a fixup.  */
02729            if (sh64_expand || opjp->reloctype != BFD_RELOC_NONE)
02730              frag_var (rs_machine_dependent,
02731                      md_relax_table[C (what, max)].rlx_length,
02732                      md_relax_table[C (what, min)].rlx_length,
02733                      C (what, init),
02734                      opjp->immediate.X_add_symbol,
02735                      opjp->immediate.X_add_number,
02736                      insn_loc);
02737            else
02738              /* This reloc-type is just temporary, so we can distinguish
02739                PTA from PT.  It is changed in shmedia_md_apply_fix to
02740                BFD_RELOC_SH_PT_16.  */
02741              insn |= shmedia_immediate_op (insn_loc, opjp, 1,
02742                                        opjp->reloctype == BFD_RELOC_NONE
02743                                        ? SHMEDIA_BFD_RELOC_PT
02744                                        : opjp->reloctype);
02745 
02746            j++;
02747            break;
02748          }
02749 
02750        case A_IMMU5:
02751          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02752                                    BFD_RELOC_SH_IMMU5);
02753          j++;
02754          break;
02755 
02756        case A_IMMU6:
02757          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02758                                    BFD_RELOC_SH_IMMU6);
02759          j++;
02760          break;
02761 
02762        case A_IMMU16:
02763          insn |= shmedia_immediate_op (insn_loc, opjp, 0,
02764                                    (opjp->reloctype
02765                                     == BFD_RELOC_NONE)
02766                                    ? BFD_RELOC_SH_IMMU16
02767                                    : opjp->reloctype);
02768          j++;
02769          break;
02770 
02771        default:
02772          BAD_CASE (argtype);
02773        }
02774     }
02775 
02776   md_number_to_chars (insn_loc, insn, 4);
02777   return 4;
02778 }
02779 
02780 /* Assemble a SHmedia instruction.  */
02781 
02782 static void
02783 shmedia_md_assemble (char *str)
02784 {
02785   char *op_end;
02786   shmedia_opcode_info *opcode;
02787   shmedia_operands_info operands;
02788   int size;
02789 
02790   opcode = shmedia_find_cooked_opcode (&str);
02791   op_end = str;
02792 
02793   if (opcode == NULL)
02794     {
02795       as_bad (_("unknown opcode"));
02796       return;
02797     }
02798 
02799   /* Start a SHmedia code region, if there has been pseudoinsns or similar
02800      seen since the last one.  */
02801   if (!seen_insn)
02802     {
02803       sh64_update_contents_mark (TRUE);
02804       sh64_set_contents_type (CRT_SH5_ISA32);
02805       seen_insn = TRUE;
02806     }
02807 
02808   op_end = shmedia_get_operands (opcode, op_end, &operands);
02809 
02810   if (op_end == NULL)
02811     {
02812       as_bad (_("invalid operands to %s"), opcode->name);
02813       return;
02814     }
02815 
02816   if (*op_end)
02817     {
02818       as_bad (_("excess operands to %s"), opcode->name);
02819       return;
02820     }
02821 
02822   size = shmedia_build_Mytes (opcode, &operands);
02823   if (size == 0)
02824     return;
02825 }
02826 
02827 /* Hook called from md_begin in tc-sh.c.  */
02828 
02829 void
02830 shmedia_md_begin (void)
02831 {
02832   const shmedia_opcode_info *shmedia_opcode;
02833   shmedia_opcode_hash_control = hash_new ();
02834 
02835   /* Create opcode table for SHmedia mnemonics.  */
02836   for (shmedia_opcode = shmedia_table;
02837        shmedia_opcode->name;
02838        shmedia_opcode++)
02839     hash_insert (shmedia_opcode_hash_control, shmedia_opcode->name,
02840                (char *) shmedia_opcode);
02841 }
02842 
02843 /* Switch instruction set.  Only valid if one of the --isa or --abi
02844    options was specified.  */
02845 
02846 static void
02847 s_sh64_mode (int ignore ATTRIBUTE_UNUSED)
02848 {
02849   char *name = input_line_pointer, ch;
02850 
02851   /* Make sure data up to this location is handled according to the
02852      previous ISA.  */
02853   sh64_update_contents_mark (TRUE);
02854 
02855   while (!is_end_of_line[(unsigned char) *input_line_pointer])
02856     input_line_pointer++;
02857   ch = *input_line_pointer;
02858   *input_line_pointer = '\0';
02859 
02860   /* If the mode was not set before, explicitly or implicitly, then we're
02861      not emitting SH64 code, so this pseudo is invalid.  */
02862   if (sh64_isa_mode == sh64_isa_unspecified)
02863     as_bad (_("The `.mode %s' directive is not valid with this architecture"),
02864            name);
02865 
02866   if (strcasecmp (name, "shcompact") == 0)
02867     sh64_isa_mode = sh64_isa_shcompact;
02868   else if (strcasecmp (name, "shmedia") == 0)
02869     sh64_isa_mode = sh64_isa_shmedia;
02870   else
02871     as_bad (_("Invalid argument to .mode: %s"), name);
02872 
02873   /* Make a new frag, marking it with the supposedly-changed ISA.  */
02874   frag_wane (frag_now);
02875   frag_new (0);
02876 
02877   /* Contents type up to this new point is the same as before; don't add a
02878      data region just because the new frag we created.  */
02879   sh64_update_contents_mark (FALSE);
02880 
02881   *input_line_pointer = ch;
02882   demand_empty_rest_of_line ();
02883 }
02884 
02885 /* Check that the right ABI is used.  Only valid if one of the --isa or
02886    --abi options was specified.  */
02887 
02888 static void
02889 s_sh64_abi (int ignore ATTRIBUTE_UNUSED)
02890 {
02891   char *name = input_line_pointer, ch;
02892 
02893   while (!is_end_of_line[(unsigned char) *input_line_pointer])
02894     input_line_pointer++;
02895   ch = *input_line_pointer;
02896   *input_line_pointer = '\0';
02897 
02898   /* If the mode was not set before, explicitly or implicitly, then we're
02899      not emitting SH64 code, so this pseudo is invalid.  */
02900   if (sh64_abi == sh64_abi_unspecified)
02901     as_bad (_("The `.abi %s' directive is not valid with this architecture"),
02902            name);
02903 
02904   if (strcmp (name, "64") == 0)
02905     {
02906       if (sh64_abi != sh64_abi_64)
02907        as_bad (_("`.abi 64' but command-line options do not specify 64-bit ABI"));
02908     }
02909   else if (strcmp (name, "32") == 0)
02910     {
02911       if (sh64_abi != sh64_abi_32)
02912        as_bad (_("`.abi 32' but command-line options do not specify 32-bit ABI"));
02913     }
02914   else
02915     as_bad (_("Invalid argument to .abi: %s"), name);
02916 
02917   *input_line_pointer = ch;
02918   demand_empty_rest_of_line ();
02919 }
02920 
02921 /* This function is the first target-specific function called after
02922    parsing command-line options.  Therefore we set default values from
02923    command-line options here and do some sanity checking we couldn't do
02924    when options were being parsed.  */
02925 
02926 const char *
02927 sh64_target_format (void)
02928 {
02929 #ifdef TE_NetBSD
02930   /* For NetBSD, if the ISA is unspecified, always use SHmedia.  */
02931   if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
02932     sh64_isa_mode = sh64_isa_shmedia;
02933 
02934   /* If the ABI is unspecified, select a default: based on how
02935      we were configured: sh64 == sh64_abi_64, else sh64_abi_32.  */
02936   if (sh64_abi == sh64_abi_unspecified)
02937     {
02938       if (preset_target_arch != 0 || sh64_isa_mode == sh64_isa_shcompact)
02939        sh64_abi = sh64_abi_32;
02940       else if (strncmp (TARGET_CPU, "sh64", 4) == 0)
02941         sh64_abi = sh64_abi_64;
02942       else
02943         sh64_abi = sh64_abi_32;
02944     }
02945 #endif
02946 
02947 #ifdef TE_LINUX
02948   if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
02949     sh64_isa_mode = sh64_isa_shmedia;
02950 
02951   if (sh64_abi == sh64_abi_unspecified)
02952     sh64_abi = sh64_abi_32;
02953 #endif
02954 
02955   if (sh64_abi == sh64_abi_64 && sh64_isa_mode == sh64_isa_unspecified)
02956     sh64_isa_mode = sh64_isa_shmedia;
02957 
02958   if (sh64_abi == sh64_abi_32 && sh64_isa_mode == sh64_isa_unspecified)
02959     sh64_isa_mode = sh64_isa_shcompact;
02960 
02961   if (sh64_isa_mode == sh64_isa_shcompact
02962       && sh64_abi == sh64_abi_unspecified)
02963     sh64_abi = sh64_abi_32;
02964 
02965   if (sh64_isa_mode == sh64_isa_shmedia
02966       && sh64_abi == sh64_abi_unspecified)
02967     sh64_abi = sh64_abi_64;
02968 
02969   if (sh64_isa_mode == sh64_isa_unspecified && ! sh64_mix)
02970     as_bad (_("-no-mix is invalid without specifying SHcompact or SHmedia"));
02971 
02972   if ((sh64_isa_mode == sh64_isa_unspecified
02973        || sh64_isa_mode == sh64_isa_shmedia)
02974       && sh64_shcompact_const_crange)
02975     as_bad (_("-shcompact-const-crange is invalid without SHcompact"));
02976 
02977   if (sh64_pt32 && sh64_abi != sh64_abi_64)
02978     as_bad (_("-expand-pt32 only valid with -abi=64"));
02979 
02980   if (! sh64_expand && sh64_isa_mode == sh64_isa_unspecified)
02981     as_bad (_("-no-expand only valid with SHcompact or SHmedia"));
02982 
02983   if (sh64_pt32 && ! sh64_expand)
02984     as_bad (_("-expand-pt32 invalid together with -no-expand"));
02985 
02986 #ifdef TE_NetBSD
02987   if (sh64_abi == sh64_abi_64)
02988     return (target_big_endian ? "elf64-sh64-nbsd" : "elf64-sh64l-nbsd");
02989   else
02990     return (target_big_endian ? "elf32-sh64-nbsd" : "elf32-sh64l-nbsd");
02991 #elif defined (TE_LINUX)
02992   if (sh64_abi == sh64_abi_64)
02993     return (target_big_endian ? "elf64-sh64big-linux" : "elf64-sh64-linux");
02994   else
02995     return (target_big_endian ? "elf32-sh64big-linux" : "elf32-sh64-linux");
02996 #else
02997   /* When the ISA is not one of SHmedia or SHcompact, use the old SH
02998      object format.  */
02999   if (sh64_isa_mode == sh64_isa_unspecified)
03000     return (target_big_endian ? "elf32-sh" : "elf32-shl");
03001   else if (sh64_abi == sh64_abi_64)
03002     return (target_big_endian ? "elf64-sh64" : "elf64-sh64l");
03003   else
03004     return (target_big_endian ? "elf32-sh64" : "elf32-sh64l");
03005 #endif
03006 }
03007 
03008 /* The worker function of TARGET_MACH.  */
03009 
03010 int
03011 sh64_target_mach (void)
03012 {
03013   /* We need to explicitly set bfd_mach_sh5 instead of the default 0.  But
03014      we only do this for the 64-bit ABI: if we do it for the 32-bit ABI,
03015      the SH5 info in the bfd_arch_info structure will be selected.
03016      However correct, as the machine has 64-bit addresses, functions
03017      expected to emit 32-bit data for addresses will start failing.  For
03018      example, the dwarf2dbg.c functions will emit 64-bit debugging format,
03019      and we don't want that in the 32-bit ABI.
03020 
03021      We could have two bfd_arch_info structures for SH64; one for the
03022      32-bit ABI and one for the rest (64-bit ABI).  But that would be a
03023      bigger kludge: it's a flaw in the BFD design, and we need to just
03024      work around it by having the default machine set here in the
03025      assembler.  For everything else but the assembler, the various bfd
03026      functions will set the machine type right to bfd_mach_sh5 from object
03027      file header flags regardless of the 0 here.  */
03028 
03029   return (sh64_abi == sh64_abi_64) ? bfd_mach_sh5 : 0;
03030 }
03031 
03032 /* This is MD_PCREL_FROM_SECTION, we we define so it is called instead of
03033    md_pcrel_from (in tc-sh.c).  */
03034 
03035 valueT
03036 shmedia_md_pcrel_from_section (struct fix *fixP, segT sec ATTRIBUTE_UNUSED)
03037 {
03038   know (fixP->fx_frag->fr_type == rs_machine_dependent);
03039 
03040   /* Use the ISA for the instruction to decide which offset to use.  We
03041      can glean it from the fisup type.  */
03042   switch (fixP->fx_r_type)
03043     {
03044     case BFD_RELOC_SH_IMM_LOW16:
03045     case BFD_RELOC_SH_IMM_MEDLOW16:
03046     case BFD_RELOC_SH_IMM_MEDHI16:
03047     case BFD_RELOC_SH_IMM_HI16:
03048     case BFD_RELOC_SH_IMM_LOW16_PCREL:
03049     case BFD_RELOC_SH_IMM_MEDLOW16_PCREL:
03050     case BFD_RELOC_SH_IMM_MEDHI16_PCREL:
03051     case BFD_RELOC_SH_IMM_HI16_PCREL:
03052     case BFD_RELOC_SH_IMMU5:
03053     case BFD_RELOC_SH_IMMU6:
03054     case BFD_RELOC_SH_IMMS6:
03055     case BFD_RELOC_SH_IMMS10:
03056     case BFD_RELOC_SH_IMMS10BY2:
03057     case BFD_RELOC_SH_IMMS10BY4:
03058     case BFD_RELOC_SH_IMMS10BY8:
03059     case BFD_RELOC_SH_IMMS16:
03060     case BFD_RELOC_SH_IMMU16:
03061     case BFD_RELOC_SH_PT_16:
03062     case SHMEDIA_BFD_RELOC_PT:
03063       /* PC-relative relocs are relative to the address of the last generated
03064         instruction, i.e. fx_size - 4.  */
03065       return SHMEDIA_MD_PCREL_FROM_FIX (fixP);
03066 
03067     case BFD_RELOC_64:
03068     case BFD_RELOC_64_PCREL:
03069       know (0 /* Shouldn't get here.  */);
03070       break;
03071 
03072     default:
03073       /* If section was SHcompact, use its function.  */
03074       return (valueT) md_pcrel_from_section (fixP, sec);
03075     }
03076 
03077   know (0 /* Shouldn't get here.  */);
03078   return 0;
03079 }
03080 
03081 /* Create one .cranges descriptor from two symbols, STARTSYM marking begin
03082    and ENDSYM marking end, and CR_TYPE specifying the type.  */
03083 
03084 static void
03085 sh64_emit_crange (symbolS *startsym, symbolS *endsym,
03086                 enum sh64_elf_cr_type cr_type)
03087 {
03088   expressionS exp;
03089   segT current_seg = now_seg;
03090   subsegT current_subseg = now_subseg;
03091 
03092   asection *cranges
03093     = bfd_make_section_old_way (stdoutput,
03094                             SH64_CRANGES_SECTION_NAME);
03095 
03096   /* Temporarily change to the .cranges section.  */
03097   subseg_set (cranges, 0);
03098 
03099   /* Emit the cr_addr part.  */
03100   exp.X_op = O_symbol;
03101   exp.X_add_number = 0;
03102   exp.X_op_symbol = NULL;
03103   exp.X_add_symbol = startsym;
03104   emit_expr (&exp, 4);
03105 
03106   /* Emit the cr_size part.  */
03107   exp.X_op = O_subtract;
03108   exp.X_add_number = 0;
03109   exp.X_add_symbol = endsym;
03110   exp.X_op_symbol = startsym;
03111   emit_expr (&exp, 4);
03112 
03113   /* Emit the cr_size part.  */
03114   exp.X_op = O_constant;
03115   exp.X_add_number = cr_type;
03116   exp.X_add_symbol = NULL;
03117   exp.X_op_symbol = NULL;
03118   emit_expr (&exp, 2);
03119 
03120   /* Now back to our regular program.  */
03121   subseg_set (current_seg, current_subseg);
03122 }
03123 
03124 /* Called when the assembler is about to emit contents of some type into
03125    SEG, so it is *known* that the type of that new contents is in
03126    NEW_CONTENTS_TYPE.  If just switching back and forth between different
03127    contents types (for example, with consecutive .mode pseudos), then this
03128    function isn't called.  */
03129 
03130 static void
03131 sh64_set_contents_type (enum sh64_elf_cr_type new_contents_type)
03132 {
03133   segment_info_type *seginfo;
03134 
03135   /* We will not be called when emitting .cranges output, since callers
03136      stop that.  Validize that assumption.  */
03137   know (!emitting_crange);
03138 
03139   seginfo = seg_info (now_seg);
03140 
03141   if (seginfo)
03142     {
03143       symbolS *symp = seginfo->tc_segment_info_data.last_contents_mark;
03144 
03145       enum sh64_elf_cr_type contents_type
03146        = seginfo->tc_segment_info_data.contents_type;
03147 
03148       /* If it was just SHcompact switching between code and constant
03149         pool, don't change contents type.  Just make sure we don't set
03150         the contents type to data, as that would join with a data-region
03151         in SHmedia mode.  */
03152       if (sh64_isa_mode == sh64_isa_shcompact
03153          && ! sh64_shcompact_const_crange)
03154        new_contents_type = CRT_SH5_ISA16;
03155 
03156       /* If nothing changed, stop here.  */
03157       if (contents_type == new_contents_type)
03158        return;
03159 
03160       /* If we're in 64-bit ABI mode, we do not emit .cranges, as it is
03161         only specified for 32-bit addresses.  It could presumably be
03162         extended, but in 64-bit ABI mode we don't have SHcompact code, so
03163         we would only use it to mark code and data.  */
03164       if (sh64_abi == sh64_abi_64)
03165        {
03166          /* Make the code type "sticky".  We don't want to set the
03167             sections contents type to data if there's any code in it as
03168             we don't have .cranges in 64-bit mode to notice the
03169             difference.  */
03170          seginfo->tc_segment_info_data.contents_type
03171            = (new_contents_type == CRT_SH5_ISA32
03172               || contents_type == CRT_SH5_ISA32)
03173            ? CRT_SH5_ISA32 : new_contents_type;
03174          return;
03175        }
03176 
03177       /* If none was marked, create a start symbol for this range and
03178         perhaps as a closing symbol for the old one.  */
03179       if (symp == NULL)
03180        symp = symbol_new (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (),
03181                         frag_now);
03182 
03183       /* We will use this symbol, so don't leave a pointer behind.  */
03184       seginfo->tc_segment_info_data.last_contents_mark = NULL;
03185 
03186       /* We'll be making only datalabel references to it, if we emit a
03187         .cranges descriptor, so remove any code flag.  */
03188       S_SET_OTHER (symp, S_GET_OTHER (symp) & ~STO_SH5_ISA32);
03189 
03190       /* If we have already marked the start of a range, we need to close
03191         and emit it before marking a new one, so emit a new .cranges
03192         descriptor into the .cranges section.  */
03193       if (seginfo->tc_segment_info_data.mode_start_symbol)
03194        {
03195          /* If we're not supposed to emit mixed-mode sections, make it an
03196             error, but continue processing.  */
03197          if (! sh64_mix
03198              && (new_contents_type == CRT_SH5_ISA32
03199                 || contents_type == CRT_SH5_ISA32))
03200            as_bad (
03201 _("SHmedia code not allowed in same section as constants and SHcompact code"));
03202 
03203          emitting_crange = TRUE;
03204          sh64_emit_crange (seginfo->tc_segment_info_data.mode_start_symbol,
03205                          symp, contents_type);
03206          emitting_crange = FALSE;
03207          seginfo->tc_segment_info_data.emitted_ranges++;
03208        }
03209 
03210       seginfo->tc_segment_info_data.mode_start_symbol = symp;
03211       seginfo->tc_segment_info_data.mode_start_subseg = now_subseg;
03212       seginfo->tc_segment_info_data.contents_type = new_contents_type;
03213 
03214       /* Always reset this, so the SHcompact code will emit a reloc when
03215         it prepares to relax.  */
03216       seginfo->tc_segment_info_data.in_code = 0;
03217     }
03218   else
03219     as_bad (_("No segment info for current section"));
03220 }
03221 
03222 /* Hook when defining symbols and labels.  We set the ST_OTHER field if
03223    the symbol is "shmedia" (with "bitor 1" automatically applied).  Simple
03224    semantics for a label being "shmedia" : It was defined when .mode
03225    SHmedia was in effect, and it was defined in a code section.  It
03226    doesn't matter whether or not an assembled opcode is nearby.  */
03227 
03228 void
03229 sh64_frob_label (symbolS *symp)
03230 {
03231   segT seg = S_GET_SEGMENT (symp);
03232   static const symbolS *null = NULL;
03233 
03234   /* Reset the tc marker for all newly created symbols.  */
03235   symbol_set_tc (symp, (symbolS **) &null);
03236 
03237   if (seg != NULL && sh64_isa_mode == sh64_isa_shmedia && subseg_text_p (seg))
03238     S_SET_OTHER (symp, S_GET_OTHER (symp) | STO_SH5_ISA32);
03239 }
03240 
03241 /* Handle the "datalabel" qualifier.  We need to call "operand", but it's
03242    static, so a function pointer is passed here instead.  FIXME: A target
03243    hook for qualifiers is needed; we currently use the md_parse_name
03244    symbol hook.  */
03245 
03246 int
03247 sh64_consume_datalabel (const char *name, expressionS *exp,
03248                      enum expr_mode mode, char *cp,
03249                      segT (*operandf) (expressionS *, enum expr_mode))
03250 {
03251   static int parsing_datalabel = 0;
03252 
03253   if (strcasecmp (name, "datalabel") == 0)
03254     {
03255       int save_parsing_datalabel = parsing_datalabel;
03256 
03257       if (parsing_datalabel)
03258        as_bad (_("duplicate datalabel operator ignored"));
03259 
03260       *input_line_pointer = *cp;
03261       parsing_datalabel = 1;
03262       (*operandf) (exp, expr_normal);
03263       parsing_datalabel = save_parsing_datalabel;
03264 
03265       if (exp->X_op == O_symbol || exp->X_op == O_PIC_reloc)
03266        {
03267          symbolS *symp = exp->X_add_symbol;
03268          segT symseg = S_GET_SEGMENT (symp);
03269 
03270          /* If the symbol is defined to something that is already a
03271             datalabel, we don't need to bother with any special handling.  */
03272          if (symseg != undefined_section
03273              && S_GET_OTHER (symp) != STO_SH5_ISA32)
03274            /* Do nothing.  */
03275            ;
03276          else
03277            {
03278              symbolS *dl_symp;
03279              const char *name = S_GET_NAME (symp);
03280              char *dl_name
03281               = xmalloc (strlen (name) + sizeof (DATALABEL_SUFFIX));
03282 
03283              /* Now we copy the datalabel-qualified symbol into a symbol
03284                with the same name, but with " DL" appended.  We mark the
03285                symbol using the TC_SYMFIELD_TYPE field with a pointer to
03286                the main symbol, so we don't have to inspect all symbol
03287                names.  Note that use of "datalabel" is not expected to
03288                be a common case.  */
03289              strcpy (dl_name, name);
03290              strcat (dl_name, DATALABEL_SUFFIX);
03291 
03292              /* A FAKE_LABEL_NAME marks "$" or ".".  There can be any
03293                number of them and all have the same (faked) name; we
03294                must make a new one each time.  */
03295              if (strcmp (name, FAKE_LABEL_NAME) == 0)
03296               dl_symp = symbol_make (dl_name);
03297              else
03298               dl_symp = symbol_find_or_make (dl_name);
03299 
03300              free (dl_name);
03301              symbol_set_value_expression (dl_symp,
03302                                       symbol_get_value_expression (symp));
03303              S_SET_SEGMENT (dl_symp, symseg);
03304              symbol_set_frag (dl_symp, symbol_get_frag (symp));
03305              symbol_set_tc (dl_symp, &symp);
03306              copy_symbol_attributes (dl_symp, symp);
03307              exp->X_add_symbol = dl_symp;
03308 
03309              /* Unset the BranchTarget mark that can be set at symbol
03310                creation or attributes copying.  */
03311              S_SET_OTHER (dl_symp, S_GET_OTHER (dl_symp) & ~STO_SH5_ISA32);
03312 
03313              /* The GLOBAL and WEAK attributes are not copied over by
03314                copy_symbol_attributes.  Do it here.  */
03315              if (S_IS_WEAK (symp))
03316               S_SET_WEAK (dl_symp);
03317              else if (S_IS_EXTERNAL (symp))
03318               S_SET_EXTERNAL (dl_symp);
03319            }
03320        }
03321       /* Complain about other types of operands than symbol, unless they
03322         have already been complained about.  A constant is always a
03323         datalabel.  Removing the low bit would therefore be wrong.
03324         Complaining about it would also be wrong.  */
03325       else if (exp->X_op != O_illegal
03326               && exp->X_op != O_absent
03327               && exp->X_op != O_constant)
03328        as_bad (_("Invalid DataLabel expression"));
03329 
03330       *cp = *input_line_pointer;
03331 
03332       return 1;
03333     }
03334 
03335   return sh_parse_name (name, exp, mode, cp);
03336 }
03337 
03338 /* This function is called just before symbols are being output.  It
03339    returns zero when a symbol must be output, non-zero otherwise.
03340    Datalabel references that were fully resolved to local symbols are not
03341    necessary to output.  We also do not want to output undefined symbols
03342    that are not used in relocs.  For symbols that are used in a reloc, it
03343    does not matter what we set here.  If it is *not* used in a reloc, then
03344    it was probably the datalabel counterpart that was used in a reloc;
03345    then we need not output the main symbol.  */
03346 
03347 int
03348 sh64_exclude_symbol (symbolS *symp)
03349 {
03350   symbolS *main_symbol = *symbol_get_tc (symp);
03351 
03352   return main_symbol != NULL || ! S_IS_DEFINED (symp);
03353 }
03354 
03355 /* If we haven't seen an insn since the last update, and location
03356    indicators have moved (a new frag, new location within frag) we have
03357    emitted data, so change contents type to data.  Forget that we have
03358    seen a sequence of insns and store the current location so we can mark
03359    a new region if needed.  */
03360 
03361 static void
03362 sh64_update_contents_mark (bfd_boolean update_type)
03363 {
03364   segment_info_type *seginfo;
03365   seginfo = seg_info (now_seg);
03366 
03367   if (seginfo != NULL)
03368     {
03369       symbolS *symp = seginfo->tc_segment_info_data.last_contents_mark;
03370 
03371       if (symp == NULL)
03372        {
03373          symp = symbol_new (FAKE_LABEL_NAME, now_seg,
03374                           (valueT) frag_now_fix (), frag_now);
03375          seginfo->tc_segment_info_data.last_contents_mark = symp;
03376        }
03377       else
03378        {
03379          /* If we have moved location since last flush, we need to emit a
03380             data range.  The previous contents type ended at the location
03381             of the last update.  */
03382          if ((S_GET_VALUE (symp) != frag_now_fix ()
03383               || symbol_get_frag (symp) != frag_now))
03384            {
03385              enum sh64_elf_cr_type contents_type
03386               = seginfo->tc_segment_info_data.contents_type;
03387 
03388              if (update_type
03389                 && contents_type != CRT_DATA
03390                 && contents_type != CRT_NONE
03391                 && ! seen_insn)
03392               {
03393                 sh64_set_contents_type (CRT_DATA);
03394                 symp = seginfo->tc_segment_info_data.last_contents_mark;
03395               }
03396 
03397              /* If the symbol wasn't used up to make up a new range
03398                descriptor, update it to this new location.  */
03399              if (symp)
03400               {
03401                 S_SET_VALUE (symp, (valueT) frag_now_fix ());
03402                 symbol_set_frag (symp, frag_now);
03403               }
03404            }
03405        }
03406     }
03407 
03408   seen_insn = FALSE;
03409 }
03410 
03411 /* Called when the assembler is about to output some data, or maybe it's
03412    just switching segments.  */
03413 
03414 void
03415 sh64_flush_pending_output (void)
03416 {
03417   sh64_update_contents_mark (TRUE);
03418   sh_flush_pending_output ();
03419 }
03420 
03421 /* Flush out the last crange descriptor after all insns have been emitted.  */
03422 
03423 static void
03424 sh64_flush_last_crange (bfd *abfd ATTRIBUTE_UNUSED, asection *seg,
03425                      void *countparg ATTRIBUTE_UNUSED)
03426 {
03427   segment_info_type *seginfo;
03428 
03429   seginfo = seg_info (seg);
03430 
03431   if (seginfo
03432       /* Only emit .cranges descriptors if we would make it more than one.  */
03433       && seginfo->tc_segment_info_data.emitted_ranges != 0)
03434     {
03435       symbolS *symp;
03436 
03437       /* We need a closing symbol, so switch to the indicated section and
03438         emit it.  */
03439 
03440       /* Change to the section we're about to handle.  */
03441       subseg_set (seg, seginfo->tc_segment_info_data.mode_start_subseg);
03442 
03443       symp = symbol_new (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (),
03444                       frag_now);
03445 
03446       /* We'll be making a datalabel reference to it, so remove any code
03447          flag.  */
03448       S_SET_OTHER (symp, S_GET_OTHER (symp) & ~STO_SH5_ISA32);
03449 
03450       sh64_emit_crange (seginfo->tc_segment_info_data.mode_start_symbol,
03451                      symp,
03452                      seginfo->tc_segment_info_data.contents_type);
03453     }
03454 }
03455 
03456 /* If and only if we see a call to md_number_to_chars without flagging the
03457    start of an insn, we set the contents type to CRT_DATA, and only when
03458    in SHmedia mode.  Note that by default we don't bother changing when
03459    going from SHcompact to data, as the constant pools in GCC-generated
03460    SHcompact code would create an inordinate amount of .cranges
03461    descriptors.  */
03462 
03463 static void
03464 sh64_flag_output (void)
03465 {
03466   if (sh64_isa_mode != sh64_isa_unspecified
03467       && !seen_insn
03468       && !sh64_end_of_assembly
03469       && !emitting_crange)
03470     {
03471       md_flush_pending_output ();
03472       sh64_set_contents_type (CRT_DATA);
03473     }
03474 }
03475 
03476 /* Vtables don't need "datalabel" but we allow it by simply deleting
03477    any we find.  */
03478 
03479 static char *
03480 strip_datalabels (void)
03481 {
03482   char *src, *dest, *start=input_line_pointer;
03483 
03484   for (src=input_line_pointer, dest=input_line_pointer; *src != '\n'; )
03485     {
03486       if (strncasecmp (src, "datalabel", 9) == 0
03487          && ISSPACE (src[9])
03488          && (src == start || !(ISALNUM (src[-1])) || src[-1] == '_'))
03489        src += 10;
03490       else
03491        *dest++ = *src++;
03492     }
03493 
03494   if (dest < src)
03495     *dest = '\n';
03496   return src + 1;
03497 }
03498 
03499 static void
03500 sh64_vtable_entry (int ignore ATTRIBUTE_UNUSED)
03501 {
03502   char *eol = strip_datalabels ();
03503 
03504   obj_elf_vtable_entry (0);
03505   input_line_pointer = eol;
03506 }
03507 
03508 static void
03509 sh64_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
03510 {
03511   char *eol = strip_datalabels ();
03512 
03513   obj_elf_vtable_inherit (0);
03514   input_line_pointer = eol;
03515 }
03516 
03517 int
03518 sh64_fake_label (const char *name)
03519 {
03520   size_t len;
03521 
03522   if (strcmp (name, FAKE_LABEL_NAME) == 0)
03523     return 1;
03524 
03525   len = strlen (name);
03526   if (len >= (sizeof (DATALABEL_SUFFIX) - 1))
03527     return strcmp (&name [len - sizeof (DATALABEL_SUFFIX) + 1],
03528                  DATALABEL_SUFFIX) == 0;
03529 
03530   return 0;
03531 }