this repo has no description
at fixPythonPipStalling 276 lines 8.8 kB view raw
1/* 2 * fmax.s 3 * 4 * by Ian Ollmann 5 * 6 * Copyright 2007 Apple Inc. All Rights Reserved. 7 */ 8 9 10#include <machine/asm.h> 11#include "abi.h" 12 13#if defined( BUILDING_FOR_CARBONCORE_LEGACY ) 14 15 #if defined( __i386__ ) 16 17 ENTRY( fmax ) 18 fldl 8+FRAME_SIZE(STACKP) //{ y } 19 fldl FRAME_SIZE(STACKP) //{ x, y } 20 fucomi %st(0), %st(0) //Check for x is NaN 21 fcmovb %st(1), %st(0) //{ x or y, y} 22 fxch //{ y, x or y } 23 fucomi %st(1), %st(0) //Check y < x or y is NaN 24 fcmovb %st(1), %st(0) //{ max, x or y } 25 fstp %st(1) //{ max } 26 ret 27 28 ENTRY( fmin ) 29 fldl 8+FRAME_SIZE(STACKP) //{ y } 30 fldl FRAME_SIZE(STACKP) //{ x, y } 31 fucomi %st(0), %st(0) //Check for x is NaN 32 fcmovb %st(1), %st(0) //{ x or y, y } 33 fucomi %st(1), %st(0) //Check x < y or y is NaN 34 fxch //{ y, x or y } 35 fcmovb %st(1), %st(0) //{ max, x or y } 36 fstp %st(1) //{ max } 37 ret 38 39 ENTRY( fdim ) 40 movsd FRAME_SIZE( STACKP), %xmm0 // x 41 movsd 8+FRAME_SIZE( STACKP), %xmm1 // y 42 movapd %xmm1, %xmm2 // x 43 ucomisd %xmm0, %xmm1 // if( x != x || y != y ) 44 jp 1f // goto 1 45 cmpltpd %xmm0, %xmm2 // y < x 46 andpd %xmm2, %xmm0 47 andpd %xmm2, %xmm1 48 1: subsd %xmm1, %xmm0 49 movsd %xmm0, FRAME_SIZE(STACKP) 50 fldl FRAME_SIZE(STACKP) 51 ret 52 53 #else 54 55 ENTRY( fmax ) 56 SUBP $16, STACKP 57 58 //create an array on the stack s[2] = { x, y } 59 movsd %xmm0, (STACKP) 60 movsd %xmm1, 8(STACKP) 61 62 //test a = x < y 63 xorq %rax, %rax 64 xorq %rdx, %rdx 65 ucomisd %xmm1, %xmm0 66 setb %al // a = x < y || isnan(y) || isnan(x) 67 ucomisd %xmm1, %xmm1 68 setp %dl // isnan(y) 69 xorq %rdx, %rax // if (isnan(y)) a = 0 70 71 // return s[a] 72 movsd (STACKP,%rax,8), %xmm0 73 ADDP $16, STACKP 74 ret 75 76 ENTRY( fmin ) 77 SUBP $16, STACKP 78 79 //create an array on the stack s[2] = { x, y } 80 movsd %xmm0, (STACKP) 81 movsd %xmm1, 8(STACKP) 82 83 //test a = y < x 84 xorq %rax, %rax 85 xorq %rdx, %rdx 86 ucomisd %xmm0, %xmm1 87 setb %al // a = y < x || isnan(y) || isnan(x) 88 ucomisd %xmm1, %xmm1 89 setp %dl // isnan(y) 90 xorq %rdx, %rax // if (isnan(y)) a = 0 91 92 // return s[a] 93 movsd (STACKP,%rax,8), %xmm0 94 ADDP $16, STACKP 95 ret 96 97 ENTRY( fdim ) 98 //a == ( y < x || isnan( y) || isnan(x) ) 99 xor %eax, %eax 100 ucomisd %xmm0, %xmm1 101 setb %al 102 103 // map a = {0,1} to a = { 0, -1ULL } 104 movd %eax, %xmm2 105 pxor %xmm3, %xmm3 106 psubq %xmm2, %xmm3 107 108 //mask x and y to zero if ( y > x && ! isnan( y) && ! isnan(x) ) 109 andpd %xmm3, %xmm1 110 andpd %xmm3, %xmm0 111 112 //Do the subtract 113 subsd %xmm1, %xmm0 114 ret 115 116 #endif 117 118#else 119 120 //Not CARBONCORE LEGACY 121 122 #if defined( __i386__ ) 123 ENTRY( fmaxf ) 124 flds 4+FRAME_SIZE(STACKP) //{ y } 125 flds FRAME_SIZE(STACKP) //{ x, y } 126 fucomi %st(0), %st(0) //Check for x is NaN 127 fcmovb %st(1), %st(0) //{ x or y, y} 128 fxch //{ y, x or y } 129 fucomi %st(1), %st(0) //Check y < x or y is NaN 130 fcmovb %st(1), %st(0) //{ max, x or y } 131 fstp %st(1) //{ max } 132 ret 133 134 ENTRY( fminf ) 135 flds 4+FRAME_SIZE(STACKP) //{ y } 136 flds FRAME_SIZE(STACKP) //{ x, y } 137 fucomi %st(0), %st(0) //Check for x is NaN 138 fcmovb %st(1), %st(0) //{ x or y, y } 139 fucomi %st(1), %st(0) //Check x < y or y is NaN 140 fxch //{ y, x or y } 141 fcmovb %st(1), %st(0) //{ max, x or y } 142 fstp %st(1) //{ max } 143 ret 144 145 //We have to use xmm here so that the subtraction doesnt take a double rounding 146 ENTRY( fdimf ) 147 movss FRAME_SIZE(STACKP), %xmm0 148 movss 4+FRAME_SIZE(STACKP), %xmm1 149 150 SUBP $4, STACKP 151 152 //a == ( y < x || isnan( y) || isnan(x) ) 153 xor %eax, %eax 154 ucomiss %xmm0, %xmm1 155 setb %al 156 157 // map a = {0,1} to a = { 0, -1ULL } 158 negl %eax 159 movd %eax, %xmm2 160 161 //mask x and y to zero if ( y > x && ! isnan( y) && ! isnan(x) ) 162 andps %xmm2, %xmm1 163 andps %xmm2, %xmm0 164 165 //Do the subtract 166 subss %xmm1, %xmm0 167 movss %xmm0, (STACKP) 168 flds (STACKP) 169 170 ADDP $4, STACKP 171 ret 172 173 174 #else 175 176 ENTRY( fmaxf ) 177 SUBP $8, STACKP 178 179 //create an array on the stack s[2] = { x, y } 180 movss %xmm0, (STACKP) 181 movss %xmm1, 4(STACKP) 182 183 //test a = x < y 184 xorq %rax, %rax 185 xorq %rdx, %rdx 186 ucomiss %xmm1, %xmm0 187 setb %al // a = x < y || isnan(y) || isnan(x) 188 ucomiss %xmm1, %xmm1 189 setp %dl // isnan(y) 190 xorq %rdx, %rax // if (isnan(y)) a = 0 191 192 // return s[a] 193 movss (STACKP,%rax,4), %xmm0 194 ADDP $8, STACKP 195 ret 196 197 ENTRY( fminf ) 198 SUBP $8, STACKP 199 200 //create an array on the stack s[2] = { x, y } 201 movss %xmm0, (STACKP) 202 movss %xmm1, 4(STACKP) 203 204 //test a = y < x 205 xorq %rax, %rax 206 xorq %rdx, %rdx 207 ucomiss %xmm0, %xmm1 208 setb %al // a = y < x || isnan(y) || isnan(x) 209 ucomiss %xmm1, %xmm1 210 setp %dl // isnan(y) 211 xorq %rdx, %rax // if (isnan(y)) a = 0 212 213 // return s[a] 214 movss (STACKP,%rax,4), %xmm0 215 ADDP $8, STACKP 216 ret 217 218 ENTRY( fdimf ) 219 //a == ( y < x || isnan( y) || isnan(x) ) 220 xor %eax, %eax 221 ucomiss %xmm0, %xmm1 222 setb %al 223 224 // map a = {0,1} to a = { 0, -1ULL } 225 negl %eax 226 movd %eax, %xmm2 227 228 //mask x and y to zero if ( y > x && ! isnan( y) && ! isnan(x) ) 229 andps %xmm2, %xmm1 230 andps %xmm2, %xmm0 231 232 //Do the subtract 233 subss %xmm1, %xmm0 234 ret 235 236 #endif 237 238 239 // long double fminl( long double a, long double b ) 240 ENTRY( fminl ) 241 fldt FIRST_ARG_OFFSET(STACKP) // {a} 242 fldt SECOND_ARG_OFFSET(STACKP) // {b,a} 243 fucomi %ST(0), %ST // test b is NaN 244 fcmovu %ST(1), %ST(0) // if( b is NaN) b = a 245 fucomi %ST(1), %ST // b > a 246 fcmovnb %ST(1), %ST(0) 247 fstp %ST(1) 248 ret 249 250 // long double fmaxl( long double a, long double b ) 251 ENTRY( fmaxl ) 252 fldt FIRST_ARG_OFFSET(STACKP) // {a} 253 fldt SECOND_ARG_OFFSET(STACKP) // {b,a} 254 fucomi %ST(0), %ST // test b is NaN 255 fcmovu %ST(1), %ST(0) // if( b is NaN) b = a 256 fld %ST(1) // {a, b, a} 257 fucomip %ST(1), %ST // a >= b 258 fcmovnb %ST(1), %ST(0) 259 fstp %ST(1) 260 ret 261 262 // long double fdiml( long double a, long double b ) 263 ENTRY( fdiml ) 264 fldz // {0} 265 fldt FIRST_ARG_OFFSET(STACKP) // {a, 0} 266 fldt SECOND_ARG_OFFSET(STACKP) // {b, a, 0} 267 fucomi %ST(1), %ST // {b, a, 0} b >= a and not NaN 268 fcmovnb %ST(2), %ST(0) // {b or 0, a, 0 } 269 fxch // {a, b or 0, 0 } 270 fcmovnb %ST(2), %ST(0) // {a or 0, b or 0, 0 } 271 fsubp // {result, 0 } 272 fstp %ST(1) // {result} 273 ret 274 275 276#endif /*BUILDING_FOR_CARBONCORE_LEGACY*/