Skip to content

Commit eb5330e

Browse files
authored
Support for loongarch64 architecture (#280)
* Support for loongarch64 architecture * fix compile error
1 parent acf58d2 commit eb5330e

File tree

8 files changed

+318
-1
lines changed

8 files changed

+318
-1
lines changed

Make.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ endif
8484
ifeq ($(findstring riscv64,$(ARCH)),riscv64)
8585
override ARCH := riscv64
8686
endif
87+
ifeq ($(findstring loongarch64,$(ARCH)),loongarch64)
88+
override ARCH := loongarch64
89+
endif
8790

8891
# If CFLAGS does not contain a -O optimization flag, default to -O3
8992
ifeq ($(findstring -O,$(CFLAGS)),)

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ test/test-float: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
8181
$(MAKE) -C test test-float
8282

8383
clean:
84-
rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o riscv64/*.o
84+
rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o loongarch64/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o riscv64/*.o
8585
rm -f libopenlibm.a libopenlibm.*$(SHLIB_EXT)*
8686
$(MAKE) -C test clean
8787

include/openlibm_fenv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <openlibm_fenv_s390.h>
1717
#elif defined(__riscv)
1818
#include <openlibm_fenv_riscv.h>
19+
#elif defined(__loongarch64)
20+
#include <openlibm_fenv_loongarch64.h>
1921
#else
2022
#error "Unsupported platform"
2123
#endif

include/openlibm_fenv_loongarch64.h

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*-
2+
* Copyright (c) 2023 Yifan An <[email protected]>
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24+
* SUCH DAMAGE.
25+
*/
26+
27+
#ifndef _FENV_H_
28+
#define _FENV_H_
29+
30+
#include <stdint.h>
31+
#include "cdefs-compat.h"
32+
33+
#ifndef __fenv_static
34+
#define __fenv_static static
35+
#endif
36+
37+
typedef uint32_t fenv_t;
38+
typedef uint32_t fexcept_t;
39+
40+
/* Exception flags */
41+
#define FE_INVALID 0x100000
42+
#define FE_DIVBYZERO 0x080000
43+
#define FE_OVERFLOW 0x040000
44+
#define FE_UNDERFLOW 0x020000
45+
#define FE_INEXACT 0x010000
46+
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
47+
FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
48+
49+
/* Rounding modes */
50+
#define FE_TONEAREST 0x0000
51+
#define FE_TOWARDZERO 0x0100
52+
#define FE_DOWNWARD 0x0200
53+
#define FE_UPWARD 0x0300
54+
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
55+
FE_UPWARD | FE_TOWARDZERO)
56+
57+
__BEGIN_DECLS
58+
59+
/* Default floating-point environment */
60+
extern const fenv_t __fe_dfl_env;
61+
#define FE_DFL_ENV (&__fe_dfl_env)
62+
63+
#define _FPU_MASK_V 0x10
64+
#define _FPU_MASK_Z 0x08
65+
#define _FPU_MASK_O 0x04
66+
#define _FPU_MASK_U 0x02
67+
#define _FPU_MASK_I 0x01
68+
69+
#define _FPUSW_SHIFT 16
70+
#define _ENABLE_MASK (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I)
71+
72+
#define __rfs(__fpsr) __asm __volatile("movfcsr2gr %0,$r0" : "=r"(__fpsr))
73+
#define __wfs(__fpsr) __asm __volatile("movgr2fcsr $r0,%0" : : "r"(__fpsr))
74+
75+
__fenv_static inline int
76+
feclearexcept(int __excepts)
77+
{
78+
fexcept_t __fpsr;
79+
80+
__rfs(__fpsr);
81+
__fpsr &= ~__excepts;
82+
__wfs(__fpsr);
83+
return (0);
84+
}
85+
86+
__fenv_static inline int
87+
fegetexceptflag(fexcept_t *__flagp, int __excepts)
88+
{
89+
fexcept_t __fpsr;
90+
91+
__rfs(__fpsr);
92+
*__flagp = __fpsr & __excepts;
93+
return (0);
94+
}
95+
96+
__fenv_static inline int
97+
fesetexceptflag(const fexcept_t *__flagp, int __excepts)
98+
{
99+
fexcept_t __fpsr;
100+
101+
__rfs(__fpsr);
102+
__fpsr &= ~__excepts;
103+
__fpsr |= *__flagp & __excepts;
104+
__wfs(__fpsr);
105+
return (0);
106+
}
107+
108+
__fenv_static inline int
109+
feraiseexcept(int __excepts)
110+
{
111+
fexcept_t __ex = __excepts;
112+
113+
fesetexceptflag(&__ex, __excepts); /* XXX */
114+
return (0);
115+
}
116+
117+
__fenv_static inline int
118+
fetestexcept(int __excepts)
119+
{
120+
fexcept_t __fpsr;
121+
122+
__rfs(__fpsr);
123+
return (__fpsr & __excepts);
124+
}
125+
126+
__fenv_static inline int
127+
fegetround(void)
128+
{
129+
fexcept_t __fpsr;
130+
131+
__rfs(__fpsr);
132+
return __fpsr & _ROUND_MASK;
133+
}
134+
135+
__fenv_static inline int
136+
fesetround(int __round)
137+
{
138+
fexcept_t __fpsr;
139+
if ((__round & ~_ROUND_MASK) != 0)
140+
return 1;
141+
142+
__rfs(__fpsr);
143+
__fpsr &= ~_ROUND_MASK;
144+
__fpsr |= __round;
145+
__wfs(__fpsr);
146+
147+
return (0);
148+
}
149+
150+
__fenv_static inline int
151+
fegetenv(fenv_t *__envp)
152+
{
153+
__rfs(*__envp);
154+
return (0);
155+
}
156+
157+
__fenv_static inline int
158+
feholdexcept(fenv_t *__envp)
159+
{
160+
fenv_t __env;
161+
162+
__rfs(__env);
163+
*__envp = __env;
164+
__env &= ~(FE_ALL_EXCEPT | _FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I);
165+
__wfs(__env);
166+
return (0);
167+
}
168+
169+
__fenv_static inline int
170+
fesetenv(const fenv_t *__envp)
171+
{
172+
__wfs(*__envp);
173+
return (0);
174+
}
175+
176+
__fenv_static inline int
177+
feupdateenv(const fenv_t *__envp)
178+
{
179+
fexcept_t __fpsr;
180+
181+
__rfs(__fpsr);
182+
__wfs(*__envp);
183+
feraiseexcept(__fpsr & FE_ALL_EXCEPT);
184+
return (0);
185+
}
186+
187+
#if __BSD_VISIBLE
188+
189+
static inline int
190+
feenableexcept(int __mask)
191+
{
192+
fenv_t __old_fpsr, __new_fpsr;
193+
194+
__rfs(__new_fpsr);
195+
__old_fpsr = (__new_fpsr & _ENABLE_MASK) << _FPUSW_SHIFT;
196+
__new_fpsr |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
197+
__wfs(__new_fpsr);
198+
return __old_fpsr;
199+
}
200+
201+
static inline int
202+
fedisableexcept(int __mask)
203+
{
204+
fenv_t __old_fpsr, __new_fpsr;
205+
206+
__rfs(__new_fpsr);
207+
__old_fpsr = (__new_fpsr & _ENABLE_MASK) << _FPUSW_SHIFT;
208+
__new_fpsr &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
209+
__wfs(__new_fpsr);
210+
return __old_fpsr;
211+
}
212+
213+
static inline int
214+
fegetexcept(void)
215+
{
216+
fenv_t __fpsr;
217+
218+
__rfs(__fpsr);
219+
return ((__fpsr & _ENABLE_MASK) << _FPUSW_SHIFT);
220+
}
221+
222+
#endif /* __BSD_VISIBLE */
223+
224+
__END_DECLS
225+
226+
#endif /* !_FENV_H_ */

