This is the mail archive of the binutils@sourceware.org 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]

Commit: RL78: Add support for G13 and G14 flags in ELF header


Hi Guys,

  I am checking in the patch below to add support for encoding the G13
  and G14 core types for the RL78 into the ELF header.  The patch adds
  a couple of new options to GAS for the RL78 (-mg13 and -mg14) which
  can be used to set the flags.  It also updates readelf and objdump to
  display the flags and the linker to issue error messages if the user
  attempts to link together objects built for different cores.

Cheers
  Nick

include/elf/ChangeLog
2015-03-19  Nick Clifton  <nickc@redhat.com>

	* rl78.h (E_FLAG_RL78_G10): Redefine.
	(E_FLAG_RL78_CPU_MASK, E_FLAG_RL78_ANY_CPU, E_FLAG_RL78_G13
	E_FLAG_RL78_G14): New flags.

gas/ChangeLog
2015-03-19  Nick Clifton  <nickc@redhat.com>

	* config/tc-rl78.c (enum options): Add G13 and G14.
	(md_longopts): Add -mg13 and -mg14.
	(md_parse_option): Handle -mg13 and -mg14.
	(md_show_usage): List -mg13 and -mg14.
	* doc/c-rl78.texi: Add description of -mg13 and -mg14 options.

bfd/ChangeLog
2015-03-19  Nick Clifton  <nickc@redhat.com>

	* elf32-rl78.c (rl78_cpu_name): New function.  Prints the name of
	the RL78 core based upon the flags.
	(rl78_elf_merge_private_bfd_data): Handle merging of G13 and G14
	flags.
	(rl78_elf_print_private_bfd_data): Use rl78_cpu_name.
	(elf32_rl78_machine): Always return bfd_mach_rl78.

diff --git a/bfd/elf32-rl78.c b/bfd/elf32-rl78.c
index acd82b9..70b49aa 100644
--- a/bfd/elf32-rl78.c
+++ b/bfd/elf32-rl78.c
@@ -1018,6 +1018,18 @@ bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch)
   no_warn_mismatch = user_no_warn_mismatch;
 }
 
+static const char *
+rl78_cpu_name (flagword flags)
+{
+  switch (flags & E_FLAG_RL78_CPU_MASK)
+    {
+    default: return "";
+    case E_FLAG_RL78_G10:     return "G10";
+    case E_FLAG_RL78_G13:     return "G13";
+    case E_FLAG_RL78_G14:     return "G14";
+    }
+}
+
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
@@ -1041,17 +1053,44 @@ rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
     {
       flagword changed_flags = old_flags ^ new_flags;
 
-      if (changed_flags & E_FLAG_RL78_G10)
+      if (changed_flags & E_FLAG_RL78_CPU_MASK)
 	{
-	  (*_bfd_error_handler)
-	    (_("RL78/G10 ABI conflict: cannot link G10 and non-G10 objects together"));
+	  flagword out_cpu = old_flags & E_FLAG_RL78_CPU_MASK;
+	  flagword in_cpu = new_flags & E_FLAG_RL78_CPU_MASK;
 
-	  if (old_flags & E_FLAG_RL78_G10)
-	    (*_bfd_error_handler) (_("- %s is G10, %s is not"),
-				   bfd_get_filename (obfd), bfd_get_filename (ibfd));
+	  if (in_cpu == E_FLAG_RL78_ANY_CPU || in_cpu == out_cpu)
+	    /* It does not matter what new_cpu may have.  */;
+	  else if (out_cpu == E_FLAG_RL78_ANY_CPU)
+	    {
+	      if (in_cpu == E_FLAG_RL78_G10)
+		{
+		  /* G10 files can only be linked with other G10 files.
+		     If the output is set to "any" this means that it is
+		     a G14 file that does not use hardware multiply/divide,
+		     but that is still incompatible with the G10 ABI.  */
+		  error = TRUE;
+
+		  (*_bfd_error_handler)
+		    (_("RL78 ABI conflict: G10 file %s cannot be linked with %s file %s"),
+		     bfd_get_filename (ibfd),
+		     rl78_cpu_name (out_cpu), bfd_get_filename (obfd));
+		}
+	      else
+		{
+		  old_flags &= ~ E_FLAG_RL78_CPU_MASK;
+		  old_flags |= in_cpu;
+		  elf_elfheader (obfd)->e_flags = old_flags;
+		}
+	    }
 	  else
-	    (*_bfd_error_handler) (_("- %s is G10, %s is not"),
-				   bfd_get_filename (ibfd), bfd_get_filename (obfd));
+	    {
+	      error = TRUE;
+
+	      (*_bfd_error_handler)
+		(_("RL78 ABI conflict: cannot link %s file %s with %s file %s"),
+		 rl78_cpu_name (in_cpu),  bfd_get_filename (ibfd),
+		 rl78_cpu_name (out_cpu), bfd_get_filename (obfd));
+	    }
 	}
 
       if (changed_flags & E_FLAG_RL78_64BIT_DOUBLES)
@@ -1065,6 +1104,7 @@ rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
 	  else
 	    (*_bfd_error_handler) (_("- %s is 64-bit, %s is not"),
 				   bfd_get_filename (ibfd), bfd_get_filename (obfd));
+	  error = TRUE;
 	}    
     }
 
@@ -1085,8 +1125,8 @@ rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
   flags = elf_elfheader (abfd)->e_flags;
   fprintf (file, _("private flags = 0x%lx:"), (long) flags);
 
