Add Nios II arch flags and compatibility tests
authorSandra Loosemore <sandra@codesourcery.com>
Wed, 1 Jul 2015 22:55:28 +0000 (15:55 -0700)
committerSandra Loosemore <sandra@codesourcery.com>
Wed, 1 Jul 2015 22:55:28 +0000 (15:55 -0700)
2015-07-01  Sandra Loosemore  <sandra@codesourcery.com>
    Cesar Philippidis  <cesar@codesourcery.com>

bfd/
* archures.c (bfd_mach_nios2r1, bfd_mach_nios2r2): New.
* bfd-in2.h: Regenerated.
* cpu-nios2.c (nios2_compatible): New.
(N): Use nios2_compatible instead of bfd_default_compatible.
(NIOS2R1_NEXT, NIOS2R2_NEXT): Define.
(arch_info_struct): New.
(bfd_nios2_arch): Chain to NIOS2R1_NEXT.
* elf32-nios2.c (is_nios2_elf): New.
(nios2_elf32_merge_private_bfd_data): New.
(nios2_elf32_object_p): New.
(bfd_elf32_bfd_merge_private_bfd_data): Define.
(elf_backend_object_p): Define.

gas/
* config/tc-nios2.c: Adjust includes.
(OPTION_MARCH): Define.
(md_longopts): Add -march option.
(nios2_architecture): New.
(nios2_use_arch): New.
(md_parse_option): Handle OPTION_MARCH.
(md_show_usage): Document -march.
(md_begin): Set arch in BFD.
(nios2_elf_final_processing): New.
* config/tc-nios2.h (elf_tc_final_processing): Define.
(nios2_elf_final_processing): New.
* doc/c-nios2.texi (-march): Add documentation.

include/elf/
* nios2.h (EF_NIOS2_ARCH_R1, EF_NIOS2_ARCH_R2): Define.

ld/testsuite/
* ld-nios2/mixed1a.d: New.
* ld-nios2/mixed1a.s: New.
* ld-nios2/mixed1b.d: New.
* ld-nios2/mixed1b.s: New.
* ld-nios2/nios2.exp: Build the new compatibility tests.

17 files changed:
bfd/ChangeLog
bfd/archures.c
bfd/bfd-in2.h
bfd/cpu-nios2.c
bfd/elf32-nios2.c
gas/ChangeLog
gas/config/tc-nios2.c
gas/config/tc-nios2.h
gas/doc/c-nios2.texi
include/elf/ChangeLog
include/elf/nios2.h
ld/testsuite/ChangeLog
ld/testsuite/ld-nios2/mixed1a.d [new file with mode: 0644]
ld/testsuite/ld-nios2/mixed1a.s [new file with mode: 0644]
ld/testsuite/ld-nios2/mixed1b.d [new file with mode: 0644]
ld/testsuite/ld-nios2/mixed1b.s [new file with mode: 0644]
ld/testsuite/ld-nios2/nios2.exp

index 5c1e94ce96160f9f0677dbe9d16943598b8ba3dd..701f17737efa7914055ee47672b855af1b857c18 100644 (file)
@@ -1,3 +1,19 @@
+2015-07-01  Sandra Loosemore  <sandra@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * archures.c (bfd_mach_nios2r1, bfd_mach_nios2r2): New.
+       * bfd-in2.h: Regenerated.
+       * cpu-nios2.c (nios2_compatible): New.
+       (N): Use nios2_compatible instead of bfd_default_compatible.
+       (NIOS2R1_NEXT, NIOS2R2_NEXT): Define.
+       (arch_info_struct): New.
+       (bfd_nios2_arch): Chain to NIOS2R1_NEXT.
+       * elf32-nios2.c (is_nios2_elf): New.
+       (nios2_elf32_merge_private_bfd_data): New.
+       (nios2_elf32_object_p): New.
+       (bfd_elf32_bfd_merge_private_bfd_data): Define.
+       (elf_backend_object_p): Define.
+
 2015-07-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Refactor.
