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]: bfd support for 68HCS12


Hi!

The new motorola microcontroller 68HCS12 is similar to the 68HC12.  It is 99.9% binary
compatible except on the two instructions movw/movb when we use PC-relative addressing
modes.  The 68HC12 needs a complex/strange offset correction (+1,-1 depending on
the src/dst modes; due to some buggy proc. internals).  The new 68HCS12 does not need that
(indeed they fixed/improve their silicium).

This patch adds the support for HCS12 to basically identify it and make sure we don't
merge HC12 code with HCS12. The bfd_mach_m6812_default corresponds to the prior-to-this-patch value
and it is accepted to merge with either HC12 or HCS12 (because it's supposed not to contain
any movb/movw; gas will ensure that if necessary).

Committed.

	Stephane

bfd/ChangeLog
2002-12-01  Stephane Carrez  <stcarrez@nerim.fr>

	* bfd-in2.h (bfd_mach_m6812): Rebuild.
	* archures.c (bfd_mach_m6812_default, bfd_mach_m6812,
	bfd_mach_m6812s): Declare.

	* elf32-m68hc12.c (m68hc12_elf_set_mach_from_flags): New function.
	(_bfd_m68hc12_elf_set_private_flags): Call it.
	(_bfd_m68hc12_elf_print_private_bfd_data): Report processor version.
	(_bfd_m68hc12_elf_merge_private_bfd_data): Merge the flags and
	report microcontroller incompatibilities (HC12 vs HCS12).
	(elf_backend_object_p): Update.

include/elf/ChangeLog
2002-12-01  Stephane Carrez  <stcarrez@nerim.fr>

	* m68hc11.h (EF_M68HC12_MACH, EF_M68HCS12_MACH): Define.
	(EF_M68HC11_MACH_MASK, EF_M68HC11_MACH): Define.
	(EF_M68HC11_MERGE_MACH, EF_M68HC11_CAN_MERGE_MACH): Define.
Index: bfd/archures.c
===================================================================
RCS file: /cvs/src/src/bfd/archures.c,v
retrieving revision 1.59
diff -u -p -r1.59 archures.c
--- bfd/archures.c	30 Nov 2002 08:39:34 -0000	1.59
+++ bfd/archures.c	1 Dec 2002 11:56:20 -0000
@@ -201,6 +201,9 @@ DESCRIPTION
 .  bfd_arch_dlx,       {* DLX *}
 .  bfd_arch_m68hc11,   {* Motorola 68HC11 *}
 .  bfd_arch_m68hc12,   {* Motorola 68HC12 *}
+.#define bfd_mach_m6812_default 0
+.#define bfd_mach_m6812         1
+.#define bfd_mach_m6812s        2
 .  bfd_arch_z8k,       {* Zilog Z8000 *}
 .#define bfd_mach_z8001		1
 .#define bfd_mach_z8002		2
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.182
diff -u -p -r1.182 bfd-in2.h
--- bfd/bfd-in2.h	30 Nov 2002 08:39:34 -0000	1.182
+++ bfd/bfd-in2.h	1 Dec 2002 11:56:23 -0000
@@ -1628,6 +1628,9 @@ enum bfd_architecture
   bfd_arch_dlx,       /* DLX */
   bfd_arch_m68hc11,   /* Motorola 68HC11 */
   bfd_arch_m68hc12,   /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812         1
+#define bfd_mach_m6812s        2
   bfd_arch_z8k,       /* Zilog Z8000 */
 #define bfd_mach_z8001         1
 #define bfd_mach_z8002         2
Index: bfd/elf32-m68hc12.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68hc12.c,v
retrieving revision 1.11
diff -u -p -r1.11 elf32-m68hc12.c
--- bfd/elf32-m68hc12.c	30 Nov 2002 08:39:37 -0000	1.11
+++ bfd/elf32-m68hc12.c	1 Dec 2002 11:56:23 -0000
@@ -633,6 +633,30 @@ elf32_m68hc11_gc_sweep_hook (abfd, info,
 }
 
 
+static bfd_boolean
+m68hc12_elf_set_mach_from_flags (abfd)
+     bfd *abfd;
+{
+  flagword flags = elf_elfheader (abfd)->e_flags;
+
+  switch (flags & EF_M68HC11_MACH_MASK)
+    {
+    case EF_M68HC12_MACH:
+      bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812);
+      break;
+    case EF_M68HCS12_MACH:
+      bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812s);
+      break;
+    case EF_M68HC11_GENERIC:
+      bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12,
+                                 bfd_mach_m6812_default);
+      break;
+    default:
+      return FALSE;
+    }
+  return TRUE;
+}
+
 /* Set and control ELF flags in ELF header.  */
 
 bfd_boolean
