Print this page

        

*** 26,36 **** /* * Copyright 2011, Richard Lowe. */ ! /* Functions in this file are duplicated in libm.m4. Keep them in sync */ #ifndef _LIBM_INLINES_H #define _LIBM_INLINES_H #ifdef __GNUC__ --- 26,36 ---- /* * Copyright 2011, Richard Lowe. */ ! /* Functions in this file are duplicated in locallibm.il. Keep them in sync */ #ifndef _LIBM_INLINES_H #define _LIBM_INLINES_H #ifdef __GNUC__
*** 45,90 **** extern __inline__ double __inline_sqrt(double d) { double ret; ! __asm__ __volatile__("fsqrtd %0,%0\n\t" : "=e" (ret) : "0" (d)); return (ret); } extern __inline__ float __inline_sqrtf(float f) { float ret; ! __asm__ __volatile__("fsqrts %0,%0\n\t" : "=f" (ret) : "0" (f)); return (ret); } extern __inline__ enum fp_class_type fp_classf(float f) { enum fp_class_type ret; __asm__ __volatile__( ! "sethi %%hi(0x80000000),%%o2\n\t" ! "andncc %0,%%o2,%0\n\t" "bne 1f\n\t" "nop\n\t" "mov 0,%0\n\t" "ba 2f\n\t" /* x is 0 */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x7f800000),%%o2\n\t" ! "andcc %0,%%o2,%%g0\n\t" "bne 1f\n\t" "nop\n\t" "mov 1,%0\n\t" "ba 2f\n\t" /* x is subnormal */ "nop\n\t" "1:\n\t" ! "cmp %0,%%o2\n\t" "bge 1f\n\t" "nop\n\t" "mov 2,%0\n\t" "ba 2f\n\t" /* x is normal */ "nop\n\t" --- 45,92 ---- extern __inline__ double __inline_sqrt(double d) { double ret; ! __asm__ __volatile__("fsqrtd %1,%0\n\t" : "=e" (ret) : "e" (d)); return (ret); } extern __inline__ float __inline_sqrtf(float f) { float ret; ! __asm__ __volatile__("fsqrts %1,%0\n\t" : "=f" (ret) : "f" (f)); return (ret); } extern __inline__ enum fp_class_type fp_classf(float f) { enum fp_class_type ret; + uint32_t tmp; + /* XXX: Separate input and output */ __asm__ __volatile__( ! "sethi %%hi(0x80000000),%1\n\t" ! "andncc %3,%1,%0\n\t" "bne 1f\n\t" "nop\n\t" "mov 0,%0\n\t" "ba 2f\n\t" /* x is 0 */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x7f800000),%1\n\t" ! "andcc %0,%1,%%g0\n\t" "bne 1f\n\t" "nop\n\t" "mov 1,%0\n\t" "ba 2f\n\t" /* x is subnormal */ "nop\n\t" "1:\n\t" ! "cmp %0,%1\n\t" "bge 1f\n\t" "nop\n\t" "mov 2,%0\n\t" "ba 2f\n\t" /* x is normal */ "nop\n\t"
*** 93,195 **** "nop\n\t" "mov 3,%0\n\t" "ba 2f\n\t" /* x is __infinity */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x00400000),%%o2\n\t" ! "andcc %0,%%o2,%%g0\n\t" "mov 4,%0\n\t" /* x is quiet NaN */ "bne 2f\n\t" "nop\n\t" "mov 5,%0\n\t" /* x is signaling NaN */ "2:\n\t" ! : "=r" (ret) ! : "0" (f) ! : "o2"); return (ret); } #define _HI_WORD(x) ((uint32_t *)&x)[0] #define _LO_WORD(x) ((uint32_t *)&x)[1] extern __inline__ enum fp_class_type fp_class(double d) { enum fp_class_type ret; __asm__ __volatile__( ! "sethi %%hi(0x80000000),%%o2\n\t" /* o2 gets 80000000 */ ! "andn %0,%%o2,%0\n\t" /* o0-o1 gets abs(x) */ ! "orcc %0,%2,%%g0\n\t" /* set cc as x is zero/nonzero */ "bne 1f\n\t" /* branch if x is nonzero */ "nop\n\t" "mov 0,%0\n\t" "ba 2f\n\t" /* x is 0 */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x7ff00000),%%o2\n\t" /* o2 gets 7ff00000 */ ! "andcc %0,%%o2,%%g0\n\t" /* cc set by __exp field of x */ "bne 1f\n\t" /* branch if normal or max __exp */ "nop\n\t" "mov 1,%0\n\t" "ba 2f\n\t" /* x is subnormal */ "nop\n\t" "1:\n\t" ! "cmp %0,%%o2\n\t" "bge 1f\n\t" /* branch if x is max __exp */ "nop\n\t" "mov 2,%0\n\t" "ba 2f\n\t" /* x is normal */ "nop\n\t" "1:\n\t" ! "andn %0,%%o2,%0\n\t" /* o0 gets msw __significand field */ ! "orcc %0,%2,%%g0\n\t" /* set cc by OR __significand */ "bne 1f\n\t" /* Branch if __nan */ "nop\n\t" "mov 3,%0\n\t" "ba 2f\n\t" /* x is __infinity */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x00080000),%%o2\n\t" ! "andcc %0,%%o2,%%g0\n\t" /* set cc by quiet/sig bit */ "be 1f\n\t" /* Branch if signaling */ "nop\n\t" "mov 4,%0\n\t" /* x is quiet NaN */ "ba 2f\n\t" "nop\n\t" "1:\n\t" "mov 5,%0\n\t" /* x is signaling NaN */ "2:\n\t" ! : "=r" (ret) ! : "0" (_HI_WORD(d)), "r" (_LO_WORD(d)) ! : "o2"); return (ret); } extern __inline__ int __swapEX(int i) { int ret; uint32_t fsr; __asm__ __volatile__( ! "and %0,0x1f,%%o1\n\t" ! "sll %%o1,5,%%o1\n\t" /* input to aexc bit location */ ".volatile\n\t" ! "st %%fsr,%2\n\t" ! "ld %2,%0\n\t" /* = fsr */ ! "andn %0,0x3e0,%%o2\n\t" ! "or %%o1,%%o2,%%o1\n\t" /* o1 = new fsr */ ! "st %%o1,%2\n\t" ! "ld %2,%%fsr\n\t" "srl %0,5,%0\n\t" "and %0,0x1f,%0\n\t" ".nonvolatile\n\t" ! : "=r" (ret) ! : "0" (i), "m" (fsr) ! : "o1", "o2"); return (ret); } /* --- 95,199 ---- "nop\n\t" "mov 3,%0\n\t" "ba 2f\n\t" /* x is __infinity */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x00400000),%1\n\t" ! "andcc %0,%1,%%g0\n\t" "mov 4,%0\n\t" /* x is quiet NaN */ "bne 2f\n\t" "nop\n\t" "mov 5,%0\n\t" /* x is signaling NaN */ "2:\n\t" ! : "+r" (ret), "=&r" (tmp) ! : "r" (f) ! : "cc"); return (ret); } #define _HI_WORD(x) ((uint32_t *)&x)[0] #define _LO_WORD(x) ((uint32_t *)&x)[1] extern __inline__ enum fp_class_type fp_class(double d) { enum fp_class_type ret; + uint32_t tmp; __asm__ __volatile__( ! "sethi %%hi(0x80000000),%1\n\t" /* %1 gets 80000000 */ ! "andn %2,%1,%0\n\t" /* %2-%0 gets abs(x) */ ! "orcc %0,%3,%%g0\n\t" /* set cc as x is zero/nonzero */ "bne 1f\n\t" /* branch if x is nonzero */ "nop\n\t" "mov 0,%0\n\t" "ba 2f\n\t" /* x is 0 */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x7ff00000),%1\n\t" /* %1 gets 7ff00000 */ ! "andcc %0,%1,%%g0\n\t" /* cc set by __exp field of x */ "bne 1f\n\t" /* branch if normal or max __exp */ "nop\n\t" "mov 1,%0\n\t" "ba 2f\n\t" /* x is subnormal */ "nop\n\t" "1:\n\t" ! "cmp %0,%1\n\t" "bge 1f\n\t" /* branch if x is max __exp */ "nop\n\t" "mov 2,%0\n\t" "ba 2f\n\t" /* x is normal */ "nop\n\t" "1:\n\t" ! "andn %0,%1,%0\n\t" /* o0 gets msw __significand field */ ! "orcc %0,%3,%%g0\n\t" /* set cc by OR __significand */ "bne 1f\n\t" /* Branch if __nan */ "nop\n\t" "mov 3,%0\n\t" "ba 2f\n\t" /* x is __infinity */ "nop\n\t" "1:\n\t" ! "sethi %%hi(0x00080000),%1\n\t" ! "andcc %0,%1,%%g0\n\t" /* set cc by quiet/sig bit */ "be 1f\n\t" /* Branch if signaling */ "nop\n\t" "mov 4,%0\n\t" /* x is quiet NaN */ "ba 2f\n\t" "nop\n\t" "1:\n\t" "mov 5,%0\n\t" /* x is signaling NaN */ "2:\n\t" ! : "=&r" (ret), "=&r" (tmp) ! : "r" (_HI_WORD(d)), "r" (_LO_WORD(d)) ! : "cc"); return (ret); } extern __inline__ int __swapEX(int i) { int ret; uint32_t fsr; + uint32_t tmp1, tmp2; __asm__ __volatile__( ! "and %4,0x1f,%3\n\t" ! "sll %3,5,%3\n\t" /* shift input to aexc bit location */ ".volatile\n\t" ! "st %%fsr,%1\n\t" ! "ld %1,%0\n\t" /* %0 = fsr */ ! "andn %0,0x3e0,%4\n\t" ! "or %3,%4,%3\n\t" /* %3 = new fsr */ ! "st %3,%1\n\t" ! "ld %1,%%fsr\n\t" "srl %0,5,%0\n\t" "and %0,0x1f,%0\n\t" ".nonvolatile\n\t" ! : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2) ! : "r" (i) ! : "cc"); return (ret); } /*
*** 206,297 **** extern __inline__ enum fp_direction_type __swapRD(enum fp_direction_type d) { enum fp_direction_type ret; uint32_t fsr; __asm__ __volatile__( ! "and %0,0x3,%0\n\t" ! "sll %0,30,%%o1\n\t" /* input to RD bit location */ ".volatile\n\t" ! "st %%fsr,%2\n\t" ! "ld %2,%0\n\t" /* o0 = fsr */ ! "set 0xc0000000,%%o4\n\t" /* mask of rounding direction bits */ ! "andn %0,%%o4,%%o2\n\t" ! "or %%o1,%%o2,%%o1\n\t" /* o1 = new fsr */ ! "st %%o1,%2\n\t" ! "ld %2,%%fsr\n\t" "srl %0,30,%0\n\t" "and %0,0x3,%0\n\t" ".nonvolatile\n\t" ! : "=r" (ret) ! : "0" (d), "m" (fsr) ! : "o1", "o2", "o4"); return (ret); } extern __inline__ int __swapTE(int i) { int ret; ! uint32_t fsr; __asm__ __volatile__( ! "and %0,0x1f,%0\n\t" ! "sll %0,23,%%o1\n\t" /* input to TEM bit location */ ".volatile\n\t" ! "st %%fsr,%2\n\t" ! "ld %2,%0\n\t" /* o0 = fsr */ "set 0x0f800000,%%o4\n\t" /* mask of TEM (Trap Enable Mode bits) */ ! "andn %0,%%o4,%%o2\n\t" ! "or %%o1,%%o2,%%o1\n\t" /* o1 = new fsr */ ! "st %%o1,%2\n\t" ! "ld %2,%%fsr\n\t" "srl %0,23,%0\n\t" "and %0,0x1f,%0\n\t" ".nonvolatile\n\t" ! : "=r" (ret) ! : "0" (i), "m" (fsr) ! : "o1", "o2", "o4"); return (ret); } extern __inline__ double sqrt(double d) { ! double ret; ! ! __asm__ __volatile__("fsqrtd %0,%0\n\t" : "=f" (ret) : "0" (d)); ! return (ret); } extern __inline__ float sqrtf(float f) { ! float ret; ! ! __asm__ __volatile__("fsqrts %0,%0\n\t" : "=f" (ret) : "0" (f)); ! return (ret); } extern __inline__ double fabs(double d) { double ret; ! __asm__ __volatile__("fabsd %0,%0\n\t" : "=e" (ret) : "0" (d)); return (ret); } extern __inline__ float fabsf(float f) { float ret; ! __asm__ __volatile__("fabss %0,%0\n\t" : "=f" (ret) : "0" (f)); return (ret); } #ifdef __cplusplus } --- 210,296 ---- extern __inline__ enum fp_direction_type __swapRD(enum fp_direction_type d) { enum fp_direction_type ret; uint32_t fsr; + uint32_t tmp1, tmp2, tmp3; __asm__ __volatile__( ! "and %5,0x3,%0\n\t" ! "sll %0,30,%2\n\t" /* shift input to RD bit location */ ".volatile\n\t" ! "st %%fsr,%1\n\t" ! "ld %1,%0\n\t" /* %0 = fsr */ ! "set 0xc0000000,%4\n\t" /* mask of rounding direction bits */ ! "andn %0,%4,%3\n\t" ! "or %2,%3,%2\n\t" /* %2 = new fsr */ ! "st %2,%1\n\t" ! "ld %1,%%fsr\n\t" "srl %0,30,%0\n\t" "and %0,0x3,%0\n\t" ".nonvolatile\n\t" ! : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3) ! : "r" (d) ! : "cc"); return (ret); } extern __inline__ int __swapTE(int i) { int ret; ! uint32_t fsr, tmp1, tmp2; __asm__ __volatile__( ! "and %4,0x1f,%0\n\t" ! "sll %0,23,%2\n\t" /* shift input to TEM bit location */ ".volatile\n\t" ! "st %%fsr,%1\n\t" ! "ld %1,%0\n\t" /* %0 = fsr */ "set 0x0f800000,%%o4\n\t" /* mask of TEM (Trap Enable Mode bits) */ ! "andn %0,%%o4,%3\n\t" ! "or %2,%3,%2\n\t" /* %2 = new fsr */ ! "st %2,%1\n\t" ! "ld %1,%%fsr\n\t" "srl %0,23,%0\n\t" "and %0,0x1f,%0\n\t" ".nonvolatile\n\t" ! : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2) ! : "r" (i) ! : "cc"); return (ret); } extern __inline__ double sqrt(double d) { ! return (__inline_sqrt(d)); } extern __inline__ float sqrtf(float f) { ! return (__inline_sqrtf(f)); } extern __inline__ double fabs(double d) { double ret; ! __asm__ __volatile__("fabsd %1,%0\n\t" : "=e" (ret) : "e" (d)); return (ret); } extern __inline__ float fabsf(float f) { float ret; ! __asm__ __volatile__("fabss %1,%0\n\t" : "=f" (ret) : "f" (f)); return (ret); } #ifdef __cplusplus }