index 677c4708e9d62bdd4c0c4d67ca4aa8f96f82ec68..95433f85adbd5e87123d120ca9a96c96df120d1c 100644 (file)
@@ -501,8 +501,10 @@ DESCRIPTION
 .  bfd_arch_aarch64,   {* AArch64  *}
 .#define bfd_mach_aarch64 0
 .#define bfd_mach_aarch64_ilp32        32
-.  bfd_arch_nios2,
-.#define bfd_mach_nios2        0
+.  bfd_arch_nios2,     {* Nios II *}
+.#define bfd_mach_nios2                0
+.#define bfd_mach_nios2r1      1
+.#define bfd_mach_nios2r2      2
 .  bfd_arch_visium,    {* Visium *}
 .#define bfd_mach_visium       1
 .  bfd_arch_last
index ce964bb355ca8beb693b717fab4e79c8d775629d..83d729eec1d2f2f25c47a05e883742086df6ea3c 100644 (file)
@@ -2294,8 +2294,10 @@ enum bfd_architecture
   bfd_arch_aarch64,   /* AArch64  */
 #define bfd_mach_aarch64 0
 #define bfd_mach_aarch64_ilp32 32
-  bfd_arch_nios2,
-#define bfd_mach_nios2 0
+  bfd_arch_nios2,      /* Nios II */
+#define bfd_mach_nios2         0
+#define bfd_mach_nios2r1       1
+#define bfd_mach_nios2r2       2
   bfd_arch_visium,     /* Visium */
 #define bfd_mach_visium        1
   bfd_arch_last
index 57539db14d25c55d16828a503c42d0180b4e1d4b..1e8f521bee08b28ce3223df8b6945f3d1ce09671 100644 (file)
 #include "bfd.h"
 #include "libbfd.h"
 
+static const bfd_arch_info_type *
+nios2_compatible (const bfd_arch_info_type *a,
+                 const bfd_arch_info_type *b)
+{
+  if (a->arch != b->arch)
+    return NULL;
+
+  if (a->bits_per_word != b->bits_per_word)
+    return NULL;
+
+  if (a->mach == bfd_mach_nios2)
+    return a;
+  else if (b->mach == bfd_mach_nios2)
+    return b;
+  else if (a->mach != b->mach)
+    return NULL;
+
+  return a;
+}
+
 #define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT)          \
   {                                                    \
     BITS_WORD, /*  bits in a word */                   \
     PRINT,                                             \
     3,                                                 \
     DEFAULT,                                           \
-    bfd_default_compatible,                            \
+    nios2_compatible,                                  \
     bfd_default_scan,                                  \
     bfd_arch_default_fill,                             \
     NEXT                                               \
   }
 
-const bfd_arch_info_type bfd_nios2_arch = N (32, 32, 0, "nios2", TRUE, NULL);
+#define NIOS2R1_NEXT &arch_info_struct[0]
+#define NIOS2R2_NEXT &arch_info_struct[1]
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+  N (32, 32, bfd_mach_nios2r1, "nios2:r1", FALSE, NIOS2R2_NEXT),
+  N (32, 32, bfd_mach_nios2r2, "nios2:r2", FALSE, NULL),
+};
+
+const bfd_arch_info_type bfd_nios2_arch = 
+  N (32, 32, 0, "nios2", TRUE, NIOS2R1_NEXT);
index 4f992bfce7f14703a4833fe48137bc07e7a7e229..6a1372b71ab9982ff47b8819d6b4bbd6947fba1f 100644 (file)
@@ -2038,6 +2038,72 @@ nios2_elf32_build_stubs (struct bfd_link_info *info)
 }
 
 
