static sym_linkS *debug_sym_link = (sym_linkS *)0;
-/* Structure to hold all of the different components describing an individual instruction. */
+/* Structure to hold all of the different components describing
+ an individual instruction. */
typedef struct
{
const CGEN_INSN * insn;
char * addr;
fragS * frag;
int num_fixups;
- fixS * fixups [CGEN_MAX_FIXUPS];
+ fixS * fixups [GAS_CGEN_MAX_FIXUPS];
int indices [MAX_OPERAND_INSTANCES];
sym_linkS *debug_sym_link;
}
This flag does not apply to them. */
static int m32r_relax;
+#if 0 /* not supported yet */
/* If non-NULL, pointer to cpu description file to read.
This allows runtime additions to the assembler. */
-static char * m32r_cpu_desc;
+static const char * m32r_cpu_desc;
+#endif
+
+/* Non-zero if warn when a high/shigh reloc has no matching low reloc.
+ Each high/shigh reloc must be paired with it's low cousin in order to
+ properly calculate the addend in a relocatable link (since there is a
+ potential carry from the low to the high/shigh).
+ This option is off by default though for user-written assembler code it
+ might make sense to make the default be on (i.e. have gcc pass a flag
+ to turn it off). This warning must not be on for GCC created code as
+ optimization may delete the low but not the high/shigh (at least we
+ shouldn't assume or require it to). */
+static int warn_unmatched_high = 0;
/* start-sanitize-m32rx */
/* Non-zero if -m32rx has been specified, in which case support for the
extended M32RX instruction set should be enabled. */
static int enable_m32rx = 0;
+/* Non-zero if -m32rx -hidden has been specified, in which case support for
+ the special M32RX instruction set should be enabled. */
+static int enable_special = 0;
+
/* Non-zero if the programmer should be warned when an explicit parallel
instruction might have constraint violations. */
static int warn_explicit_parallel_conflicts = 1;
/* start-sanitize-m32rx */
#define OPTION_M32RX (OPTION_MD_BASE)
{"m32rx", no_argument, NULL, OPTION_M32RX},
-#define OPTION_WARN (OPTION_MD_BASE + 1)
- {"warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_WARN},
- {"Wp", no_argument, NULL, OPTION_WARN},
-#define OPTION_NO_WARN (OPTION_MD_BASE + 2)
- {"no-warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_WARN},
- {"Wnp", no_argument, NULL, OPTION_NO_WARN},
+#define OPTION_WARN_PARALLEL (OPTION_MD_BASE + 1)
+ {"warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_WARN_PARALLEL},
+ {"Wp", no_argument, NULL, OPTION_WARN_PARALLEL},
+#define OPTION_NO_WARN_PARALLEL (OPTION_MD_BASE + 2)
+ {"no-warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_WARN_PARALLEL},
+ {"Wnp", no_argument, NULL, OPTION_NO_WARN_PARALLEL},
+#define OPTION_SPECIAL (OPTION_MD_BASE + 3)
+ {"hidden", no_argument, NULL, OPTION_SPECIAL},
/* end-sanitize-m32rx */
+ /* Sigh. I guess all warnings must now have both variants. */
+#define OPTION_WARN_UNMATCHED (OPTION_MD_BASE + 4)
+ {"warn-unmatched-high", OPTION_WARN_UNMATCHED},
+ {"Wuh", OPTION_WARN_UNMATCHED},
+#define OPTION_NO_WARN_UNMATCHED (OPTION_MD_BASE + 5)
+ {"no-warn-unmatched-high", OPTION_WARN_UNMATCHED},
+ {"Wnuh", OPTION_WARN_UNMATCHED},
+
#if 0 /* not supported yet */
-#define OPTION_RELAX (OPTION_MD_BASE + 3)
+#define OPTION_RELAX (OPTION_MD_BASE + 6)
{"relax", no_argument, NULL, OPTION_RELAX},
-#define OPTION_CPU_DESC (OPTION_MD_BASE + 4)
+#define OPTION_CPU_DESC (OPTION_MD_BASE + 7)
{"cpu-desc", required_argument, NULL, OPTION_CPU_DESC},
#endif
allow_m32rx (1);
break;
- case OPTION_WARN:
+ case OPTION_WARN_PARALLEL:
warn_explicit_parallel_conflicts = 1;
break;
- case OPTION_NO_WARN:
+ case OPTION_NO_WARN_PARALLEL:
warn_explicit_parallel_conflicts = 0;
break;
+
+ case OPTION_SPECIAL:
+ if (enable_m32rx)
+ enable_special = 1;
+ else
+ {
+ extern char * myname;
+
+ /* Pretend that we do not recognise this option. */
+ fprintf (stderr, _("%s: unrecognised option: -hidden\n"), myname);
+ return 0;
+ }
+ break;
/* end-sanitize-m32rx */
+
+ case OPTION_WARN_UNMATCHED:
+ warn_unmatched_high = 1;
+ break;
+
+ case OPTION_NO_WARN_UNMATCHED:
+ warn_unmatched_high = 0;
+ break;
#if 0 /* not supported yet */
case OPTION_RELAX:
m32r_cpu_desc = arg;
break;
#endif
+
default:
return 0;
}
md_show_usage (stream)
FILE * stream;
{
+ fprintf (stream, _(" M32R specific command line options:\n"));
+
/* start-sanitize-m32rx */
- fprintf (stream, _("M32R/X specific command line options:\n"));
fprintf (stream, _("\
---m32rx support the extended m32rx instruction set\n"));
-
+ -m32rx support the extended m32rx instruction set\n"));
fprintf (stream, _("\
--O try to combine instructions in parallel\n"));
+ -O try to combine instructions in parallel\n"));
fprintf (stream, _("\
---warn-explicit-parallel-conflicts warn when parallel instrucitons violate contraints\n"));
+ -warn-explicit-parallel-conflicts warn when parallel instructions\n"));
+ fprintf (stream, _("\
+ violate contraints\n"));
fprintf (stream, _("\
---no-warn-explicit-parallel-conflicts do not warn when parallel instrucitons violate contraints\n"));
+ -no-warn-explicit-parallel-conflicts do not warn when parallel\n"));
fprintf (stream, _("\
---Wp synonym for --warn-explicit-parallel-conflicts\n"));
+ instructions violate contraints\n"));
fprintf (stream, _("\
---Wnp synonym for --no-warn-explicit-parallel-conflicts\n"));
+ -Wp synonym for -warn-explicit-parallel-conflicts\n"));
+ fprintf (stream, _("\
+ -Wnp synonym for -no-warn-explicit-parallel-conflicts\n"));
/* end-sanitize-m32rx */
+ fprintf (stream, _("\
+ -warn-unmatched-high warn when an (s)high reloc has no matching low reloc\n"));
+ fprintf (stream, _("\
+ -no-warn-unmatched-high do not warn about missing low relocs\n"));
+ fprintf (stream, _("\
+ -Wuh synonym for -warn-unmatched-high\n"));
+ fprintf (stream, _("\
+ -Wnuh synonym for -no-warn-unmatched-high\n"));
+
#if 0
fprintf (stream, _("\
---relax create linker relaxable code\n"));
+ -relax create linker relaxable code\n"));
fprintf (stream, _("\
---cpu-desc provide runtime cpu description file\n"));
+ -cpu-desc provide runtime cpu description file\n"));
#endif
}
{ "scomm", m32r_scomm, 0 },
{ "debugsym", debug_sym, 0 },
/* start-sanitize-m32rx */
+ /* Not documented as so far there is no need for them.... */
{ "m32r", allow_m32rx, 0 },
{ "m32rx", allow_m32rx, 1 },
/* end-sanitize-m32rx */
int len;
int max;
{
- if ((fill == NULL || (* fill == 0 && len == 1))
+ /* Only do this if the fill pattern wasn't specified. */
+ if (fill == NULL
&& (now_seg->flags & SEC_CODE) != 0
/* Only do this special handling if aligning to at least a
4 byte boundary. */
frag_align_pattern (n, multi_nop_pattern, sizeof multi_nop_pattern,
max ? max - 2 : 0);
}
+
+ prev_insn.insn = NULL;
return 1;
}
return 0;
}
-static void
-assemble_nop (opcode)
- int opcode;
-{
- char * f = frag_more (2);
- md_number_to_chars (f, opcode, 2);
-}
-
/* If the last instruction was the first of 2 16 bit insns,
output a nop to move the PC to a 32 bit boundary.
symbol_table_insert (symbolP);
if (S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section)
+ /* xgettext:c-format */
as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
else
{
char *save_input_line = input_line_pointer;
sym_linkS *next_syms;
- expressionS exp;
if (!syms)
return;
}
/* Cover function to fill_insn called after a label and at end of assembly.
-
The result is always 1: we're called in a conditional to see if the
current line is a label. */
subseg_set (prev_seg, prev_subseg);
fill_insn (0);
-
+
subseg_set (seg, subseg);
}
-
+
+ if (done && debug_sym_link)
+ {
+ expand_debug_syms (debug_sym_link, 1);
+ debug_sym_link = (sym_linkS *)0;
+ }
+
return 1;
}
\f
subsegT subseg;
/* Initialize the `cgen' interface. */
-
- /* This is a callback from cgen to gas to parse operands. */
- cgen_parse_operand_fn = cgen_parse_operand;
/* Set the machine number and endian. */
- CGEN_SYM (init_asm) (0 /* mach number */,
- target_big_endian ?
- CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
+ gas_cgen_opcode_desc = m32r_cgen_opcode_open (0 /* mach number */,
+ target_big_endian ?
+ CGEN_ENDIAN_BIG
+ : CGEN_ENDIAN_LITTLE);
+ m32r_cgen_init_asm (gas_cgen_opcode_desc);
+
+ /* This is a callback from cgen to gas to parse operands. */
+ cgen_set_parse_operand_fn (gas_cgen_opcode_desc, gas_cgen_parse_operand);
#if 0 /* not supported yet */
/* If a runtime cpu description file was provided, parse it. */
{
const char * errmsg;
- errmsg = cgen_read_cpu_file (m32r_cpu_desc);
+ errmsg = cgen_read_cpu_file (gas_cgen_opcode_desc, m32r_cpu_desc);
if (errmsg != NULL)
as_bad ("%s: %s", m32r_cpu_desc, errmsg);
}
}
else
{
- /* Scan operand list of 'b' looking for an operand that references
- the same hardware element, and which goes in the right direction. */
+ /* Scan operand list of 'b' looking for an operand that
+ references the same hardware element, and which goes in the
+ right direction. */
for (b_index = 0;
CGEN_OPERAND_INSTANCE_TYPE (b_operands) != CGEN_OPERAND_INSTANCE_END;
b_index ++, b_operands ++)
bfd_vma value;
- if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
+ if (CGEN_OPCODE_ENDIAN (gas_cgen_opcode_desc) == CGEN_ENDIAN_BIG)
{
value = bfd_getb16 ((bfd_byte *) buffer);
value |= 0x8000;
{
/* Force the top bit of the second insn to be set. */
- buffer [CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG ? 0 : 1] |= 0x80;
+ buffer [CGEN_OPCODE_ENDIAN (gas_cgen_opcode_desc) == CGEN_ENDIAN_BIG ? 0 : 1]
+ |= 0x80;
}
#endif /* ! CGEN_INT_INSN */
debug_sym_link = (sym_linkS *)0;
/* Parse the first instruction. */
- if (! (first.insn = CGEN_SYM (assemble_insn)
- (str, & first.fields, first.buffer, & errmsg)))
+ if (! (first.insn = m32r_cgen_assemble_insn
+ (gas_cgen_opcode_desc, str, & first.fields, first.buffer, & errmsg)))
{
as_bad (errmsg);
return;
}
- if (! enable_m32rx
+ if (! enable_special
+ && CGEN_INSN_ATTR (first.insn, CGEN_INSN_SPECIAL))
+ {
+ /* xgettext:c-format */
+ as_bad (_("unknown instruction '%s'"), str);
+ return;
+ }
+ else if (! enable_m32rx
/* FIXME: Need standard macro to perform this test. */
&& CGEN_INSN_ATTR (first.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
{
+ /* xgettext:c-format */
as_bad (_("instruction '%s' is for the M32RX only"), str);
return;
}
-
+
/* Check to see if this is an allowable parallel insn. */
if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_PIPE) == PIPE_NONE)
{
+ /* xgettext:c-format */
as_bad (_("instruction '%s' cannot be executed in parallel."), str);
return;
}
str = str2 + 2; /* Advanced past the parsed string. */
str2 = str3; /* Remember the entire string in case it is needed for error messages. */
+ /* Convert the opcode to lower case. */
+ {
+ char *s2 = str;
+
+ while (isspace (*s2 ++))
+ continue;
+
+ --s2;
+
+ while (isalnum (*s2))
+ {
+ if (isupper ((unsigned char) *s2))
+ *s2 = tolower (*s2);
+ s2 ++;
+ }
+ }
+
/* Preserve any fixups that have been generated and reset the list to empty. */
- cgen_save_fixups();
+ gas_cgen_save_fixups ();
/* Get the indices of the operands of the instruction. */
/* FIXME: CGEN_FIELDS is already recorded, but relying on that fact
version (eg relaxability). When aliases behave differently this
may have to change. */
first.orig_insn = first.insn;
- first.insn = m32r_cgen_lookup_get_insn_operands (NULL,
- bfd_getb16 ((char *) first.buffer),
- 16,
- first.indices);
+ first.insn = m32r_cgen_lookup_get_insn_operands
+ (gas_cgen_opcode_desc, NULL, bfd_getb16 ((char *) first.buffer), 16,
+ first.indices);
+
if (first.insn == NULL)
as_fatal (_("internal error: m32r_cgen_lookup_get_insn_operands failed for first insn"));
second.debug_sym_link = NULL;
/* Parse the second instruction. */
- if (! (second.insn = CGEN_SYM (assemble_insn)
- (str, & second.fields, second.buffer, & errmsg)))
+ if (! (second.insn = m32r_cgen_assemble_insn
+ (gas_cgen_opcode_desc, str, & second.fields, second.buffer, & errmsg)))
{
as_bad (errmsg);
return;
}
/* Check it. */
- if (! enable_m32rx
+ if (! enable_special
+ && CGEN_INSN_ATTR (second.insn, CGEN_INSN_SPECIAL))
+ {
+ /* xgettext:c-format */
+ as_bad (_("unknown instruction '%s'"), str);
+ return;
+ }
+ else if (! enable_m32rx
&& CGEN_INSN_ATTR (second.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
{
+ /* xgettext:c-format */
as_bad (_("instruction '%s' is for the M32RX only"), str);
return;
}
/* Check to see if this is an allowable parallel insn. */
if (CGEN_INSN_ATTR (second.insn, CGEN_INSN_PIPE) == PIPE_NONE)
{
+ /* xgettext:c-format */
as_bad (_("instruction '%s' cannot be executed in parallel."), str);
return;
}
if (CGEN_INSN_NUM (first.insn) != M32R_INSN_NOP
&& CGEN_INSN_NUM (second.insn) != M32R_INSN_NOP)
{
+ /* xgettext:c-format */
as_bad (_("'%s': only the NOP instruction can be issued in parallel on the m32r"), str2);
return;
}
/* Get the indices of the operands of the instruction. */
second.orig_insn = second.insn;
- second.insn = m32r_cgen_lookup_get_insn_operands (NULL,
- bfd_getb16 ((char *) second.buffer),
- 16,
- second.indices);
+ second.insn = m32r_cgen_lookup_get_insn_operands
+ (gas_cgen_opcode_desc, NULL, bfd_getb16 ((char *) second.buffer), 16,
+ second.indices);
+
if (second.insn == NULL)
as_fatal (_("internal error: m32r_cgen_lookup_get_insn_operands failed for second insn"));
if (warn_explicit_parallel_conflicts)
{
if (first_writes_to_seconds_operands (& first, & second, false))
+ /* xgettext:c-format */
as_warn (_("%s: output of 1st instruction is the same as an input to 2nd instruction - is this intentional ?"), str2);
if (first_writes_to_seconds_operands (& second, & first, false))
+ /* xgettext:c-format */
as_warn (_("%s: output of 2nd instruction is the same as an input to 1st instruction - is this intentional ?"), str2);
}
if ((errmsg = (char *) can_make_parallel (& first, & second)) == NULL)
{
/* Get the fixups for the first instruction. */
- cgen_swap_fixups ();
+ gas_cgen_swap_fixups ();
/* Write it out. */
expand_debug_syms (first.debug_sym_link, 1);
- cgen_asm_finish_insn (first.orig_insn, first.buffer,
+ gas_cgen_finish_insn (first.orig_insn, first.buffer,
CGEN_FIELDS_BITSIZE (& first.fields), 0, NULL);
/* Force the top bit of the second insn to be set. */
make_parallel (second.buffer);
/* Get its fixups. */
- cgen_restore_fixups ();
+ gas_cgen_restore_fixups ();
/* Write it out. */
expand_debug_syms (second.debug_sym_link, 1);
- cgen_asm_finish_insn (second.orig_insn, second.buffer,
+ gas_cgen_finish_insn (second.orig_insn, second.buffer,
CGEN_FIELDS_BITSIZE (& second.fields), 0, NULL);
}
/* Try swapping the instructions to see if they work that way. */
{
/* Write out the second instruction first. */
expand_debug_syms (second.debug_sym_link, 1);
- cgen_asm_finish_insn (second.orig_insn, second.buffer,
+ gas_cgen_finish_insn (second.orig_insn, second.buffer,
CGEN_FIELDS_BITSIZE (& second.fields), 0, NULL);
/* Force the top bit of the first instruction to be set. */
make_parallel (first.buffer);
/* Get the fixups for the first instruction. */
- cgen_restore_fixups ();
+ gas_cgen_restore_fixups ();
/* Write out the first instruction. */
expand_debug_syms (first.debug_sym_link, 1);
- cgen_asm_finish_insn (first.orig_insn, first.buffer,
+ gas_cgen_finish_insn (first.orig_insn, first.buffer,
CGEN_FIELDS_BITSIZE (& first.fields), 0, NULL);
}
else
char * str2 = NULL;
/* Initialize GAS's cgen interface for a new instruction. */
- cgen_asm_init_parse ();
+ gas_cgen_init_parse ();
/* start-sanitize-m32rx */
/* Look for a parallel instruction seperator. */
insn.debug_sym_link = debug_sym_link;
debug_sym_link = (sym_linkS *)0;
- insn.insn = CGEN_SYM (assemble_insn) (str, & insn.fields, insn.buffer, & errmsg);
+ insn.insn = m32r_cgen_assemble_insn
+ (gas_cgen_opcode_desc, str, & insn.fields, insn.buffer, & errmsg);
+
if (!insn.insn)
{
as_bad (errmsg);
}
/* start-sanitize-m32rx */
- if (! enable_m32rx && CGEN_INSN_ATTR (insn.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
+ if (! enable_special
+ && CGEN_INSN_ATTR (insn.insn, CGEN_INSN_SPECIAL))
{
+ /* xgettext:c-format */
+ as_bad (_("unknown instruction '%s'"), str);
+ return;
+ }
+ else if (! enable_m32rx
+ && CGEN_INSN_ATTR (insn.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
+ {
+ /* xgettext:c-format */
as_bad (_("instruction '%s' is for the M32RX only"), str);
return;
}
if (prev_insn.insn || seen_relaxable_p)
{
/* ??? If calling fill_insn too many times turns us into a memory
- pig, can we call assemble_nop instead of !seen_relaxable_p? */
+ pig, can we call a fn to assemble a nop instead of
+ !seen_relaxable_p? */
fill_insn (0);
}
expand_debug_syms (insn.debug_sym_link, 2);
/* Doesn't really matter what we pass for RELAX_P here. */
- cgen_asm_finish_insn (insn.insn, insn.buffer,
+ gas_cgen_finish_insn (insn.insn, insn.buffer,
CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
}
else
{
/* Get the indices of the operands of the instruction.
FIXME: See assemble_parallel for notes on orig_insn. */
- insn.insn = m32r_cgen_lookup_get_insn_operands (NULL,
- bfd_getb16 ((char *) insn.buffer),
- 16,
- insn.indices);
+ insn.insn = m32r_cgen_lookup_get_insn_operands
+ (gas_cgen_opcode_desc, NULL, bfd_getb16 ((char *) insn.buffer),
+ 16, insn.indices);
+
if (insn.insn == NULL)
as_fatal (_("internal error: m32r_cgen_get_insn_operands failed"));
}
/* Ensure each pair of 16 bit insns is in the same frag. */
frag_grow (4);
- cgen_asm_finish_insn (insn.orig_insn, insn.buffer,
+ gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
CGEN_FIELDS_BITSIZE (& insn.fields),
1 /*relax_p*/, &fi);
insn.addr = fi.addr;
input_line_pointer ++; /* skip ',' */
if ((size = get_absolute_expression ()) < 0)
{
+ /* xgettext:c-format */
as_warn (_(".SCOMMon length (%ld.) <0! Ignored."), (long) size);
ignore_rest_of_line ();
return;
if (S_IS_DEFINED (symbolP))
{
+ /* xgettext:c-format */
as_bad (_("Ignoring attempt to re-define symbol `%s'."),
S_GET_NAME (symbolP));
ignore_rest_of_line ();
if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
{
+ /* xgettext:c-format */
as_bad (_("Length of .scomm \"%s\" is already %ld. Not changed to %ld."),
S_GET_NAME (symbolP),
(long) S_GET_VALUE (symbolP),
segT segment;
{
int old_fr_fix = fragP->fr_fix;
- char * opcode = fragP->fr_opcode;
/* The only thing we have to handle here are symbols outside of the
current segment. They may be undefined or in a different segment in
#if 0 /* Can't use this, but leave in for illustration. */
/* Change 16 bit insn to 32 bit insn. */
- opcode[0] |= 0x80;
+ fragP->fr_opcode[0] |= 0x80;
/* Increase known (fixed) size of fragment. */
fragP->fr_fix += 2;
fragP->fr_symbol,
fragP->fr_offset, 1 /* pcrel */,
/* FIXME: Can't use a real BFD reloc here.
- cgen_md_apply_fix3 can't handle it. */
+ gas_cgen_md_apply_fix3 can't handle it. */
BFD_RELOC_M32R_26_PCREL);
/* Mark this fragment as finished. */
{
assert (fragP->fr_subtype != 1);
assert (fragP->fr_cgen.insn != 0);
- cgen_record_fixup (fragP,
- /* Offset of branch insn in frag. */
- fragP->fr_fix + extension - 4,
- fragP->fr_cgen.insn,
- 4 /*length*/,
- /* FIXME: quick hack */
+ gas_cgen_record_fixup (fragP,
+ /* Offset of branch insn in frag. */
+ fragP->fr_fix + extension - 4,
+ fragP->fr_cgen.insn,
+ 4 /*length*/,
+ /* FIXME: quick hack */
#if 0
- CGEN_OPERAND_ENTRY (fragP->fr_cgen.opindex),
+ CGEN_OPERAND_ENTRY (fragP->fr_cgen.opindex),
#else
- CGEN_OPERAND_ENTRY (M32R_OPERAND_DISP24),
+ CGEN_OPERAND_ENTRY (M32R_OPERAND_DISP24),
#endif
- fragP->fr_cgen.opinfo,
- fragP->fr_symbol, fragP->fr_offset);
+ fragP->fr_cgen.opinfo,
+ fragP->fr_symbol, fragP->fr_offset);
}
#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)
*FIXP may be modified if desired. */
bfd_reloc_code_real_type
-CGEN_SYM (lookup_reloc) (insn, operand, fixP)
+md_cgen_lookup_reloc (insn, operand, fixP)
const CGEN_INSN * insn;
const CGEN_OPERAND * operand;
fixS * fixP;
if (fixP->tc_fix_data.opinfo != 0)
return fixP->tc_fix_data.opinfo;
break;
+ default : /* avoid -Wall warning */
+ break;
}
return BFD_RELOC_NONE;
}
int opinfo;
expressionS * exp;
{
- fixS * fixP = cgen_record_fixup_exp (frag, where, insn, length,
- operand, opinfo, exp);
+ fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
+ operand, opinfo, exp);
switch (CGEN_OPERAND_TYPE (operand))
{
|| fixP->tc_fix_data.opinfo == BFD_RELOC_M32R_HI16_ULO)
m32r_record_hi16 (fixP->tc_fix_data.opinfo, fixP, now_seg);
break;
+ default : /* avoid -Wall warning */
+ break;
}
return fixP;
if (f != NULL)
break;
- if (pass == 1)
+ if (pass == 1
+ && warn_unmatched_high)
as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
_("Unmatched high/shigh reloc"));
}
m32r_force_relocation (fix)
fixS * fix;
{
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+ return 1;
+
if (! m32r_relax)
return 0;
int i;
int prec;
LITTLENUM_TYPE words [MAX_LITTLENUMS];
- LITTLENUM_TYPE * wordP;
char * t;
char * atof_ieee ();
if (prev_insn.insn || seen_relaxable_p)
(void) m32r_fill_insn (0);
}
+
+boolean
+m32r_fix_adjustable (fixP)
+ fixS *fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}