1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _BASE_INLINES_H 28 #define _BASE_INLINES_H 29 30 #include <sys/ccompile.h> 31 #include <sys/types.h> 32 33 #if !defined(__lint) && defined(__GNUC__) 34 35 /* 36 * At the moment these inlines exist only for sparc and sparcv9 and these 37 * functions are implemented in C for x86. 38 */ 39 40 #if defined(__sparc) 41 extern __GNU_INLINE double 42 __mul_set(double x, double y, int *pe) 43 { 44 double __result; 45 uint32_t __fsr; 46 uint32_t *__addr = &__fsr; 47 48 __asm__ __volatile__( 49 "fmuld %4, %5, %0\n\t" 50 "st %%fsr, %3\n\t" 51 "ld %3, %2\n\t" 52 "and %2, 1, %2\n\t" 53 "st %2, %1" 54 : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr) 55 : "e" (x), "e" (y)); 56 return (__result); 57 } 58 #endif /* __sparc */ 59 60 #if defined(__sparc) 61 extern __GNU_INLINE double 62 __div_set(double x, double y, int *pe) 63 { 64 double __result; 65 uint32_t __fsr; 66 uint32_t *__addr = &__fsr; 67 68 __asm__ __volatile__( 69 "fdivd %4, %5, %0\n\t" 70 "st %%fsr, %3\n\t" 71 "ld %3, %2\n\t" 72 "and %2, 1, %2\n\t" 73 "st %2, %1" 74 : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr) 75 : "e" (x), "e" (y)); 76 return (__result); 77 } 78 #endif /* __sparc */ 79 80 #if defined(__sparc) 81 extern __GNU_INLINE double 82 __dabs(double *x) 83 { 84 double __result; 85 86 __asm__ __volatile__( 87 #if defined(__sparcv9) 88 "fabsd %1, %0" 89 #else 90 "fabss %1, %0" 91 #endif 92 : "=e" (__result) 93 : "0" (*x)); 94 return (__result); 95 } 96 #endif /* __sparc */ 97 98 #if defined(__sparc) 99 extern __GNU_INLINE void 100 __get_ieee_flags(__ieee_flags_type *b) 101 { 102 uint32_t __fsr; 103 104 /* 105 * It's preferable to let the assembler insert the nops as 106 * needed; however, it warns as it does so. Add them here for now. 107 */ 108 __asm__ __volatile__( 109 "st %%fsr, %0\n\t" 110 "st %%g0, %1\n\t" 111 "ld %1, %%fsr\n\t" 112 "nop; nop; nop" 113 : "=m" (*b), "=m" (__fsr)); 114 } 115 #endif /* __sparc */ 116 117 #if defined(__sparc) 118 extern __GNU_INLINE void 119 __set_ieee_flags(__ieee_flags_type *b) 120 { 121 /* 122 * It's preferable to let the assembler insert the nops as 123 * needed; however, it warns as it does so. Add them here for now. 124 */ 125 __asm__ __volatile__( 126 "ld %0, %%fsr\n\t" 127 "nop; nop; nop" 128 : /* no outputs */ 129 : "m" (*b)); 130 } 131 #endif /* __sparc */ 132 133 #endif /* !__lint && __GNUC__ */ 134 135 #endif /* _BASE_INLINES_H */ 136