^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fp_emu.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright Roman Zippel, 1997. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * notice, and the entire permission notice in its entirety,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * including the disclaimer of warranties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 3. The name of the author may not be used to endorse or promote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * products derived from this software without specific prior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * ALTERNATIVELY, this product may be distributed under the terms of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * the GNU General Public License, in which case the provisions of the GPL are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * required INSTEAD OF the above restrictions. (This clause is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * necessary due to a potential bad interaction between the GPL and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * the restrictions contained in a BSD-style copyright.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifndef _FP_EMU_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define _FP_EMU_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <asm/math-emu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #ifndef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define IS_INF(a) ((a)->exp == 0x7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define IS_ZERO(a) ((a)->mant.m64 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define fp_set_sr(bit) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) FPDATA->fpsr |= 1 << (bit); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define fp_set_quotient(quotient) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) FPDATA->fpsr &= 0xff00ffff; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) FPDATA->fpsr |= ((quotient) & 0xff) << 16; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* linkage for several useful functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Normalize the extended struct, return 0 for a NaN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define fp_normalize_ext(fpreg) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) register struct fp_ext *reg asm ("a0") = fpreg; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) register int res asm ("d0"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) asm volatile ("jsr fp_conv_ext2ext" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) : "=d" (res) : "a" (reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) : "a1", "d1", "d2", "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) res; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define fp_copy_ext(dest, src) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *dest = *src; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define fp_monadic_check(dest, src) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) fp_copy_ext(dest, src); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (!fp_normalize_ext(dest)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return dest; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define fp_dyadic_check(dest, src) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!fp_normalize_ext(dest)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return dest; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!fp_normalize_ext(src)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) fp_copy_ext(dest, src); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return dest; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) extern const struct fp_ext fp_QNaN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) extern const struct fp_ext fp_Inf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define fp_set_nan(dest) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) fp_set_sr(FPSR_EXC_OPERR); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *dest = fp_QNaN; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* TODO check rounding mode? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define fp_set_ovrflw(dest) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) fp_set_sr(FPSR_EXC_OVFL); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dest->exp = 0x7fff; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dest->mant.m64 = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define fp_conv_ext2long(src) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) register struct fp_ext *__src asm ("a0") = src; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) register int __res asm ("d0"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) asm volatile ("jsr fp_conv_ext2long" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) : "=d" (__res) : "a" (__src) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) : "a1", "d1", "d2", "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) __res; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define fp_conv_long2ext(dest, src) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) register struct fp_ext *__dest asm ("a0") = dest; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) register int __src asm ("d0") = src; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) asm volatile ("jsr fp_conv_ext2long" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) : : "d" (__src), "a" (__dest) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) : "a1", "d1", "d2", "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #else /* __ASSEMBLY__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * set, reset or clear a bit in the fp status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .macro fp_set_sr bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bset #(\bit&7),(FPD_FPSR+3-(\bit/8),FPDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .macro fp_clr_sr bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) bclr #(\bit&7),(FPD_FPSR+3-(\bit/8),FPDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .macro fp_tst_sr bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) btst #(\bit&7),(FPD_FPSR+3-(\bit/8),FPDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif /* __ASSEMBLY__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #endif /* _FP_EMU_H */