From patchwork Fri Nov 17 10:00:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Yujie X-Patchwork-Id: 1865037 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SWsrV4p1Sz1yRM for ; Fri, 17 Nov 2023 21:02:02 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BE7B73858422 for ; Fri, 17 Nov 2023 10:01:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:470:142:3::10]) by sourceware.org (Postfix) with ESMTPS id C6CAE3858438 for ; Fri, 17 Nov 2023 10:00:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C6CAE3858438 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C6CAE3858438 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:470:142:3::10 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700215235; cv=none; b=oYIg9xgBC1ciegiUWduxfaOo+BRyf911lGswpwGZol7lG83aD3O/IDEaFp+/Evj7J362PyjiM5ubHQeW6jZosxFN3lEE5NOAGdGZjVdVIPoJqEr12KnBQb/9yrKYQZKu6OkShqfAL0qybiPm8WVuQvAjRhk+VTyN+5LwVBN1iJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700215235; c=relaxed/simple; bh=mmCYPamLJLBPWp+fYaneGxh2Q/QliA0cI2+zn5A8VJw=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=N8+jHScTg70MuvZ770HElb18IgKivXMT+BmYhyIrpqr4WrBg1GIzYVApmKJpkbqTbwGsZrehg60xOZxb2Rf/zW/5dg+mNCHycEQ/6G+HZe26NrrwEguVbA8tMVcGG3gS1Kpp4h37fM6Tme6buZtppmMhTs2Zzg0/deHIpCpNca4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r3veG-0001jD-Si for gcc-patches@gcc.gnu.org; Fri, 17 Nov 2023 05:00:32 -0500 Received: from loongson.cn (unknown [114.243.104.185]) by gateway (Coremail) with SMTP id _____8Cx7+u5OVdlEsc6AA--.49412S3; Fri, 17 Nov 2023 18:00:25 +0800 (CST) Received: from localhost.localdomain (unknown [114.243.104.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxPC+yOVdluDlFAA--.7540S5; Fri, 17 Nov 2023 18:00:22 +0800 (CST) From: Yang Yujie To: gcc-patches@gcc.gnu.org Cc: ibuclaw@gdcproject.org, chenglulu@loongson.cn, xuchenghua@loongson.cn, Yang Yujie Subject: [PATCH 3/3] libphobos: Adjust LoongArch definitons. Date: Fri, 17 Nov 2023 18:00:07 +0800 Message-ID: <20231117100007.2566030-4-yangyujie@loongson.cn> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231117100007.2566030-1-yangyujie@loongson.cn> References: <20231117100007.2566030-1-yangyujie@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxPC+yOVdluDlFAA--.7540S5 X-CM-SenderInfo: 51dqw5pxmlvqxorr0wxvrqhubq/1tbiAQASAGVWzaoJjwAAsB X-Coremail-Antispam: 1Uk129KBj9fXoW3tF15Wr4DCF1Utw1kZF45XFc_yoW8XFyUKo W8GrW5ur4xG3Z5ZFyqkw1Du347Xr109F9xKry5tF4DJa15Crn5Jw45Za15WaySyF9xGrs7 Xa45uFyq9F1Fyr95l-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY17kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUAVWUtwAv7VC2z280 aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxU7MmhUUUUU Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangyujie@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, SPF_FAIL, SPF_HELO_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Upstream commits: https://github.com/dlang/phobos/commit/870eb5d5d6972b12dd4b69d48ef049abee811b6b https://github.com/dlang/dmd/commit/9cb5517290fac5d28f52c11c254115c0f1086b69 libphobos/ChangeLog: * libdruntime/core/stdc/fenv.d: Fix LongArch FP rounding mode constants. * libdruntime/core/vararg.d: Add LoongArch64 support. * libdruntime/core/stdc/stdarg.d: Same. * libdruntime/core/sys/linux/sys/auxv.d: Same. * libdruntime/core/sys/elf/package.d: Define EM_LOONGARCH (258). * libdruntime/core/sys/linux/sys/mman.d: Reference corresponding glibc header in comment. * libdruntime/core/thread/fiber.d: Save $r21 in fiber contexts. * src/std/math/hardware.d: Implement FP control. * libdruntime/config/loongarch/switchcontext.S: New file. --- .../config/loongarch/switchcontext.S | 133 ++++++++++++++++++ libphobos/libdruntime/core/stdc/fenv.d | 8 +- libphobos/libdruntime/core/stdc/stdarg.d | 6 + libphobos/libdruntime/core/sys/elf/package.d | 2 + .../libdruntime/core/sys/linux/sys/auxv.d | 17 +++ .../libdruntime/core/sys/linux/sys/mman.d | 1 + libphobos/libdruntime/core/thread/fiber.d | 55 +++++--- libphobos/libdruntime/core/vararg.d | 7 + libphobos/src/std/math/hardware.d | 77 ++++++++++ 9 files changed, 279 insertions(+), 27 deletions(-) create mode 100644 libphobos/libdruntime/config/loongarch/switchcontext.S diff --git a/libphobos/libdruntime/config/loongarch/switchcontext.S b/libphobos/libdruntime/config/loongarch/switchcontext.S new file mode 100644 index 00000000000..edfb9b67e8f --- /dev/null +++ b/libphobos/libdruntime/config/loongarch/switchcontext.S @@ -0,0 +1,133 @@ +/* LoongArch support code for fibers and multithreading. + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "../common/threadasm.S" + +/** + * Performs a context switch. + * + * $a0 - void** - ptr to old stack pointer + * $a1 - void* - new stack pointer + * + */ + +#if defined(__loongarch_lp64) +# define GPR_L ld.d +# define GPR_S st.d +# define SZ_GPR 8 +# define ADDSP(si) addi.d $sp, $sp, si +#elif defined(__loongarch64_ilp32) +# define GPR_L ld.w +# define GPR_S st.w +# define SZ_GPR 4 +# define ADDSP(si) addi.w $sp, $sp, si +#else +# error Unsupported GPR size (must be 64-bit or 32-bit). +#endif + +#if defined(__loongarch_double_float) +# define FPR_L fld.d +# define FPR_S fst.d +# define SZ_FPR 8 +#elif defined(__loongarch_single_float) +# define FPR_L fld.s +# define FPR_S fst.s +# define SZ_FPR 4 +#else +# define SZ_FPR 0 +#endif + + .text + .align 2 + .global fiber_switchContext + .type fiber_switchContext, @function +fiber_switchContext: + .cfi_startproc + ADDSP(-11 * SZ_GPR) + + // fp regs and return address are stored below the stack + // because we don't want the GC to scan them. + + // return address (r1) + GPR_S $r1, $sp, -SZ_GPR + +#if SZ_FPR != 0 + // callee-saved scratch FPRs (f24-f31) + FPR_S $f24, $sp, -SZ_GPR-1*SZ_FPR + FPR_S $f25, $sp, -SZ_GPR-2*SZ_FPR + FPR_S $f26, $sp, -SZ_GPR-3*SZ_FPR + FPR_S $f27, $sp, -SZ_GPR-4*SZ_FPR + FPR_S $f28, $sp, -SZ_GPR-5*SZ_FPR + FPR_S $f29, $sp, -SZ_GPR-6*SZ_FPR + FPR_S $f30, $sp, -SZ_GPR-7*SZ_FPR + FPR_S $f31, $sp, -SZ_GPR-8*SZ_FPR +#endif + + // callee-saved GPRs (r21, fp (r22), r23-r31) + GPR_S $r21, $sp, 0*SZ_GPR + GPR_S $fp, $sp, 1*SZ_GPR + GPR_S $s0, $sp, 2*SZ_GPR + GPR_S $s1, $sp, 3*SZ_GPR + GPR_S $s2, $sp, 4*SZ_GPR + GPR_S $s3, $sp, 5*SZ_GPR + GPR_S $s4, $sp, 6*SZ_GPR + GPR_S $s5, $sp, 7*SZ_GPR + GPR_S $s6, $sp, 8*SZ_GPR + GPR_S $s7, $sp, 9*SZ_GPR + GPR_S $s8, $sp, 10*SZ_GPR + + // swap stack pointer + GPR_S $sp, $a0, 0 + move $sp, $a1 + + GPR_L $r1, $sp, -SZ_GPR + +#if SZ_FPR != 0 + FPR_L $f24, $sp, -SZ_GPR-1*SZ_FPR + FPR_L $f25, $sp, -SZ_GPR-2*SZ_FPR + FPR_L $f26, $sp, -SZ_GPR-3*SZ_FPR + FPR_L $f27, $sp, -SZ_GPR-4*SZ_FPR + FPR_L $f28, $sp, -SZ_GPR-5*SZ_FPR + FPR_L $f29, $sp, -SZ_GPR-6*SZ_FPR + FPR_L $f30, $sp, -SZ_GPR-7*SZ_FPR + FPR_L $f31, $sp, -SZ_GPR-8*SZ_FPR +#endif + + GPR_L $r21, $sp, 0*SZ_GPR + GPR_L $fp, $sp, 1*SZ_GPR + GPR_L $s0, $sp, 2*SZ_GPR + GPR_L $s1, $sp, 3*SZ_GPR + GPR_L $s2, $sp, 4*SZ_GPR + GPR_L $s3, $sp, 5*SZ_GPR + GPR_L $s4, $sp, 6*SZ_GPR + GPR_L $s5, $sp, 7*SZ_GPR + GPR_L $s6, $sp, 8*SZ_GPR + GPR_L $s7, $sp, 9*SZ_GPR + GPR_L $s8, $sp, 10*SZ_GPR + + ADDSP(11 * SZ_GPR) + + jr $r1 // return + .cfi_endproc + .size fiber_switchContext,.-fiber_switchContext diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d index 288f9c25dc6..0051ecdb7c9 100644 --- a/libphobos/libdruntime/core/stdc/fenv.d +++ b/libphobos/libdruntime/core/stdc/fenv.d @@ -797,7 +797,7 @@ else } else version (LoongArch64) { - // Define bits representing exceptions in the FPSR status word. + // Define bits representing exceptions in the Flags field in FCSR{0,2}. enum { FE_INEXACT = 0x010000, /// @@ -808,13 +808,13 @@ else FE_ALL_EXCEPT = 0x1f0000, /// } - // Define bits representing rounding modes in the FPCR Rmode field. + // Define bits representing rounding modes in the RM field in FCSR{0,3}. enum { FE_TONEAREST = 0x000, /// FE_TOWARDZERO = 0x100, /// - FE_DOWNWARD = 0x200, /// - FE_UPWARD = 0x300, /// + FE_UPWARD = 0x200, /// + FE_DOWNWARD = 0x300, /// } } else diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d index 5b79813ae1b..0ba1ebe34e3 100644 --- a/libphobos/libdruntime/core/stdc/stdarg.d +++ b/libphobos/libdruntime/core/stdc/stdarg.d @@ -257,6 +257,12 @@ T va_arg(T)(ref va_list ap) ap += T.sizeof.alignUp; return *p; } + else version (LoongArch64) + { + auto p = cast(T*) ap; + ap += T.sizeof.alignUp; + return *p; + } else version (MIPS_Any) { auto p = cast(T*) ap; diff --git a/libphobos/libdruntime/core/sys/elf/package.d b/libphobos/libdruntime/core/sys/elf/package.d index b120ee58f69..60e05d97036 100644 --- a/libphobos/libdruntime/core/sys/elf/package.d +++ b/libphobos/libdruntime/core/sys/elf/package.d @@ -339,6 +339,8 @@ enum EM_CSKY = 252; enum EM_NUM = 253; +enum EM_LOONGARCH = 258; + enum EM_ALPHA = 0x9026; enum EV_NONE = 0; diff --git a/libphobos/libdruntime/core/sys/linux/sys/auxv.d b/libphobos/libdruntime/core/sys/linux/sys/auxv.d index 5f098e98e02..1099fae497f 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/auxv.d +++ b/libphobos/libdruntime/core/sys/linux/sys/auxv.d @@ -13,6 +13,7 @@ extern (C): version (MIPS32) version = MIPS_Any; version (MIPS64) version = MIPS_Any; +version (LoongArch64) version = LoongArch_Any; version (PPC) version = PPC_Any; version (PPC64) version = PPC_Any; version (S390) version = IBMZ_Any; @@ -156,3 +157,19 @@ else version (IBMZ_Any) enum HWCAP_S390_TE = 1024; enum HWCAP_S390_VX = 2048; } +else version (LoongArch_Any) +{ + enum HWCAP_LOONGARCH_CPUCFG = 0x00000001; + enum HWCAP_LOONGARCH_LAM = 0x00000002; + enum HWCAP_LOONGARCH_UAL = 0x00000004; + enum HWCAP_LOONGARCH_FPU = 0x00000008; + enum HWCAP_LOONGARCH_LSX = 0x00000010; + enum HWCAP_LOONGARCH_LASX = 0x00000020; + enum HWCAP_LOONGARCH_CRC32 = 0x00000040; + enum HWCAP_LOONGARCH_COMPLEX = 0x00000080; + enum HWCAP_LOONGARCH_CRYPTO = 0x00000100; + enum HWCAP_LOONGARCH_LVZ = 0x00000200; + enum HWCAP_LOONGARCH_LBT_X86 = 0x00000400; + enum HWCAP_LOONGARCH_LBT_ARM = 0x00000800; + enum HWCAP_LOONGARCH_LBT_MIPS = 0x00001000; +} diff --git a/libphobos/libdruntime/core/sys/linux/sys/mman.d b/libphobos/libdruntime/core/sys/linux/sys/mman.d index 7ed78ef6436..e4765af1490 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/mman.d +++ b/libphobos/libdruntime/core/sys/linux/sys/mman.d @@ -432,6 +432,7 @@ else version (MIPS_Any) MAP_HUGETLB = 0x80000, } } +// http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/bits/mman-map-flags-generic.h else version (LoongArch64) { static if (_DEFAULT_SOURCE) enum diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d index 65878bc1c66..e0838bcffef 100644 --- a/libphobos/libdruntime/core/thread/fiber.d +++ b/libphobos/libdruntime/core/thread/fiber.d @@ -178,8 +178,12 @@ private } else version (LoongArch64) { - version = AsmLoongArch64_Posix; - version = AsmExternal; + version (Posix) + { + version = AsmLoongArch64_Posix; + version = AsmExternal; + version = AlignFiberStackTo16Byte; + } } version (Posix) @@ -1442,27 +1446,6 @@ private: pstack -= ABOVE; *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint; } - else version (AsmLoongArch64_Posix) - { - version (StackGrowsDown) {} - else static assert(0); - - // Like others, FP registers and return address (ra) are kept - // below the saved stack top (tstack) to hide from GC scanning. - // The newp stack should look like this on LoongArch64: - // 18: fp <- pstack - // ... - // 9: s0 <- newp tstack - // 8: ra [&fiber_entryPoint] - // 7: fs7 - // ... - // 1: fs1 - // 0: fs0 - pstack -= 10 * size_t.sizeof; // skip s0-s8 and fp - // set $ra - push( cast(size_t) &fiber_entryPoint ); - pstack += size_t.sizeof; - } else version (AsmAArch64_Posix) { // Like others, FP registers and return address (lr) are kept @@ -1558,6 +1541,32 @@ private: push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] - Bottom of stack } } + else version (AsmLoongArch64_Posix) + { + // Like others, FP registers and return address ($r1) are kept + // below the saved stack top (tstack) to hide from GC scanning. + // fiber_switchContext expects newp sp to look like this: + // 10: $r21 (reserved) + // 9: $r22 (frame pointer) + // 8: $r23 + // ... + // 0: $r31 <-- newp tstack + // -1: $r1 (return address) [&fiber_entryPoint] + // -2: $f24 + // ... + // -9: $f31 + + version (StackGrowsDown) {} + else + static assert(false, "Only full descending stacks supported on LoongArch64"); + + // Only need to set return address ($r1). Everything else is fine + // zero initialized. + pstack -= size_t.sizeof * 11; // skip past space reserved for $r21-$r31 + push (cast(size_t) &fiber_entryPoint); + pstack += size_t.sizeof; // adjust sp (newp) above lr + } + else static if ( __traits( compiles, ucontext_t ) ) { getcontext( &m_utxt ); diff --git a/libphobos/libdruntime/core/vararg.d b/libphobos/libdruntime/core/vararg.d index 2c3e9659fb6..e6dd47d06d3 100644 --- a/libphobos/libdruntime/core/vararg.d +++ b/libphobos/libdruntime/core/vararg.d @@ -129,6 +129,13 @@ void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) ap += tsize.alignUp; parmn[0..tsize] = p[0..tsize]; } + else version (LoongArch64) + { + const tsize = ti.tsize; + auto p = cast(void*) ap; + ap += tsize.alignUp; + parmn[0..tsize] = p[0..tsize]; + } else version (MIPS_Any) { const tsize = ti.tsize; diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d index 81c7302b4c1..e2ca3dbe064 100644 --- a/libphobos/src/std/math/hardware.d +++ b/libphobos/src/std/math/hardware.d @@ -33,6 +33,7 @@ version (SPARC64) version = SPARC_Any; version (SystemZ) version = IBMZ_Any; version (RISCV32) version = RISCV_Any; version (RISCV64) version = RISCV_Any; +version (LoongArch64) version = LoongArch_Any; version (D_InlineAsm_X86) version = InlineAsm_X86_Any; version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; @@ -60,6 +61,7 @@ else version (X86_Any) version = IeeeFlagsSupport; else version (PPC_Any) version = IeeeFlagsSupport; else version (RISCV_Any) version = IeeeFlagsSupport; else version (MIPS_Any) version = IeeeFlagsSupport; +else version (LoongArch_Any) version = IeeeFlagsSupport; else version (ARM_Any) version = IeeeFlagsSupport; // Struct FloatingPointControl is only available if hardware FP units are available. @@ -90,6 +92,7 @@ private: // The ARM and PowerPC FPSCR is a 32-bit register. // The SPARC FSR is a 32bit register (64 bits for SPARC 7 & 8, but high bits are uninteresting). // The RISC-V (32 & 64 bit) fcsr is 32-bit register. + // THe LoongArch fcsr (fcsr0) is a 32-bit register. uint flags; version (CRuntime_Microsoft) @@ -174,6 +177,20 @@ private: return result; } } + else version (LoongArch_Any) + { + version (D_SoftFloat) + return 0; + else + { + uint result = void; + asm pure nothrow @nogc + { + "movfcsr2gr %0,$r2" : "=r" (result); + } + return result & EXCEPTIONS_MASK; + } + } else assert(0, "Not yet supported"); } @@ -273,6 +290,18 @@ private: } } } + else version (LoongArch_Any) + { + version (D_SoftFloat) + return; + else + { + asm nothrow @nogc + { + "movgr2fcsr $r2,$r0"; + } + } + } else assert(0, "Not yet supported"); } @@ -725,6 +754,21 @@ nothrow @nogc: | inexactException, } } + else version (LoongArch_Any) + { + enum : ExceptionMask + { + inexactException = 0x00, + divByZeroException = 0x01, + overflowException = 0x02, + underflowException = 0x04, + invalidException = 0x08, + severeExceptions = overflowException | divByZeroException + | invalidException, + allExceptions = severeExceptions | underflowException + | inexactException, + } + } else version (MIPS_Any) { enum : ExceptionMask @@ -812,6 +856,8 @@ nothrow @nogc: return true; else version (MIPS_Any) return true; + else version (LoongArch_Any) + return true; else version (ARM_Any) { // The hasExceptionTraps_impl function is basically pure, @@ -885,6 +931,10 @@ private: { alias ControlState = uint; } + else version (LoongArch_Any) + { + alias ControlState = uint; + } else version (MIPS_Any) { alias ControlState = uint; @@ -959,6 +1009,20 @@ private: } return cont; } + else version (LoongArch_Any) + { + version (D_SoftFloat) + return 0; + else + { + ControlState cont; + asm pure nothrow @nogc + { + "movfcsr2gr %0,$r0" : "=r" (cont); + } + cont &= (roundingMask | allExceptions); + } + } else version (RISCV_Any) { version (D_SoftFloat) @@ -1068,6 +1132,19 @@ private: } } } + else version (LoongArch_Any) + { + version (D_SoftFloat) + return; + else + { + asm nothrow @nogc + { + "movgr2fcsr $r0,%0" : + : "r" (newState & (roundingMask | allExceptions)); + } + } + } else version (RISCV_Any) { version (D_SoftFloat)