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