Home | History | Annotate | Line # | Download | only in i386
      1      1.1  joerg // This file is dual licensed under the MIT and the University of Illinois Open
      2      1.1  joerg // Source Licenses. See LICENSE.TXT for details.
      3      1.1  joerg 
      4      1.1  joerg #include "../assembly.h"
      5      1.1  joerg 
      6      1.1  joerg // float __floatundisf(du_int a);
      7      1.1  joerg 
      8      1.1  joerg // Note that there is a hardware instruction, fildll, that does most of what
      9      1.1  joerg // this function needs to do.  However, because of our ia32 ABI, it will take
     10      1.1  joerg // a write-small read-large stall, so the software implementation here is
     11      1.1  joerg // actually several cycles faster.
     12      1.1  joerg 
     13      1.1  joerg // This is a branch-free implementation.  A branchy implementation might be
     14      1.1  joerg // faster for the common case if you know something a priori about the input
     15      1.1  joerg // distribution.
     16      1.1  joerg 
     17      1.1  joerg /* branch-free x87 implementation - one cycle slower than without x87.
     18      1.1  joerg 
     19      1.1  joerg #ifdef __i386__
     20      1.1  joerg 
     21  1.1.1.4  joerg CONST_SECTION
     22  1.1.1.2  joerg .balign 3
     23      1.1  joerg 
     24      1.1  joerg 		.quad	0x43f0000000000000
     25      1.1  joerg twop64:	.quad	0x0000000000000000
     26      1.1  joerg 
     27      1.1  joerg #define			TWOp64			twop64-0b(%ecx,%eax,8)
     28      1.1  joerg 
     29      1.1  joerg .text
     30  1.1.1.2  joerg .balign 4
     31      1.1  joerg DEFINE_COMPILERRT_FUNCTION(__floatundisf)
     32      1.1  joerg 	movl		8(%esp),		%eax
     33      1.1  joerg 	movd		8(%esp),		%xmm1
     34      1.1  joerg 	movd		4(%esp),		%xmm0
     35      1.1  joerg 	punpckldq	%xmm1,			%xmm0
     36      1.1  joerg 	calll		0f
     37      1.1  joerg 0:	popl		%ecx
     38      1.1  joerg 	sarl		$31,			%eax
     39      1.1  joerg 	movq		%xmm0,			4(%esp)
     40      1.1  joerg 	fildll		4(%esp)
     41      1.1  joerg 	faddl		TWOp64
     42      1.1  joerg 	fstps		4(%esp)
     43      1.1  joerg 	flds		4(%esp)
     44      1.1  joerg 	ret
     45      1.1  joerg END_COMPILERRT_FUNCTION(__floatundisf)
     46      1.1  joerg 
     47      1.1  joerg #endif // __i386__
     48      1.1  joerg 
     49      1.1  joerg */
     50      1.1  joerg 
     51      1.1  joerg /* branch-free, x87-free implementation - faster at the expense of code size */
     52      1.1  joerg 
     53      1.1  joerg #ifdef __i386__
     54      1.1  joerg 
     55  1.1.1.4  joerg CONST_SECTION
     56  1.1.1.3  joerg 
     57  1.1.1.3  joerg 	.balign 16
     58  1.1.1.3  joerg twop52:
     59  1.1.1.3  joerg 	.quad 0x4330000000000000
     60  1.1.1.3  joerg 	.quad 0x0000000000000fff
     61  1.1.1.3  joerg 
     62  1.1.1.3  joerg 	.balign 16
     63  1.1.1.3  joerg sticky:
     64  1.1.1.3  joerg 	.quad 0x0000000000000000
     65  1.1.1.3  joerg 	.long 0x00000012
     66  1.1.1.3  joerg 
     67  1.1.1.3  joerg 	.balign 16
     68  1.1.1.3  joerg twelve:
     69  1.1.1.3  joerg 	.long 0x00000000
     70      1.1  joerg 
     71      1.1  joerg #define			TWOp52			twop52-0b(%ecx)
     72      1.1  joerg #define			STICKY			sticky-0b(%ecx,%eax,8)
     73      1.1  joerg 
     74      1.1  joerg .text
     75  1.1.1.2  joerg .balign 4
     76      1.1  joerg DEFINE_COMPILERRT_FUNCTION(__floatundisf)
     77      1.1  joerg 	movl		8(%esp),		%eax
     78      1.1  joerg 	movd		8(%esp),		%xmm1
     79      1.1  joerg 	movd		4(%esp),		%xmm0
     80      1.1  joerg 	punpckldq	%xmm1,			%xmm0
     81      1.1  joerg 
     82      1.1  joerg 	calll		0f
     83      1.1  joerg 0:	popl		%ecx
     84      1.1  joerg 	shrl		%eax					// high 31 bits of input as sint32
     85      1.1  joerg 	addl		$0x7ff80000,	%eax
     86      1.1  joerg 	sarl		$31,			%eax	// (big input) ? -1 : 0
     87      1.1  joerg 	movsd		STICKY,			%xmm1	// (big input) ? 0xfff : 0
     88      1.1  joerg 	movl		$12,			%edx
     89      1.1  joerg 	andl		%eax,			%edx	// (big input) ? 12 : 0
     90      1.1  joerg 	movd		%edx,			%xmm3
     91      1.1  joerg 	andpd		%xmm0,			%xmm1	// (big input) ? input & 0xfff : 0
     92      1.1  joerg 	movsd		TWOp52,			%xmm2	// 0x1.0p52
     93      1.1  joerg 	psrlq		%xmm3,			%xmm0	// (big input) ? input >> 12 : input
     94      1.1  joerg 	orpd		%xmm2,			%xmm1	// 0x1.0p52 + ((big input) ? input & 0xfff : input)
     95      1.1  joerg 	orpd		%xmm1,			%xmm0	// 0x1.0p52 + ((big input) ? (input >> 12 | input & 0xfff) : input)
     96      1.1  joerg 	subsd		%xmm2,			%xmm0	// (double)((big input) ? (input >> 12 | input & 0xfff) : input)
     97      1.1  joerg 	cvtsd2ss	%xmm0,			%xmm0	// (float)((big input) ? (input >> 12 | input & 0xfff) : input)
     98      1.1  joerg 	pslld		$23,			%xmm3
     99      1.1  joerg 	paddd		%xmm3,			%xmm0	// (float)input
    100      1.1  joerg 	movd		%xmm0,			4(%esp)
    101      1.1  joerg 	flds		4(%esp)
    102      1.1  joerg 	ret
    103      1.1  joerg END_COMPILERRT_FUNCTION(__floatundisf)
    104      1.1  joerg 
    105      1.1  joerg #endif // __i386__
    106