+#define is_nios2_elf(bfd) \
+  (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+   && elf_object_id (bfd) == NIOS2_ELF_DATA)
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+static bfd_boolean
+nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  flagword old_flags;
+  flagword new_flags;
+
+  if (!is_nios2_elf (ibfd) || !is_nios2_elf (obfd))
+    return TRUE;
+
+  /* Check if we have the same endianness.  */
+  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+    return FALSE;
+
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  old_flags = elf_elfheader (obfd)->e_flags;
+  if (!elf_flags_init (obfd))
+    {
+      /* First call, no flags set.  */
+      elf_flags_init (obfd) = TRUE;
+      elf_elfheader (obfd)->e_flags = new_flags;
+
+      switch (new_flags)
+       {
+       default:
+       case EF_NIOS2_ARCH_R1:
+         bfd_default_set_arch_mach (obfd, bfd_arch_nios2, bfd_mach_nios2r1);
+         break;
+       case EF_NIOS2_ARCH_R2:
+         if (bfd_big_endian (ibfd))
+           {
+             (*_bfd_error_handler)
+               (_("error: %B: Big-endian R2 is not supported."), ibfd);
+             bfd_set_error (bfd_error_bad_value);
+             return FALSE;
+           }
+         bfd_default_set_arch_mach (obfd, bfd_arch_nios2, bfd_mach_nios2r2);
+         break;
+       }
+    }
+
+  /* Incompatible flags.  */
+  else if (new_flags != old_flags)
+    {
+      /* So far, the only incompatible flags denote incompatible
+        architectures.  */
+      (*_bfd_error_handler)
+       (_("error: %B: Conflicting CPU architectures %d/%d"),
+        ibfd, new_flags, old_flags);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
+  /* Merge Tag_compatibility attributes and any common GNU ones.  */
+  _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+  return TRUE;
+}
+
+
 /* Implement bfd_elf32_bfd_reloc_type_lookup:
    Given a BFD reloc type, return a howto structure.  */
 static reloc_howto_type *
@@ -3707,6 +3773,29 @@ nios2_elf32_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
+/* Set the right machine number for a NIOS2 ELF file.  */
+
+static bfd_boolean
+nios2_elf32_object_p (bfd *abfd)
+{
+  unsigned long mach;
+
+  mach = elf_elfheader (abfd)->e_flags;
+
+  switch (mach)
+    {
+    default:
+    case EF_NIOS2_ARCH_R1:
+      bfd_default_set_arch_mach (abfd, bfd_arch_nios2, bfd_mach_nios2r1);
+      break;
+    case EF_NIOS2_ARCH_R2:
+      bfd_default_set_arch_mach (abfd, bfd_arch_nios2, bfd_mach_nios2r2);
+      break;
+    }
+
+  return TRUE;
+}
+
 /* Implement elf_backend_check_relocs:
    Look through the relocs for a section during the first phase.  */
 static bfd_boolean
@@ -5256,6 +5345,9 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define bfd_elf32_bfd_link_hash_table_create \
                                          nios2_elf32_link_hash_table_create
 
+#define bfd_elf32_bfd_merge_private_bfd_data \
+                                         nios2_elf32_merge_private_bfd_data
+
 /* Relocation table lookup macros.  */
 
 #define bfd_elf32_bfd_reloc_type_lookup          nios2_elf32_bfd_reloc_type_lookup
@@ -5292,6 +5384,7 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define elf_backend_size_dynamic_sections nios2_elf32_size_dynamic_sections
 #define elf_backend_add_symbol_hook      nios2_elf_add_symbol_hook
 #define elf_backend_copy_indirect_symbol  nios2_elf32_copy_indirect_symbol
+#define elf_backend_object_p             nios2_elf32_object_p
 
 #define elf_backend_grok_prstatus        nios2_grok_prstatus
 #define elf_backend_grok_psinfo                  nios2_grok_psinfo
