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 | |
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')
-rw-r--r-- | gas/ChangeLog | 10 | ||||
-rw-r--r-- | gas/config/tc-m68hc11.c | 112 | ||||
-rw-r--r-- | gas/config/tc-m68hc11.h | 3 |
3 files changed, 125 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index a8455be..3d08c0b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,15 @@ 2002-08-13 Stephane Carrez <stcarrez@nerim.fr> + * 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 <stcarrez@nerim.fr> + * config/tc-m68hc11.c (md_begin): Take into account additional page operand for call instruction. (print_opcode_format): Likewise. 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; +} diff --git a/gas/config/tc-m68hc11.h b/gas/config/tc-m68hc11.h index 08cae51..418b7b5 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 *)); |