From eb086b59403b077816b495b61ffb3d7b41b37e83 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Tue, 13 Aug 2002 21:52:57 +0000 Subject: [PATCH] * 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. --- gas/ChangeLog | 10 ++++ gas/config/tc-m68hc11.c | 112 ++++++++++++++++++++++++++++++++++++++++ gas/config/tc-m68hc11.h | 3 ++ 3 files changed, 125 insertions(+) diff --git a/gas/ChangeLog b/gas/ChangeLog index a8455bedd84..3d08c0bce04 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2002-08-13 Stephane Carrez + + * 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. + 2002-08-13 Stephane Carrez * config/tc-m68hc11.c (md_begin): Take into account additional diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index e50e72871f4..d5707845089 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; +} diff --git a/gas/config/tc-m68hc11.h b/gas/config/tc-m68hc11.h index 08cae511412..418b7b5afda 100644 --- a/gas/config/tc-m68hc11.h +++ b/gas/config/tc-m68hc11.h @@ -104,5 +104,8 @@ extern struct relax_type md_relax_table[]; S_SET_VALUE (sym, (valueT) frag_now_fix ()); \ } while (0) +#define elf_tc_final_processing m68hc11_elf_final_processing +extern void m68hc11_elf_final_processing PARAMS ((void)); + #define tc_print_statistics(FILE) m68hc11_print_statistics (FILE) extern void m68hc11_print_statistics PARAMS ((FILE *)); -- 2.30.2