This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Support control of ELF ABI flags in gas HC11/HC12


Hi!

This patch adds the support in GAS to set the ELF ABI flags for HC11/HC12.
It adds pseudo ops that allow control of these flags (followed Mips mostly).

Committed on mainline.

	Stephane

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.
Index: config/tc-m68hc11.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68hc11.h,v
retrieving revision 1.7
diff -u -p -r1.7 tc-m68hc11.h
--- config/tc-m68hc11.h	29 Jun 2002 15:52:31 -0000	1.7
+++ config/tc-m68hc11.h	13 Aug 2002 21:49:17 -0000
@@ -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 *));
Index: config/tc-m68hc11.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68hc11.c,v
retrieving revision 1.25
diff -u -p -r1.25 tc-m68hc11.c
--- config/tc-m68hc11.c	13 Aug 2002 21:38:15 -0000	1.25
+++ config/tc-m68hc11.c	13 Aug 2002 21:49:18 -0000
@@ -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
@@ -2937,4 +3041,12 @@ md_apply_fix3 (fixP, valP, seg)
       as_fatal (_("Line %d: unknown relocation type: 0x%x."),
 		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;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]