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 * This file is intended to contain gcc-style inline assembly that corresponds 37 * to base.il for all architectures. At the moment these inlines exist only 38 * for sparc and sparcv9 and these functions are implemented in C for x86. 39 * They should be inlined here for gcc if a new x86 base.il is created. 40 */ 41 42 #if defined(__sparc) 43 extern __GNU_INLINE double 44 __mul_set(double x, double y, int *pe) 45 { 46 double __result; 47 uint32_t __fsr; 48 uint32_t *__addr = &__fsr; 49 50 __asm__ __volatile__( 51 "fmuld %4, %5, %0\n\t" 52 "st %%fsr, %3\n\t" 53 "ld %3, %2\n\t" 54 "and %2, 1, %2\n\t" 55 "st %2, %1" 56 : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr) 57 : "e" (x), "e" (y)); 58 return (__result); 59 } 60 #endif /* __sparc */ 61 62 #if defined(__sparc) 63 extern __GNU_INLINE double 64 __div_set(double x, double y, int *pe) 65 { 66 double __result; 67 uint32_t __fsr; 68 uint32_t *__addr = &__fsr; 69 70 __asm__ __volatile__( 71 "fdivd %4, %5, %0\n\t" 72 "st %%fsr, %3\n\t" 73 "ld %3, %2\n\t" 74 "and %2, 1, %2\n\t" 75 "st %2, %1" 76 : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr) 77 : "e" (x), "e" (y)); 78 return (__result); 79 } 80 #endif /* __sparc */ 81 82 #if defined(__sparc) 83 extern __GNU_INLINE double 84 __dabs(double *x) 85 { 86 double __result; 87 88 __asm__ __volatile__( 89 #if defined(__sparcv9) 90 "fabsd %1, %0" 91 #else 92 "fabss %1, %0" 93 #endif 94 : "=e" (__result) 95 : "0" (*x)); 96 return (__result); 97 } 98 #endif /* __sparc */ 99 100 #if defined(__sparc) 101 extern __GNU_INLINE void 102 __get_ieee_flags(__ieee_flags_type *b) 103 { 104 uint32_t __fsr; 105 106 /* 107 * It's preferable to let the assembler insert the nops as 108 * needed; however, it warns as it does so. Add them here for now. 109 */ 110 __asm__ __volatile__( 111 "st %%fsr, %0\n\t" 112 "st %%g0, %1\n\t" 113 "ld %1, %%fsr\n\t" 114 "nop; nop; nop" 115 : "=m" (*b), "=m" (__fsr)); 116 } 117 #endif /* __sparc */ 118 119 #if defined(__sparc) 120 extern __GNU_INLINE void 121 __set_ieee_flags(__ieee_flags_type *b) 122 { 123 /* 124 * It's preferable to let the assembler insert the nops as 125 * needed; however, it warns as it does so. Add them here for now. 126 */ 127 __asm__ __volatile__( 128 "ld %0, %%fsr\n\t" 129 "nop; nop; nop" 130 : /* no outputs */ 131 : "m" (*b)); 132 } 133 #endif /* __sparc */ 134 135 #endif /* !__lint && __GNUC__ */ 136 137 #endif /* _BASE_INLINES_H */ 138