gcc/LoongArch-Add-fscaleb.-s-d-instructions-as-ldexp-sf-.patch
ticat_fp 7e7be47bfd LoongArch: Sync patch from gcc upstream
Signed-off-by: ticat_fp <fanpeng@loongson.cn>
2024-03-27 09:22:13 +08:00

156 lines
4.4 KiB
Diff
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From e3d69a3b7a4e00e8bba88b8b4abaa1c17bc083d5 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Tue, 8 Nov 2022 12:14:35 +0800
Subject: [PATCH 029/124] LoongArch: Add fscaleb.{s,d} instructions as
ldexp{sf,df}3
This allows optimizing __builtin_ldexp{,f} and __builtin_scalbn{,f} with
-fno-math-errno.
IMODE is added because we can't hard code SI for operand 2: fscaleb.d
instruction always take the high half of both source registers into
account. See my_ldexp_long in the test case.
gcc/ChangeLog:
* config/loongarch/loongarch.md (UNSPEC_FSCALEB): New unspec.
(type): Add fscaleb.
(IMODE): New mode attr.
(ldexp<mode>3): New instruction template.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/fscaleb.c: New test.
Signed-off-by: Peng Fan <fanpeng@loongson.cn>
Signed-off-by: ticat_fp <fanpeng@loongson.cn>
---
gcc/config/loongarch/loongarch.md | 26 ++++++++++-
gcc/testsuite/gcc.target/loongarch/fscaleb.c | 48 ++++++++++++++++++++
2 files changed, 72 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/loongarch/fscaleb.c
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index eb127c346..c141c9add 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -41,6 +41,7 @@
UNSPEC_FTINT
UNSPEC_FTINTRM
UNSPEC_FTINTRP
+ UNSPEC_FSCALEB
;; Override return address for exception handling.
UNSPEC_EH_RETURN
@@ -220,6 +221,7 @@
;; fcmp floating point compare
;; fcopysign floating point copysign
;; fcvt floating point convert
+;; fscaleb floating point scale
;; fsqrt floating point square root
;; frsqrt floating point reciprocal square root
;; multi multiword sequence (or user asm statements)
@@ -231,8 +233,8 @@
"unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
prefetch,prefetchx,condmove,mgtf,mftg,const,arith,logical,
shift,slt,signext,clz,trap,imul,idiv,move,
- fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcopysign,fcvt,fsqrt,
- frsqrt,accext,accmod,multi,atomic,syncloop,nop,ghost"
+ fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcopysign,fcvt,fscaleb,
+ fsqrt,frsqrt,accext,accmod,multi,atomic,syncloop,nop,ghost"
(cond [(eq_attr "jirl" "!unset") (const_string "call")
(eq_attr "got" "load") (const_string "load")
@@ -418,6 +420,10 @@
;; the controlling mode.
(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
+;; This attribute gives the integer mode that has the same size of a
+;; floating-point mode.
+(define_mode_attr IMODE [(SF "SI") (DF "DI")])
+
;; This code iterator allows signed and unsigned widening multiplications
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
@@ -1014,7 +1020,23 @@
"fcopysign.<fmt>\t%0,%1,%2"
[(set_attr "type" "fcopysign")
(set_attr "mode" "<UNITMODE>")])
+
+;;
+;; ....................
+;;
+;; FLOATING POINT SCALE
+;;
+;; ....................
+(define_insn "ldexp<mode>3"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:<IMODE> 2 "register_operand" "f")]
+ UNSPEC_FSCALEB))]
+ "TARGET_HARD_FLOAT"
+ "fscaleb.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fscaleb")
+ (set_attr "mode" "<UNITMODE>")])
;;
;; ...................
diff --git a/gcc/testsuite/gcc.target/loongarch/fscaleb.c b/gcc/testsuite/gcc.target/loongarch/fscaleb.c
new file mode 100644
index 000000000..f18470fbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/fscaleb.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno" } */
+/* { dg-final { scan-assembler-times "fscaleb\\.s" 3 } } */
+/* { dg-final { scan-assembler-times "fscaleb\\.d" 4 } } */
+/* { dg-final { scan-assembler-times "slli\\.w" 1 } } */
+
+double
+my_scalbln (double a, long b)
+{
+ return __builtin_scalbln (a, b);
+}
+
+double
+my_scalbn (double a, int b)
+{
+ return __builtin_scalbn (a, b);
+}
+
+double
+my_ldexp (double a, int b)
+{
+ return __builtin_ldexp (a, b);
+}
+
+float
+my_scalblnf (float a, long b)
+{
+ return __builtin_scalblnf (a, b);
+}
+
+float
+my_scalbnf (float a, int b)
+{
+ return __builtin_scalbnf (a, b);
+}
+
+float
+my_ldexpf (float a, int b)
+{
+ return __builtin_ldexpf (a, b);
+}
+
+/* b must be sign-extended */
+double
+my_ldexp_long (double a, long b)
+{
+ return __builtin_ldexp (a, b);
+}
--
2.33.0