@@ -645,7 +669,7 @@ _bfd_m68hc12_elf_set_private_flags (abfd
 
   elf_elfheader (abfd)->e_flags = flags;
   elf_flags_init (abfd) = TRUE;
-  return TRUE;
+  return m68hc12_elf_set_mach_from_flags (abfd);
 }
 
 /* Merge backend specific data from an object file to the output
@@ -669,7 +693,6 @@ _bfd_m68hc12_elf_merge_private_bfd_data 
     return TRUE;
 
   new_flags = elf_elfheader (ibfd)->e_flags;
-  elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
   old_flags = elf_elfheader (obfd)->e_flags;
 
   if (! elf_flags_init (obfd))
@@ -707,10 +730,24 @@ _bfd_m68hc12_elf_merge_private_bfd_data 
 	 bfd_archive_filename (ibfd));
       ok = FALSE;
     }
-  new_flags &= ~EF_M68HC11_ABI;
-  old_flags &= ~EF_M68HC11_ABI;
+
+  /* Processor compatibility.  */
+  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
+    {
+      (*_bfd_error_handler)
+	(_("%s: linking files compiled for HCS12 with "
+           "others compiled for HC12"),
+	 bfd_archive_filename (ibfd));
+      ok = FALSE;
+    }
+  new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
+               | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
+
+  elf_elfheader (obfd)->e_flags = new_flags;
 
   /* Warn about any other mismatches */
+  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
+  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
   if (new_flags != old_flags)
     {
       (*_bfd_error_handler)
@@ -750,17 +787,19 @@ _bfd_m68hc12_elf_print_private_bfd_data 
     fprintf (file, _("[abi=16-bit int,"));
 
   if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
-    fprintf (file, _(" 64-bit double]"));
+    fprintf (file, _(" 64-bit double,"));
   else
-    fprintf (file, _(" 32-bit double]"));
+    fprintf (file, _(" 32-bit double,"));
 
+  if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
+    fprintf (file, _(" cpu=HCS12]"));
+  else
+    fprintf (file, _(" cpu=HC12]"));    
   fputc ('\n', file);
 
   return TRUE;
 }
 
-/* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
-   The Motorola spec says to use a different Elf machine code.  */
 #define ELF_ARCH		bfd_arch_m68hc12
 #define ELF_MACHINE_CODE	EM_68HC12
 #define ELF_MAXPAGESIZE		0x1000
@@ -772,7 +811,7 @@ _bfd_m68hc12_elf_print_private_bfd_data 
 #define elf_info_to_howto_rel	m68hc11_info_to_howto_rel
 #define elf_backend_gc_mark_hook     elf32_m68hc11_gc_mark_hook
 #define elf_backend_gc_sweep_hook    elf32_m68hc11_gc_sweep_hook
-#define elf_backend_object_p	0
+#define elf_backend_object_p		m68hc12_elf_set_mach_from_flags
 #define elf_backend_final_write_processing	0
 /* Disabled as this backend uses the generic linker.  */
 #define elf_backend_can_gc_sections		0
Index: include/elf/m68hc11.h
===================================================================
RCS file: /cvs/src/src/include/elf/m68hc11.h,v
retrieving revision 1.3
diff -u -p -r1.3 m68hc11.h
--- include/elf/m68hc11.h	13 Aug 2002 13:02:25 -0000	1.3
+++ include/elf/m68hc11.h	1 Dec 2002 11:56:24 -0000
@@ -64,6 +64,24 @@ END_RELOC_NUMBERS (R_M68HC11_max)
 /* Uses 68HC12 memory banks.  */
 #define E_M68HC12_BANKS 0x000000004
 
+#define EF_M68HC11_MACH_MASK 0xF0
+#define EF_M68HC11_GENERIC   0x00 /* Generic 68HC12/backward compatibility.  */
+#define EF_M68HC12_MACH      0x10 /* 68HC12 microcontroller.  */
+#define EF_M68HCS12_MACH     0x20 /* 68HCS12 microcontroller.  */
+#define EF_M68HC11_MACH(mach) ((mach) & EF_M68HC11_MACH_MASK)
+
+/* True if we can merge machines.  A generic HC12 can work on any proc
+   but once we have specific code, merge is not possible.  */
+#define EF_M68HC11_CAN_MERGE_MACH(mach1, mach2) \
+  ((EF_M68HC11_MACH (mach1) == EF_M68HC11_MACH (mach2)) \
+   || (EF_M68HC11_MACH (mach1) == EF_M68HC11_GENERIC) \
+   || (EF_M68HC11_MACH (mach2) == EF_M68HC11_GENERIC))
+
+#define EF_M68HC11_MERGE_MACH(mach1, mach2) \
+  (((EF_M68HC11_MACH (mach1) == EF_M68HC11_MACH (mach2)) \
+    || (EF_M68HC11_MACH (mach1) == EF_M68HC11_GENERIC)) ? \
+      EF_M68HC11_MACH (mach2) : EF_M68HC11_MACH (mach1))
+
 
 /* Special values for the st_other field in the symbol table.  These
    are used for 68HC12 to identify far functions (must be called with

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