[RFC] RISC-V: Add support for RV64E/lp64e

Message ID 20220713050953.7812-1-palmer@rivosinc.com
State Deferred, archived
Headers
Series [RFC] RISC-V: Add support for RV64E/lp64e |

Commit Message

Palmer Dabbelt July 13, 2022, 5:09 a.m. UTC
  gcc/ChangeLog

	* config.gcc (riscv): Accept rv64e and lp64e.
	* config/riscv/arch-canonicalize: Likewise.
	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Likewise.
	* config/riscv/riscv-opts.h (riscv_abi_type): Likewise.
	* config/riscv/riscv.cc (riscv_option_override): Likewise
	* config/riscv/riscv.h (UNITS_PER_FP_ARG): Likewise.
	(STACK_BOUNDARY): Likewise.
	(ABI_STACK_BOUNDARY): Likewise.
	(MAX_ARGS_IN_REGISTERS): Likewise.
	(ABI_SPEC): Likewise.
	* config/riscv/riscv.opt (abi_type): Likewise.
	* doc/invoke.texi (RISC-V) <-mabi>: Likewise.
---
This is all still in flight, but evidently RV64E exists.  I haven't
tested this at all, but given that we don't even have the ABI docs lined
up yet it's likely a bit away from being mergable.
---
 gcc/config.gcc                     |  8 +++++---
 gcc/config/riscv/arch-canonicalize |  2 +-
 gcc/config/riscv/riscv-c.cc        |  1 +
 gcc/config/riscv/riscv-opts.h      |  1 +
 gcc/config/riscv/riscv.cc          |  6 ++++--
 gcc/config/riscv/riscv.h           | 11 +++++++----
 gcc/config/riscv/riscv.opt         |  3 +++
 gcc/doc/invoke.texi                |  5 +++--
 8 files changed, 25 insertions(+), 12 deletions(-)
  

Comments

