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