index 77965773c522aec8e2f383ea85977e57a52d7049..470cd9f7c1a2e7f46afa36add7f9184397381028 100644 (file)
@@ -1,3 +1,19 @@
+2015-07-01  Sandra Loosemore  <sandra@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * config/tc-nios2.c: Adjust includes.
+       (OPTION_MARCH): Define.
+       (md_longopts): Add -march option.
+       (nios2_architecture): New.
+       (nios2_use_arch): New.
+       (md_parse_option): Handle OPTION_MARCH.
+       (md_show_usage): Document -march.
+       (md_begin): Set arch in BFD.
+       (nios2_elf_final_processing): New.
+       * config/tc-nios2.h (elf_tc_final_processing): Define.
+       (nios2_elf_final_processing): New.
+       * doc/c-nios2.texi (-march): Add documentation.
+
 2015-06-30  Amit Pawar  <Amit.Pawar@amd.com>
 
        * config/tc-i386.c (cpu_arch): Add .mwaitx.
index 2fb26b82c4bfc3e19dfc4c9585b6013cebfc62c1..549ca98f5f7c5de085536e8e683a671582683fad 100644 (file)
@@ -25,6 +25,7 @@
 #include "elf/nios2.h"
 #include "tc-nios2.h"
 #include "bfd.h"
+#include "libbfd.h"
 #include "dwarf2dbg.h"
 #include "subsegs.h"
 #include "safe-ctype.h"
@@ -80,7 +81,9 @@ struct option md_longopts[] = {
 #define OPTION_EB (OPTION_MD_BASE + 3)
   {"EB", no_argument, NULL, OPTION_EB},
 #define OPTION_EL (OPTION_MD_BASE + 4)
-  {"EL", no_argument, NULL, OPTION_EL}
+  {"EL", no_argument, NULL, OPTION_EL},
+#define OPTION_MARCH (OPTION_MD_BASE + 5)
+  {"march", required_argument, NULL, OPTION_MARCH}
 };
 
 size_t md_longopts_size = sizeof (md_longopts);
@@ -212,6 +215,9 @@ static symbolS *nios2_last_label;
 symbolS *GOT_symbol;
 #endif
 
+/* The processor architecture value, EF_NIOS2_ARCH_R1 by default.  */
+static int nios2_architecture = EF_NIOS2_ARCH_R1;
+
 \f
 /** Utility routines.  */
 /* Function md_chars_to_number takes the sequence of
@@ -2209,6 +2215,34 @@ output_movia (nios2_insn_infoS *insn)
 \f
 /** External interfaces.  */
 
+/* Update the selected architecture based on ARCH, giving an error if
+   ARCH is an invalid value.  */
+
+static void
+nios2_use_arch (const char *arch)
+{
+  if (strcmp (arch, "nios2") == 0 || strcmp (arch, "r1") == 0)
+    {
+      nios2_architecture |= EF_NIOS2_ARCH_R1;
+      nios2_opcodes = (struct nios2_opcode *) nios2_r1_opcodes;
+      nios2_num_opcodes = nios2_num_r1_opcodes;
+      nop32 = nop_r1;
+      nop16 = NULL;
+      return;
+    }
+  else if (strcmp (arch, "r2") == 0)
+    {
+      nios2_architecture |= EF_NIOS2_ARCH_R2;
+      nios2_opcodes = (struct nios2_opcode *) nios2_r2_opcodes;
+      nios2_num_opcodes = nios2_num_r2_opcodes;
+      nop32 = nop_r2;
+      nop16 = nop_r2_cdx;
+      return;
+    }
+
+  as_bad (_("unknown architecture '%s'"), arch);
+}
+
 /* The following functions are called by machine-independent parts of
    the assembler. */
 int
@@ -2235,6 +2269,9 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
     case OPTION_EL:
       target_big_endian = 0;
       break;
+    case OPTION_MARCH:
+      nios2_use_arch (arg);
+      break;
     default:
       return 0;
       break;