Palmer Dabbelt July 14, 2022, 6:06 p.m. UTC | #1
On Tue, 12 Jul 2022 22:09:53 PDT (-0700), Palmer Dabbelt wrote:
> gcc/ChangeLog
>
> 	* config.gcc (riscv): Accept rv64e and lp64e.
> 	* config/riscv/arch-canonicalize: Likewise.
> 	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Likewise.
> 	* config/riscv/riscv-opts.h (riscv_abi_type): Likewise.
> 	* config/riscv/riscv.cc (riscv_option_override): Likewise
> 	* config/riscv/riscv.h (UNITS_PER_FP_ARG): Likewise.
> 	(STACK_BOUNDARY): Likewise.
> 	(ABI_STACK_BOUNDARY): Likewise.
> 	(MAX_ARGS_IN_REGISTERS): Likewise.
> 	(ABI_SPEC): Likewise.
> 	* config/riscv/riscv.opt (abi_type): Likewise.
> 	* doc/invoke.texi (RISC-V) <-mabi>: Likewise.
> ---
> This is all still in flight, but evidently RV64E exists.  I haven't
> tested this at all, but given that we don't even have the ABI docs lined
> up yet it's likely a bit away from being mergable.
> ---
>  gcc/config.gcc                     |  8 +++++---
>  gcc/config/riscv/arch-canonicalize |  2 +-
>  gcc/config/riscv/riscv-c.cc        |  1 +
>  gcc/config/riscv/riscv-opts.h      |  1 +
>  gcc/config/riscv/riscv.cc          |  6 ++++--
>  gcc/config/riscv/riscv.h           | 11 +++++++----
>  gcc/config/riscv/riscv.opt         |  3 +++
>  gcc/doc/invoke.texi                |  5 +++--
>  8 files changed, 25 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 4e3b15bb5e9..4617ecb8d9b 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -4637,7 +4637,7 @@ case "${target}" in
>
>  		# Infer arch from --with-arch, --target, and --with-abi.
>  		case "${with_arch}" in
> -		rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
> +		rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g*)
>  			# OK.
>  			;;
>  		"")
> @@ -4645,12 +4645,13 @@ case "${target}" in
>  			case "${with_abi}" in
>  			ilp32e) with_arch="rv32e" ;;
>  			ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
> +			lp64e) with_arch="rv64e" ;;
>  			lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
>  			*) with_arch="rv${xlen}gc" ;;
>  			esac
>  			;;
>  		*)
> -			echo "--with-arch=${with_arch} is not supported.  The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
> +			echo "--with-arch=${with_arch} is not supported.  The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, or rv64g." 1>&2
>  			exit 1
>  			;;
>  		esac
> @@ -4672,6 +4673,7 @@ case "${target}" in
>  			rv32e*) with_abi=ilp32e ;;
>  			rv32*) with_abi=ilp32 ;;
>  			rv64*d* | rv64g*) with_abi=lp64d ;;
> +			rv64e*) with_abi=lp64e ;;
>  			rv64*) with_abi=lp64 ;;
>  			esac
>  			;;
> @@ -4687,7 +4689,7 @@ case "${target}" in
>  		ilp32,rv32* | ilp32e,rv32e* \
>  		| ilp32f,rv32*f* | ilp32f,rv32g* \
>  		| ilp32d,rv32*d* | ilp32d,rv32g* \
> -		| lp64,rv64* \
> +		| lp64,rv64* | lp64e,rv64e* \
>  		| lp64f,rv64*f* | lp64f,rv64g* \
>  		| lp64d,rv64*d* | lp64d,rv64g*)
>  			;;
> diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
> index fd7651ac491..8db3e88ddd7 100755
> --- a/gcc/config/riscv/arch-canonicalize
> +++ b/gcc/config/riscv/arch-canonicalize
> @@ -71,7 +71,7 @@ def arch_canonicalize(arch, isa_spec):
>    new_arch = ""
>    extra_long_ext = []
>    std_exts = []
> -  if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
> +  if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64e', 'rv64i', 'rv64g']:
>      new_arch = arch[:5].replace("g", "i")
>      if arch[:5] in ['rv32g', 'rv64g']:
>        std_exts = ['m', 'a', 'f', 'd']
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index eb7ef09297e..4614dc6b6d9 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -67,6 +67,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
>    switch (riscv_abi)
>      {
>      case ABI_ILP32E:
> +    case ABI_LP64E:
>        builtin_define ("__riscv_abi_rve");
>        gcc_fallthrough ();
>
> diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
> index 1e153b3a6e7..70fe708cbae 100644
> --- a/gcc/config/riscv/riscv-opts.h
> +++ b/gcc/config/riscv/riscv-opts.h
> @@ -27,6 +27,7 @@ enum riscv_abi_type {
>    ABI_ILP32F,
>    ABI_ILP32D,
>    ABI_LP64,
> +  ABI_LP64E,
>    ABI_LP64F,
>    ABI_LP64D
>  };
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 2e83ca07394..51b7195c17b 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -5047,8 +5047,10 @@ riscv_option_override (void)
>      error ("requested ABI requires %<-march%> to subsume the %qc extension",
>  	   UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
>
> -  if (TARGET_RVE && riscv_abi != ABI_ILP32E)
> +  if (riscv_xlen == 32 && TARGET_RVE && riscv_abi != ABI_ILP32E)
>      error ("rv32e requires ilp32e ABI");
> +  if (riscv_xlen == 64 && TARGET_RVE && riscv_abi != ABI_LP64E)
> +    error ("rv64e requires lp64e ABI");
>
>    /* We do not yet support ILP32 on RV64.  */
>    if (BITS_PER_WORD != POINTER_SIZE)
> @@ -5140,7 +5142,7 @@ riscv_conditional_register_usage (void)
>  	fixed_regs[r] = 1;
>      }
>
> -  if (riscv_abi == ABI_ILP32E)
> +  if (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E)
>      {
>        for (int r = 16; r <= 31; r++)
>  	call_used_regs[r] = 1;
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index 6f7f4d3fbdc..40d23208975 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -159,7 +159,7 @@ ASM_MISA_SPEC
>  /* The largest type that can be passed in floating-point registers.  */
>  #define UNITS_PER_FP_ARG						\
>    ((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E			\
> -    || riscv_abi == ABI_LP64)						\
> +    || riscv_abi == ABI_LP64 || riscv_abi == ABI_LP64E)			\
>     ? 0 									\
>     : ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))
>
> @@ -182,10 +182,11 @@ ASM_MISA_SPEC
>
>  /* The smallest supported stack boundary the calling convention supports.  */
>  #define STACK_BOUNDARY \
> -  (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 2 * BITS_PER_WORD)
> +  ((riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E ? 1 : 2) * BITS_PER_WORD)
>
>  /* The ABI stack alignment.  */
> -#define ABI_STACK_BOUNDARY (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 128)
> +#define ABI_STACK_BOUNDARY \
> +  (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E ? BITS_PER_WORD : 128)
>
>  /* There is no point aligning anything to a rounder boundary than this.  */
>  #define BIGGEST_ALIGNMENT 128
> @@ -573,7 +574,8 @@ enum reg_class
>  #define GP_RETURN GP_ARG_FIRST
>  #define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)
>
> -#define MAX_ARGS_IN_REGISTERS (riscv_abi == ABI_ILP32E ? 6 : 8)
> +#define MAX_ARGS_IN_REGISTERS \
> +  (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E ? 6 : 8)
>
>  /* Symbolic macros for the first/last argument registers.  */
>
> @@ -966,6 +968,7 @@ extern unsigned riscv_stack_boundary;
>    "%{mabi=ilp32e:ilp32e}" \
>    "%{mabi=ilp32f:ilp32f}" \
>    "%{mabi=ilp32d:ilp32d}" \
> +  "%{mabi=lp64e:lp64e}" \
>    "%{mabi=lp64:lp64}" \
>    "%{mabi=lp64f:lp64f}" \
>    "%{mabi=lp64d:lp64d}" \
> diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
> index 9e9fe6d8ccd..94061ec9664 100644
> --- a/gcc/config/riscv/riscv.opt
> +++ b/gcc/config/riscv/riscv.opt
> @@ -64,6 +64,9 @@ Enum(abi_type) String(ilp32d) Value(ABI_ILP32D)
>  EnumValue
>  Enum(abi_type) String(lp64) Value(ABI_LP64)
>
> +EnumValue
> +Enum(abi_type) String(lp64e) Value(ABI_LP64E)
> +
>  EnumValue
>  Enum(abi_type) String(lp64f) Value(ABI_LP64F)
>
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index d5ff1018372..a43e3ec50de 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -28215,8 +28215,9 @@ conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
>  implement on some ISAs: for example, @samp{-march=rv32if -mabi=ilp32d} is
>  invalid because the ABI requires 64-bit values be passed in F registers, but F
>  registers are only 32 bits wide.  There is also the @samp{ilp32e} ABI that can
> -only be used with the @samp{rv32e} architecture.  This ABI is not well
> -specified at present, and is subject to change.
> +only be used with the @samp{rv32e} architecture and the @samp{lp64e} ABI that
> +can only be used with the @samp{rv64e} architecture.  These two ABIs are not
> +well specified at present, and are subject to change.
>
>  @item -mfdiv
>  @itemx -mno-fdiv

