This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: [PATCH] Add sh4-nommu-nofpu architecture
- From: Joern Rennecke <renneckej at superh dot com>
- To: aoliva at redhat dot com (Alexandre Oliva)
- Cc: joern dot rennecke at superh dot com (Joern Rennecke), andrew dot stubbs at superh dot com (Andrew Stubbs), binutils at sources dot redhat dot com (binutils)
- Date: Mon, 8 Mar 2004 18:11:45 +0000 (GMT)
- Subject: Re: [PATCH] Add sh4-nommu-nofpu architecture
>
> On Mar 4, 2004, Joern Rennecke <joern.rennecke@superh.com> wrote:
>
> >> > +#define EF_SH4_NOMMU_NOFPU 0x12
> >>
> >> You must adjust EF_SH_MERGE_MACH to match this new value.
>
> > You are right; I also see that the EF_* section has gone to seed.
> > I think we want something like this for mainline and the gdb 6.1 branch
> > (The latter because of the EF_SH4_NOFPU / EF_SH4A_NOFPU renumbering):
>
> You definitely don't want to change these numbers. They're already in
> binaries that are out there. This unfortunately means EF_SH_MERGE
> gets more complicated, but such is life.
The crucial test is are they in third-party libraries, or in tools
used to generate ones? As long as they are confined to toolchains
used and upgraded as a whole, it's not that much of a worry.
Well, if we have such usage, I think the macro EF_SH_MERGE_MACH
has become unmaintainable. We need a translation to a saner numbering
scheme to do the merge, like this:
2004-03-08 J"orn Rennecke <joern.rennecke@superh.com>
include/elf:
* sh.h (EF_SH_I_INT, EF_SH_I_SH1, EF_SH_I_SH2): New macros.
(EF_SH_I_SH3, EF_SH_I_SH4, EF_SH_I_SH4A, EF_SH_I_MMU): Likewise.
(EF_SH_I_Fxx, EF_SH_I_DSP, EF_SH_I_FPU, EF_SH_I_DFP): Likewise.
(EF_SH_I_HAS_DSP, EF_SH_I_HAS_FP, EF_SH_I_TABLE): Likewise.
(EF_SH4_NOMMU_NOFPU): 7.
(EF_SH_HAS_DSP, EF_SH_HAS_FP, EF_SH_MERGE_MACH): Delete.
bfd:
* elf32-sh.c (sh_elf_merge_private_data): Update.
Index: include/elf/sh.h
===================================================================
RCS file: /cvs/src/src/include/elf/sh.h,v
retrieving revision 1.17
diff -p -r1.17 sh.h
*** include/elf/sh.h 3 Mar 2004 18:01:49 -0000 1.17
--- include/elf/sh.h 8 Mar 2004 17:52:21 -0000
***************
*** 20,25 ****
--- 20,44 ----
#ifndef _ELF_SH_H
#define _ELF_SH_H
+ /* For historical reasons, the EF_SH* processor numbers are jumbled up.
+ So for processing we translate them into EF_SH_I_* internal flags */
+ #define EF_SH_I_INT 0xf /* Integer instruction set mask. */
+ #define EF_SH_I_SH1 0x0
+ #define EF_SH_I_SH2 0x1
+ #define EF_SH_I_SH3 0x2
+ #define EF_SH_I_SH4 0x3
+ #define EF_SH_I_SH4A 0x4
+ #define EF_SH_I_MMU 0x8
+ #define EF_SH_I_Fxx 0x30 /* 0xFxxx opcode disposition mask */
+ #define EF_SH_I_DSP 0x10
+ #define EF_SH_I_FPU 0x20 /* single precision (exact) / any fpu (bit set) */
+ #define EF_SH_I_DFP 0x30 /* double precision fpu */
+
+ #define EF_SH_I_HAS_DSP(flags) (((flags) & EF_SH_I_Fxx ) == EF_SH_I_DSP)
+ #define EF_SH_I_HAS_FP(flags) ((flags) & EF_SH_I_FPU)
+ /* bfd/elf32-sh.c:sh_elf_merge_private_data ORs together EF_SH_I_MMU and
+ EF_SH_I_Fxx fields. */
+
/* Processor specific flags for the ELF header e_flags field. */
#define EF_SH_MACH_MASK 0x1f
***************
*** 27,37 ****
#define EF_SH1 1
#define EF_SH2 2
#define EF_SH3 3
- #define EF_SH_HAS_DSP(flags) (((flags) & EF_SH_MACH_MASK & ~3) == 4)
#define EF_SH_DSP 4
#define EF_SH3_DSP 5
#define EF_SH4AL_DSP 6
! #define EF_SH_HAS_FP(flags) ((flags) & 8)
#define EF_SH3E 8
#define EF_SH4 9
#define EF_SH2E 11
--- 46,55 ----
#define EF_SH1 1
#define EF_SH2 2
#define EF_SH3 3
#define EF_SH_DSP 4
#define EF_SH3_DSP 5
#define EF_SH4AL_DSP 6
! #define EF_SH4_NOMMU_NOFPU 7
#define EF_SH3E 8
#define EF_SH4 9
#define EF_SH2E 11
***************
*** 39,83 ****
#define EF_SH4_NOFPU 0x10
#define EF_SH4A_NOFPU 0x11
- #define EF_SH4_NOMMU_NOFPU 0x12
/* This one can only mix in objects from other EF_SH5 objects. */
#define EF_SH5 10
! #define EF_SH_MERGE_MACH(mach1, mach2) \
! (((((mach1) == EF_SH3 || (mach1) == EF_SH_UNKNOWN) && (mach2) == EF_SH_DSP) \
! || ((mach1) == EF_SH_DSP \
! && ((mach2) == EF_SH3 || (mach2) == EF_SH_UNKNOWN))) \
! ? EF_SH3_DSP \
! : (((mach1) < EF_SH3 && (mach2) == EF_SH_UNKNOWN) \
! || ((mach2) < EF_SH3 && (mach1) == EF_SH_UNKNOWN)) \
! ? EF_SH3 \
! : ((mach1) == EF_SH2E && EF_SH_HAS_FP (mach2)) \
! ? (mach2) \
! : ((mach2) == EF_SH2E && EF_SH_HAS_FP (mach1)) \
! ? (mach1) \
! : (((mach1) == EF_SH2E && (mach2) == EF_SH_UNKNOWN) \
! || ((mach2) == EF_SH2E && (mach1) == EF_SH_UNKNOWN)) \
! ? EF_SH2E \
! : (((mach1) == EF_SH3E && (mach2) == EF_SH_UNKNOWN) \
! || ((mach2) == EF_SH3E && (mach1) == EF_SH_UNKNOWN)) \
! ? EF_SH4 \
! /* ??? SH4? Why not SH3E? */ \
! : ((((mach1) == EF_SH4_NOFPU || (mach1) == EF_SH4A_NOFPU) \
! && EF_SH_HAS_DSP (mach2)) \
! || (((mach2) == EF_SH4_NOFPU || (mach2) == EF_SH4A_NOFPU) \
! && EF_SH_HAS_DSP (mach1))) \
! ? EF_SH4AL_DSP \
! : ((mach1) == EF_SH4_NOFPU && EF_SH_HAS_FP (mach2)) \
! ? ((mach2) < EF_SH4A) ? EF_SH4 : (mach2) \
! : ((mach2) == EF_SH4_NOFPU && EF_SH_HAS_FP (mach1)) \
! ? ((mach1) < EF_SH4A) ? EF_SH4 : (mach1) \
! : ((mach1) == EF_SH4A_NOFPU && EF_SH_HAS_FP (mach2)) \
! ? ((mach2) <= EF_SH4A) ? EF_SH4A : (mach2) \
! : ((mach2) == EF_SH4A_NOFPU && EF_SH_HAS_FP (mach1)) \
! ? ((mach1) <= EF_SH4A) ? EF_SH4A : (mach1) \
! : (((mach1) == EF_SH2E ? 7 : (mach1)) > ((mach2) == EF_SH2E ? 7 : (mach2)) \
! ? (mach1) : (mach2)))
/* Flags for the st_other symbol field.
Keep away from the STV_ visibility flags (bit 0..1). */
--- 57,83 ----
#define EF_SH4_NOFPU 0x10
#define EF_SH4A_NOFPU 0x11
/* This one can only mix in objects from other EF_SH5 objects. */
#define EF_SH5 10
! #define EF_SH_I_TABLE \
! /* EF_SH_UNKNOWN */ EF_SH_I_SH3 , \
! /* EF_SH1 */ EF_SH_I_SH1 , \
! /* EF_SH2 */ EF_SH_I_SH2 , \
! /* EF_SH3 */ EF_SH_I_SH3 , \
! /* EF_SH_DSP */ EF_SH_I_SH2 | EF_SH_I_DSP, \
! /* EF_SH3_DSP */ EF_SH_I_SH3 | EF_SH_I_MMU | EF_SH_I_DSP, \
! /* EF_SHAL_DSP */ EF_SH_I_SH4A | EF_SH_I_MMU | EF_SH_I_DSP, \
! /* EF_SH4_NOMMU_NOFPU */ EF_SH_I_SH4 , \
! /* EF_SH3E */ EF_SH_I_SH3 | EF_SH_I_MMU | EF_SH_I_FPU, \
! /* EF_SH4 */ EF_SH_I_SH4 | EF_SH_I_MMU | EF_SH_I_DFP, \
! /* EF_SH5 */ 0, \
! /* EF_SH2E */ EF_SH_I_SH2 | EF_SH_I_FPU, \
! /* EF_SH4A */ EF_SH_I_SH4A | EF_SH_I_MMU | EF_SH_I_DFP, \
! /* 13, 14, 15 */ 0, 0, 0, \
! /* EF_SH4_NOFPU */ EF_SH_I_SH4 | EF_SH_I_MMU , \
! /* EF_SH4A_NOFPU */ EF_SH_I_SH4A | EF_SH_I_MMU
/* Flags for the st_other symbol field.
Keep away from the STV_ visibility flags (bit 0..1). */
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.101
diff -p -r1.101 elf32-sh.c
*** bfd/elf32-sh.c 3 Mar 2004 18:01:49 -0000 1.101
--- bfd/elf32-sh.c 8 Mar 2004 17:52:21 -0000
*************** sh_elf_copy_private_data (bfd * ibfd, bf
*** 6922,6928 ****
static bfd_boolean
sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
{
! flagword old_flags, new_flags;
if (! _bfd_generic_verify_endian_match (ibfd, obfd))
return FALSE;
--- 6922,6930 ----
static bfd_boolean
sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
{
! const flagword table[] = { EF_SH_I_TABLE };
! flagword old_flags, new_flags, old_iflags, new_iflags;
! flagword int_instr_set, mmu_fxx, no_fpu, i, best, best_try;
if (! _bfd_generic_verify_endian_match (ibfd, obfd))
return FALSE;
*************** sh_elf_merge_private_data (bfd *ibfd, bf
*** 6937,6956 ****
elf_flags_init (obfd) = TRUE;
elf_elfheader (obfd)->e_flags = EF_SH1;
}
! old_flags = elf_elfheader (obfd)->e_flags;
! new_flags = elf_elfheader (ibfd)->e_flags;
! if ((EF_SH_HAS_DSP (old_flags) && EF_SH_HAS_FP (new_flags))
! || (EF_SH_HAS_DSP (new_flags) && EF_SH_HAS_FP (old_flags)))
{
(*_bfd_error_handler)
("%s: uses %s instructions while previous modules use %s instructions",
bfd_archive_filename (ibfd),
! EF_SH_HAS_DSP (new_flags) ? "dsp" : "floating point",
! EF_SH_HAS_DSP (new_flags) ? "floating point" : "dsp");
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
! elf_elfheader (obfd)->e_flags = EF_SH_MERGE_MACH (old_flags, new_flags);
return sh_elf_set_mach_from_flags (obfd);
}
--- 6939,6979 ----
elf_flags_init (obfd) = TRUE;
elf_elfheader (obfd)->e_flags = EF_SH1;
}
! old_flags = elf_elfheader (obfd)->e_flags & EF_SH_MACH_MASK;
! new_flags = elf_elfheader (ibfd)->e_flags & EF_SH_MACH_MASK;
! old_iflags = table[old_flags];
! new_iflags = table[new_flags];
! if ((EF_SH_I_HAS_DSP (old_iflags) && EF_SH_I_HAS_FP (new_iflags))
! || (EF_SH_I_HAS_DSP (new_iflags) && EF_SH_I_HAS_FP (old_iflags)))
{
(*_bfd_error_handler)
("%s: uses %s instructions while previous modules use %s instructions",
bfd_archive_filename (ibfd),
! EF_SH_I_HAS_DSP (new_iflags) ? "dsp" : "floating point",
! EF_SH_I_HAS_DSP (new_iflags) ? "floating point" : "dsp");
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
! if (old_flags == EF_SH_UNKNOWN && EF_SH_I_HAS_FP (new_iflags))
! old_iflags = table[EF_SH4];
! else if (new_flags == EF_SH_UNKNOWN && EF_SH_I_HAS_FP (old_iflags))
! new_iflags = table[EF_SH4];
! int_instr_set = ((old_iflags & EF_SH_I_INT) > (new_iflags & EF_SH_I_INT)
! ? (old_iflags & EF_SH_I_INT) : (new_iflags & EF_SH_I_INT));
! mmu_fxx = (old_iflags | new_iflags) & (EF_SH_I_MMU | EF_SH_I_Fxx);
! no_fpu = EF_SH_I_HAS_DSP (mmu_fxx) ? EF_SH_I_FPU : 0;
! best_try = ~0;
! for (i = sizeof (table) / sizeof(table[0]) - 1; i > EF_SH_UNKNOWN; i--)
! {
! flagword try = table[i];
!
! if (best_try > try
! && (try & EF_SH_I_INT) >= int_instr_set
! && (try & EF_SH_I_Fxx) >= mmu_fxx
! && ! (try & no_fpu))
! best = i, best_try = try;
! }
! elf_elfheader (obfd)->e_flags = i;
return sh_elf_set_mach_from_flags (obfd);
}