@@ -2262,9 +2299,11 @@ md_show_usage (FILE *stream)
           "branches with jmp sequences (default)\n"
           "  -no-relax             do not replace any branches or calls\n"
           "  -EB                   force big-endian byte ordering\n"
-          "  -EL                   force little-endian byte ordering\n");
+          "  -EL                   force little-endian byte ordering\n"
+          "  -march=ARCH           enable instructions from architecture ARCH\n");
 }
 
+
 /* This function is called once, at assembler startup time.
    It should set up all the tables, etc. that the MD part of the
    assembler will need. */
@@ -2274,6 +2313,19 @@ md_begin (void)
   int i;
   const char *inserted;
 
+  switch (nios2_architecture)
+    {
+    default:
+    case EF_NIOS2_ARCH_R1:
+      bfd_default_set_arch_mach (stdoutput, bfd_arch_nios2, bfd_mach_nios2r1);
+      break;
+    case EF_NIOS2_ARCH_R2:
+      if (target_big_endian)
+       as_fatal (_("Big-endian R2 is not supported."));
+      bfd_default_set_arch_mach (stdoutput, bfd_arch_nios2, bfd_mach_nios2r2);
+      break;
+    }
+
   /* Create and fill a hashtable for the Nios II opcodes, registers and 
      arguments.  */
   nios2_opcode_hash = hash_new ();
@@ -2747,3 +2799,13 @@ nios2_frame_initial_instructions (void)
 {
   cfi_add_CFA_def_cfa (27, 0);
 }
+
+#ifdef OBJ_ELF
+/* Some special processing for a Nios II ELF file.  */
+
+void
+nios2_elf_final_processing (void)
+{
+  elf_elfheader (stdoutput)->e_flags = nios2_architecture;
+}
+#endif
index 2e69caff43515a8c0ef207e3058cfde2701a7a6c..8b9a7d816f77b70804984a59005e2517f8baa7b0 100644 (file)
@@ -118,4 +118,7 @@ extern int nios2_regname_to_dw2regnum (char *regname);
 #define tc_cfi_frame_initial_instructions  nios2_frame_initial_instructions
 extern void nios2_frame_initial_instructions (void);
 
+#define elf_tc_final_processing nios2_elf_final_processing
+extern void nios2_elf_final_processing (void);
+
 #endif /* TC_NIOS2 */
index 1fb29f2268754ebae0de156b0f65ed8325e2463a..880346dadb19754286b96876a260c1692323916d 100644 (file)
@@ -58,6 +58,16 @@ Generate big-endian output.
 @item -EL
 Generate little-endian output.  This is the default.
 
+@cindex @code{march} command line option, Nios II
+@item -march=@var{architecture}
+This option specifies the target architecture.  The assembler issues
+an error message if an attempt is made to assemble an instruction which
+will not execute on the target architecture.  The following architecture
+names are recognized:
+@code{r1},
+@code{r2}.  
+The default is @code{r1}.
+
 @end table
 @c man end
 
index 3e7671c5b6aef4e8f8cdbbf6b89dcf9ae3211914..0c03d8e0d3f30918a4f6cfe9e58a4cccd6ba0b2b 100644 (file)
@@ -1,3 +1,8 @@
+2015-07-01  Sandra Loosemore  <sandra@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * nios2.h (EF_NIOS2_ARCH_R1, EF_NIOS2_ARCH_R2): Define.
+
 2015-05-29  Roland McGrath  <mcgrathr@google.com>
 
        * common.h (GNU_ABI_TAG_SYLLABLE): New macro.
index 429b8ba2451f061e03a5caaff03f24e5dd8053da..07f937f8df936a641eaf7ba2b94a3860746345a9 100644 (file)
@@ -93,4 +93,9 @@ END_RELOC_NUMBERS (R_NIOS2_maxext)
 /* Address of _gp.  */
 #define DT_NIOS2_GP 0x70000002
 
