From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from va-2-39.ptr.blmpb.com (va-2-39.ptr.blmpb.com [209.127.231.39]) by sourceware.org (Postfix) with ESMTPS id AC04B3858427 for ; Mon, 25 Dec 2023 10:37:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AC04B3858427 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=oss.cipunited.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=oss.cipunited.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AC04B3858427 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.127.231.39 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703500667; cv=none; b=qIqiqcYHk+YqJHfYOOfuJ9OKuSGRZw01V8OrqNRu/9fshJfe9Tj4u/qG+Ve1GAK0R2J1LYcjwn/jXha+KPoytV+94otIBl3YrKC7BZdtwua1fx2+0LL1M+2wMmR0Hx8ZSewKqPvle/Ug8fR5LFdaFxD8yjyAIXa5YUJ5bfyHluY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703500667; c=relaxed/simple; bh=2A8jlg1RJ8nUgF1d12vBlk1O3UhWynbP5ZM20qR8Gos=; h=DKIM-Signature:To:From:Subject:Mime-Version:Date:Message-Id; b=fQ2hNcS/Sizj5KcBxspoqEL1NC/y6zavvD8Ye7mrQQQ7TK4a3RfDloS5sMft1k10FiMwlB2Q4XeClWsf1qhi2yD67U4pssjdmT6JoPSFTEemZ7tkhhvC4BNJpin0rt8mw6ljaO9tsqM06TdS7W6PJVsQhYc/raI26mzJhpcWjdY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2303200042; d=oss.cipunited.com; t=1703500652; h=from:subject:mime-version:from:date:message-id:subject:to:cc: reply-to:content-type:mime-version:in-reply-to:message-id; bh=mI26F7KdUzhPDpHCESKlIdYBMsWvCc6Tp1SJd6+WYBQ=; b=OJi9jgY6aWmwRQIHw6igDI/P2L2Yt9HNv5GmeaNa/l50XZWTcJ5CkystDRoBS+9L1H8YjU NO1DBQfgTPRxUQ/AkSX3V3b/IuWsil7NU1M2mjV4Zu41vJ/Crs6ntkWSGNrBk1gf2b619f dsoL4VXXuRYQEyTGsBi6THOsjE+iy30m4jJdxUP1ctXnciN/usniAZ0SQOXrokP85kp6mg eoh6V7AlsoLI1KmdZ/mwXkLaVJ+J8+RSYxcg1O7pBNsx0vaX/OsH5VfGc3LdZl+2cpiYB7 RWWS+lrSgAKa9eiOI3YBEHUr99/KANS3IYquwjsZZp4+ShjqMNJPvRNDDlBgXg== To: X-Mailer: git-send-email 2.43.0.windows.1 X-Lms-Return-Path: From: "Junxian Zhu" Subject: [PATCH 2/2] MIPS: Hard-float rounding instructions support Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Cc: , "Junxian Zhu" Date: Mon, 25 Dec 2023 18:35:49 +0800 References: <20231225103548.1615-2-zhujunxian@oss.cipunited.com> X-Original-From: zhujunxian@oss.cipunited.com Message-Id: <20231225103548.1615-4-zhujunxian@oss.cipunited.com> In-Reply-To: <20231225103548.1615-2-zhujunxian@oss.cipunited.com> Content-Transfer-Encoding: 7bit Received: from localhost.localdomain ([1.192.71.159]) by smtp.feishu.cn with ESMTPS; Mon, 25 Dec 2023 18:37:31 +0800 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00,DKIM_ADSP_NXDOMAIN,DKIM_INVALID,DKIM_SIGNED,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,MSGID_FROM_MTA_HEADER,NO_DNS_FOR_FROM,SPF_HELO_NONE,SPF_NONE,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 List-Id: From: Junxian Zhu Use hardware floating-point rounding instructions to implement roundeven, trunc, ceil and floor. * sysdeps/mips/mips32/Implies: Add source path. * sysdeps/mips/mips64/Implies: Likewise. * sysdeps/mips/fpu/Makefile: Newfile. * sysdeps/mips/fpu/s_ceil.c: Likewise. * sysdeps/mips/fpu/s_ceil_fpu.S: Likewise. * sysdeps/mips/fpu/s_ceilf.c: Likewise. * sysdeps/mips/fpu/s_ceilf_fpu.S: Likewise. * sysdeps/mips/fpu/s_floor.c: Likewise. * sysdeps/mips/fpu/s_floor_fpu.S: Likewise. * sysdeps/mips/fpu/s_floorf.c: Likewise. * sysdeps/mips/fpu/s_floorf_fpu.S: Likewise. * sysdeps/mips/fpu/s_roundeven.c: Likewise. * sysdeps/mips/fpu/s_roundeven_fpu.S: Likewise. * sysdeps/mips/fpu/s_roundevenf.c: Likewise. * sysdeps/mips/fpu/s_roundevenf_fpu.S: Likewise. * sysdeps/mips/fpu/s_trunc.c: Likewise. * sysdeps/mips/fpu/s_trunc_fpu.S: Likewise. * sysdeps/mips/fpu/s_truncf.c: Likewise. * sysdeps/mips/fpu/s_truncf_fpu.S: Likewise. Signed-off-by: Rong Zhang Signed-off-by: Junxian Zhu --- sysdeps/mips/fpu/Makefile | 12 ++++ sysdeps/mips/fpu/s_ceil.c | 30 ++++++++++ sysdeps/mips/fpu/s_ceil_fpu.S | 90 +++++++++++++++++++++++++++++ sysdeps/mips/fpu/s_ceilf.c | 30 ++++++++++ sysdeps/mips/fpu/s_ceilf_fpu.S | 82 ++++++++++++++++++++++++++ sysdeps/mips/fpu/s_floor.c | 24 ++++++++ sysdeps/mips/fpu/s_floor_fpu.S | 88 ++++++++++++++++++++++++++++ sysdeps/mips/fpu/s_floorf.c | 24 ++++++++ sysdeps/mips/fpu/s_floorf_fpu.S | 80 +++++++++++++++++++++++++ sysdeps/mips/fpu/s_roundeven.c | 24 ++++++++ sysdeps/mips/fpu/s_roundeven_fpu.S | 87 ++++++++++++++++++++++++++++ sysdeps/mips/fpu/s_roundevenf.c | 24 ++++++++ sysdeps/mips/fpu/s_roundevenf_fpu.S | 79 +++++++++++++++++++++++++ sysdeps/mips/fpu/s_trunc.c | 24 ++++++++ sysdeps/mips/fpu/s_trunc_fpu.S | 84 +++++++++++++++++++++++++++ sysdeps/mips/fpu/s_truncf.c | 24 ++++++++ sysdeps/mips/fpu/s_truncf_fpu.S | 76 ++++++++++++++++++++++++ sysdeps/mips/mips32/Implies | 1 + sysdeps/mips/mips64/Implies | 1 + 19 files changed, 884 insertions(+) create mode 100644 sysdeps/mips/fpu/Makefile create mode 100644 sysdeps/mips/fpu/s_ceil.c create mode 100644 sysdeps/mips/fpu/s_ceil_fpu.S create mode 100644 sysdeps/mips/fpu/s_ceilf.c create mode 100644 sysdeps/mips/fpu/s_ceilf_fpu.S create mode 100644 sysdeps/mips/fpu/s_floor.c create mode 100644 sysdeps/mips/fpu/s_floor_fpu.S create mode 100644 sysdeps/mips/fpu/s_floorf.c create mode 100644 sysdeps/mips/fpu/s_floorf_fpu.S create mode 100644 sysdeps/mips/fpu/s_roundeven.c create mode 100644 sysdeps/mips/fpu/s_roundeven_fpu.S create mode 100644 sysdeps/mips/fpu/s_roundevenf.c create mode 100644 sysdeps/mips/fpu/s_roundevenf_fpu.S create mode 100644 sysdeps/mips/fpu/s_trunc.c create mode 100644 sysdeps/mips/fpu/s_trunc_fpu.S create mode 100644 sysdeps/mips/fpu/s_truncf.c create mode 100644 sysdeps/mips/fpu/s_truncf_fpu.S diff --git a/sysdeps/mips/fpu/Makefile b/sysdeps/mips/fpu/Makefile new file mode 100644 index 0000000000..ad537d6bf1 --- /dev/null +++ b/sysdeps/mips/fpu/Makefile @@ -0,0 +1,12 @@ +ifeq ($(subdir),math) +sysdep_routines += s_floor_fpu s_floorf_fpu \ + s_ceil_fpu s_ceilf_fpu \ + s_trunc_fpu s_truncf_fpu \ + s_roundeven_fpu s_roundevenf_fpu + +libm-sysdep_routines += s_floor_fpu s_floorf_fpu \ + s_ceil_fpu s_ceilf_fpu \ + s_trunc_fpu s_truncf_fpu \ + s_roundeven_fpu s_roundevenf_fpu + +endif diff --git a/sysdeps/mips/fpu/s_ceil.c b/sysdeps/mips/fpu/s_ceil.c new file mode 100644 index 0000000000..91a90a70c5 --- /dev/null +++ b/sysdeps/mips/fpu/s_ceil.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_ceil_fpu.S b/sysdeps/mips/fpu/s_ceil_fpu.S new file mode 100644 index 0000000000..13d4f85ad3 --- /dev/null +++ b/sysdeps/mips/fpu/s_ceil_fpu.S @@ -0,0 +1,90 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__ceil) + .set push + .set noreorder + .set noat +# $f0=ret, $f12=double, a0=int64/int32_h, a1=int32_l, a2=sign, a3=exp +#if __mips == 64 + dmfc1 a0, $f12 # assign int64 +#else + mfhc1 a0, $f12 # assign int64 +#endif + cfc1 t0, $f26 + ceil.l.d $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 52, 11 # assign exp +#else + dsrl a3, a0, 52 + andi a3, a3, 0x7ff +#endif +#else + ext a3, a0, 20, 11 # assign exp +#endif + sltiu AT, a3, 1023 + bnez AT, SMALL # exp < 1023 + ctc1 t0, $f26 + sltiu AT, a3, 1023+54 + beqz AT, BIG # exp >= 1023+54 + li AT, 0x7ff + + jr ra + cvt.d.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0x7ff, no frac + nop +NAN_INF: + jr ra + add.d $f0, $f12, $f12 # return double + double +SMALL: +#if __mips == 64 + dsrl a2, a0, 63 +#else + srl a2, a0, 31 +#endif + beqz a2, SMALL_POSITIVE # sign == 0 + nop +SMALL_NEGATIVE: # return -0.0 + jr ra + neg.d $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.d.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.d $f0, $f12 + .set pop + +END (__ceil) +libm_alias_double (__ceil, ceil) + +#endif + diff --git a/sysdeps/mips/fpu/s_ceilf.c b/sysdeps/mips/fpu/s_ceilf.c new file mode 100644 index 0000000000..a7f81c7539 --- /dev/null +++ b/sysdeps/mips/fpu/s_ceilf.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_ceilf_fpu.S b/sysdeps/mips/fpu/s_ceilf_fpu.S new file mode 100644 index 0000000000..7952894f73 --- /dev/null +++ b/sysdeps/mips/fpu/s_ceilf_fpu.S @@ -0,0 +1,82 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__ceilf) + .set push + .set noreorder + .set noat +# f0=ret, f12=float, a0=int32, a2=sign, a3=exp + mfc1 a0, $f12 # assign int32 + cfc1 t0, $f26 + ceil.l.s $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 23, 8 # assign exp +#else + dsrl a3, a0, 23 + andi a3, a3, 0x1ff +#endif +#else + ext a3, a0, 23, 8 # assign exp +#endif + sltiu AT, a3, 127 + bnez AT, SMALL # exp < 127 + ctc1 t0, $f26 + sltiu AT, a3, 127+25 + beqz AT, BIG # exp >= 127+25 + li AT, 0xff + + jr ra + cvt.s.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0xff, no frac + nop +NAN_INF: + jr ra + add.s $f0, $f12, $f12 # return double + double +SMALL: + srl a2, a0, 31 + beqz a2, SMALL_POSITIVE # sign == 0 + nop +SMALL_NEGATIVE: # return -0.0 + jr ra + neg.s $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.s.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.s $f0, $f12 + .set pop + +END (__ceilf) +libm_alias_float (__ceil, ceil) + +#endif + diff --git a/sysdeps/mips/fpu/s_floor.c b/sysdeps/mips/fpu/s_floor.c new file mode 100644 index 0000000000..4b43dc9ad9 --- /dev/null +++ b/sysdeps/mips/fpu/s_floor.c @@ -0,0 +1,24 @@ +/* Round double to integer away from zero. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_floor_fpu.S b/sysdeps/mips/fpu/s_floor_fpu.S new file mode 100644 index 0000000000..fda661fd3a --- /dev/null +++ b/sysdeps/mips/fpu/s_floor_fpu.S @@ -0,0 +1,88 @@ +/* Round double to integer away from zero. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__floor) + .set push + .set noreorder + .set noat +# f0=ret, f12=double, a0=int64/int32_h, a1=int32_l, a2=sign, a3=exp +#if __mips == 64 + dmfc1 a0, $f12 # assign int64 +#else + mfhc1 a0, $f12 # assign int64 +#endif + cfc1 t0, $f26 + floor.l.d $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 52, 11 # assign exp +#else + dsrl a3, a0, 52 + andi a3, a3, 0x7ff +#endif +#else + ext a3, a0, 20, 11 # assign exp +#endif + sltiu AT, a3, 1023 + bnez AT, SMALL # exp < 1023 + ctc1 t0, $f26 + sltiu AT, a3, 1023+54 + beqz AT, BIG # exp >= 1023+54 + li AT, 0x7ff + + jr ra + cvt.d.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0x7ff, no frac + nop +NAN_INF: + jr ra + add.d $f0, $f12, $f12 # return double + double +SMALL: +#if __mips == 64 + dsrl a2, a0, 63 +#else + srl a2, a0, 31 +#endif + beqz a2, SMALL_POSITIVE # sign == 0 + li AT, 0xbff # used by SMALL_NEGATIVE +SMALL_NEGATIVE: + mfhc1 t1, $f0 + bnez t1, SMALL_POSITIVE # sign == 0 + nop + + jr ra + neg.d $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.d.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.d $f0, $f12 + .set pop + +END (__floor) +libm_alias_double (__floor, floor) + +#endif + diff --git a/sysdeps/mips/fpu/s_floorf.c b/sysdeps/mips/fpu/s_floorf.c new file mode 100644 index 0000000000..30cfda7820 --- /dev/null +++ b/sysdeps/mips/fpu/s_floorf.c @@ -0,0 +1,24 @@ +/* Round double to integer away from zero. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_floorf_fpu.S b/sysdeps/mips/fpu/s_floorf_fpu.S new file mode 100644 index 0000000000..8edd234dbc --- /dev/null +++ b/sysdeps/mips/fpu/s_floorf_fpu.S @@ -0,0 +1,80 @@ +/* Round double to integer away from zero. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__floorf) + .set push + .set noreorder + .set noat +# f0=ret, f12=float, a0=int32, a2=sign, a3=exp + mfc1 a0, $f12 # assign int32 + cfc1 t0, $f26 + floor.l.s $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 23, 8 # assign exp +#else + dsrl a3, a0, 23 + andi a3, a3, 0x1ff +#endif +#else + ext a3, a0, 23, 8 # assign exp +#endif + sltiu AT, a3, 127 + bnez AT, SMALL # exp < 127 + ctc1 t0, $f26 + sltiu AT, a3, 127+25 + beqz AT, BIG # exp >= 127+25 + li AT, 0xff + + jr ra + cvt.s.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0xff, no frac + nop +NAN_INF: + jr ra + add.s $f0, $f12, $f12 # return double + double +SMALL: + srl a2, a0, 31 + beqz a2, SMALL_POSITIVE # sign == 0 + li AT, 0xbff # used by SMALL_NEGATIVE +SMALL_NEGATIVE: + mfhc1 t1, $f0 + bnez t1, SMALL_POSITIVE # sign == 0 + nop + + jr ra + neg.s $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.s.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.s $f0, $f12 + .set pop + +END (__floorf) +libm_alias_float (__floor, floor) + +#endif + diff --git a/sysdeps/mips/fpu/s_roundeven.c b/sysdeps/mips/fpu/s_roundeven.c new file mode 100644 index 0000000000..dace85a70b --- /dev/null +++ b/sysdeps/mips/fpu/s_roundeven.c @@ -0,0 +1,24 @@ +/* Round to nearest integer value, rounding halfway cases to even. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_roundeven_fpu.S b/sysdeps/mips/fpu/s_roundeven_fpu.S new file mode 100644 index 0000000000..aef6434886 --- /dev/null +++ b/sysdeps/mips/fpu/s_roundeven_fpu.S @@ -0,0 +1,87 @@ +/* Round to nearest integer value, rounding halfway cases to even. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__roundeven) + .set push + .set noreorder + .set noat +# f0=ret, f12=double, a0=int64/int32_h, a1=int32_l, a2=sign, a3=exp +#if __mips == 64 + dmfc1 a0, $f12 # assign int64 +#else + mfhc1 a0, $f12 # assign int64 +#endif + cfc1 t0, $f26 + round.l.d $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 52, 11 # assign exp +#else + dsrl a3, a0, 52 + andi a3, a3, 0x7ff +#endif +#else + ext a3, a0, 20, 11 # assign exp +#endif + sltiu AT, a3, 1023 + bnez AT, SMALL # exp < 1023 + ctc1 t0, $f26 + sltiu AT, a3, 1023+54 + beqz AT, BIG # exp >= 1023+54 + li AT, 0x7ff + + jr ra + cvt.d.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0x7ff, no frac + nop +NAN_INF: + jr ra + add.d $f0, $f12, $f12 # return double + double +SMALL: +#if __mips == 64 + dsrl a2, a0, 63 +#else + srl a2, a0, 31 +#endif + beqz a2, SMALL_POSITIVE # sign == 0 + nop +SMALL_NEGATIVE: + mfhc1 t1, $f0 + bnez t1, SMALL_POSITIVE # sign == 0 + nop + + jr ra + neg.d $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.d.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.d $f0, $f12 + .set pop + +END (__roundeven) +libm_alias_double (__roundeven, roundeven) + +#endif diff --git a/sysdeps/mips/fpu/s_roundevenf.c b/sysdeps/mips/fpu/s_roundevenf.c new file mode 100644 index 0000000000..5bb35901db --- /dev/null +++ b/sysdeps/mips/fpu/s_roundevenf.c @@ -0,0 +1,24 @@ +/* Round to nearest integer value, rounding halfway cases to even. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_roundevenf_fpu.S b/sysdeps/mips/fpu/s_roundevenf_fpu.S new file mode 100644 index 0000000000..e946e50d8f --- /dev/null +++ b/sysdeps/mips/fpu/s_roundevenf_fpu.S @@ -0,0 +1,79 @@ +/* Round to nearest integer value, rounding halfway cases to even. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__roundevenf) + .set push + .set noreorder + .set noat +# f0=ret, f12=float, a0=int32, a2=sign, a3=exp + mfc1 a0, $f12 # assign int32 + cfc1 t0, $f26 + round.l.s $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 23, 8 # assign exp +#else + dsrl a3, a0, 23 + andi a3, a3, 0x1ff +#endif +#else + ext a3, a0, 23, 8 # assign exp +#endif + sltiu AT, a3, 127 + bnez AT, SMALL # exp < 127 + ctc1 t0, $f26 + sltiu AT, a3, 127+25 + beqz AT, BIG # exp >= 127+25 + li AT, 0xff + + jr ra + cvt.s.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0xff, no frac + nop +NAN_INF: + jr ra + add.s $f0, $f12, $f12 # return double + double +SMALL: + srl a2, a0, 31 + beqz a2, SMALL_POSITIVE # sign == 0 + nop +SMALL_NEGATIVE: + mfhc1 t1, $f0 + bnez t1, SMALL_POSITIVE # sign == 0 + nop + + jr ra + neg.s $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.s.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.s $f0, $f12 + .set pop + +END (__roundevenf) +libm_alias_float (__roundeven, roundeven) + +#endif diff --git a/sysdeps/mips/fpu/s_trunc.c b/sysdeps/mips/fpu/s_trunc.c new file mode 100644 index 0000000000..3865026c70 --- /dev/null +++ b/sysdeps/mips/fpu/s_trunc.c @@ -0,0 +1,24 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_trunc_fpu.S b/sysdeps/mips/fpu/s_trunc_fpu.S new file mode 100644 index 0000000000..3a7947507f --- /dev/null +++ b/sysdeps/mips/fpu/s_trunc_fpu.S @@ -0,0 +1,84 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__trunc) + .set push + .set noreorder + .set noat +# f0=ret, f12=double, a0=int64/int32_h, a1=int32_l, a2=sign, a3=exp +#if __mips == 64 + dmfc1 a0, $f12 # assign int64 +#else + mfhc1 a0, $f12 # assign int64 +#endif + cfc1 t0, $f26 + trunc.l.d $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 52, 11 # assign exp +#else + dsrl a3, a0, 52 + andi a3, a3, 0x7ff +#endif +#else + ext a3, a0, 20, 11 # assign exp +#endif + sltiu AT, a3, 1023 + bnez AT, SMALL # exp < 1023 + ctc1 t0, $f26 + sltiu AT, a3, 1023+54 + beqz AT, BIG # exp >= 1023+54 + li AT, 0x7ff + + jr ra + cvt.d.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0x7ff, no frac + nop +NAN_INF: + jr ra + add.d $f0, $f12, $f12 # return double + double +SMALL: +#if __mips == 64 + dsrl a2, a0, 63 +#else + srl a2, a0, 31 +#endif + beqz a2, SMALL_POSITIVE # sign == 0 + nop +SMALL_NEGATIVE: # return -0.0 + jr ra + neg.d $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.d.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.d $f0, $f12 + .set pop + +END (__trunc) +libm_alias_double (__trunc, trunc) + +#endif + diff --git a/sysdeps/mips/fpu/s_truncf.c b/sysdeps/mips/fpu/s_truncf.c new file mode 100644 index 0000000000..59ef17bf74 --- /dev/null +++ b/sysdeps/mips/fpu/s_truncf.c @@ -0,0 +1,24 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !((__mips_fpr == 64) && (__mips_hard_float == 1) \ + && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) + +# include + +#endif diff --git a/sysdeps/mips/fpu/s_truncf_fpu.S b/sysdeps/mips/fpu/s_truncf_fpu.S new file mode 100644 index 0000000000..1878d88e3c --- /dev/null +++ b/sysdeps/mips/fpu/s_truncf_fpu.S @@ -0,0 +1,76 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if ((__mips_fpr == 64) && (__mips_hard_float == 1) && ((__mips == 32 && __mips_isa_rev > 1) || __mips == 64)) +#include +#include +#include + +ENTRY(__truncf) + .set push + .set noreorder + .set noat +# f0=ret, f12=float, a0=int32, a2=sign, a3=exp + mfc1 a0, $f12 # assign int32 + cfc1 t0, $f26 + trunc.l.s $f0, $f12 +#if __mips == 64 +#if __mips_isa_rev > 1 + dext a3, a0, 23, 8 # assign exp +#else + dsrl a3, a0, 23 + andi a3, a3, 0x1ff +#endif +#else + ext a3, a0, 23, 8 # assign exp +#endif + sltiu AT, a3, 127 + bnez AT, SMALL # exp < 127 + ctc1 t0, $f26 + sltiu AT, a3, 127+25 + beqz AT, BIG # exp >= 127+25 + li AT, 0xff + + jr ra + cvt.s.l $f0, $f0 +BIG: + bne AT, a3, RETURN_AS_IS # exp != 0xff, no frac + nop +NAN_INF: + jr ra + add.s $f0, $f12, $f12 # return double + double +SMALL: + srl a2, a0, 31 + beqz a2, SMALL_POSITIVE # sign == 0 + nop +SMALL_NEGATIVE: # return -0.0 + jr ra + neg.s $f0, $f0 +SMALL_POSITIVE: + jr ra + cvt.s.l $f0, $f0 +RETURN_AS_IS: + jr ra + mov.s $f0, $f12 + .set pop + +END (__truncf) +libm_alias_float (__trunc, trunc) + +#endif + diff --git a/sysdeps/mips/mips32/Implies b/sysdeps/mips/mips32/Implies index 6473f2517c..71b3678c6c 100644 --- a/sysdeps/mips/mips32/Implies +++ b/sysdeps/mips/mips32/Implies @@ -1,3 +1,4 @@ +mips/fpu mips/ieee754 mips wordsize-32 diff --git a/sysdeps/mips/mips64/Implies b/sysdeps/mips/mips64/Implies index 826ff1541f..8885ebd564 100644 --- a/sysdeps/mips/mips64/Implies +++ b/sysdeps/mips/mips64/Implies @@ -1,4 +1,5 @@ # MIPS uses IEEE 754 floating point. +mips/fpu mips/ieee754 ieee754/flt-32 ieee754/dbl-64 -- 2.43.0.windows.1