We'll also need something like

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index eb7ef09297e..5b8c0ea07ea 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -41,8 +41,10 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
   if (TARGET_RVC)
     builtin_define ("__riscv_compressed");
 
-  if (TARGET_RVE)
+  if (TARGET_RVE && UNITS_PER_WORD == 4)
     builtin_define ("__riscv_32e");
+  else if (TARGET_RVE && UNITS_PER_WORD == 8)
+    builtin_define ("__riscv_64e");
 
   if (TARGET_ATOMIC)
     builtin_define ("__riscv_atomic");
  

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4e3b15bb5e9..4617ecb8d9b 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4637,7 +4637,7 @@  case "${target}" in
 
 		# Infer arch from --with-arch, --target, and --with-abi.
 		case "${with_arch}" in
-		rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
+		rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g*)
 			# OK.
 			;;
 		"")
@@ -4645,12 +4645,13 @@  case "${target}" in
 			case "${with_abi}" in
 			ilp32e) with_arch="rv32e" ;;
 			ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
+			lp64e) with_arch="rv64e" ;;
 			lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
 			*) with_arch="rv${xlen}gc" ;;
 			esac
 			;;
 		*)
-			echo "--with-arch=${with_arch} is not supported.  The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
+			echo "--with-arch=${with_arch} is not supported.  The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, or rv64g." 1>&2
 			exit 1
 			;;
 		esac
@@ -4672,6 +4673,7 @@  case "${target}" in
 			rv32e*) with_abi=ilp32e ;;
 			rv32*) with_abi=ilp32 ;;
 			rv64*d* | rv64g*) with_abi=lp64d ;;
+			rv64e*) with_abi=lp64e ;;
 			rv64*) with_abi=lp64 ;;
 			esac
 			;;
@@ -4687,7 +4689,7 @@  case "${target}" in
 		ilp32,rv32* | ilp32e,rv32e* \
 		| ilp32f,rv32*f* | ilp32f,rv32g* \
 		| ilp32d,rv32*d* | ilp32d,rv32g* \
-		| lp64,rv64* \
+		| lp64,rv64* | lp64e,rv64e* \
 		| lp64f,rv64*f* | lp64f,rv64g* \
 		| lp64d,rv64*d* | lp64d,rv64g*)
 			;;
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
index fd7651ac491..8db3e88ddd7 100755
--- a/gcc/config/riscv/arch-canonicalize
+++ b/gcc/config/riscv/arch-canonicalize
@@ -71,7 +71,7 @@  def arch_canonicalize(arch, isa_spec):
   new_arch = ""
   extra_long_ext = []
   std_exts = []
