PARAMS ((struct m68hc11_opcode *, operand *, int));
static int relaxable_symbol PARAMS ((symbolS *));
+/* Pseudo op to control the ELF flags. */
+static void s_m68hc11_mode PARAMS ((int));
+
+/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
+ are using 'rtc' for returning. It is necessary to use 'call'
+ to invoke them. This is also used by the debugger to correctly
+ find the stack frame. */
+static void s_m68hc11_mark_symbol PARAMS ((int));
+
/* Controls whether relative branches can be turned into long branches.
When the relative offset is too large, the insn are changed:
bra -> jmp
/* The opcodes sorted by name and filtered by current cpu. */
static struct m68hc11_opcode *m68hc11_sorted_opcodes;
+/* ELF flags to set in the output file header. */
+static int elf_flags = 0;
+
/* These are the machine dependent pseudo-ops. These are included so
the assembler can work on the output from the SUN C compiler, which
generates these. */
/* Motorola ALIS. */
{"xrefb", s_ignore, 0}, /* Same as xref */
+ /* .mode instruction (ala SH). */
+ {"mode", s_m68hc11_mode, 0},
+
+ /* .far instruction. */
+ {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
+
+ /* .interrupt instruction. */
+ {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
+
{0, 0, 0}
};
\f
else
build_insn (opcode, operands, nb_operands);
}
+
+\f
+/* Pseudo op to control the ELF flags. */
+static void
+s_m68hc11_mode (x)
+ int x ATTRIBUTE_UNUSED;
+{
+ char *name = input_line_pointer, ch;
+
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (strcmp (name, "mshort") == 0)
+ {
+ elf_flags &= ~E_M68HC11_I32;
+ }
+ else if (strcmp (name, "mlong") == 0)
+ {
+ elf_flags |= E_M68HC11_I32;
+ }
+ else if (strcmp (name, "mshort-double") == 0)
+ {
+ elf_flags &= ~E_M68HC11_F64;
+ }
+ else if (strcmp (name, "mlong-double") == 0)
+ {
+ elf_flags |= E_M68HC11_F64;
+ }
+ else
+ {
+ as_warn (_("Invalid mode: %s\n"), name);
+ }
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
+ are using 'rtc' for returning. It is necessary to use 'call'
+ to invoke them. This is also used by the debugger to correctly
+ find the stack frame. */
+static void
+s_m68hc11_mark_symbol (mark)
+ int mark;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ asymbol *bfdsym;
+ elf_symbol_type *elfsym;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ bfdsym = symbol_get_bfdsym (symbolP);
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+
+ assert (elfsym);
+
+ /* Mark the symbol far (using rtc for function return). */
+ elfsym->internal_elf_sym.st_other |= mark;
+
+ if (c == ',')
+ {
+ input_line_pointer ++;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
\f
/* Relocation, relaxation and frag conversions. */
long
fixP->fx_line, fixP->fx_r_type);
}
}
+
+/* Set the ELF specific flags. */
+void
+m68hc11_elf_final_processing ()
+{
+ elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
+ elf_elfheader (stdoutput)->e_flags |= elf_flags;
+}