Projects
home:lf14:branches:Mega:23.09
gcc
_service:tar_scm:LoongArch-Add-fscaleb.-s-d-ins...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:LoongArch-Add-fscaleb.-s-d-instructions-as-ldexp-sf-.patch of Package gcc
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2