aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-m68hc11.c
diff options
context:
space:
mode:
authorStephane Carrez <stcarrez@nerim.fr>2002-08-13 21:52:57 +0000
committerStephane Carrez <stcarrez@nerim.fr>2002-08-13 21:52:57 +0000
commiteb086b59403b077816b495b61ffb3d7b41b37e83 (patch)
tree06bed124f79a669c86aa0fd520daea7c532b892f /gas/config/tc-m68hc11.c
parent0680b1201a4f52c5658c5f119630482e92884f94 (diff)
downloadgdb-eb086b59403b077816b495b61ffb3d7b41b37e83.zip
gdb-eb086b59403b077816b495b61ffb3d7b41b37e83.tar.gz
gdb-eb086b59403b077816b495b61ffb3d7b41b37e83.tar.bz2
* config/tc-m68hc11.c (m68hc11_elf_final_processing): New function.
(md_pseudo_table): Add .mode, .far and .interrupt pseudo op. (s_m68hc11_mode): New function for .mode pseudo op. (s_m68hc11_mark_symbol): New function for .far and .interrupt pseudo op. * config/tc-m68hc11.h (elf_tc_final_processing): Define. (m68hc11_elf_final_processing): Declare.
Diffstat (limited to 'gas/config/tc-m68hc11.c')
-rw-r--r--gas/config/tc-m68hc11.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c
index e50e728..d570784 100644
--- a/gas/config/tc-m68hc11.c
+++ b/gas/config/tc-m68hc11.c
@@ -182,6 +182,15 @@ static void build_insn
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
@@ -229,6 +238,9 @@ static int num_opcodes;
/* 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. */
@@ -252,6 +264,15 @@ const pseudo_typeS md_pseudo_table[] = {
/* 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}
};
@@ -2488,6 +2509,89 @@ md_assemble (str)
else
build_insn (opcode, operands, nb_operands);
}
+
+
+/* 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 ();
+}
/* Relocation, relaxation and frag conversions. */
long
@@ -2938,3 +3042,11 @@ md_apply_fix3 (fixP, valP, seg)
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;
+}