diff options
author | Stephane Carrez <stcarrez@nerim.fr> | 2002-08-13 21:52:57 +0000 |
---|---|---|
committer | Stephane Carrez <stcarrez@nerim.fr> | 2002-08-13 21:52:57 +0000 |
commit | eb086b59403b077816b495b61ffb3d7b41b37e83 (patch) | |
tree | 06bed124f79a669c86aa0fd520daea7c532b892f /gas/config/tc-m68hc11.c | |
parent | 0680b1201a4f52c5658c5f119630482e92884f94 (diff) | |
download | gdb-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.c | 112 |
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; +} |