+/* Processor specific flags for the Elf header e_flags field.  */
+
+#define EF_NIOS2_ARCH_R1 0x00000000
+#define EF_NIOS2_ARCH_R2 0x00000001
+
 #endif /* _ELF_NIOS2_H */
index e4f913f0cdae981164a7d0b48f94407f3de3cfb6..0e611b99c106f20a04c8b25e12ce0c4e7da592fc 100644 (file)
@@ -1,3 +1,12 @@
+2015-07-01  Sandra Loosemore  <sandra@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * ld-nios2/mixed1a.d: New.
+       * ld-nios2/mixed1a.s: New.
+       * ld-nios2/mixed1b.d: New.
+       * ld-nios2/mixed1b.s: New.
+       * ld-nios2/nios2.exp: Build the new compatibility tests.
+
 2015-06-27  H.J. Lu  <hongjiu.lu@intel.com>
 
        * ld-xtensa/tlsbin.rd: Updated.
diff --git a/ld/testsuite/ld-nios2/mixed1a.d b/ld/testsuite/ld-nios2/mixed1a.d
new file mode 100644 (file)
index 0000000..0c7d666
--- /dev/null
@@ -0,0 +1,9 @@
+#name: NIOS2 mixed1a
+#source: mixed1a.s
+#as: -march=r2
+#readelf: -h
+
+ELF Header:
+#...
+  Flags:                             0x1
+#...
diff --git a/ld/testsuite/ld-nios2/mixed1a.s b/ld/testsuite/ld-nios2/mixed1a.s
new file mode 100644 (file)
index 0000000..8742f1c
--- /dev/null
@@ -0,0 +1,9 @@
+# Test linking incompatible object file types. 
+
+.text
+.global        _start
+_start:
+       movhi   r2, %hiadj(foo)
+       addi    r2, r2, %lo(foo)
+       ldw     r2, 0(r2)
+       cmpeq   r2, r2, zero
diff --git a/ld/testsuite/ld-nios2/mixed1b.d b/ld/testsuite/ld-nios2/mixed1b.d
new file mode 100644 (file)
index 0000000..a702c5a
--- /dev/null
@@ -0,0 +1,9 @@
+#name: NIOS2 mixed1b
+#source: mixed1b.s
+#as: -march=r1
+#readelf: -h
+
+ELF Header:
+#...
+  Flags:                             0x0
+#...
diff --git a/ld/testsuite/ld-nios2/mixed1b.s b/ld/testsuite/ld-nios2/mixed1b.s
new file mode 100644 (file)
index 0000000..0d07590
--- /dev/null
@@ -0,0 +1,3 @@
+# Test linking incompatible object file types. 
+
+.comm  foo,4,4
index 22080b49d7a54f8ecbabc6668f814c7160380d32..b8ffd49ef0a0a4b83784f8029dd1db999d2ab157 100644 (file)
@@ -1,7 +1,31 @@
 if { ! [istarget nios2-*-*] } {
-    return
+    return 
 }
 
 foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.d]] {
     run_dump_test [file rootname $test]
 }
+
+global link_output
+global ld
+
+set test_name "NIOS2 Mixed R1 and R2 objects"
+set test mixed1
+
+if ![ld_assemble $as "-march=r1 $srcdir/$subdir/${test}a.s" tmpdir/${test}a.o] {
+    unresolved "Build mixed1a.o"
+    return
+}
+
+if ![ld_assemble $as "-march=r2 $srcdir/$subdir/${test}b.s" tmpdir/${test}b.o] {
+    unresolved "Build mixed1b.o"
+    return
+}
+
+if { ![ld_simple_link $ld tmpdir/$test "tmpdir/${test}a.o tmpdir/${test}b.o"] } {
+    if [string match "*architecture * is incompatible*" $link_output] {
+       pass "$test_name"
+    } {
+       fail "$test_name"
+    }
+}