This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH]: bfd support for 68HCS12
- From: Stephane Carrez <stcarrez at nerim dot fr>
- To: binutils at sources dot redhat dot com
- Date: Sun, 01 Dec 2002 14:18:09 +0100
- Subject: [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