-  if (flags & E_FLAG_RL78_G10)
-    fprintf (file, _(" [G10]"));
+  if (flags & E_FLAG_RL78_CPU_MASK)
+    fprintf (file, " [%s]", rl78_cpu_name (flags));
 
   if (flags & E_FLAG_RL78_64BIT_DOUBLES)
     fprintf (file, _(" [64-bit doubles]"));
@@ -1098,12 +1138,9 @@ rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
 /* Return the MACH for an e_flags value.  */
 
 static int
-elf32_rl78_machine (bfd * abfd)
+elf32_rl78_machine (bfd * abfd ATTRIBUTE_UNUSED)
 {
-  if ((elf_elfheader (abfd)->e_flags & EF_RL78_CPU_MASK) == EF_RL78_CPU_RL78)
-    return bfd_mach_rl78;
-
-  return 0;
+  return bfd_mach_rl78;
 }
 
 static bfd_boolean
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 20cfc47..adf2a91 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3256,8 +3256,13 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
 	  break;
 
 	case EM_RL78:
-	  if (e_flags & E_FLAG_RL78_G10)
-	    strcat (buf, ", G10");
+	  switch (e_flags & E_FLAG_RL78_CPU_MASK)
+	    {
+	    case E_FLAG_RL78_ANY_CPU: break;
+	    case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
+	    case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
+	    case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
+	    }
 	  if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
 	    strcat (buf, ", 64-bit doubles");
 	  break;
diff --git a/gas/config/tc-rl78.c b/gas/config/tc-rl78.c
index abc05a0..337b819 100644
--- a/gas/config/tc-rl78.c
+++ b/gas/config/tc-rl78.c
@@ -281,6 +281,8 @@ enum options
 {
   OPTION_RELAX = OPTION_MD_BASE,
   OPTION_G10,
+  OPTION_G13,
+  OPTION_G14,
   OPTION_32BIT_DOUBLES,
   OPTION_64BIT_DOUBLES,
 };
@@ -293,6 +295,9 @@ struct option md_longopts[] =
 {
   {"relax", no_argument, NULL, OPTION_RELAX},
   {"mg10", no_argument, NULL, OPTION_G10},
+  {"mg13", no_argument, NULL, OPTION_G13},
+  {"mg14", no_argument, NULL, OPTION_G14},
+  {"mrl78", no_argument, NULL, OPTION_G14},
   {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
   {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
   {NULL, no_argument, NULL, 0}
@@ -309,9 +314,20 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
       return 1;
 
     case OPTION_G10:
+      elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
       elf_flags |= E_FLAG_RL78_G10;
       return 1;
 
+    case OPTION_G13:
+      elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
+      elf_flags |= E_FLAG_RL78_G13;
+      return 1;
+
+    case OPTION_G14:
+      elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
+      elf_flags |= E_FLAG_RL78_G14;
+      return 1;
+
     case OPTION_32BIT_DOUBLES:
       elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
       return 1;
@@ -328,6 +344,9 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
 {
   fprintf (stream, _(" RL78 specific command line options:\n"));
   fprintf (stream, _("  --mg10            Enable support for G10 variant\n"));
+  fprintf (stream, _("  --mg13            Selects the G13 core.\n"));
+  fprintf (stream, _("  --mg14            Selects the G14 core [default]\n"));
+  fprintf (stream, _("  --mrl78           Alias for --mg14\n"));
   fprintf (stream, _("  --m32bit-doubles  [default]\n"));
   fprintf (stream, _("  --m64bit-doubles\n"));
 }
diff --git a/gas/doc/c-rl78.texi b/gas/doc/c-rl78.texi
index fee16f1..5cb568f 100644
--- a/gas/doc/c-rl78.texi
+++ b/gas/doc/c-rl78.texi
@@ -32,6 +32,15 @@ Enable support for link-time relaxation.
 Mark the generated binary as targeting the G10 variant of the RL78
 architecture.
 
+@item mg13
+Mark the generated binary as targeting the G13 variant of the RL78
+architecture.
+
+@item mg14
+@itemx mrl78
+Mark the generated binary as targeting the G14 variant of the RL78
+architecture.  This is the default.
+
 @item m32bit-doubles
 Mark the generated binary as one that uses 32-bits to hold the
 @code{double} floating point type.  This is the default.
diff --git a/include/elf/rl78.h b/include/elf/rl78.h
index e7df0d7..b5236d9 100644
--- a/include/elf/rl78.h
+++ b/include/elf/rl78.h
@@ -106,7 +106,11 @@ END_RELOC_NUMBERS (R_RL78_max)
 /* Values for the e_flags field in the ELF header.  */
 #define E_FLAG_RL78_64BIT_DOUBLES	(1 << 0)
 #define E_FLAG_RL78_DSP			(1 << 1) /* Defined in the RL78 CPU Object file specification, but not explained.  */
-#define E_FLAG_RL78_G10			(1 << 2) /* CPU is missing register banks 1-3, so uses different ABI.  */
+#define E_FLAG_RL78_CPU_MASK            0x0c
+#define E_FLAG_RL78_ANY_CPU             0x00     /* CPU not specified.  Assume no CPU specific code usage.  */
+#define E_FLAG_RL78_G10			0x04     /* CPU is missing register banks 1-3, so uses different ABI.  */
+#define E_FLAG_RL78_G13			0x08     /* CPU uses a peripheral for multiply/divide.  */
+#define E_FLAG_RL78_G14			0x0c     /* CPU has multiply/divide instructions.  */
 
 /* These define the addend field of R_RL78_RH_RELAX relocations.  */
 #define RL78_RELAXA_MASK	0x000000f0	/* Mask for relax types */


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