@@ -251,6 +251,24 @@ config_target_isa:
((t.cpu_arch == CPU_NATIVE && constrained.arch) ?
t.isa.fpu : DEFAULT_ISA_EXT_FPU);
+ /* "loongarch64" is not really strictly defined: which FPU does it have?
+ So if -march=loongarch64 and -mfpu not explicitly provided, use the
+ minimal -mfpu setting suitable for the ABI. */
+ if (t.cpu_arch == CPU_LOONGARCH64 && !constrained.fpu)
+ switch (t.abi.base)
+ {
+ case ABI_BASE_LP64D:
+ t.isa.fpu = ISA_EXT_FPU64;
+ break;
+ case ABI_BASE_LP64F:
+ t.isa.fpu = ISA_EXT_FPU32;
+ break;
+ case ABI_BASE_LP64S:
+ t.isa.fpu = ISA_EXT_NOFPU;
+ break;
+ default:
+ gcc_unreachable ();
+ }
/* 4. ABI-ISA compatibility */
/* Note:
@@ -676,7 +676,7 @@ enum reg_class
point values. */
#define GP_RETURN (GP_REG_FIRST + 4)
-#define FP_RETURN ((TARGET_SOFT_FLOAT) ? GP_RETURN : (FP_REG_FIRST + 0))
+#define FP_RETURN ((TARGET_SOFT_FLOAT_ABI) ? GP_RETURN : (FP_REG_FIRST + 0))
#define MAX_ARGS_IN_REGISTERS 8
@@ -1154,6 +1154,6 @@ struct GTY (()) machine_function
/* The largest type that can be passed in floating-point registers. */
/* TODO: according to mabi. */
#define UNITS_PER_FP_ARG \
- (TARGET_HARD_FLOAT ? (TARGET_DOUBLE_FLOAT ? 8 : 4) : 0)
+ (TARGET_HARD_FLOAT_ABI ? (TARGET_DOUBLE_FLOAT_ABI ? 8 : 4) : 0)
#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN)
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=loongarch64 -O2" } */
+/* { dg-final { scan-assembler-not "frecip\\.d" } } */
+
+/* With the "default" -march=loongarch64, -mabi=lp64s implies -mfpu=0 so
+ we won't puzzle people. */
+
+double
+t (double x)
+{
+ return 1.0 / x;
+}
new file mode 100644
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=la464 -O2" } */
+/* { dg-final { scan-assembler "frecip\\.s" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.w" } } */
+/* { dg-final { scan-assembler "movfr2gr\\.s" } } */
+
+#include "flt-abi-isa-6.c"
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=loongarch64 -O2 -mfpu=64" } */
+/* { dg-final { scan-assembler "frecip\\.d" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.d" } } */
+/* { dg-final { scan-assembler "movfr2gr\\.d" } } */
+
+/* With -mabi=lp64s and -mfpu=64, we can use the FPU to calculate the
+ answer but we need to move the argument from a0 to a FPR, then move
+ the answer from a FPR back to a0. */
+
+#include "flt-abi-isa-1.c"
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=la464 -O2" } */
+/* { dg-final { scan-assembler "frecip\\.d" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.d" } } */
+/* { dg-final { scan-assembler "movfr2gr\\.d" } } */
+
+/* We know LA464 has a 64-bit FPU, so we can use it to calculate the
+ answer but we need to move the argument from a0 to a FPR, then move
+ the answer from a FPR back to a0. */
+
+#include "flt-abi-isa-1.c"
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64f -march=loongarch64 -O2 -mfpu=64" } */
+/* { dg-final { scan-assembler "frecip\\.d" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.d" } } */
+/* { dg-final { scan-assembler "movfr2gr\\.d" } } */
+
+/* With -mabi=lp64f and -mfpu=64, we can use the FPU to calculate the
+ answer but we need to move the argument from a0 to a FPR, then move
+ the answer from a FPR back to a0 as the LP64F ABI mandates passing
+ double values via GPR (like LP64S). */
+
+#include "flt-abi-isa-1.c"
new file mode 100644
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=la464 -O2 -mfpu=none" } */
+/* { dg-final { scan-assembler-not "frecip\\.d" } } */
+
+/* Explicitly disable FPU on LA464. */
+
+#include "flt-abi-isa-1.c"
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64f -march=loongarch64 -O2" } */
+/* { dg-final { scan-assembler "frecip\\.s" } } */
+/* { dg-final { scan-assembler-not "movgr2fr" } } */
+/* { dg-final { scan-assembler-not "movfr2gr" } } */
+
+float
+t (float x)
+{
+ return 1.0 / x;
+}
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=loongarch64 -O2" } */
+/* { dg-final { scan-assembler-not "frecip\\.s" } } */
+
+#include "flt-abi-isa-6.c"
new file mode 100644
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=loongarch64 -O2 -mfpu=32" } */
+/* { dg-final { scan-assembler "frecip\\.s" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.w" } } */
+/* { dg-final { scan-assembler "movfr2gr\\.s" } } */
+
+#include "flt-abi-isa-6.c"
new file mode 100644
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64s -march=loongarch64 -O2 -mfpu=64" } */
+/* { dg-final { scan-assembler "frecip\\.s" } } */
+/* { dg-final { scan-assembler "movgr2fr\\.w" } } */
+/* { dg-final { scan-assembler "movfr2gr\\.s" } } */
+
+#include "flt-abi-isa-6.c"