RISC-V: Update ABI to the elf_flags after parsing elf attributes.
authorNelson Chu <nelson.chu@sifive.com>
Mon, 19 Oct 2020 05:10:42 +0000 (22:10 -0700)
committerNelson Chu <nelson.chu@sifive.com>
Mon, 9 Nov 2020 01:48:56 +0000 (09:48 +0800)
Originally, if the -mabi option isn't set, then assembler will set the
abi according to the architecture string in the riscv_after_parse_args.
But we should also check and reset the abi later since the architecture
string may be reset by the elf attributes.  Therefore, set the abi to
the elf_flags in the riscv_after_parse_args seems too early.  Besides,
we have to set the abi_xlen before assembling any instruction, so it
should be safe to call riscv_set_abi_by_arch at the place that we set
start_assemble to TRUE.  However, one minor case is that we won't call
the md_assemble when we are assembling an file without any instruction.
It seems that we still need to set the abi in riscv_elf_final_processing,
to make sure that abi can be updated according to the elf arch attributes.

For the rv32i and most elf toolchains, this patch can fix the mis-matched
ABI errors for Run pr26391-5 and Run pr26391-6 testcases.  Besides, it
also correct the elf header flags of the output objects.  Consider the
new testcases, mabi-fail-02 and mabi-noabi-attr-[01|02|03], they are
failed before applying this patch.

But I still get the mis-matched ABI errors for the following toolchains
when runnung the riscv-gnu-toolchain regressions,

newlib-rv32imafc-ilp32f-[medlow|medany]
linux-rv32imac-ilp32-[medlow|medany]
linux-rv32imafdc-ilp32-[medlow|medany}
linux-rv64imac-lp64-[medlow|medany]
linux-rv64imafdc-lp64-[medlow|medany}

For the newlib-rv32imafc-ilp32f, although we try to choose the abi
according to the elf attributes, we will use FLOAT_ABI_SOFT rather
than the FLOAT_ABI_SINGLE for the assmebly file wihtout setting the
-mabi, but compiler will set the abi to FLOAT_ABI_SINGLE for the
C files.

As for the linux toolchains, we also get fails for Run pr26391-5 and
Run pr26391-6 testcases.  Since the linux toolchain won't generate elf
attributes to correct the ISA, and the --with-arch configure option
isn't set, assembler will try to set the default arch to rv[32|64]g,
which means the FLOAT_ABI_DOUBLE will be choosed, and may be conflict
with the abi set by the toolchain.

Therefore, I would suggest that it's is more safe to set the --with-arch
when building binutils, but it may break some testcases.  For example,
ld-scripts/fill and ld-scripts/empty-address-2 may be broken when c-ext
is set.  We might insert R_RISCV_ALIGN to make sure the 4-byte alignment,
but the dump result will be a bit different from what the testcase expected.

However, this patch only fix the problem - the abi, elf_flags and the
instruction, which is generated according to the abi_xlen, are all fixed
once the elf attributes are set for most elf toolchains. Other mis-matched
ABI problems should be fixed when we always build the binutils with the
--with-arch= configure option.

gas/
* config/tc-riscv.c (explicit_mabi): New boolean to indicate if
the -mabi= option is explictly set.
(md_parse_option): Set explicit_mabi to TRUE if -mabi is set.
(riscv_set_abi_by_arch): New function.  If the -mabi option isn't
set, then we set the abi according to the architecture string.
Otherwise, check if there are conflicts between architecture
and abi setting.
(riscv_after_parse_args): Move the abi setting to md_assemble nad
riscv_elf_final_processing.
(md_assemble): Call the riscv_set_abi_by_arch when we set the
start_assemble to TRUE.
(riscv_elf_final_processing): Likewise, in case the file without
any instruction.

