-/* tc-sh64.c -- Assemble code for the Hitachi Super-H SHcompact and SHmedia.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation.
+/* tc-sh64.c -- Assemble code for the SuperH SH SHcompact and SHmedia.
+ Copyright (C) 2000-2015 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* This file defines SHmedia ISA-specific functions and includes tc-sh.c.
The SHcompact ISA is in all useful aspects the "old" sh4 as implemented
#define HAVE_SH64
-#include <stdio.h>
#include "as.h"
#include "safe-ctype.h"
#include "opcodes/sh64-opc.h"
symbol" or local symbol. */
#define DATALABEL_SUFFIX " DL"
-/* See shmedia_md_apply_fix3 and shmedia_md_pcrel_from_section for usage. */
+/* See shmedia_md_apply_fix and shmedia_md_pcrel_from_section for usage. */
#define SHMEDIA_MD_PCREL_FROM_FIX(FIXP) \
((FIXP)->fx_size + (FIXP)->fx_where + (FIXP)->fx_frag->fr_address - 4)
/* A note that says if we're in a sequence of insns without label
settings, segment or ISA mode changes or emitted data. */
-static boolean seen_insn = false;
+static bfd_boolean seen_insn = FALSE;
-/* This is set to true in shmedia_md_end, so that we don't emit any
+/* This is set to TRUE in shmedia_md_end, so that we don't emit any
.cranges entries when the assembler calls output functions while
grinding along after all input is seen. */
-static boolean sh64_end_of_assembly = false;
+static bfd_boolean sh64_end_of_assembly = FALSE;
/* Controlled by the option -no-mix, this invalidates mixing SHcompact and
SHmedia code in the same section, and also invalidates mixing data and
SHmedia code in the same section. No .cranges will therefore be
emitted, unless -shcompact-const-crange is specified and there is a
constant pool in SHcompact code. */
-static boolean sh64_mix = true;
+static bfd_boolean sh64_mix = TRUE;
-static boolean sh64_shcompact_const_crange = false;
+static bfd_boolean sh64_shcompact_const_crange = FALSE;
/* Controlled by the option -no-expand, this says whether or not we expand
MOVI and PT/PTA/PTB. When we do not expand these insns to fit an
operand, we will emit errors for operands out of range and generate the
basic instruction and reloc for an external symbol. */
-static boolean sh64_expand = true;
+static bfd_boolean sh64_expand = TRUE;
/* Controlled by the option -expand-pt32, this says whether we expand
PT/PTA/PTB of an external symbol to (only) 32 or (the full) 64 bits
when -abi=64 is in effect. */
-static boolean sh64_pt32 = false;
+static bfd_boolean sh64_pt32 = FALSE;
/* When emitting a .cranges descriptor, we want to avoid getting recursive
calls through emit_expr. */
-static boolean emitting_crange = false;
+static bfd_boolean emitting_crange = FALSE;
/* SHmedia mnemonics. */
static struct hash_control *shmedia_opcode_hash_control = NULL;
(SHMEDIA_NOP_OPC >> 16) & 255, (SHMEDIA_NOP_OPC >> 24) & 255
};
-static void shmedia_md_begin PARAMS ((void));
-static int shmedia_parse_reg PARAMS ((char *, int *, int *, shmedia_arg_type));
-static void shmedia_md_assemble PARAMS ((char *));
-static void shmedia_md_apply_fix3 PARAMS ((fixS *, valueT *));
-static int shmedia_md_estimate_size_before_relax PARAMS ((fragS *, segT));
-static int shmedia_init_reloc PARAMS ((arelent *, fixS *));
-static char *shmedia_get_operands PARAMS ((shmedia_opcode_info *, char *, shmedia_operands_info *));
-static void s_sh64_mode PARAMS ((int));
-static void s_sh64_abi PARAMS ((int));
-static void shmedia_md_convert_frag PARAMS ((bfd *, segT, fragS *, boolean));
-static void shmedia_check_limits PARAMS ((offsetT *, bfd_reloc_code_real_type, fixS *));
-static void sh64_set_contents_type PARAMS ((enum sh64_elf_cr_type));
-static void shmedia_get_operand PARAMS ((char **, shmedia_operand_info *, shmedia_arg_type));
-static unsigned long shmedia_immediate_op PARAMS ((char *, shmedia_operand_info *, int, bfd_reloc_code_real_type));
-static char *shmedia_parse_exp PARAMS ((char *, shmedia_operand_info *));
-static void shmedia_frob_file_before_adjust PARAMS ((void));
-static void sh64_emit_crange PARAMS ((symbolS *, symbolS *, enum sh64_elf_cr_type));
-static void sh64_flush_last_crange PARAMS ((bfd *, asection *, PTR));
-static void sh64_flag_output PARAMS ((void));
-static void sh64_update_contents_mark PARAMS ((boolean));
-static void sh64_vtable_entry PARAMS ((int));
-static void sh64_vtable_inherit PARAMS ((int));
-static char * strip_datalabels PARAMS ((void));
-static int shmedia_build_Mytes PARAMS ((shmedia_opcode_info *, shmedia_operands_info *));
-static shmedia_opcode_info * shmedia_find_cooked_opcode PARAMS ((char **));
-static unsigned long shmedia_mask_number PARAMS ((unsigned long, bfd_reloc_code_real_type));
+static void shmedia_md_begin (void);
+static int shmedia_parse_reg (char *, int *, int *, shmedia_arg_type);
+static void shmedia_md_assemble (char *);
+static void shmedia_md_apply_fix (fixS *, valueT *);
+static int shmedia_md_estimate_size_before_relax (fragS *, segT);
+static int shmedia_init_reloc (arelent *, fixS *);
+static char *shmedia_get_operands (shmedia_opcode_info *, char *,
+ shmedia_operands_info *);
+static void s_sh64_mode (int);
+static void s_sh64_abi (int);
+static void shmedia_md_convert_frag (bfd *, segT, fragS *, bfd_boolean);
+static void shmedia_check_limits (offsetT *, bfd_reloc_code_real_type,
+ fixS *);
+static void sh64_set_contents_type (enum sh64_elf_cr_type);
+static void shmedia_get_operand (char **, shmedia_operand_info *,
+ shmedia_arg_type);
+static unsigned long shmedia_immediate_op (char *, shmedia_operand_info *,
+ int, bfd_reloc_code_real_type);
+static char *shmedia_parse_exp (char *, shmedia_operand_info *);
+static void shmedia_frob_file_before_adjust (void);
+static void sh64_emit_crange (symbolS *, symbolS *, enum sh64_elf_cr_type);
+static void sh64_flush_last_crange (bfd *, asection *, void *);
+static void sh64_flag_output (void);
+static void sh64_update_contents_mark (bfd_boolean);
+static void sh64_vtable_entry (int);
+static void sh64_vtable_inherit (int);
+static char *strip_datalabels (void);
+static int shmedia_build_Mytes (shmedia_opcode_info *,
+ shmedia_operands_info *);
+static shmedia_opcode_info *shmedia_find_cooked_opcode (char **);
+static unsigned long shmedia_mask_number (unsigned long,
+ bfd_reloc_code_real_type);
#include "tc-sh.c"
void
-shmedia_md_end ()
+shmedia_md_end (void)
{
symbolS *symp;
/* First, update the last range to include whatever data was last
emitted. */
- sh64_update_contents_mark (true);
+ sh64_update_contents_mark (TRUE);
/* Make sure frags generated after this point are not marked with the
wrong ISA; make them easily spottable. We still want to distinguish
if (sh64_isa_mode != sh64_isa_unspecified)
sh64_isa_mode = sh64_isa_sh5_guard;
- sh64_end_of_assembly = true;
+ sh64_end_of_assembly = TRUE;
bfd_map_over_sections (stdoutput, sh64_flush_last_crange, NULL);
+ offset" value. */
static void
-shmedia_frob_file_before_adjust ()
+shmedia_frob_file_before_adjust (void)
{
symbolS *symp;
for (symp = symbol_rootP; symp != NULL; symp = symp->sy_next)
if (mainsym != NULL
&& S_GET_OTHER (mainsym) != STO_SH5_ISA32
- && (S_IS_EXTERN (mainsym) || S_IS_WEAK (mainsym)))
+ && (S_IS_EXTERNAL (mainsym) || S_IS_WEAK (mainsym)))
{
symp->sy_value.X_op = O_symbol;
symp->sy_value.X_add_symbol = mainsym;
static in read.c. That solution was discarded a too kludgy. */
void
-sh64_do_align (n, fill, len, max)
- int n;
- const char *fill;
- int len;
- int max;
+sh64_do_align (int n, const char *fill, int len, int max)
{
/* Update region, or put a data region in front. */
- sh64_update_contents_mark (true);
+ sh64_update_contents_mark (TRUE);
/* Only make a frag if we HAVE to... */
if (n != 0 && !need_pass_2)
}
/* Update mark for current region with current type. */
- sh64_update_contents_mark (false);
+ sh64_update_contents_mark (FALSE);
}
/* The MAX_MEM_FOR_RS_ALIGN_CODE worker. We have to find out the ISA of
assembly). */
int
-sh64_max_mem_for_rs_align_code ()
+sh64_max_mem_for_rs_align_code (void)
{
segment_info_type *seginfo;
fragS *mode_start_frag;
/* Put in SHmedia NOP:s if the alignment was created when in SHmedia mode. */
void
-sh64_handle_align (frag)
- fragS * frag;
+sh64_handle_align (fragS * frag)
{
int bytes = frag->fr_next->fr_address - frag->fr_address - frag->fr_fix;
char * p = frag->fr_literal + frag->fr_fix;
/* Set SEC_SH64_ISA32 for SHmedia sections. */
void
-shmedia_frob_section_type (sec)
- asection *sec;
+shmedia_frob_section_type (asection *sec)
{
segment_info_type *seginfo;
seginfo = seg_info (sec);
target-specific semantics. This target is ELF only (semantics not
defined for other formats), so we use the target-specific pointer
field of the ELF section data. */
- if (seginfo)
+ if (seginfo && sh64_abi == sh64_abi_32)
{
struct sh64_section_data *sec_elf_data;
flagword sec_type = 0;
else if (seginfo->tc_segment_info_data.contents_type == CRT_SH5_ISA32)
sec_type = SHF_SH5_ISA32;
- sec_elf_data = sh64_elf_section_data (sec);
+ sec_elf_data = sh64_elf_section_data (sec)->sh64_info;
if (sec_elf_data == NULL)
{
sec_elf_data = xcalloc (1, sizeof (*sec_elf_data));
- sh64_elf_section_data (sec) = sec_elf_data;
+ sh64_elf_section_data (sec)->sh64_info = sec_elf_data;
}
sec_elf_data->contents_flags = sec_type;
seems too much for little benefit. */
void
-sh64_adjust_symtab ()
+sh64_adjust_symtab (void)
{
symbolS *symp;
/* Fill-in an allocated arelent. */
static int
-shmedia_init_reloc (rel, fixP)
- arelent *rel;
- fixS *fixP;
+shmedia_init_reloc (arelent *rel, fixS *fixP)
{
/* Adjust parts of *relp according to *fixp, and tell that it has been
done, so default initializations will not happen. */
return 0;
}
-/* Hook called from md_apply_fix3 in tc-sh.c. */
+/* Hook called from md_apply_fix in tc-sh.c. */
static void
-shmedia_md_apply_fix3 (fixP, valp)
- fixS *fixP;
- valueT *valp;
+shmedia_md_apply_fix (fixS *fixP, valueT *valp)
{
offsetT val = *valp;
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
/* Because write.c calls MD_PCREL_FROM_SECTION twice, we need to
undo one of the adjustments, if the relocation is not
actually for a symbol within the same segment (which we
- cannot check, because we're not called from md_apply_fix3, so
+ cannot check, because we're not called from md_apply_fix, so
we have to keep the reloc). FIXME: This is a bug in
write.c:fixup_segment affecting most targets that change
ordinary relocs to pcrel relocs in md_apply_fix. */
if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
{
/* Emit error for an out-of-range value. */
- shmedia_check_limits (valp, fixP->fx_r_type, fixP);
+ shmedia_check_limits ((offsetT *) valp, fixP->fx_r_type, fixP);
switch (fixP->fx_r_type)
{
insn | ((val & (0x3ff << 2)) << (10 - 2)), 4);
break;
+ case BFD_RELOC_SH_IMMS10BY8:
+ md_number_to_chars (buf,
+ insn | ((val & (0x3ff << 3)) << (10 - 3)), 4);
+ break;
+
case BFD_RELOC_SH_SHMEDIA_CODE:
/* We just ignore and remove this one for the moment. FIXME:
Use it when implementing relaxing. */
/* Hook called from md_convert_frag in tc-sh.c. */
static void
-shmedia_md_convert_frag (output_bfd, seg, fragP, final)
- bfd *output_bfd ATTRIBUTE_UNUSED;
- segT seg ATTRIBUTE_UNUSED;
- fragS *fragP;
- boolean final;
+shmedia_md_convert_frag (bfd *output_bfd ATTRIBUTE_UNUSED,
+ segT seg ATTRIBUTE_UNUSED, fragS *fragP,
+ bfd_boolean final)
{
/* Pointer to first byte in variable-sized part of the frag. */
char *var_partp;
and offsets to varying parts. */
symbolS *symbolP = fragP->fr_symbol;
- boolean reloc_needed
+ bfd_boolean reloc_needed
= (! final
|| sh_relax
|| symbolP == NULL
|| ! S_IS_DEFINED (symbolP)
- || S_IS_EXTERN (symbolP)
+ || S_IS_EXTERNAL (symbolP)
|| S_IS_WEAK (symbolP)
|| (S_GET_SEGMENT (fragP->fr_symbol) != absolute_section
&& S_GET_SEGMENT (fragP->fr_symbol) != seg));
reloc. */
static unsigned long
-shmedia_mask_number (number, how)
- unsigned long number;
- bfd_reloc_code_real_type how;
+shmedia_mask_number (unsigned long number, bfd_reloc_code_real_type how)
{
switch (how)
{
non-NULL, as_bad otherwise. */
static void
-shmedia_check_limits (valp, reloc, fixp)
- offsetT *valp;
- bfd_reloc_code_real_type reloc;
- fixS *fixp;
+shmedia_check_limits (offsetT *valp, bfd_reloc_code_real_type reloc,
+ fixS *fixp)
{
offsetT val = *valp;
case BFD_RELOC_SH_IMMU16:
if (val < 0 || val > (1 << 16) - 1)
- msg = _("invalid operand, not an 16-bit unsigned value: %d");
+ msg = _("invalid operand, not a 16-bit unsigned value: %d");
break;
case BFD_RELOC_SH_PT_16:
"or" into the opcode (non-zero if the value was a constant number). */
static unsigned long
-shmedia_immediate_op (where, op, pcrel, how)
- char *where;
- shmedia_operand_info *op;
- int pcrel;
- bfd_reloc_code_real_type how;
+shmedia_immediate_op (char *where, shmedia_operand_info *op, int pcrel,
+ bfd_reloc_code_real_type how)
{
unsigned long retval = 0;
chars consumed. */
static int
-shmedia_parse_reg (src, mode, reg, argtype)
- char *src;
- int *mode;
- int *reg;
- shmedia_arg_type argtype;
+shmedia_parse_reg (char *src, int *mode, int *reg, shmedia_arg_type argtype)
{
int l0 = TOLOWER (src[0]);
int l1 = l0 ? TOLOWER (src[1]) : 0;
/* Called from md_estimate_size_before_relax in tc-sh.c */
static int
-shmedia_md_estimate_size_before_relax (fragP, segment_type)
- fragS *fragP;
- segT segment_type ATTRIBUTE_UNUSED;
+shmedia_md_estimate_size_before_relax (fragS *fragP,
+ segT segment_type ATTRIBUTE_UNUSED)
{
int old_fr_fix;
expressionS *exp;
/* For ELF, we can't relax externally visible symbols; see tc-i386.c. */
- boolean sym_relaxable
+ bfd_boolean sym_relaxable
= (fragP->fr_symbol
&& S_GET_SEGMENT (fragP->fr_symbol) == segment_type
&& ! S_IS_EXTERNAL (fragP->fr_symbol)
/* MOVI expansions that get here have not been converted to
PC-relative frags, but instead expanded by
md_number_to_chars or by calling shmedia_md_convert_frag
- with final == false. We must not have them around as
+ with final == FALSE. We must not have them around as
frags anymore; symbols would be prematurely evaluated
when relaxing. We will not need to have md_convert_frag
called again with them; any further handling is through
datatypes adjusted. */
static char *
-shmedia_parse_exp (s, op)
- char *s;
- shmedia_operand_info *op;
+shmedia_parse_exp (char *s, shmedia_operand_info *op)
{
char *save;
- char *new;
+ char *new_pointer;
save = input_line_pointer;
input_line_pointer = s;
expression (&op->immediate);
if (op->immediate.X_op == O_absent)
as_bad (_("missing operand"));
- new = input_line_pointer;
+ new_pointer = input_line_pointer;
input_line_pointer = save;
- return new;
+ return new_pointer;
}
/* Parse an operand. Store pointer to next character in *PTR. */
static void
-shmedia_get_operand (ptr, op, argtype)
- char **ptr;
- shmedia_operand_info *op;
- shmedia_arg_type argtype;
+shmedia_get_operand (char **ptr, shmedia_operand_info *op,
+ shmedia_arg_type argtype)
{
char *src = *ptr;
int mode = -1;
how much text was consumed. */
static char *
-shmedia_get_operands (info, args, operands)
- shmedia_opcode_info *info;
- char *args;
- shmedia_operands_info *operands;
+shmedia_get_operands (shmedia_opcode_info *info, char *args,
+ shmedia_operands_info *operands)
{
char *ptr = args;
int i;
*STR_P to the first character after the last one read. */
static shmedia_opcode_info *
-shmedia_find_cooked_opcode (str_p)
- char **str_p;
+shmedia_find_cooked_opcode (char **str_p)
{
char *str = *str_p;
char *op_start;
/* The machine independent code will convert CMP/EQ into cmp/EQ
because it thinks the '/' is the end of the symbol. Moreover,
all but the first sub-insn is a parallel processing insn won't
- be capitailzed. Instead of hacking up the machine independent
+ be capitalized. Instead of hacking up the machine independent
code, we just deal with it here. */
c = TOLOWER (c);
name[nlen] = c;
/* Build up an instruction, including allocating the frag. */
static int
-shmedia_build_Mytes (opcode, operands)
- shmedia_opcode_info *opcode;
- shmedia_operands_info *operands;
+shmedia_build_Mytes (shmedia_opcode_info *opcode,
+ shmedia_operands_info *operands)
{
unsigned long insn = opcode->opcode_base;
int i, j;
/* Don't allow complex expressions here. */
if (opjp->immediate.X_op_symbol != NULL)
- return 0;
+ {
+ as_bad (_("invalid operand: expression in PT target"));
+ return 0;
+ }
if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
init = max = min = SH64PCRELPLT;
/* Don't allow complex expressions here. */
if (opjp->immediate.X_op_symbol != NULL)
- return 0;
+ {
+ as_bad (_("invalid operand: expression in PT target"));
+ return 0;
+ }
if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
init = max = min = SH64PCRELPLT;
insn_loc);
else
/* This reloc-type is just temporary, so we can distinguish
- PTA from PT. It is changed in shmedia_md_apply_fix3 to
+ PTA from PT. It is changed in shmedia_md_apply_fix to
BFD_RELOC_SH_PT_16. */
insn |= shmedia_immediate_op (insn_loc, opjp, 1,
opjp->reloctype == BFD_RELOC_NONE
/* Assemble a SHmedia instruction. */
static void
-shmedia_md_assemble (str)
- char *str;
+shmedia_md_assemble (char *str)
{
char *op_end;
shmedia_opcode_info *opcode;
/* Start a SHmedia code region, if there has been pseudoinsns or similar
seen since the last one. */
- if (seen_insn == false)
+ if (!seen_insn)
{
- sh64_update_contents_mark (true);
+ sh64_update_contents_mark (TRUE);
sh64_set_contents_type (CRT_SH5_ISA32);
- seen_insn = true;
+ seen_insn = TRUE;
}
op_end = shmedia_get_operands (opcode, op_end, &operands);
/* Hook called from md_begin in tc-sh.c. */
void
-shmedia_md_begin ()
+shmedia_md_begin (void)
{
const shmedia_opcode_info *shmedia_opcode;
shmedia_opcode_hash_control = hash_new ();
options was specified. */
static void
-s_sh64_mode (ignore)
- int ignore ATTRIBUTE_UNUSED;
+s_sh64_mode (int ignore ATTRIBUTE_UNUSED)
{
char *name = input_line_pointer, ch;
/* Make sure data up to this location is handled according to the
previous ISA. */
- sh64_update_contents_mark (true);
+ sh64_update_contents_mark (TRUE);
while (!is_end_of_line[(unsigned char) *input_line_pointer])
input_line_pointer++;
/* Contents type up to this new point is the same as before; don't add a
data region just because the new frag we created. */
- sh64_update_contents_mark (false);
+ sh64_update_contents_mark (FALSE);
*input_line_pointer = ch;
demand_empty_rest_of_line ();
--abi options was specified. */
static void
-s_sh64_abi (ignore)
- int ignore ATTRIBUTE_UNUSED;
+s_sh64_abi (int ignore ATTRIBUTE_UNUSED)
{
char *name = input_line_pointer, ch;
when options were being parsed. */
const char *
-sh64_target_format ()
+sh64_target_format (void)
{
+#ifdef TE_NetBSD
+ /* For NetBSD, if the ISA is unspecified, always use SHmedia. */
+ if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
+ sh64_isa_mode = sh64_isa_shmedia;
+
+ /* If the ABI is unspecified, select a default: based on how
+ we were configured: sh64 == sh64_abi_64, else sh64_abi_32. */
+ if (sh64_abi == sh64_abi_unspecified)
+ {
+ if (preset_target_arch != 0 || sh64_isa_mode == sh64_isa_shcompact)
+ sh64_abi = sh64_abi_32;
+ else if (strncmp (TARGET_CPU, "sh64", 4) == 0)
+ sh64_abi = sh64_abi_64;
+ else
+ sh64_abi = sh64_abi_32;
+ }
+#endif
+
#ifdef TE_LINUX
- return "FIXME: No linux target yet";
+ if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
+ sh64_isa_mode = sh64_isa_shmedia;
+
+ if (sh64_abi == sh64_abi_unspecified)
+ sh64_abi = sh64_abi_32;
#endif
if (sh64_abi == sh64_abi_64 && sh64_isa_mode == sh64_isa_unspecified)
if (sh64_pt32 && ! sh64_expand)
as_bad (_("-expand-pt32 invalid together with -no-expand"));
+#ifdef TE_NetBSD
+ if (sh64_abi == sh64_abi_64)
+ return (target_big_endian ? "elf64-sh64-nbsd" : "elf64-sh64l-nbsd");
+ else
+ return (target_big_endian ? "elf32-sh64-nbsd" : "elf32-sh64l-nbsd");
+#elif defined (TE_LINUX)
+ if (sh64_abi == sh64_abi_64)
+ return (target_big_endian ? "elf64-sh64big-linux" : "elf64-sh64-linux");
+ else
+ return (target_big_endian ? "elf32-sh64big-linux" : "elf32-sh64-linux");
+#else
/* When the ISA is not one of SHmedia or SHcompact, use the old SH
object format. */
if (sh64_isa_mode == sh64_isa_unspecified)
return (target_big_endian ? "elf64-sh64" : "elf64-sh64l");
else
return (target_big_endian ? "elf32-sh64" : "elf32-sh64l");
+#endif
}
/* The worker function of TARGET_MACH. */
int
-sh64_target_mach ()
+sh64_target_mach (void)
{
/* We need to explicitly set bfd_mach_sh5 instead of the default 0. But
we only do this for the 64-bit ABI: if we do it for the 32-bit ABI,
md_pcrel_from (in tc-sh.c). */
valueT
-shmedia_md_pcrel_from_section (fixP, sec)
- struct fix *fixP;
- segT sec ATTRIBUTE_UNUSED;
+shmedia_md_pcrel_from_section (struct fix *fixP, segT sec ATTRIBUTE_UNUSED)
{
- know (fixP->fx_frag->fr_type == rs_machine_dependent);
-
/* Use the ISA for the instruction to decide which offset to use. We
can glean it from the fisup type. */
switch (fixP->fx_r_type)
case BFD_RELOC_64:
case BFD_RELOC_64_PCREL:
- know (0 /* Shouldn't get here. */);
- break;
+ /* Fall through. */
default:
/* If section was SHcompact, use its function. */
and ENDSYM marking end, and CR_TYPE specifying the type. */
static void
-sh64_emit_crange (startsym, endsym, cr_type)
- symbolS *startsym;
- symbolS *endsym;
- enum sh64_elf_cr_type cr_type;
+sh64_emit_crange (symbolS *startsym, symbolS *endsym,
+ enum sh64_elf_cr_type cr_type)
{
expressionS exp;
segT current_seg = now_seg;
function isn't called. */
static void
-sh64_set_contents_type (new_contents_type)
- enum sh64_elf_cr_type new_contents_type;
+sh64_set_contents_type (enum sh64_elf_cr_type new_contents_type)
{
segment_info_type *seginfo;
/* We will not be called when emitting .cranges output, since callers
stop that. Validize that assumption. */
- know (emitting_crange == false);
+ know (!emitting_crange);
seginfo = seg_info (now_seg);
as_bad (
_("SHmedia code not allowed in same section as constants and SHcompact code"));
- emitting_crange = true;
+ emitting_crange = TRUE;
sh64_emit_crange (seginfo->tc_segment_info_data.mode_start_symbol,
symp, contents_type);
- emitting_crange = false;
+ emitting_crange = FALSE;
seginfo->tc_segment_info_data.emitted_ranges++;
}
doesn't matter whether or not an assembled opcode is nearby. */
void
-sh64_frob_label (symp)
- symbolS *symp;
+sh64_frob_label (symbolS *symp)
{
segT seg = S_GET_SEGMENT (symp);
static const symbolS *null = NULL;
symbol hook. */
int
-sh64_consume_datalabel (name, exp, cp, operandf)
- const char *name;
- expressionS *exp;
- char *cp;
- segT (*operandf) PARAMS ((expressionS *));
+sh64_consume_datalabel (const char *name, expressionS *exp,
+ enum expr_mode mode, char *cp,
+ segT (*operandf) (expressionS *, enum expr_mode))
{
static int parsing_datalabel = 0;
*input_line_pointer = *cp;
parsing_datalabel = 1;
- (*operandf) (exp);
+ (*operandf) (exp, expr_normal);
parsing_datalabel = save_parsing_datalabel;
if (exp->X_op == O_symbol || exp->X_op == O_PIC_reloc)
else
{
symbolS *dl_symp;
- const char *name = S_GET_NAME (symp);
+ const char * sname = S_GET_NAME (symp);
char *dl_name
- = xmalloc (strlen (name) + sizeof (DATALABEL_SUFFIX));
+ = xmalloc (strlen (sname) + sizeof (DATALABEL_SUFFIX));
/* Now we copy the datalabel-qualified symbol into a symbol
with the same name, but with " DL" appended. We mark the
the main symbol, so we don't have to inspect all symbol
names. Note that use of "datalabel" is not expected to
be a common case. */
- strcpy (dl_name, name);
+ strcpy (dl_name, sname);
strcat (dl_name, DATALABEL_SUFFIX);
/* A FAKE_LABEL_NAME marks "$" or ".". There can be any
number of them and all have the same (faked) name; we
must make a new one each time. */
- if (strcmp (name, FAKE_LABEL_NAME) == 0)
+ if (strcmp (sname, FAKE_LABEL_NAME) == 0)
dl_symp = symbol_make (dl_name);
else
dl_symp = symbol_find_or_make (dl_name);
return 1;
}
- return sh_parse_name (name, exp, cp);
+ return sh_parse_name (name, exp, mode, cp);
}
/* This function is called just before symbols are being output. It
then we need not output the main symbol. */
int
-sh64_exclude_symbol (symp)
- symbolS *symp;
+sh64_exclude_symbol (symbolS *symp)
{
symbolS *main_symbol = *symbol_get_tc (symp);
a new region if needed. */
static void
-sh64_update_contents_mark (update_type)
- boolean update_type;
+sh64_update_contents_mark (bfd_boolean update_type)
{
segment_info_type *seginfo;
seginfo = seg_info (now_seg);
}
}
- seen_insn = false;
+ seen_insn = FALSE;
}
/* Called when the assembler is about to output some data, or maybe it's
just switching segments. */
void
-sh64_flush_pending_output ()
+sh64_flush_pending_output (void)
{
- sh64_update_contents_mark (true);
+ sh64_update_contents_mark (TRUE);
sh_flush_pending_output ();
}
/* Flush out the last crange descriptor after all insns have been emitted. */
static void
-sh64_flush_last_crange (abfd, seg, countparg)
- bfd *abfd ATTRIBUTE_UNUSED;
- asection *seg;
- PTR countparg ATTRIBUTE_UNUSED;
+sh64_flush_last_crange (bfd *abfd ATTRIBUTE_UNUSED, asection *seg,
+ void *countparg ATTRIBUTE_UNUSED)
{
segment_info_type *seginfo;
descriptors. */
static void
-sh64_flag_output ()
+sh64_flag_output (void)
{
if (sh64_isa_mode != sh64_isa_unspecified
- && seen_insn == false
- && sh64_end_of_assembly == false
- && ! emitting_crange)
+ && !seen_insn
+ && !sh64_end_of_assembly
+ && !emitting_crange)
{
md_flush_pending_output ();
sh64_set_contents_type (CRT_DATA);
any we find. */
static char *
-strip_datalabels ()
+strip_datalabels (void)
{
char *src, *dest, *start=input_line_pointer;
}
static void
-sh64_vtable_entry (ignore)
- int ignore ATTRIBUTE_UNUSED;
+sh64_vtable_entry (int ignore ATTRIBUTE_UNUSED)
{
char *eol = strip_datalabels ();
}
static void
-sh64_vtable_inherit (ignore)
- int ignore ATTRIBUTE_UNUSED;
+sh64_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
{
char *eol = strip_datalabels ();
obj_elf_vtable_inherit (0);
input_line_pointer = eol;
}
+
+int
+sh64_fake_label (const char *name)
+{
+ size_t len;
+
+ if (strcmp (name, FAKE_LABEL_NAME) == 0)
+ return 1;
+
+ len = strlen (name);
+ if (len >= (sizeof (DATALABEL_SUFFIX) - 1))
+ return strcmp (&name [len - sizeof (DATALABEL_SUFFIX) + 1],
+ DATALABEL_SUFFIX) == 0;
+
+ return 0;
+}