/* tc-mips.c -- assemble code for a MIPS chip.
- Copyright (C) 1993-2015 Free Software Foundation, Inc.
+ Copyright (C) 1993-2016 Free Software Foundation, Inc.
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
static void mips_ip (char *str, struct mips_cl_insn * ip);
static void mips16_ip (char *str, struct mips_cl_insn * ip);
static void mips16_immed
- (char *, unsigned int, int, bfd_reloc_code_real_type, offsetT,
+ (const char *, unsigned int, int, bfd_reloc_code_real_type, offsetT,
unsigned int, unsigned long *);
static size_t my_getSmallExpression
(expressionS *, bfd_reloc_code_real_type *, char *);
}
/* Return the length of a microMIPS instruction in bytes. If bits of
- the mask beyond the low 16 are 0, then it is a 16-bit instruction.
- Otherwise assume a 32-bit instruction; 48-bit instructions (0x1f
- major opcode) will require further modifications to the opcode
- table. */
+ the mask beyond the low 16 are 0, then it is a 16-bit instruction,
+ otherwise it is a 32-bit instruction. */
static inline unsigned int
micromips_insn_length (const struct mips_opcode *mo)
as_bad (_("-G may not be used in position-independent code"));
g_switch_value = 0;
}
+ else if (mips_abicalls)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_bad (_("-G may not be used with abicalls"));
+ g_switch_value = 0;
+ }
if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
as_warn (_("could not set architecture and machine"));
is the length that the user requested, or 0 if none. */
static void
-mips16_immed (char *file, unsigned int line, int type,
+mips16_immed (const char *file, unsigned int line, int type,
bfd_reloc_code_real_type reloc, offsetT val,
unsigned int user_insn_length, unsigned long *insn)
{
char *name;
symbolS *p;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
p = (symbolS *) symbol_find_or_make (name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
return p;
}
void
s_change_section (int ignore ATTRIBUTE_UNUSED)
{
+ char *saved_ilp;
char *section_name;
- char c;
+ char c, endc;
char next_c = 0;
int section_type;
int section_flag;
int section_entry_size;
int section_alignment;
- section_name = input_line_pointer;
- c = get_symbol_end ();
+ saved_ilp = input_line_pointer;
+ endc = get_symbol_name (§ion_name);
+ c = (endc == '"' ? input_line_pointer[1] : endc);
if (c)
- next_c = *(input_line_pointer + 1);
+ next_c = input_line_pointer [(endc == '"' ? 2 : 1)];
/* Do we have .section Name<,"flags">? */
if (c != ',' || (c == ',' && next_c == '"'))
{
- /* just after name is now '\0'. */
- *input_line_pointer = c;
- input_line_pointer = section_name;
+ /* Just after name is now '\0'. */
+ (void) restore_line_pointer (endc);
+ input_line_pointer = saved_ilp;
obj_elf_section (ignore);
return;
}
+
+ section_name = xstrdup (section_name);
+ c = restore_line_pointer (endc);
+
input_line_pointer++;
/* Do we have .section Name<,type><,flag><,entry_size><,alignment> */
section_type = get_absolute_expression ();
else
section_type = 0;
+
if (*input_line_pointer++ == ',')
section_flag = get_absolute_expression ();
else
section_flag = 0;
+
if (*input_line_pointer++ == ',')
section_entry_size = get_absolute_expression ();
else
section_entry_size = 0;
+
if (*input_line_pointer++ == ',')
section_alignment = get_absolute_expression ();
else
section_alignment = 0;
+
/* FIXME: really ignore? */
(void) section_alignment;
- section_name = xstrdup (section_name);
-
/* When using the generic form of .section (as implemented by obj-elf.c),
there's no way to set the section type to SHT_MIPS_DWARF. Users have
traditionally had to fall back on the more common @progbits instead.
do
{
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = symbol_find_or_make (name);
S_SET_EXTERNAL (symbolP);
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
/* On Irix 5, every global symbol that is not explicitly labelled as
being a function is apparently labelled as being an object. */
char *secname;
asection *sec;
- secname = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&secname);
sec = bfd_get_section_by_name (stdoutput, secname);
if (sec == NULL)
as_bad (_("%s: no such section"), secname);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
if (sec != NULL && (sec->flags & SEC_CODE) != 0)
flag = BSF_FUNCTION;
char *opt;
char c;
- opt = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&opt);
if (*opt == 'O')
{
else
as_warn (_("unrecognized option \"%s\""), opt);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
symbolS *symbolP;
expressionS exp;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = symbol_find_or_make (name);
S_SET_WEAK (symbolP);
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
if (! is_end_of_line[(unsigned char) *input_line_pointer])
{
if (align > 4)
align = 4;
- return ((addr + (1 << align) - 1) & (-1 << align));
+ return ((addr + (1 << align) - 1) & -(1 << align));
}
/* Utility routine, called from above as well. If called while the