loongarch64/Make.files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$(CUR_SRCS) = fenv.c

loongarch64/fenv.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#define __fenv_static
2+
#include <fenv.h>
3+
4+
#ifdef __GNUC_GNU_INLINE__
5+
#error "This file must be compiled with C99 'inline' semantics"
6+
#endif
7+
8+
/*
9+
* Hopefully the system ID byte is immutable, so it's valid to use
10+
* this as a default environment.
11+
*/
12+
const fenv_t __fe_dfl_env = 0;
13+
14+
extern inline int feclearexcept(int __excepts);
15+
extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts);
16+
extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
17+
extern inline int feraiseexcept(int __excepts);
18+
extern inline int fetestexcept(int __excepts);
19+
extern inline int fegetround(void);
20+
extern inline int fesetround(int __round);
21+
extern inline int fegetenv(fenv_t *__envp);
22+
extern inline int feholdexcept(fenv_t *__envp);
23+
extern inline int fesetenv(const fenv_t *__envp);
24+
extern inline int feupdateenv(const fenv_t *__envp);
25+
extern inline int feenableexcept(int __mask);
26+
extern inline int fedisableexcept(int __mask);
27+
extern inline int fegetexcept(void);

src/fpmath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include "s390_fpmath.h"
4646
#elif defined(__riscv)
4747
#include "riscv_fpmath.h"
48+
#elif defined(__loongarch64)
49+
#include "loongarch64_fpmath.h"
4850
#endif
4951

5052
/* Definitions provided directly by GCC and Clang. */

src/loongarch64_fpmath.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*-
2+
* Copyright (c) 2023 Yifan An <[email protected]>
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24+
* SUCH DAMAGE.
25+
*/
26+
27+
#include <stdint.h>
28+
29+
union IEEEl2bits {
30+
long double e;
31+
struct {
32+
uint64_t manl :64;
33+
uint64_t manh :48;
34+
unsigned int exp :15;
35+
unsigned int sign :1;
36+
} bits;
37+
struct {
38+
uint64_t manl :64;
39+
uint64_t manh :48;
40+
unsigned int expsign :16;
41+
} xbits;
42+
};
43+
44+
#define LDBL_NBIT 0
45+
#define LDBL_IMPLICIT_NBIT
46+
#define mask_nbit_l(u) ((void)0)
47+
48+
#define LDBL_MANH_SIZE 48
49+
#define LDBL_MANL_SIZE 64
50+
51+
#define LDBL_TO_ARRAY32(u, a) do { \
52+
(a)[0] = (uint32_t)(u).bits.manl; \
53+
(a)[1] = (uint32_t)((u).bits.manl >> 32); \
54+
(a)[2] = (uint32_t)(u).bits.manh; \
55+
(a)[3] = (uint32_t)((u).bits.manh >> 32); \
56+
} while(0)

0 commit comments

Comments
 (0)