* testsuite/gas/riscv/mabi-attr-01.s: New testcase.
* testsuite/gas/riscv/mabi-attr-02.s: Likewise.
* testsuite/gas/riscv/mabi-attr-03.s: Likewise.
* testsuite/gas/riscv/mabi-fail-01.d: Likewise.
* testsuite/gas/riscv/mabi-fail-01.l: Likewise.
* testsuite/gas/riscv/mabi-fail-02.d: Likewise.
* testsuite/gas/riscv/mabi-fail-02.l: Likewise.
* testsuite/gas/riscv/mabi-noabi-attr-01a.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-attr-01b.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-attr-02a.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-attr-02b.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-attr-03a.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-attr-03b.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-march-01.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-march-02.d: Likewise.
* testsuite/gas/riscv/mabi-noabi-march-03.d: Likewise.

18 files changed:
gas/ChangeLog
gas/config/tc-riscv.c
gas/testsuite/gas/riscv/mabi-attr-01.s [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-attr-02.s [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-attr-03.s [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-fail-01.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-fail-01.l [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-fail-02.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-fail-02.l [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-attr-01a.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-attr-01b.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-attr-02a.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-attr-02b.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-attr-03a.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-attr-03b.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-march-01.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-march-02.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mabi-noabi-march-03.d [new file with mode: 0644]

index a38b38963c0c2a044f33fed5ca0f570fe344af41..786d0881ca978dcc6a98052634b0174ea6256b41 100644 (file)
@@ -1,3 +1,35 @@
+2020-11-09  Nelson Chu  <nelson.chu@sifive.com>
+
+       * config/tc-riscv.c (explicit_mabi): New boolean to indicate if
+       the -mabi= option is explictly set.
+       (md_parse_option): Set explicit_mabi to TRUE if -mabi is set.
+       (riscv_set_abi_by_arch): New function.  If the -mabi option isn't
+       set, then we set the abi according to the architecture string.
+       Otherwise, check if there are conflicts between architecture
+       and abi setting.
+       (riscv_after_parse_args): Move the abi setting to md_assemble nad
+       riscv_elf_final_processing.
+       (md_assemble): Call the riscv_set_abi_by_arch when we set the
+       start_assemble to TRUE.
+       (riscv_elf_final_processing): Likewise, in case the file without
+       any instruction.
+       * testsuite/gas/riscv/mabi-attr-01.s: New testcase.
+       * testsuite/gas/riscv/mabi-attr-02.s: Likewise.
+       * testsuite/gas/riscv/mabi-attr-03.s: Likewise.
+       * testsuite/gas/riscv/mabi-fail-01.d: Likewise.
+       * testsuite/gas/riscv/mabi-fail-01.l: Likewise.
+       * testsuite/gas/riscv/mabi-fail-02.d: Likewise.
+       * testsuite/gas/riscv/mabi-fail-02.l: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-attr-01a.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-attr-01b.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-attr-02a.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-attr-02b.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-attr-03a.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-attr-03b.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-march-01.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-march-02.d: Likewise.
+       * testsuite/gas/riscv/mabi-noabi-march-03.d: Likewise.
+
 2020-11-04  Przemyslaw Wirkus  <przemyslaw.wirkus@arm.com>
 
        * testsuite/gas/aarch64/armv8-ras-1_1-invalid.d: New test.
index 7c228430adb9dfcaee737350a9ed3bae56f37cff..2340ff57e4cb9aa84c9fed743fe506121e270d08 100644 (file)
@@ -91,6 +91,14 @@ static enum riscv_priv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
 static unsigned xlen = 0; /* width of an x-register */
 static unsigned abi_xlen = 0; /* width of a pointer in the ABI */
 static bfd_boolean rve_abi = FALSE;
+enum float_abi {
+  FLOAT_ABI_DEFAULT = -1,
+  FLOAT_ABI_SOFT,
+  FLOAT_ABI_SINGLE,
+  FLOAT_ABI_DOUBLE,
+  FLOAT_ABI_QUAD
+};
+static enum float_abi float_abi = FLOAT_ABI_DEFAULT;
 
 #define LOAD_ADDRESS_INSN (abi_xlen == 64 ? "ld" : "lw")
 #define ADD32_INSN (xlen == 64 ? "addiw" : "addi")
@@ -311,6 +319,50 @@ riscv_set_arch (const char *s)
   riscv_parse_subset (&rps, s);
 }
 
+/* Indicate -mabi= option is explictly set.  */
+static bfd_boolean explicit_mabi = FALSE;
+
+static void
+riscv_set_abi (unsigned new_xlen, enum float_abi new_float_abi, bfd_boolean rve)
+{
+  abi_xlen = new_xlen;
+  float_abi = new_float_abi;
+  rve_abi = rve;
+}
+
+/* If the -mabi option isn't set, then we set the abi according to the arch
+   string.  Otherwise, check if there are conflicts between architecture
+   and abi setting.  */
+
+static void
+riscv_set_abi_by_arch (void)
+{
+  if (!explicit_mabi)
+    {
+      if (riscv_subset_supports ("q"))
+       riscv_set_abi (xlen, FLOAT_ABI_QUAD, FALSE);
+      else if (riscv_subset_supports ("d"))
+       riscv_set_abi (xlen, FLOAT_ABI_DOUBLE, FALSE);
+      else
+       riscv_set_abi (xlen, FLOAT_ABI_SOFT, FALSE);
+    }
+  else
+    {
+      gas_assert (abi_xlen != 0 && xlen != 0 && float_abi != FLOAT_ABI_DEFAULT);
+      if (abi_xlen > xlen)
+       as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen, xlen);
+      else if (abi_xlen < xlen)
+       as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen, xlen);
+    }
+
+  /* Update the EF_RISCV_FLOAT_ABI field of elf_flags.  */
+  elf_flags &= ~EF_RISCV_FLOAT_ABI;
+  elf_flags |= float_abi << 1;
+
+  if (rve_abi)
+    elf_flags |= EF_RISCV_RVE;
+}
+
 /* Handle of the OPCODE hash table.  */
 static htab_t op_hash = NULL;
 
@@ -2542,6 +2594,7 @@ md_assemble (char *str)
   if (!start_assemble)
     {
       start_assemble = TRUE;
+      riscv_set_abi_by_arch ();
 
       /* Set the default_priv_spec according to the priv attributes.  */
       if (!riscv_set_default_priv_spec (NULL))
@@ -2613,23 +2666,6 @@ struct option md_longopts[] =
 };
 size_t md_longopts_size = sizeof (md_longopts);
 
-enum float_abi {
-  FLOAT_ABI_DEFAULT = -1,
-  FLOAT_ABI_SOFT,
-  FLOAT_ABI_SINGLE,
-  FLOAT_ABI_DOUBLE,
-  FLOAT_ABI_QUAD
-};
-static enum float_abi float_abi = FLOAT_ABI_DEFAULT;
-
-static void
-riscv_set_abi (unsigned new_xlen, enum float_abi new_float_abi, bfd_boolean rve)
-{
-  abi_xlen = new_xlen;
-  float_abi = new_float_abi;
-  rve_abi = rve;
-}
-
 int
 md_parse_option (int c, const char *arg)
 {
@@ -2670,6 +2706,7 @@ md_parse_option (int c, const char *arg)
        riscv_set_abi (64, FLOAT_ABI_QUAD, FALSE);
       else
        return 0;
+      explicit_mabi = TRUE;
       break;
 
     case OPTION_RELAX:
@@ -2754,36 +2791,6 @@ riscv_after_parse_args (void)
   if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
     riscv_set_default_priv_spec (DEFAULT_RISCV_PRIV_SPEC);
 
-  /* Infer ABI from ISA if not specified on command line.  */
-  if (abi_xlen == 0)
-    abi_xlen = xlen;
-  else if (abi_xlen > xlen)
-    as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen, xlen);
-  else if (abi_xlen < xlen)
-    as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen, xlen);
-
-  if (float_abi == FLOAT_ABI_DEFAULT)
-    {
-      riscv_subset_t *subset;
-
-      /* Assume soft-float unless D extension is present.  */
-      float_abi = FLOAT_ABI_SOFT;
-
-      for (subset = riscv_subsets.head; subset != NULL; subset = subset->next)
-       {
-         if (strcasecmp (subset->name, "D") == 0)
-           float_abi = FLOAT_ABI_DOUBLE;
-         if (strcasecmp (subset->name, "Q") == 0)
-           float_abi = FLOAT_ABI_QUAD;
-       }
-    }
-
-  if (rve_abi)
-    elf_flags |= EF_RISCV_RVE;
-
-  /* Insert float_abi into the EF_RISCV_FLOAT_ABI field of elf_flags.  */
-  elf_flags |= float_abi * (EF_RISCV_FLOAT_ABI & ~(EF_RISCV_FLOAT_ABI << 1));
-
   /* If the CIE to be produced has not been overridden on the command line,
      then produce version 3 by default.  This allows us to use the full
      range of registers in a .cfi_return_column directive.  */
@@ -3514,6 +3521,7 @@ tc_riscv_regname_to_dw2regnum (char *regname)
 void
 riscv_elf_final_processing (void)
 {
+  riscv_set_abi_by_arch ();
   elf_elfheader (stdoutput)->e_flags |= elf_flags;
 }
 
diff --git a/gas/testsuite/gas/riscv/mabi-attr-01.s b/gas/testsuite/gas/riscv/mabi-attr-01.s
new file mode 100644 (file)
index 0000000..178f798
--- /dev/null
@@ -0,0 +1,6 @@
+       .attribute arch,"rv32i"
+       .option pic
+       .extern foo
+       .text
+foo:
+       la      a0, foo
diff --git a/gas/testsuite/gas/riscv/mabi-attr-02.s b/gas/testsuite/gas/riscv/mabi-attr-02.s
new file mode 100644 (file)
index 0000000..667d1a6
--- /dev/null
@@ -0,0 +1,6 @@
+       .attribute arch,"rv32ifd"
+       .option pic
+       .extern foo
+       .text
+foo:
+       la      a0, foo
diff --git a/gas/testsuite/gas/riscv/mabi-attr-03.s b/gas/testsuite/gas/riscv/mabi-attr-03.s
new file mode 100644 (file)
index 0000000..6be03e7
--- /dev/null
@@ -0,0 +1,6 @@
+       .attribute arch,"rv64ifdq"
+       .option pic
+       .extern foo
+       .text
+foo:
+       la      a0, foo
diff --git a/gas/testsuite/gas/riscv/mabi-fail-01.d b/gas/testsuite/gas/riscv/mabi-fail-01.d
new file mode 100644 (file)
index 0000000..7804934
--- /dev/null
@@ -0,0 +1,3 @@
+#as: -march-attr -mabi=lp64d
+#source: mabi-attr-01.s
+#error_output: mabi-fail-01.l
diff --git a/gas/testsuite/gas/riscv/mabi-fail-01.l b/gas/testsuite/gas/riscv/mabi-fail-01.l
new file mode 100644 (file)
index 0000000..65bf0ac
--- /dev/null
@@ -0,0 +1,2 @@
+.*Assembler messages:
+.*Error: can't have 64-bit ABI on 32-bit ISA
diff --git a/gas/testsuite/gas/riscv/mabi-fail-02.d b/gas/testsuite/gas/riscv/mabi-fail-02.d
new file mode 100644 (file)
index 0000000..2d6cfb0
--- /dev/null
@@ -0,0 +1,3 @@
+#as: -march-attr -mabi=ilp32
+#source: mabi-attr-03.s
+#error_output: mabi-fail-02.l
diff --git a/gas/testsuite/gas/riscv/mabi-fail-02.l b/gas/testsuite/gas/riscv/mabi-fail-02.l
new file mode 100644 (file)
index 0000000..8d45a07
--- /dev/null
@@ -0,0 +1,2 @@
+.*Assembler messages:
+.*Error: 32-bit ABI not yet supported on 64-bit ISA
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-attr-01a.d b/gas/testsuite/gas/riscv/mabi-noabi-attr-01a.d
new file mode 100644 (file)
index 0000000..11d3ed9
--- /dev/null
@@ -0,0 +1,10 @@
+#as: -march-attr -march=rv64ifd
+#readelf: -h
+#source: mabi-attr-01.s
+
+ELF Header:
+#...
+[      ]+Class:[       ]+ELF32
+#...
+[      ]+Flags:[       ]+0x0
+#...
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-attr-01b.d b/gas/testsuite/gas/riscv/mabi-noabi-attr-01b.d
new file mode 100644 (file)
index 0000000..b50ac3c
--- /dev/null
@@ -0,0 +1,12 @@
+#as: -march-attr -march=rv64ifd
+#objdump: -d
+#source: mabi-attr-01.s
+
+.*:[   ]+file format elf32.*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+#...
+[      ]+[0-9a-f]+:[   ]+00052503[     ]+lw[   ]+a0,0\(a0\) # .*
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-attr-02a.d b/gas/testsuite/gas/riscv/mabi-noabi-attr-02a.d
new file mode 100644 (file)
index 0000000..9668066
--- /dev/null
@@ -0,0 +1,10 @@
+#as: -march-attr -march=rv64i
+#readelf: -h
+#source: mabi-attr-02.s
+
+ELF Header:
+#...
+[      ]+Class:[       ]+ELF32
+#...
+[      ]+Flags:[       ]+0x4, double-float ABI
+#...
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-attr-02b.d b/gas/testsuite/gas/riscv/mabi-noabi-attr-02b.d
new file mode 100644 (file)
index 0000000..a69d0bc
--- /dev/null
@@ -0,0 +1,12 @@
+#as: -march-attr -march=rv64i
+#objdump: -d
+#source: mabi-attr-02.s
+
+.*:[   ]+file format elf32.*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+#...
+[      ]+[0-9a-f]+:[   ]+00052503[     ]+lw[   ]+a0,0\(a0\) # .*
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-attr-03a.d b/gas/testsuite/gas/riscv/mabi-noabi-attr-03a.d
new file mode 100644 (file)
index 0000000..4392b5c
--- /dev/null
@@ -0,0 +1,10 @@
+#as: -march-attr -march=rv32i
+#readelf: -h
+#source: mabi-attr-03.s
+
+ELF Header:
+#...
+[      ]+Class:[       ]+ELF64
+#...
+[      ]+Flags:[       ]+0x6, quad-float ABI
+#...
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-attr-03b.d b/gas/testsuite/gas/riscv/mabi-noabi-attr-03b.d
new file mode 100644 (file)
index 0000000..917ab8c
--- /dev/null
@@ -0,0 +1,12 @@
+#as: -march-attr -march=rv32i
+#objdump: -d
+#source: mabi-attr-03.s
+
+.*:[   ]+file format elf64.*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+#...
+[      ]+[0-9a-f]+:[   ]+00053503[     ]+ld[   ]+a0,0\(a0\) # .*
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-march-01.d b/gas/testsuite/gas/riscv/mabi-noabi-march-01.d
new file mode 100644 (file)
index 0000000..8ca280e
--- /dev/null
@@ -0,0 +1,10 @@
+#as: -march=rv32i
+#readelf: -h
+#source: empty.s
+
+ELF Header:
+#...
+[      ]+Class:[       ]+ELF32
+#...
+[      ]+Flags:[       ]+0x0
+#...
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-march-02.d b/gas/testsuite/gas/riscv/mabi-noabi-march-02.d
new file mode 100644 (file)
index 0000000..453fe7b
--- /dev/null
@@ -0,0 +1,10 @@
+#as: -march=rv32ifd
+#readelf: -h
+#source: empty.s
+
+ELF Header:
+#...
+[      ]+Class:[       ]+ELF32
+#...
+[      ]+Flags:[       ]+0x4, double-float ABI
+#...
diff --git a/gas/testsuite/gas/riscv/mabi-noabi-march-03.d b/gas/testsuite/gas/riscv/mabi-noabi-march-03.d
new file mode 100644 (file)
index 0000000..ab2ffc3
--- /dev/null
@@ -0,0 +1,10 @@
+#as: -march=rv64ifdq
+#readelf: -h
+#source: empty.s
+
+ELF Header:
+#...
+[      ]+Class:[       ]+ELF64
+#...
+[      ]+Flags:[       ]+0x6, quad-float ABI
+#...