-  if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
+  if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64e', 'rv64i', 'rv64g']:
     new_arch = arch[:5].replace("g", "i")
     if arch[:5] in ['rv32g', 'rv64g']:
       std_exts = ['m', 'a', 'f', 'd']
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index eb7ef09297e..4614dc6b6d9 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -67,6 +67,7 @@  riscv_cpu_cpp_builtins (cpp_reader *pfile)
   switch (riscv_abi)
     {
     case ABI_ILP32E:
+    case ABI_LP64E:
       builtin_define ("__riscv_abi_rve");
       gcc_fallthrough ();
 
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 1e153b3a6e7..70fe708cbae 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -27,6 +27,7 @@  enum riscv_abi_type {
   ABI_ILP32F,
   ABI_ILP32D,
   ABI_LP64,
+  ABI_LP64E,
   ABI_LP64F,
   ABI_LP64D
 };
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 2e83ca07394..51b7195c17b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5047,8 +5047,10 @@  riscv_option_override (void)
     error ("requested ABI requires %<-march%> to subsume the %qc extension",
 	   UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
 
-  if (TARGET_RVE && riscv_abi != ABI_ILP32E)
+  if (riscv_xlen == 32 && TARGET_RVE && riscv_abi != ABI_ILP32E)
     error ("rv32e requires ilp32e ABI");
+  if (riscv_xlen == 64 && TARGET_RVE && riscv_abi != ABI_LP64E)
+    error ("rv64e requires lp64e ABI");
 
   /* We do not yet support ILP32 on RV64.  */
   if (BITS_PER_WORD != POINTER_SIZE)
@@ -5140,7 +5142,7 @@  riscv_conditional_register_usage (void)
 	fixed_regs[r] = 1;
     }
 
-  if (riscv_abi == ABI_ILP32E)
+  if (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E)
     {
       for (int r = 16; r <= 31; r++)
 	call_used_regs[r] = 1;
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 6f7f4d3fbdc..40d23208975 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -159,7 +159,7 @@  ASM_MISA_SPEC
 /* The largest type that can be passed in floating-point registers.  */
 #define UNITS_PER_FP_ARG						\
   ((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E			\
-    || riscv_abi == ABI_LP64)						\
+    || riscv_abi == ABI_LP64 || riscv_abi == ABI_LP64E)			\
    ? 0 									\
    : ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))
 
@@ -182,10 +182,11 @@  ASM_MISA_SPEC
 
 /* The smallest supported stack boundary the calling convention supports.  */
 #define STACK_BOUNDARY \
-  (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 2 * BITS_PER_WORD)
+  ((riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E ? 1 : 2) * BITS_PER_WORD)
 
 /* The ABI stack alignment.  */
-#define ABI_STACK_BOUNDARY (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 128)
+#define ABI_STACK_BOUNDARY \
+  (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E ? BITS_PER_WORD : 128)
 
 /* There is no point aligning anything to a rounder boundary than this.  */
 #define BIGGEST_ALIGNMENT 128
@@ -573,7 +574,8 @@  enum reg_class
 #define GP_RETURN GP_ARG_FIRST
 #define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)
 
-#define MAX_ARGS_IN_REGISTERS (riscv_abi == ABI_ILP32E ? 6 : 8)
+#define MAX_ARGS_IN_REGISTERS \
+  (riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E ? 6 : 8)
 
 /* Symbolic macros for the first/last argument registers.  */
 
@@ -966,6 +968,7 @@  extern unsigned riscv_stack_boundary;
   "%{mabi=ilp32e:ilp32e}" \
   "%{mabi=ilp32f:ilp32f}" \
   "%{mabi=ilp32d:ilp32d}" \
+  "%{mabi=lp64e:lp64e}" \
   "%{mabi=lp64:lp64}" \
   "%{mabi=lp64f:lp64f}" \
   "%{mabi=lp64d:lp64d}" \
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 9e9fe6d8ccd..94061ec9664 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -64,6 +64,9 @@  Enum(abi_type) String(ilp32d) Value(ABI_ILP32D)
 EnumValue
 Enum(abi_type) String(lp64) Value(ABI_LP64)
 
+EnumValue
+Enum(abi_type) String(lp64e) Value(ABI_LP64E)
+
 EnumValue
 Enum(abi_type) String(lp64f) Value(ABI_LP64F)
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d5ff1018372..a43e3ec50de 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -28215,8 +28215,9 @@  conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
 implement on some ISAs: for example, @samp{-march=rv32if -mabi=ilp32d} is
 invalid because the ABI requires 64-bit values be passed in F registers, but F
 registers are only 32 bits wide.  There is also the @samp{ilp32e} ABI that can
-only be used with the @samp{rv32e} architecture.  This ABI is not well
-specified at present, and is subject to change.
+only be used with the @samp{rv32e} architecture and the @samp{lp64e} ABI that
+can only be used with the @samp{rv64e} architecture.  These two ABIs are not
+well specified at present, and are subject to change.
 
 @item -mfdiv
 @itemx -mno-fdiv