summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-06-26 16:47:03 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-06-26 16:47:03 +0000
commitb3a6901e66f55b35aa9e01bcb24134e6a65ea004 (patch)
tree4d57d73575ea3f7e30bf430920d6e96fa2a369c1
parent8cbe163cba77c772621f89ddb33793ac170b1fa2 (diff)
Initial import of compiler-rt.
- git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@74292 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--BlocksRuntime/Block.h25
-rw-r--r--BlocksRuntime/Block_private.h29
-rw-r--r--BlocksRuntime/data.c30
-rw-r--r--BlocksRuntime/runtime.c30
-rw-r--r--LICENSE.TXT63
-rw-r--r--Makefile194
-rw-r--r--README.txt133
-rw-r--r--lib/Makefile.mk20
-rw-r--r--lib/absvdi2.c29
-rw-r--r--lib/absvsi2.c29
-rw-r--r--lib/absvti2.c33
-rw-r--r--lib/addvdi3.c36
-rw-r--r--lib/addvsi3.c36
-rw-r--r--lib/addvti3.c40
-rw-r--r--lib/apple_versioning.c146
-rw-r--r--lib/ashldi3.c40
-rw-r--r--lib/ashlti3.c44
-rw-r--r--lib/ashrdi3.c41
-rw-r--r--lib/ashrti3.c45
-rw-r--r--lib/clear_cache.c38
-rw-r--r--lib/clzdi2.c28
-rw-r--r--lib/clzsi2.c51
-rw-r--r--lib/clzti2.c32
-rw-r--r--lib/cmpdi2.c36
-rw-r--r--lib/cmpti2.c40
-rw-r--r--lib/ctzdi2.c28
-rw-r--r--lib/ctzsi2.c54
-rw-r--r--lib/ctzti2.c32
-rw-r--r--lib/divdc3.c58
-rw-r--r--lib/divdi3.c30
-rw-r--r--lib/divsc3.c58
-rw-r--r--lib/divsi3.c30
-rw-r--r--lib/divti3.c34
-rw-r--r--lib/divxc3.c62
-rw-r--r--lib/enable_execute_stack.c36
-rw-r--r--lib/eprintf.c31
-rw-r--r--lib/ffsdi2.c31
-rw-r--r--lib/ffsti2.c35
-rw-r--r--lib/fixdfdi.c41
-rw-r--r--lib/fixdfti.c43
-rw-r--r--lib/fixsfdi.c39
-rw-r--r--lib/fixsfti.c43
-rw-r--r--lib/fixunsdfdi.c42
-rw-r--r--lib/fixunsdfsi.c39
-rw-r--r--lib/fixunsdfti.c44
-rw-r--r--lib/fixunssfdi.c40
-rw-r--r--lib/fixunssfsi.c40
-rw-r--r--lib/fixunssfti.c44
-rw-r--r--lib/fixunsxfdi.c40
-rw-r--r--lib/fixunsxfsi.c40
-rw-r--r--lib/fixunsxfti.c45
-rw-r--r--lib/fixxfdi.c41
-rw-r--r--lib/fixxfti.c44
-rw-r--r--lib/floatdidf.c102
-rw-r--r--lib/floatdisf.c76
-rw-r--r--lib/floatdixf.c43
-rw-r--r--lib/floattidf.c83
-rw-r--r--lib/floattisf.c82
-rw-r--r--lib/floattixf.c83
-rw-r--r--lib/floatundidf.c101
-rw-r--r--lib/floatundisf.c73
-rw-r--r--lib/floatundixf.c40
-rw-r--r--lib/floatuntidf.c80
-rw-r--r--lib/floatuntisf.c79
-rw-r--r--lib/floatuntixf.c80
-rw-r--r--lib/gcc_personality_v0.c237
-rw-r--r--lib/i386/Makefile.mk22
-rw-r--r--lib/i386/ashldi3.s65
-rw-r--r--lib/i386/ashrdi3.s75
-rw-r--r--lib/i386/divdi3.s160
-rw-r--r--lib/i386/floatdidf.s32
-rw-r--r--lib/i386/floatdisf.s30
-rw-r--r--lib/i386/floatdixf.s28
-rw-r--r--lib/i386/floatundidf.s43
-rw-r--r--lib/i386/floatundisf.s95
-rw-r--r--lib/i386/floatundixf.s34
-rw-r--r--lib/i386/lshrdi3.s65
-rw-r--r--lib/i386/moddi3.s165
-rw-r--r--lib/i386/muldi3.s28
-rw-r--r--lib/i386/udivdi3.s113
-rw-r--r--lib/i386/umoddi3.s124
-rw-r--r--lib/int_lib.h143
-rw-r--r--lib/lshrdi3.c40
-rw-r--r--lib/lshrti3.c44
-rw-r--r--lib/moddi3.c31
-rw-r--r--lib/modsi3.c22
-rw-r--r--lib/modti3.c35
-rw-r--r--lib/muldc3.c73
-rw-r--r--lib/muldi3.c53
-rw-r--r--lib/mulsc3.c73
-rw-r--r--lib/multi3.c57
-rw-r--r--lib/mulvdi3.c56
-rw-r--r--lib/mulvsi3.c56
-rw-r--r--lib/mulvti3.c60
-rw-r--r--lib/mulxc3.c77
-rw-r--r--lib/negdi2.c22
-rw-r--r--lib/negti2.c26
-rw-r--r--lib/negvdi2.c28
-rw-r--r--lib/negvsi2.c28
-rw-r--r--lib/negvti2.c32
-rw-r--r--lib/paritydi2.c26
-rw-r--r--lib/paritysi2.c26
-rw-r--r--lib/parityti2.c30
-rw-r--r--lib/popcountdi2.c35
-rw-r--r--lib/popcountsi2.c32
-rw-r--r--lib/popcountti2.c43
-rw-r--r--lib/powidf2.c33
-rw-r--r--lib/powisf2.c33
-rw-r--r--lib/powitf2.c37
-rw-r--r--lib/powixf2.c37
-rw-r--r--lib/ppc/DD.h46
-rw-r--r--lib/ppc/Makefile.mk22
-rw-r--r--lib/ppc/divtc3.c88
-rw-r--r--lib/ppc/fixtfdi.c100
-rw-r--r--lib/ppc/fixunstfdi.c58
-rw-r--r--lib/ppc/floatditf.c34
-rw-r--r--lib/ppc/floatunditf.c40
-rw-r--r--lib/ppc/gcc_qadd.c74
-rw-r--r--lib/ppc/gcc_qdiv.c53
-rw-r--r--lib/ppc/gcc_qmul.c51
-rw-r--r--lib/ppc/gcc_qsub.c74
-rw-r--r--lib/ppc/multc3.c92
-rw-r--r--lib/ppc/restFP.s43
-rw-r--r--lib/ppc/saveFP.s40
-rw-r--r--lib/subvdi3.c36
-rw-r--r--lib/subvsi3.c36
-rw-r--r--lib/subvti3.c40
-rw-r--r--lib/trampoline_setup.c46
-rw-r--r--lib/ucmpdi2.c36
-rw-r--r--lib/ucmpti2.c40
-rw-r--r--lib/udivdi3.c24
-rw-r--r--lib/udivmoddi4.c236
-rw-r--r--lib/udivmodti4.c241
-rw-r--r--lib/udivsi3.c61
-rw-r--r--lib/udivti3.c28
-rw-r--r--lib/umoddi3.c26
-rw-r--r--lib/umodsi3.c22
-rw-r--r--lib/umodti3.c30
-rw-r--r--lib/x86_64/Makefile.mk22
-rw-r--r--lib/x86_64/floatdidf.c15
-rw-r--r--lib/x86_64/floatdisf.c13
-rw-r--r--lib/x86_64/floatdixf.c15
-rw-r--r--lib/x86_64/floatundidf.s40
-rw-r--r--lib/x86_64/floatundisf.s30
-rw-r--r--lib/x86_64/floatundixf.s60
-rw-r--r--make/AppleBI.mk85
-rw-r--r--make/config.mk57
-rwxr-xr-xmake/filter-inputs25
-rw-r--r--make/subdir.mk43
-rw-r--r--make/util.mk29
-rw-r--r--test/Unit/absvdi2_test.c64
-rw-r--r--test/Unit/absvsi2_test.c64
-rw-r--r--test/Unit/absvti2_test.c80
-rw-r--r--test/Unit/addvdi3_test.c58
-rw-r--r--test/Unit/addvsi3_test.c58
-rw-r--r--test/Unit/addvti3_test.c92
-rw-r--r--test/Unit/ashldi3_test.c77
-rw-r--r--test/Unit/ashlti3_test.c173
-rw-r--r--test/Unit/ashrdi3_test.c118
-rw-r--r--test/Unit/ashrti3_test.c171
-rw-r--r--test/Unit/clear_cache_test.c59
-rw-r--r--test/Unit/clzdi2_test.c68
-rw-r--r--test/Unit/clzsi2_test.c599
-rw-r--r--test/Unit/clzti2_test.c88
-rw-r--r--test/Unit/cmpdi2_test.c77
-rw-r--r--test/Unit/cmpti2_test.c110
-rw-r--r--test/Unit/ctzdi2_test.c67
-rw-r--r--test/Unit/ctzsi2_test.c569
-rw-r--r--test/Unit/ctzti2_test.c82
-rw-r--r--test/Unit/divdc3_test.c370
-rw-r--r--test/Unit/divdi3_test.c58
-rw-r--r--test/Unit/divsc3_test.c370
-rw-r--r--test/Unit/divsi3_test.c56
-rw-r--r--test/Unit/divtc3_test.c380
-rw-r--r--test/Unit/divti3_test.c76
-rw-r--r--test/Unit/divxc3_test.c377
-rw-r--r--test/Unit/enable_execute_stack_test.c57
-rw-r--r--test/Unit/ffsdi2_test.c66
-rw-r--r--test/Unit/ffsti2_test.c81
-rw-r--r--test/Unit/fixdfdi_test.c94
-rw-r--r--test/Unit/fixdfti_test.c121
-rw-r--r--test/Unit/fixsfdi_test.c84
-rw-r--r--test/Unit/fixsfti_test.c109
-rw-r--r--test/Unit/fixunsdfdi_test.c106
-rw-r--r--test/Unit/fixunsdfsi_test.c100
-rw-r--r--test/Unit/fixunsdfti_test.c128
-rw-r--r--test/Unit/fixunssfdi_test.c95
-rw-r--r--test/Unit/fixunssfsi_test.c93
-rw-r--r--test/Unit/fixunssfti_test.c120
-rw-r--r--test/Unit/fixunstfdi_test.c119
-rw-r--r--test/Unit/fixunsxfdi_test.c122
-rw-r--r--test/Unit/fixunsxfsi_test.c107
-rw-r--r--test/Unit/fixunsxfti_test.c139
-rw-r--r--test/Unit/fixxfdi_test.c114
-rw-r--r--test/Unit/fixxfti_test.c144
-rw-r--r--test/Unit/floatdidf_test.c137
-rw-r--r--test/Unit/floatdisf_test.c95
-rw-r--r--test/Unit/floatdixf_test.c144
-rw-r--r--test/Unit/floattidf_test.c178
-rw-r--r--test/Unit/floattisf_test.c134
-rw-r--r--test/Unit/floattixf_test.c210
-rw-r--r--test/Unit/floatundidf_test.c132
-rw-r--r--test/Unit/floatundisf_test.c96
-rw-r--r--test/Unit/floatundixf_test.c144
-rw-r--r--test/Unit/floatuntidf_test.c172
-rw-r--r--test/Unit/floatuntisf_test.c163
-rw-r--r--test/Unit/floatuntixf_test.c217
-rw-r--r--test/Unit/gcc_personality_test.c46
-rw-r--r--test/Unit/gcc_personality_test_helper.cxx85
-rw-r--r--test/Unit/int_lib.h163
-rw-r--r--test/Unit/lshrdi3_test.c118
-rw-r--r--test/Unit/lshrti3_test.c171
-rw-r--r--test/Unit/moddi3_test.c62
-rw-r--r--test/Unit/modsi3_test.c58
-rw-r--r--test/Unit/modti3_test.c93
-rw-r--r--test/Unit/muldc3_test.c366
-rw-r--r--test/Unit/muldi3_test.c110
-rw-r--r--test/Unit/mulsc3_test.c370
-rw-r--r--test/Unit/multc3_test.c373
-rw-r--r--test/Unit/multi3_test.c132
-rw-r--r--test/Unit/mulvdi3_test.c175
-rw-r--r--test/Unit/mulvsi3_test.c148
-rw-r--r--test/Unit/mulvti3_test.c258
-rw-r--r--test/Unit/mulxc3_test.c373
-rw-r--r--test/Unit/negdi2_test.c84
-rw-r--r--test/Unit/negti2_test.c125
-rw-r--r--test/Unit/negvdi2_test.c57
-rw-r--r--test/Unit/negvsi2_test.c56
-rw-r--r--test/Unit/negvti2_test.c107
-rw-r--r--test/Unit/paritydi2_test.c51
-rw-r--r--test/Unit/paritysi2_test.c50
-rw-r--r--test/Unit/parityti2_test.c62
-rw-r--r--test/Unit/popcountdi2_test.c63
-rw-r--r--test/Unit/popcountsi2_test.c62
-rw-r--r--test/Unit/popcountti2_test.c80
-rw-r--r--test/Unit/powidf2_test.c224
-rw-r--r--test/Unit/powisf2_test.c224
-rw-r--r--test/Unit/powitf2_test.c230
-rw-r--r--test/Unit/powixf2_test.c230
-rw-r--r--test/Unit/ppc/DD.h14
-rw-r--r--test/Unit/ppc/fixtfdi_test.c477
-rw-r--r--test/Unit/ppc/floatditf_test.c30
-rw-r--r--test/Unit/ppc/floatditf_test.h38018
-rw-r--r--test/Unit/ppc/floatunditf_test.c30
-rw-r--r--test/Unit/ppc/floatunditf_test.h19014
-rw-r--r--test/Unit/ppc/qadd_test.c1872
-rw-r--r--test/Unit/ppc/qdiv_test.c795
-rw-r--r--test/Unit/ppc/qmul_test.c793
-rw-r--r--test/Unit/ppc/qsub_test.c1874
-rwxr-xr-xtest/Unit/ppc/test18
-rw-r--r--test/Unit/subvdi3_test.c60
-rw-r--r--test/Unit/subvsi3_test.c60
-rw-r--r--test/Unit/subvti3_test.c78
-rwxr-xr-xtest/Unit/test36
-rw-r--r--test/Unit/trampoline_setup_test.c49
-rw-r--r--test/Unit/ucmpdi2_test.c75
-rw-r--r--test/Unit/ucmpti2_test.c114
-rw-r--r--test/Unit/udivdi3_test.c44
-rw-r--r--test/Unit/udivmoddi4_test.c20639
-rw-r--r--test/Unit/udivmodti4_test.c65351
-rw-r--r--test/Unit/udivsi3_test.c175
-rw-r--r--test/Unit/udivti3_test.c65
-rw-r--r--test/Unit/umoddi3_test.c44
-rw-r--r--test/Unit/umodsi3_test.c175
-rw-r--r--test/Unit/umodti3_test.c63
-rw-r--r--test/timing/ashldi3.c49
-rw-r--r--test/timing/ashrdi3.c49
-rw-r--r--test/timing/divdi3.c52
-rw-r--r--test/timing/floatdidf.c47
-rw-r--r--test/timing/floatdisf.c47
-rw-r--r--test/timing/floatdixf.c47
-rw-r--r--test/timing/floatundidf.c44
-rw-r--r--test/timing/floatundisf.c47
-rw-r--r--test/timing/floatundixf.c47
-rw-r--r--test/timing/lshrdi3.c49
-rw-r--r--test/timing/moddi3.c52
-rw-r--r--test/timing/muldi3.c52
-rw-r--r--test/timing/negdi2.c50
-rwxr-xr-xtest/timing/time40
-rw-r--r--test/timing/timing.h28
-rw-r--r--test/timing/udivdi3.c52
-rw-r--r--test/timing/umoddi3.c52
282 files changed, 171808 insertions, 36 deletions
diff --git a/BlocksRuntime/Block.h b/BlocksRuntime/Block.h
index eb94bcb69..406e2b3df 100644
--- a/BlocksRuntime/Block.h
+++ b/BlocksRuntime/Block.h
@@ -1,11 +1,24 @@
/*
- * Block.h
+ * Block.h
*
-Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
*
*/
diff --git a/BlocksRuntime/Block_private.h b/BlocksRuntime/Block_private.h
index dd56fa808..386b4455b 100644
--- a/BlocksRuntime/Block_private.h
+++ b/BlocksRuntime/Block_private.h
@@ -1,16 +1,25 @@
/*
* Block_private.h
- * Blaine Garst
- * 2/13/2008
*
- * SPI for Blocks
-
-Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
+ * Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
*/
#ifndef _BLOCK_PRIVATE_H_
diff --git a/BlocksRuntime/data.c b/BlocksRuntime/data.c
index 5f20a00af..7d76270ea 100644
--- a/BlocksRuntime/data.c
+++ b/BlocksRuntime/data.c
@@ -1,15 +1,25 @@
/*
- * data.c
- * libclosure
+ * data.c
+ *
+ * Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
*
- * Created by Blaine Garst on 4/3/08.
-
-Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
*/
/********************
diff --git a/BlocksRuntime/runtime.c b/BlocksRuntime/runtime.c
index 7e71df4e5..0a6df838a 100644
--- a/BlocksRuntime/runtime.c
+++ b/BlocksRuntime/runtime.c
@@ -1,15 +1,25 @@
/*
- * runtime.c
- * libclosure
+ * runtime.c
+ *
+ * Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
*
- * Created by Blaine Garst on 2/1/08.
-
-Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
*/
#include "Block_private.h"
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 000000000..a5e1345f6
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,63 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties. Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program Directory
+------- ---------
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..16ee1a460
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,194 @@
+SubDirs := lib
+
+# Set default rule before anything else.
+all::
+
+include make/config.mk
+include make/util.mk
+# If SRCROOT is defined, assume we are doing an Apple style build. We
+# should be able to use RC_XBS for this but that is unused during
+# "make installsrc".
+ifdef SRCROOT
+ include make/AppleBI.mk
+endif
+
+# Make sure we don't build with a missing ProjObjRoot.
+ifeq ($(ProjObjRoot),)
+$(error Refusing to build with empty ProjObjRoot variable)
+endif
+
+##############
+
+###
+# Rules
+
+###
+# Top level targets
+
+# Provide default clean target which is extended by other templates.
+.PHONY: clean
+clean::
+
+# Test
+.PHONY: test
+test:
+ cd test/Unit && ./test
+
+# Template: Config_template Config
+#
+# This template is used once per Config at the top-level.
+define Config_template
+$(call Set,ActiveConfig,$1)
+$(call Set,ActiveObjPath,$(ProjObjRoot)/$(ActiveConfig))
+$(call Set,ActiveLibGen,$(ActiveObjPath)/libcompiler_rt.Generic.a)
+$(call Set,ActiveLibOpt,$(ActiveObjPath)/libcompiler_rt.Optimized.a)
+
+# The sublibraries to use for a generic version.
+$(call Set,GenericInputs,$(foreach arch,$(Archs),$(ActiveObjPath)/$(arch)/libcompiler_rt.Generic.a))
+# The sublibraries to use for an optimized version.
+$(call Set,OptimizedInputs,$(foreach arch,$(Archs),$(ActiveObjPath)/$(arch)/libcompiler_rt.Optimized.a))
+
+# Provide top-level fat archive targets.
+$(ActiveLibGen): $(GenericInputs) $(ActiveObjPath)/.dir
+ $(Summary) " UNIVERSAL: $(ActiveConfig): $$@"
+ -$(Verb) $(RM) $$@
+ $(Verb) $(Lipo) -create -output $$@ $(GenericInputs)
+$(ActiveLibOpt): $(OptimizedInputs) $(ActiveObjPath)/.dir
+ $(Summary) " UNIVERSAL: $(ActiveConfig): $$@"
+ -$(Verb) $(RM) $$@
+ $(Verb) $(Lipo) -create -output $$@ $(OptimizedInputs)
+.PRECIOUS: $(ActiveObjPath)/.dir
+
+# Add to target lists.
+all:: $(ActiveConfig) $(ActiveLibGen) $(ActiveLibOpt)
+
+# Remove entire config directory on clean.
+clean:: $(ActiveObjPath)/.remove
+endef
+
+# Template: CNA_template Config Arch
+#
+# This template is used once per Config/Arch at the top-level.
+define CNA_template
+$(call Set,ActiveConfig,$1)
+$(call Set,ActiveArch,$2)
+$(call Set,ActiveObjPath,$(ProjObjRoot)/$(ActiveConfig)/$(ActiveArch))
+$(call Set,ActiveLibGen,$(ActiveObjPath)/libcompiler_rt.Generic.a)
+$(call Set,ActiveLibOpt,$(ActiveObjPath)/libcompiler_rt.Optimized.a)
+
+# Initialize inputs lists. This are extended by the CNA_subdir
+# template. The one tricky bit is that we need to use these quoted,
+# because they are not complete until the entire makefile has been
+# processed.
+$(call Set,GenericInputs.$(ActiveConfig).$(ActiveArch),)
+$(call Set,OptimizedInputs.$(ActiveConfig).$(ActiveArch),)
+# Final.Inputs is created once we have loaded all the subdirectories
+# and know what the correct inputs are.
+
+# Provide top-level archive targets.
+$(ActiveLibGen): $(ActiveObjPath)/.dir
+ $(Summary) " ARCHIVE: $(ActiveConfig)/$(ActiveArch): $$@"
+ -$(Verb) $(RM) $$@
+ $(Verb) $(Archive) $$@ $$(Generic.Inputs.$(ActiveConfig).$(ActiveArch))
+ $(Verb) $(Ranlib) $$@
+# FIXME: The dependency on ActiveLibGen is a hack, this picks up the
+# dependencies on the generic inputs.
+$(ActiveLibOpt): $(ActiveLibGen) $(ActiveObjPath)/.dir
+ $(Summary) " ARCHIVE: $(ActiveConfig)/$(ActiveArch): $$@"
+ -$(Verb) $(RM) $$@
+ $(Verb) $(Archive) $$@ $$(Final.Inputs.$(ActiveConfig).$(ActiveArch))
+ $(Verb) $(Ranlib) $$@
+.PRECIOUS: $(ActiveObjPath)/.dir
+
+# Provide some default "alias" targets.
+$(ActiveConfig):: $(ActiveLibGen) $(ActiveLibOpt)
+$(ActiveArch):: $(ActiveLibGen) $(ActiveLibOpt)
+$(ActiveConfig)-$(ActiveArch):: $(ActiveLibGen) $(ActiveLibOpt)
+endef
+
+$(foreach config,$(Configs), \
+ $(foreach arch,$(Archs), \
+ $(eval $(call CNA_template,$(config),$(arch)))))
+
+$(foreach config,$(Configs), \
+ $(eval $(call Config_template,$(config))))
+
+###
+# How to build things.
+
+# Define rules for building on each configuration & architecture. This
+# is not exactly obvious, but variables inside the template are being
+# expanded during the make processing, so automatic variables must be
+# quoted and normal assignment cannot be used.
+
+# Template: CNA_template Config Arch Dir
+# Uses: GetArgs, Dependencies, ObjNames
+#
+# This template is used once per Config/Arch/Dir.
+define CNA_subdir_template
+$(call Set,ActiveConfig,$1)
+$(call Set,ActiveArch,$2)
+$(call Set,ActiveDir,$3)
+$(call Set,ActiveSrcPath,$(ProjSrcRoot)/$(ActiveDir))
+$(call Set,ActiveObjPath,$(ProjObjRoot)/$(ActiveDir)/$(ActiveConfig)/$(ActiveArch))
+
+$(call Set,ActiveFlags,$(call GetArgs,$(ActiveConfig),$(ActiveArch)))
+$(call Set,ActiveObjects,$(ObjNames:%=$(ActiveObjPath)/%))
+
+# Add to the input list for the appropriate library and update the
+# dependency.
+$(call Append,$(Target).Inputs.$(ActiveConfig).$(ActiveArch),$(ActiveObjects))
+$(ProjObjRoot)/$(ActiveConfig)/$(ActiveArch)/libcompiler_rt.$(Target).a: $(ActiveObjects)
+
+$(ActiveObjPath)/%.o: $(ActiveSrcPath)/%.s $(Dependencies) $(ActiveObjPath)/.dir
+ $(Summary) " ASSEMBLE: $(ActiveConfig)/$(ActiveArch): $$<"
+ $(Verb) $(CC) -c -o $$@ $(ActiveFlags) $$<
+.PRECIOUS: $(ActiveObjPath)/.dir
+
+$(ActiveObjPath)/%.o: $(ActiveSrcPath)/%.c $(Dependencies) $(ActiveObjPath)/.dir
+ $(Summary) " COMPILE: $(ActiveConfig)/$(ActiveArch): $$<"
+ $(Verb) $(CC) -c -o $$@ $(ActiveFlags) $$<
+.PRECIOUS: $(ActiveObjPath)/.dir
+
+# Remove entire config directory on clean.
+clean:: $(ProjObjRoot)/$(ActiveDir)/$(ActiveConfig)/.remove
+endef
+
+###
+# Directory handling magic.
+
+# Create directories as needed, and timestamp their creation.
+%/.dir:
+ $(Summary) " MKDIR: $*"
+ $(Verb) $(MKDIR) $* > /dev/null
+ $(Verb) $(DATE) > $@
+
+# Remove directories
+%/.remove:
+ $(Verb) $(RM) -r $*
+
+###
+# Include child makefile fragments
+
+$(foreach subdir,$(SubDirs),$(eval include $(subdir)/Makefile.mk))
+
+###
+# Determine the actual inputs for an optimized library.
+
+# Template: Final_CNA_template Config Arch
+# Uses: GetArgs, Dependencies, ObjNames
+#
+# This template is used once per Config/Arch.
+define Final_CNA_template
+$(call Set,ActiveConfig,$1)
+$(call Set,ActiveArch,$2)
+
+$(call Set,Final.Inputs.$(ActiveConfig).$(ActiveArch),\
+ $(shell make/filter-inputs \
+ $(Optimized.Inputs.$(ActiveConfig).$(ActiveArch)) \
+ $(Generic.Inputs.$(ActiveConfig).$(ActiveArch))))
+endef
+
+$(foreach config,$(Configs), \
+ $(foreach arch,$(Archs), \
+ $(eval $(call Final_CNA_template,$(config),$(arch)))))
diff --git a/README.txt b/README.txt
new file mode 100644
index 000000000..bf93f6000
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,133 @@
+Compiler-RT
+================================
+
+This directory and its subdirectories contain source code for the compiler
+support routines.
+
+Compiler-RT is open source software. You may freely distribute it under the
+terms of the license agreement found in LICENSE.txt.
+
+================================
+
+This is a replacment library for libgcc. Each function is contained
+in its own file. Each function has a corresponding unit test under
+test/Unit.
+
+A rudimentary script to test each file is in the file called
+test/Unit/test.
+
+Here is the specification for this library:
+
+http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc
+
+Here is a synopsis of the contents of this library:
+
+typedef int si_int;
+typedef unsigned su_int;
+
+typedef long long di_int;
+typedef unsigned long long du_int;
+
+// Integral bit manipulation
+
+di_int __ashldi3(di_int a, si_int b); // a << b
+di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill)
+di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill)
+
+si_int __clzsi2(si_int a); // count leading zeroes
+si_int __clzdi2(di_int a); // count leading zeroes
+si_int __ctzsi2(si_int a); // count trailing zeroes
+si_int __ctzdi2(di_int a); // count trailing zeroes
+
+si_int __ffsdi2(di_int a); // find least significant 1 bit
+
+si_int __paritysi2(si_int a); // bit parity
+si_int __paritydi2(di_int a); // bit parity
+
+si_int __popcountsi2(si_int a); // bit population
+si_int __popcountdi2(di_int a); // bit population
+
+// Integral arithmetic
+
+di_int __negdi2 (di_int a); // -a
+di_int __muldi3 (di_int a, di_int b); // a * b
+di_int __divdi3 (di_int a, di_int b); // a / b signed
+du_int __udivdi3 (du_int a, du_int b); // a / b unsigned
+di_int __moddi3 (di_int a, di_int b); // a % b signed
+du_int __umoddi3 (du_int a, du_int b); // a % b unsigned
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b
+
+// Integral arithmetic with trapping overflow
+
+si_int __absvsi2(si_int a); // abs(a)
+di_int __absvdi2(di_int a); // abs(a)
+
+si_int __negvsi2(si_int a); // -a
+di_int __negvdi2(di_int a); // -a
+
+si_int __addvsi3(si_int a, si_int b); // a + b
+di_int __addvdi3(di_int a, di_int b); // a + b
+
+si_int __subvsi3(si_int a, si_int b); // a - b
+di_int __subvdi3(di_int a, di_int b); // a - b
+
+si_int __mulvsi3(si_int a, si_int b); // a * b
+di_int __mulvdi3(di_int a, di_int b); // a * b
+
+// Integral comparison: a < b -> 0
+// a == b -> 1
+// a > b -> 2
+
+si_int __cmpdi2 (di_int a, di_int b);
+si_int __ucmpdi2(du_int a, du_int b);
+
+// Integral / floating point conversion
+
+di_int __fixsfdi( float a);
+di_int __fixdfdi( double a);
+di_int __fixxfdi(long double a);
+
+su_int __fixunssfsi( float a);
+su_int __fixunsdfsi( double a);
+su_int __fixunsxfsi(long double a);
+
+du_int __fixunssfdi( float a);
+du_int __fixunsdfdi( double a);
+du_int __fixunsxfdi(long double a);
+
+float __floatdisf(di_int a);
+double __floatdidf(di_int a);
+long double __floatdixf(di_int a);
+
+float __floatundisf(du_int a);
+double __floatundidf(du_int a);
+long double __floatundixf(du_int a);
+
+// Floating point raised to integer power
+
+float __powisf2( float a, si_int b); // a ^ b
+double __powidf2( double a, si_int b); // a ^ b
+long double __powixf2(long double a, si_int b); // a ^ b
+
+// Complex arithmetic
+
+// (a + ib) * (c + id)
+
+ float _Complex __mulsc3( float a, float b, float c, float d);
+ double _Complex __muldc3(double a, double b, double c, double d);
+long double _Complex __mulxc3(long double a, long double b,
+ long double c, long double d);
+
+// (a + ib) / (c + id)
+
+ float _Complex __divsc3( float a, float b, float c, float d);
+ double _Complex __divdc3(double a, double b, double c, double d);
+long double _Complex __divxc3(long double a, long double b,
+ long double c, long double d);
+
+Preconditions are listed for each function at the definition when there are any.
+Any preconditions reflect the specification at
+http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc.
+
+Assumptions are listed in "int_lib.h", and in individual files. Where possible
+assumptions are checked at compile time.
diff --git a/lib/Makefile.mk b/lib/Makefile.mk
new file mode 100644
index 000000000..0855879ea
--- /dev/null
+++ b/lib/Makefile.mk
@@ -0,0 +1,20 @@
+#===- lib/Makefile.mk --------------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+Dir := lib
+SubDirs := i386 ppc x86_64
+
+Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
+ObjNames := $(Sources:%.c=%.o)
+Target := Generic
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
+
+include make/subdir.mk
diff --git a/lib/absvdi2.c b/lib/absvdi2.c
new file mode 100644
index 000000000..b49554ecc
--- /dev/null
+++ b/lib/absvdi2.c
@@ -0,0 +1,29 @@
+//===-- absvdi2.c - Implement __absvdi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __absvdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: absolute value
+
+// Effects: aborts if abs(x) < 0
+
+di_int
+__absvdi2(di_int a)
+{
+ const int N = (int)(sizeof(di_int) * CHAR_BIT);
+ if (a == ((di_int)1 << (N-1)))
+ abort();
+ const di_int t = a >> (N - 1);
+ return (a ^ t) - t;
+}
diff --git a/lib/absvsi2.c b/lib/absvsi2.c
new file mode 100644
index 000000000..5b28da089
--- /dev/null
+++ b/lib/absvsi2.c
@@ -0,0 +1,29 @@
+//===-- absvsi2.c - Implement __absvsi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __absvsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: absolute value
+
+// Effects: aborts if abs(x) < 0
+
+si_int
+__absvsi2(si_int a)
+{
+ const int N = (int)(sizeof(si_int) * CHAR_BIT);
+ if (a == (1 << (N-1)))
+ abort();
+ const si_int t = a >> (N - 1);
+ return (a ^ t) - t;
+}
diff --git a/lib/absvti2.c b/lib/absvti2.c
new file mode 100644
index 000000000..c0869719d
--- /dev/null
+++ b/lib/absvti2.c
@@ -0,0 +1,33 @@
+//===-- absvti2.c - Implement __absvdi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __absvti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: absolute value
+
+// Effects: aborts if abs(x) < 0
+
+ti_int
+__absvti2(ti_int a)
+{
+ const int N = (int)(sizeof(ti_int) * CHAR_BIT);
+ if (a == ((ti_int)1 << (N-1)))
+ abort();
+ const ti_int s = a >> (N - 1);
+ return (a ^ s) - s;
+}
+
+#endif
diff --git a/lib/addvdi3.c b/lib/addvdi3.c
new file mode 100644
index 000000000..88436e86c
--- /dev/null
+++ b/lib/addvdi3.c
@@ -0,0 +1,36 @@
+//===-- addvdi3.c - Implement __addvdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __addvdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a + b
+
+// Effects: aborts if a + b overflows
+
+di_int
+__addvdi3(di_int a, di_int b)
+{
+ di_int s = a + b;
+ if (b >= 0)
+ {
+ if (s < a)
+ abort();
+ }
+ else
+ {
+ if (s >= a)
+ abort();
+ }
+ return s;
+}
diff --git a/lib/addvsi3.c b/lib/addvsi3.c
new file mode 100644
index 000000000..0eb10c242
--- /dev/null
+++ b/lib/addvsi3.c
@@ -0,0 +1,36 @@
+//===-- addvsi3.c - Implement __addvsi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __addvsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a + b
+
+// Effects: aborts if a + b overflows
+
+si_int
+__addvsi3(si_int a, si_int b)
+{
+ si_int s = a + b;
+ if (b >= 0)
+ {
+ if (s < a)
+ abort();
+ }
+ else
+ {
+ if (s >= a)
+ abort();
+ }
+ return s;
+}
diff --git a/lib/addvti3.c b/lib/addvti3.c
new file mode 100644
index 000000000..5c87d3e8c
--- /dev/null
+++ b/lib/addvti3.c
@@ -0,0 +1,40 @@
+//===-- addvti3.c - Implement __addvti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __addvti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a + b
+
+// Effects: aborts if a + b overflows
+
+ti_int
+__addvti3(ti_int a, ti_int b)
+{
+ ti_int s = a + b;
+ if (b >= 0)
+ {
+ if (s < a)
+ abort();
+ }
+ else
+ {
+ if (s >= a)
+ abort();
+ }
+ return s;
+}
+
+#endif
diff --git a/lib/apple_versioning.c b/lib/apple_versioning.c
new file mode 100644
index 000000000..44373f4d7
--- /dev/null
+++ b/lib/apple_versioning.c
@@ -0,0 +1,146 @@
+//===-- apple_versioning.c - Adds versioning symbols for ld ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+
+
+#if __APPLE__
+ #if __ppc__
+ #define NOT_HERE_BEFORE_10_6(sym) \
+ extern const char sym##_tmp3 __asm("$ld$hide$os10.3$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp3 = 0; \
+ extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
+ extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
+ #else
+ #define NOT_HERE_BEFORE_10_6(sym) \
+ extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
+ extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
+ #endif
+
+
+//
+// Symbols in libSystem.dylib in 10.6 and later,
+// but are in libgcc_s.dylib in earlier versions
+//
+NOT_HERE_BEFORE_10_6(__absvdi2)
+NOT_HERE_BEFORE_10_6(__absvsi2)
+NOT_HERE_BEFORE_10_6(__absvti2)
+NOT_HERE_BEFORE_10_6(__addvdi3)
+NOT_HERE_BEFORE_10_6(__addvsi3)
+NOT_HERE_BEFORE_10_6(__addvti3)
+NOT_HERE_BEFORE_10_6(__ashldi3)
+NOT_HERE_BEFORE_10_6(__ashlti3)
+NOT_HERE_BEFORE_10_6(__ashrdi3)
+NOT_HERE_BEFORE_10_6(__ashrti3)
+NOT_HERE_BEFORE_10_6(__clear_cache)
+NOT_HERE_BEFORE_10_6(__clzdi2)
+NOT_HERE_BEFORE_10_6(__clzsi2)
+NOT_HERE_BEFORE_10_6(__clzti2)
+NOT_HERE_BEFORE_10_6(__cmpdi2)
+NOT_HERE_BEFORE_10_6(__cmpti2)
+NOT_HERE_BEFORE_10_6(__ctzdi2)
+NOT_HERE_BEFORE_10_6(__ctzsi2)
+NOT_HERE_BEFORE_10_6(__ctzti2)
+NOT_HERE_BEFORE_10_6(__divdc3)
+NOT_HERE_BEFORE_10_6(__divdi3)
+NOT_HERE_BEFORE_10_6(__divsc3)
+NOT_HERE_BEFORE_10_6(__divtc3)
+NOT_HERE_BEFORE_10_6(__divti3)
+NOT_HERE_BEFORE_10_6(__divxc3)
+NOT_HERE_BEFORE_10_6(__enable_execute_stack)
+NOT_HERE_BEFORE_10_6(__ffsdi2)
+NOT_HERE_BEFORE_10_6(__ffsti2)
+NOT_HERE_BEFORE_10_6(__fixdfdi)
+NOT_HERE_BEFORE_10_6(__fixdfti)
+NOT_HERE_BEFORE_10_6(__fixsfdi)
+NOT_HERE_BEFORE_10_6(__fixsfti)
+NOT_HERE_BEFORE_10_6(__fixtfdi)
+NOT_HERE_BEFORE_10_6(__fixunsdfdi)
+NOT_HERE_BEFORE_10_6(__fixunsdfsi)
+NOT_HERE_BEFORE_10_6(__fixunsdfti)
+NOT_HERE_BEFORE_10_6(__fixunssfdi)
+NOT_HERE_BEFORE_10_6(__fixunssfsi)
+NOT_HERE_BEFORE_10_6(__fixunssfti)
+NOT_HERE_BEFORE_10_6(__fixunstfdi)
+NOT_HERE_BEFORE_10_6(__fixunsxfdi)
+NOT_HERE_BEFORE_10_6(__fixunsxfsi)
+NOT_HERE_BEFORE_10_6(__fixunsxfti)
+NOT_HERE_BEFORE_10_6(__fixxfdi)
+NOT_HERE_BEFORE_10_6(__fixxfti)
+NOT_HERE_BEFORE_10_6(__floatdidf)
+NOT_HERE_BEFORE_10_6(__floatdisf)
+NOT_HERE_BEFORE_10_6(__floatditf)
+NOT_HERE_BEFORE_10_6(__floatdixf)
+NOT_HERE_BEFORE_10_6(__floattidf)
+NOT_HERE_BEFORE_10_6(__floattisf)
+NOT_HERE_BEFORE_10_6(__floattixf)
+NOT_HERE_BEFORE_10_6(__floatundidf)
+NOT_HERE_BEFORE_10_6(__floatundisf)
+NOT_HERE_BEFORE_10_6(__floatunditf)
+NOT_HERE_BEFORE_10_6(__floatundixf)
+NOT_HERE_BEFORE_10_6(__floatuntidf)
+NOT_HERE_BEFORE_10_6(__floatuntisf)
+NOT_HERE_BEFORE_10_6(__floatuntixf)
+NOT_HERE_BEFORE_10_6(__gcc_personality_v0)
+NOT_HERE_BEFORE_10_6(__lshrdi3)
+NOT_HERE_BEFORE_10_6(__lshrti3)
+NOT_HERE_BEFORE_10_6(__moddi3)
+NOT_HERE_BEFORE_10_6(__modti3)
+NOT_HERE_BEFORE_10_6(__muldc3)
+NOT_HERE_BEFORE_10_6(__muldi3)
+NOT_HERE_BEFORE_10_6(__mulsc3)
+NOT_HERE_BEFORE_10_6(__multc3)
+NOT_HERE_BEFORE_10_6(__multi3)
+NOT_HERE_BEFORE_10_6(__mulvdi3)
+NOT_HERE_BEFORE_10_6(__mulvsi3)
+NOT_HERE_BEFORE_10_6(__mulvti3)
+NOT_HERE_BEFORE_10_6(__mulxc3)
+NOT_HERE_BEFORE_10_6(__negdi2)
+NOT_HERE_BEFORE_10_6(__negti2)
+NOT_HERE_BEFORE_10_6(__negvdi2)
+NOT_HERE_BEFORE_10_6(__negvsi2)
+NOT_HERE_BEFORE_10_6(__negvti2)
+NOT_HERE_BEFORE_10_6(__paritydi2)
+NOT_HERE_BEFORE_10_6(__paritysi2)
+NOT_HERE_BEFORE_10_6(__parityti2)
+NOT_HERE_BEFORE_10_6(__popcountdi2)
+NOT_HERE_BEFORE_10_6(__popcountsi2)
+NOT_HERE_BEFORE_10_6(__popcountti2)
+NOT_HERE_BEFORE_10_6(__powidf2)
+NOT_HERE_BEFORE_10_6(__powisf2)
+NOT_HERE_BEFORE_10_6(__powitf2)
+NOT_HERE_BEFORE_10_6(__powixf2)
+NOT_HERE_BEFORE_10_6(__subvdi3)
+NOT_HERE_BEFORE_10_6(__subvsi3)
+NOT_HERE_BEFORE_10_6(__subvti3)
+NOT_HERE_BEFORE_10_6(__ucmpdi2)
+NOT_HERE_BEFORE_10_6(__ucmpti2)
+NOT_HERE_BEFORE_10_6(__udivdi3)
+NOT_HERE_BEFORE_10_6(__udivmoddi4)
+NOT_HERE_BEFORE_10_6(__udivmodti4)
+NOT_HERE_BEFORE_10_6(__udivti3)
+NOT_HERE_BEFORE_10_6(__umoddi3)
+NOT_HERE_BEFORE_10_6(__umodti3)
+
+
+#if __ppc__
+NOT_HERE_BEFORE_10_6(__gcc_qadd)
+NOT_HERE_BEFORE_10_6(__gcc_qdiv)
+NOT_HERE_BEFORE_10_6(__gcc_qmul)
+NOT_HERE_BEFORE_10_6(__gcc_qsub)
+NOT_HERE_BEFORE_10_6(__trampoline_setup)
+#endif
+
+
+#endif // __APPLE__
+
diff --git a/lib/ashldi3.c b/lib/ashldi3.c
new file mode 100644
index 000000000..e9e24c31d
--- /dev/null
+++ b/lib/ashldi3.c
@@ -0,0 +1,40 @@
+//===-- ashldi3.c - Implement __ashldi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ashldi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a << b
+
+// Precondition: 0 <= b < bits_in_dword
+
+di_int
+__ashldi3(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) // bits_in_word <= b < bits_in_dword
+ {
+ result.low = 0;
+ result.high = input.low << (b - bits_in_word);
+ }
+ else // 0 <= b < bits_in_word
+ {
+ if (b == 0)
+ return a;
+ result.low = input.low << b;
+ result.high = (input.high << b) | (input.low >> (bits_in_word - b));
+ }
+ return result.all;
+}
diff --git a/lib/ashlti3.c b/lib/ashlti3.c
new file mode 100644
index 000000000..1b6968192
--- /dev/null
+++ b/lib/ashlti3.c
@@ -0,0 +1,44 @@
+//===-- ashlti3.c - Implement __ashlti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ashlti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: a << b
+
+// Precondition: 0 <= b < bits_in_tword
+
+ti_int
+__ashlti3(ti_int a, si_int b)
+{
+ const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
+ twords input;
+ twords result;
+ input.all = a;
+ if (b & bits_in_dword) // bits_in_dword <= b < bits_in_tword
+ {
+ result.low = 0;
+ result.high = input.low << (b - bits_in_dword);
+ }
+ else // 0 <= b < bits_in_dword
+ {
+ if (b == 0)
+ return a;
+ result.low = input.low << b;
+ result.high = (input.high << b) | (input.low >> (bits_in_dword - b));
+ }
+ return result.all;
+}
+
+#endif
diff --git a/lib/ashrdi3.c b/lib/ashrdi3.c
new file mode 100644
index 000000000..fc2e6d843
--- /dev/null
+++ b/lib/ashrdi3.c
@@ -0,0 +1,41 @@
+//===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ashrdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: arithmetic a >> b
+
+// Precondition: 0 <= b < bits_in_dword
+
+di_int
+__ashrdi3(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) // bits_in_word <= b < bits_in_dword
+ {
+ // result.high = input.high < 0 ? -1 : 0
+ result.high = input.high >> (bits_in_word - 1);
+ result.low = input.high >> (b - bits_in_word);
+ }
+ else // 0 <= b < bits_in_word
+ {
+ if (b == 0)
+ return a;
+ result.high = input.high >> b;
+ result.low = (input.high << (bits_in_word - b)) | (input.low >> b);
+ }
+ return result.all;
+}
diff --git a/lib/ashrti3.c b/lib/ashrti3.c
new file mode 100644
index 000000000..bfdd2eb99
--- /dev/null
+++ b/lib/ashrti3.c
@@ -0,0 +1,45 @@
+//===-- ashrti3.c - Implement __ashrti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ashrti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: arithmetic a >> b
+
+// Precondition: 0 <= b < bits_in_tword
+
+ti_int
+__ashrti3(ti_int a, si_int b)
+{
+ const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
+ twords input;
+ twords result;
+ input.all = a;
+ if (b & bits_in_dword) // bits_in_dword <= b < bits_in_tword
+ {
+ // result.high = input.high < 0 ? -1 : 0
+ result.high = input.high >> (bits_in_dword - 1);
+ result.low = input.high >> (b - bits_in_dword);
+ }
+ else // 0 <= b < bits_in_dword
+ {
+ if (b == 0)
+ return a;
+ result.high = input.high >> b;
+ result.low = (input.high << (bits_in_dword - b)) | (input.low >> b);
+ }
+ return result.all;
+}
+
+#endif
diff --git a/lib/clear_cache.c b/lib/clear_cache.c
new file mode 100644
index 000000000..8176c24e6
--- /dev/null
+++ b/lib/clear_cache.c
@@ -0,0 +1,38 @@
+//===-- clear_cache.c - Implement __clear_cache ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#if __APPLE__
+ #include <libkern/OSCacheControl.h>
+#endif
+
+//
+// The compiler generates calls to __clear_cache() when creating
+// trampoline functions on the stack for use with nested functions.
+// It is expected to invalidate the instruction cache for the
+// specified range.
+//
+void __clear_cache(void* start, void* end)
+{
+#if __i386__ || __x86_64__
+//
+// Intel processors have a unified instruction and data cache
+// so there is nothing to do
+//
+#else
+ #if __APPLE__
+ // On Darwin, sys_icache_invalidate() provides this functionality
+ sys_icache_invalidate(start, end-start);
+ #else
+ abort();
+ #endif
+#endif
+}
+
diff --git a/lib/clzdi2.c b/lib/clzdi2.c
new file mode 100644
index 000000000..7e58a5aa7
--- /dev/null
+++ b/lib/clzdi2.c
@@ -0,0 +1,28 @@
+//===-- clzdi2.c - Implement __clzdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __clzdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+si_int
+__clzdi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ const si_int f = -(x.high == 0);
+ return __builtin_clz((x.high & ~f) | (x.low & f)) +
+ (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
+}
diff --git a/lib/clzsi2.c b/lib/clzsi2.c
new file mode 100644
index 000000000..52062ab22
--- /dev/null
+++ b/lib/clzsi2.c
@@ -0,0 +1,51 @@
+//===-- clzsi2.c - Implement __clzsi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __clzsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+si_int
+__clzsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ si_int t = ((x & 0xFFFF0000) == 0) << 4; // if (x is small) t = 16 else 0
+ x >>= 16 - t; // x = [0 - 0xFFFF]
+ su_int r = t; // r = [0, 16]
+ // return r + clz(x)
+ t = ((x & 0xFF00) == 0) << 3;
+ x >>= 8 - t; // x = [0 - 0xFF]
+ r += t; // r = [0, 8, 16, 24]
+ // return r + clz(x)
+ t = ((x & 0xF0) == 0) << 2;
+ x >>= 4 - t; // x = [0 - 0xF]
+ r += t; // r = [0, 4, 8, 12, 16, 20, 24, 28]
+ // return r + clz(x)
+ t = ((x & 0xC) == 0) << 1;
+ x >>= 2 - t; // x = [0 - 3]
+ r += t; // r = [0 - 30] and is even
+ // return r + clz(x)
+// switch (x)
+// {
+// case 0:
+// return r + 2;
+// case 1:
+// return r + 1;
+// case 2:
+// case 3:
+// return r;
+// }
+ return r + ((2 - x) & -((x & 2) == 0));
+}
diff --git a/lib/clzti2.c b/lib/clzti2.c
new file mode 100644
index 000000000..b53106977
--- /dev/null
+++ b/lib/clzti2.c
@@ -0,0 +1,32 @@
+//===-- clzti2.c - Implement __clzti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __clzti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+si_int
+__clzti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ const di_int f = -(x.high == 0);
+ return __builtin_clzll((x.high & ~f) | (x.low & f)) +
+ ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
+}
+
+#endif
diff --git a/lib/cmpdi2.c b/lib/cmpdi2.c
new file mode 100644
index 000000000..f398ea257
--- /dev/null
+++ b/lib/cmpdi2.c
@@ -0,0 +1,36 @@
+//===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __cmpdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+si_int
+__cmpdi2(di_int a, di_int b)
+{
+ dwords x;
+ x.all = a;
+ dwords y;
+ y.all = b;
+ if (x.high < y.high)
+ return 0;
+ if (x.high > y.high)
+ return 2;
+ if (x.low < y.low)
+ return 0;
+ if (x.low > y.low)
+ return 2;
+ return 1;
+}
diff --git a/lib/cmpti2.c b/lib/cmpti2.c
new file mode 100644
index 000000000..775977a74
--- /dev/null
+++ b/lib/cmpti2.c
@@ -0,0 +1,40 @@
+//===-- cmpti2.c - Implement __cmpti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __cmpti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+si_int
+__cmpti2(ti_int a, ti_int b)
+{
+ twords x;
+ x.all = a;
+ twords y;
+ y.all = b;
+ if (x.high < y.high)
+ return 0;
+ if (x.high > y.high)
+ return 2;
+ if (x.low < y.low)
+ return 0;
+ if (x.low > y.low)
+ return 2;
+ return 1;
+}
+
+#endif
diff --git a/lib/ctzdi2.c b/lib/ctzdi2.c
new file mode 100644
index 000000000..8ea3ab319
--- /dev/null
+++ b/lib/ctzdi2.c
@@ -0,0 +1,28 @@
+//===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ctzdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+si_int
+__ctzdi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ const si_int f = -(x.low == 0);
+ return __builtin_ctz((x.high & f) | (x.low & ~f)) +
+ (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
+}
diff --git a/lib/ctzsi2.c b/lib/ctzsi2.c
new file mode 100644
index 000000000..1e6c2fe18
--- /dev/null
+++ b/lib/ctzsi2.c
@@ -0,0 +1,54 @@
+//===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ctzsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+si_int
+__ctzsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ si_int t = ((x & 0x0000FFFF) == 0) << 4; // if (x has no small bits) t = 16 else 0
+ x >>= t; // x = [0 - 0xFFFF] + higher garbage bits
+ su_int r = t; // r = [0, 16]
+ // return r + ctz(x)
+ t = ((x & 0x00FF) == 0) << 3;
+ x >>= t; // x = [0 - 0xFF] + higher garbage bits
+ r += t; // r = [0, 8, 16, 24]
+ // return r + ctz(x)
+ t = ((x & 0x0F) == 0) << 2;
+ x >>= t; // x = [0 - 0xF] + higher garbage bits
+ r += t; // r = [0, 4, 8, 12, 16, 20, 24, 28]
+ // return r + ctz(x)
+ t = ((x & 0x3) == 0) << 1;
+ x >>= t;
+ x &= 3; // x = [0 - 3]
+ r += t; // r = [0 - 30] and is even
+ // return r + ctz(x)
+// The branch-less return statement below is equivalent
+// to the following switch statement:
+// switch (x)
+// {
+// case 0:
+// return r + 2;
+// case 2:
+// return r + 1;
+// case 1:
+// case 3:
+// return r;
+// }
+ return r + ((2 - (x >> 1)) & -((x & 1) == 0));
+}
diff --git a/lib/ctzti2.c b/lib/ctzti2.c
new file mode 100644
index 000000000..828db2662
--- /dev/null
+++ b/lib/ctzti2.c
@@ -0,0 +1,32 @@
+//===-- ctzti2.c - Implement __ctzti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ctzti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+si_int
+__ctzti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ const di_int f = -(x.low == 0);
+ return __builtin_ctzll((x.high & f) | (x.low & ~f)) +
+ ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
+}
+
+#endif
diff --git a/lib/divdc3.c b/lib/divdc3.c
new file mode 100644
index 000000000..1b19e665f
--- /dev/null
+++ b/lib/divdc3.c
@@ -0,0 +1,58 @@
+//===-- divdc3.c - Implement __divdc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __divdc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+double _Complex
+__divdc3(double __a, double __b, double __c, double __d)
+{
+ int __ilogbw = 0;
+ double __logbw = logb(fmax(fabs(__c), fabs(__d)));
+ if (isfinite(__logbw))
+ {
+ __ilogbw = (int)__logbw;
+ __c = scalbn(__c, -__ilogbw);
+ __d = scalbn(__d, -__ilogbw);
+ }
+ double __denom = __c * __c + __d * __d;
+ double _Complex z;
+ __real__ z = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
+ __imag__ z = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ if ((__denom == 0.0) && (!isnan(__a) || !isnan(__b)))
+ {
+ __real__ z = copysign(INFINITY, __c) * __a;
+ __imag__ z = copysign(INFINITY, __c) * __b;
+ }
+ else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+ {
+ __a = copysign(isinf(__a) ? 1.0 : 0.0, __a);
+ __b = copysign(isinf(__b) ? 1.0 : 0.0, __b);
+ __real__ z = INFINITY * (__a * __c + __b * __d);
+ __imag__ z = INFINITY * (__b * __c - __a * __d);
+ }
+ else if (isinf(__logbw) && __logbw > 0.0 && isfinite(__a) && isfinite(__b))
+ {
+ __c = copysign(isinf(__c) ? 1.0 : 0.0, __c);
+ __d = copysign(isinf(__d) ? 1.0 : 0.0, __d);
+ __real__ z = 0.0 * (__a * __c + __b * __d);
+ __imag__ z = 0.0 * (__b * __c - __a * __d);
+ }
+ }
+ return z;
+}
diff --git a/lib/divdi3.c b/lib/divdi3.c
new file mode 100644
index 000000000..9580156b9
--- /dev/null
+++ b/lib/divdi3.c
@@ -0,0 +1,30 @@
+//===-- divdi3.c - Implement __divdi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __divdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+// Returns: a / b
+
+di_int
+__divdi3(di_int a, di_int b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+ di_int s_a = a >> bits_in_dword_m1; // s_a = a < 0 ? -1 : 0
+ di_int s_b = b >> bits_in_dword_m1; // s_b = b < 0 ? -1 : 0
+ a = (a ^ s_a) - s_a; // negate if s_a == -1
+ b = (b ^ s_b) - s_b; // negate if s_b == -1
+ s_a ^= s_b; // sign of quotient
+ return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; // negate if s_a == -1
+}
diff --git a/lib/divsc3.c b/lib/divsc3.c
new file mode 100644
index 000000000..bea15cdc4
--- /dev/null
+++ b/lib/divsc3.c
@@ -0,0 +1,58 @@
+//===-- divsc3.c - Implement __divsc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __divsc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+float _Complex
+__divsc3(float __a, float __b, float __c, float __d)
+{
+ int __ilogbw = 0;
+ float __logbw = logbf(fmaxf(fabsf(__c), fabsf(__d)));
+ if (isfinite(__logbw))
+ {
+ __ilogbw = (int)__logbw;
+ __c = scalbnf(__c, -__ilogbw);
+ __d = scalbnf(__d, -__ilogbw);
+ }
+ float __denom = __c * __c + __d * __d;
+ float _Complex z;
+ __real__ z = scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw);
+ __imag__ z = scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ if ((__denom == 0) && (!isnan(__a) || !isnan(__b)))
+ {
+ __real__ z = copysignf(INFINITY, __c) * __a;
+ __imag__ z = copysignf(INFINITY, __c) * __b;
+ }
+ else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+ {
+ __a = copysignf(isinf(__a) ? 1 : 0, __a);
+ __b = copysignf(isinf(__b) ? 1 : 0, __b);
+ __real__ z = INFINITY * (__a * __c + __b * __d);
+ __imag__ z = INFINITY * (__b * __c - __a * __d);
+ }
+ else if (isinf(__logbw) && __logbw > 0 && isfinite(__a) && isfinite(__b))
+ {
+ __c = copysignf(isinf(__c) ? 1 : 0, __c);
+ __d = copysignf(isinf(__d) ? 1 : 0, __d);
+ __real__ z = 0 * (__a * __c + __b * __d);
+ __imag__ z = 0 * (__b * __c - __a * __d);
+ }
+ }
+ return z;
+}
diff --git a/lib/divsi3.c b/lib/divsi3.c
new file mode 100644
index 000000000..8d720eb1d
--- /dev/null
+++ b/lib/divsi3.c
@@ -0,0 +1,30 @@
+//===-- divsi3.c - Implement __divsi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __divsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+su_int __udivsi3(su_int n, su_int d);
+
+// Returns: a / b
+
+si_int
+__divsi3(si_int a, si_int b)
+{
+ const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1;
+ si_int s_a = a >> bits_in_word_m1; // s_a = a < 0 ? -1 : 0
+ si_int s_b = b >> bits_in_word_m1; // s_b = b < 0 ? -1 : 0
+ a = (a ^ s_a) - s_a; // negate if s_a == -1
+ b = (b ^ s_b) - s_b; // negate if s_b == -1
+ s_a ^= s_b; // sign of quotient
+ return (__udivsi3(a, b) ^ s_a) - s_a; // negate if s_a == -1
+}
diff --git a/lib/divti3.c b/lib/divti3.c
new file mode 100644
index 000000000..b8eda254c
--- /dev/null
+++ b/lib/divti3.c
@@ -0,0 +1,34 @@
+//===-- divti3.c - Implement __divti3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __divti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+// Returns: a / b
+
+ti_int
+__divti3(ti_int a, ti_int b)
+{
+ const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
+ ti_int s_a = a >> bits_in_tword_m1; // s_a = a < 0 ? -1 : 0
+ ti_int s_b = b >> bits_in_tword_m1; // s_b = b < 0 ? -1 : 0
+ a = (a ^ s_a) - s_a; // negate if s_a == -1
+ b = (b ^ s_b) - s_b; // negate if s_b == -1
+ s_a ^= s_b; // sign of quotient
+ return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; // negate if s_a == -1
+}
+
+#endif
diff --git a/lib/divxc3.c b/lib/divxc3.c
new file mode 100644
index 000000000..4ee09b9db
--- /dev/null
+++ b/lib/divxc3.c
@@ -0,0 +1,62 @@
+//===-- divxc3.c - Implement __divxc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __divxc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+long double _Complex
+__divxc3(long double __a, long double __b, long double __c, long double __d)
+{
+ int __ilogbw = 0;
+ long double __logbw = logbl(fmaxl(fabsl(__c), fabsl(__d)));
+ if (isfinite(__logbw))
+ {
+ __ilogbw = (int)__logbw;
+ __c = scalbnl(__c, -__ilogbw);
+ __d = scalbnl(__d, -__ilogbw);
+ }
+ long double __denom = __c * __c + __d * __d;
+ long double _Complex z;
+ __real__ z = scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
+ __imag__ z = scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ if ((__denom == 0) && (!isnan(__a) || !isnan(__b)))
+ {
+ __real__ z = copysignl(INFINITY, __c) * __a;
+ __imag__ z = copysignl(INFINITY, __c) * __b;
+ }
+ else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+ {
+ __a = copysignl(isinf(__a) ? 1 : 0, __a);
+ __b = copysignl(isinf(__b) ? 1 : 0, __b);
+ __real__ z = INFINITY * (__a * __c + __b * __d);
+ __imag__ z = INFINITY * (__b * __c - __a * __d);
+ }
+ else if (isinf(__logbw) && __logbw > 0 && isfinite(__a) && isfinite(__b))
+ {
+ __c = copysignl(isinf(__c) ? 1 : 0, __c);
+ __d = copysignl(isinf(__d) ? 1 : 0, __d);
+ __real__ z = 0 * (__a * __c + __b * __d);
+ __imag__ z = 0 * (__b * __c - __a * __d);
+ }
+ }
+ return z;
+}
+
+#endif
diff --git a/lib/enable_execute_stack.c b/lib/enable_execute_stack.c
new file mode 100644
index 000000000..2c1878238
--- /dev/null
+++ b/lib/enable_execute_stack.c
@@ -0,0 +1,36 @@
+//===-- enable_execute_stack.c - Implement __enable_execute_stack ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+#include <sys/mman.h>
+
+
+//
+// The compiler generates calls to __enable_execute_stack() when creating
+// trampoline functions on the stack for use with nested functions.
+// It is expected to mark the page(s) containing the address
+// and the next 48 bytes as executable. Since the stack is normally rw-
+// that means changing the protection on those page(s) to rwx.
+//
+void __enable_execute_stack(void* addr)
+{
+#if __APPLE__
+ // On Darwin, pagesize is always 4096 bytes
+ const uintptr_t pageSize = 4096;
+#else
+ abort();
+#endif
+ const uintptr_t pageAlignMask = ~(pageSize-1);
+ uintptr_t p = (uintptr_t)addr;
+ unsigned char* startPage = (unsigned char*)(p & pageAlignMask);
+ unsigned char* endPage = (unsigned char*)((p+48+pageSize) & pageAlignMask);
+ mprotect(startPage, endPage-startPage, PROT_READ | PROT_WRITE | PROT_EXEC);
+}
+
+
diff --git a/lib/eprintf.c b/lib/eprintf.c
new file mode 100644
index 000000000..56d6c18fb
--- /dev/null
+++ b/lib/eprintf.c
@@ -0,0 +1,31 @@
+//===---------- eprintf.c - Implements __eprintf --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+//
+// __eprintf() was used in an old version of <assert.h>.
+// It can eventually go away, but it is needed when linking
+// .o files built with the old <assert.h>.
+//
+// It should never be exported from a dylib, so it is marked
+// visibility hidden.
+//
+__attribute__((visibility("hidden")))
+void __eprintf(const char* format, const char* assertion_expression,
+ const char* line, const char* file)
+{
+ fprintf(stderr, format, assertion_expression, line, file);
+ fflush(stderr);
+ abort();
+}
diff --git a/lib/ffsdi2.c b/lib/ffsdi2.c
new file mode 100644
index 000000000..93afc6ce3
--- /dev/null
+++ b/lib/ffsdi2.c
@@ -0,0 +1,31 @@
+//===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ffsdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: the index of the least significant 1-bit in a, or
+// the value zero if a is zero. The least significant bit is index one.
+
+si_int
+__ffsdi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ if (x.low == 0)
+ {
+ if (x.high == 0)
+ return 0;
+ return __builtin_ctz(x.high) + (1 + sizeof(si_int) * CHAR_BIT);
+ }
+ return __builtin_ctz(x.low) + 1;
+}
diff --git a/lib/ffsti2.c b/lib/ffsti2.c
new file mode 100644
index 000000000..194c2cbb4
--- /dev/null
+++ b/lib/ffsti2.c
@@ -0,0 +1,35 @@
+//===-- ffsti2.c - Implement __ffsti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ffsti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: the index of the least significant 1-bit in a, or
+// the value zero if a is zero. The least significant bit is index one.
+
+si_int
+__ffsti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ if (x.low == 0)
+ {
+ if (x.high == 0)
+ return 0;
+ return __builtin_ctzll(x.high) + (1 + sizeof(di_int) * CHAR_BIT);
+ }
+ return __builtin_ctzll(x.low) + 1;
+}
+
+#endif
diff --git a/lib/fixdfdi.c b/lib/fixdfdi.c
new file mode 100644
index 000000000..87368b7e5
--- /dev/null
+++ b/lib/fixdfdi.c
@@ -0,0 +1,41 @@
+//===-- fixdfdi.c - Implement __fixdfdi -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixdfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// su_int is a 32 bit integral type
+// value in double is representable in di_int (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+di_int
+__fixdfdi(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0)
+ return 0;
+ di_int s = (si_int)(fb.u.high & 0x80000000) >> 31;
+ dwords r;
+ r.high = (fb.u.high & 0x000FFFFF) | 0x00100000;
+ r.low = fb.u.low;
+ if (e > 52)
+ r.all <<= (e - 52);
+ else
+ r.all >>= (52 - e);
+ return (r.all ^ s) - s;
+}
diff --git a/lib/fixdfti.c b/lib/fixdfti.c
new file mode 100644
index 000000000..94fc8d3d1
--- /dev/null
+++ b/lib/fixdfti.c
@@ -0,0 +1,43 @@
+//===-- fixdfti.c - Implement __fixdfti -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixdfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// su_int is a 32 bit integral type
+// value in double is representable in ti_int (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+ti_int
+__fixdfti(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0)
+ return 0;
+ ti_int s = (si_int)(fb.u.high & 0x80000000) >> 31;
+ ti_int r = 0x0010000000000000uLL | (0x000FFFFFFFFFFFFFuLL & fb.u.all);
+ if (e > 52)
+ r <<= (e - 52);
+ else
+ r >>= (52 - e);
+ return (r ^ s) - s;
+}
+
+#endif
diff --git a/lib/fixsfdi.c b/lib/fixsfdi.c
new file mode 100644
index 000000000..5458f0276
--- /dev/null
+++ b/lib/fixsfdi.c
@@ -0,0 +1,39 @@
+//===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixsfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// su_int is a 32 bit integral type
+// value in float is representable in di_int (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+di_int
+__fixsfdi(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0)
+ return 0;
+ di_int s = (si_int)(fb.u & 0x80000000) >> 31;
+ di_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return (r ^ s) - s;
+}
diff --git a/lib/fixsfti.c b/lib/fixsfti.c
new file mode 100644
index 000000000..8e3958757
--- /dev/null
+++ b/lib/fixsfti.c
@@ -0,0 +1,43 @@
+//===-- fixsfti.c - Implement __fixsfti -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixsfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// su_int is a 32 bit integral type
+// value in float is representable in ti_int (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+ti_int
+__fixsfti(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0)
+ return 0;
+ ti_int s = (si_int)(fb.u & 0x80000000) >> 31;
+ ti_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return (r ^ s) - s;
+}
+
+#endif
diff --git a/lib/fixunsdfdi.c b/lib/fixunsdfdi.c
new file mode 100644
index 000000000..f7e1041ad
--- /dev/null
+++ b/lib/fixunsdfdi.c
@@ -0,0 +1,42 @@
+//===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunsdfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// du_int is a 64 bit integral type
+// value in double is representable in du_int or is negative
+// (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+du_int
+__fixunsdfdi(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0 || (fb.u.high & 0x80000000))
+ return 0;
+ udwords r;
+ r.high = (fb.u.high & 0x000FFFFF) | 0x00100000;
+ r.low = fb.u.low;
+ if (e > 52)
+ r.all <<= (e - 52);
+ else
+ r.all >>= (52 - e);
+ return r.all;
+}
diff --git a/lib/fixunsdfsi.c b/lib/fixunsdfsi.c
new file mode 100644
index 000000000..383a35efe
--- /dev/null
+++ b/lib/fixunsdfsi.c
@@ -0,0 +1,39 @@
+//===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunsdfsi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned int, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// su_int is a 32 bit integral type
+// value in double is representable in su_int or is negative
+// (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+su_int
+__fixunsdfsi(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0 || (fb.u.high & 0x80000000))
+ return 0;
+ return (
+ 0x80000000u |
+ ((fb.u.high & 0x000FFFFF) << 11) |
+ (fb.u.low >> 21)
+ ) >> (31 - e);
+}
diff --git a/lib/fixunsdfti.c b/lib/fixunsdfti.c
new file mode 100644
index 000000000..4b88c6f6b
--- /dev/null
+++ b/lib/fixunsdfti.c
@@ -0,0 +1,44 @@
+//===-- fixunsdfti.c - Implement __fixunsdfti -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunsdfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// tu_int is a 64 bit integral type
+// value in double is representable in tu_int or is negative
+// (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+tu_int
+__fixunsdfti(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0 || (fb.u.high & 0x80000000))
+ return 0;
+ tu_int r = 0x0010000000000000uLL | (fb.u.all & 0x000FFFFFFFFFFFFFuLL);
+ if (e > 52)
+ r <<= (e - 52);
+ else
+ r >>= (52 - e);
+ return r;
+}
+
+#endif
diff --git a/lib/fixunssfdi.c b/lib/fixunssfdi.c
new file mode 100644
index 000000000..6495c68e7
--- /dev/null
+++ b/lib/fixunssfdi.c
@@ -0,0 +1,40 @@
+//===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunssfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// du_int is a 64 bit integral type
+// value in float is representable in du_int or is negative
+// (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+du_int
+__fixunssfdi(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0 || (fb.u & 0x80000000))
+ return 0;
+ du_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return r;
+}
diff --git a/lib/fixunssfsi.c b/lib/fixunssfsi.c
new file mode 100644
index 000000000..45c09cd53
--- /dev/null
+++ b/lib/fixunssfsi.c
@@ -0,0 +1,40 @@
+//===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunssfsi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned int, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// su_int is a 32 bit integral type
+// value in float is representable in su_int or is negative
+// (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+su_int
+__fixunssfsi(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0 || (fb.u & 0x80000000))
+ return 0;
+ su_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return r;
+}
diff --git a/lib/fixunssfti.c b/lib/fixunssfti.c
new file mode 100644
index 000000000..b2f47a824
--- /dev/null
+++ b/lib/fixunssfti.c
@@ -0,0 +1,44 @@
+//===-- fixunssfti.c - Implement __fixunssfti -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunssfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// tu_int is a 64 bit integral type
+// value in float is representable in tu_int or is negative
+// (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+tu_int
+__fixunssfti(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0 || (fb.u & 0x80000000))
+ return 0;
+ tu_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return r;
+}
+
+#endif
diff --git a/lib/fixunsxfdi.c b/lib/fixunsxfdi.c
new file mode 100644
index 000000000..b0abb9362
--- /dev/null
+++ b/lib/fixunsxfdi.c
@@ -0,0 +1,40 @@
+//===-- fixunsxfdi.c - Implement __fixunsxfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunsxfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// du_int is a 64 bit integral type
+// value in long double is representable in du_int or is negative
+// (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+du_int
+__fixunsxfdi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.low & 0x00007FFF) - 16383;
+ if (e < 0 || (fb.u.high.low & 0x00008000))
+ return 0;
+ return fb.u.low.all >> (63 - e);
+}
+
+#endif
diff --git a/lib/fixunsxfsi.c b/lib/fixunsxfsi.c
new file mode 100644
index 000000000..2c186a689
--- /dev/null
+++ b/lib/fixunsxfsi.c
@@ -0,0 +1,40 @@
+//===-- fixunsxfsi.c - Implement __fixunsxfsi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunsxfsi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned int, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// su_int is a 32 bit integral type
+// value in long double is representable in su_int or is negative
+// (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+su_int
+__fixunsxfsi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.low & 0x00007FFF) - 16383;
+ if (e < 0 || (fb.u.high.low & 0x00008000))
+ return 0;
+ return fb.u.low.high >> (31 - e);
+}
+
+#endif
diff --git a/lib/fixunsxfti.c b/lib/fixunsxfti.c
new file mode 100644
index 000000000..993594dfa
--- /dev/null
+++ b/lib/fixunsxfti.c
@@ -0,0 +1,45 @@
+//===-- fixunsxfti.c - Implement __fixunsxfti -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixunsxfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// tu_int is a 64 bit integral type
+// value in long double is representable in tu_int or is negative
+// (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+tu_int
+__fixunsxfti(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.low & 0x00007FFF) - 16383;
+ if (e < 0 || (fb.u.high.low & 0x00008000))
+ return 0;
+ tu_int r = fb.u.low.all;
+ if (e > 63)
+ r <<= (e - 63);
+ else
+ r >>= (63 - e);
+ return r;
+}
+
+#endif
diff --git a/lib/fixxfdi.c b/lib/fixxfdi.c
new file mode 100644
index 000000000..2a7d20814
--- /dev/null
+++ b/lib/fixxfdi.c
@@ -0,0 +1,41 @@
+//===-- fixxfdi.c - Implement __fixxfdi -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixxfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// su_int is a 32 bit integral type
+// value in long double is representable in di_int (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+di_int
+__fixxfdi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.low & 0x00007FFF) - 16383;
+ if (e < 0)
+ return 0;
+ di_int s = -(si_int)((fb.u.high.low & 0x00008000) >> 15);
+ di_int r = fb.u.low.all;
+ r = (du_int)r >> (63 - e);
+ return (r ^ s) - s;
+}
+
+#endif
diff --git a/lib/fixxfti.c b/lib/fixxfti.c
new file mode 100644
index 000000000..d9cb3eaf0
--- /dev/null
+++ b/lib/fixxfti.c
@@ -0,0 +1,44 @@
+//===-- fixxfti.c - Implement __fixxfti -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __fixxfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// su_int is a 32 bit integral type
+// value in long double is representable in ti_int (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+ti_int
+__fixxfti(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.low & 0x00007FFF) - 16383;
+ if (e < 0)
+ return 0;
+ ti_int s = -(si_int)((fb.u.high.low & 0x00008000) >> 15);
+ ti_int r = fb.u.low.all;
+ if (e > 63)
+ r <<= (e - 63);
+ else
+ r >>= (63 - e);
+ return (r ^ s) - s;
+}
+
+#endif
diff --git a/lib/floatdidf.c b/lib/floatdidf.c
new file mode 100644
index 000000000..f76d1b899
--- /dev/null
+++ b/lib/floatdidf.c
@@ -0,0 +1,102 @@
+//===-- floatdidf.c - Implement __floatdidf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatdidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// di_int is a 64 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+#ifndef __SOFT_FP__
+// Support for systems that have hardware floating-point; we'll set the inexact flag
+// as a side-effect of this computation.
+#include <stdint.h>
+
+double
+__floatdidf(di_int a)
+{
+ static const double twop52 = 0x1.0p52;
+ static const double twop32 = 0x1.0p32;
+
+ union { int64_t x; double d; } low = { .d = twop52 };
+
+ const double high = (int32_t)(a >> 32) * twop32;
+ low.x |= a & INT64_C(0x00000000ffffffff);
+
+ const double result = (high - twop52) + low.d;
+ return result;
+}
+
+#else
+// Support for systems that don't have hardware floating-point; there are no flags to
+// set, and we don't want to code-gen to an unknown soft-float implementation.
+
+double
+__floatdidf(di_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(di_int) * CHAR_BIT;
+ const di_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __builtin_clzll(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > DBL_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit DBL_MANT_DIG-1 bits to the right of 1
+ // Q = bit DBL_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = ((du_int)a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
+ if (a & ((du_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ double_bits fb;
+ fb.u.high = ((su_int)s & 0x80000000) | // sign
+ ((e + 1023) << 20) | // exponent
+ ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
+ fb.u.low = (su_int)a; // mantissa-low
+ return fb.f;
+}
+#endif
diff --git a/lib/floatdisf.c b/lib/floatdisf.c
new file mode 100644
index 000000000..5a9284819
--- /dev/null
+++ b/lib/floatdisf.c
@@ -0,0 +1,76 @@
+//===-- floatdisf.c - Implement __floatdisf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatdisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// di_int is a 64 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+float
+__floatdisf(di_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(di_int) * CHAR_BIT;
+ const di_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __builtin_clzll(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > FLT_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit FLT_MANT_DIG-1 bits to the right of 1
+ // Q = bit FLT_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = ((du_int)a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
+ if (a & ((du_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ float_bits fb;
+ fb.u = ((su_int)s & 0x80000000) | // sign
+ ((e + 127) << 23) | // exponent
+ ((su_int)a & 0x007FFFFF); // mantissa
+ return fb.f;
+}
diff --git a/lib/floatdixf.c b/lib/floatdixf.c
new file mode 100644
index 000000000..8d6911ec0
--- /dev/null
+++ b/lib/floatdixf.c
@@ -0,0 +1,43 @@
+//===-- floatdixf.c - Implement __floatdixf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatdixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// di_int is a 64 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+long double
+__floatdixf(di_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(di_int) * CHAR_BIT;
+ const di_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int clz = __builtin_clzll(a);
+ int e = (N - 1) - clz ; // exponent
+ long_double_bits fb;
+ fb.u.high.low = ((su_int)s & 0x00008000) | // sign
+ (e + 16383); // exponent
+ fb.u.low.all = a << clz; // mantissa
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floattidf.c b/lib/floattidf.c
new file mode 100644
index 000000000..0f72b33f3
--- /dev/null
+++ b/lib/floattidf.c
@@ -0,0 +1,83 @@
+//===-- floattidf.c - Implement __floattidf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floattidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// ti_int is a 128 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+si_int __clzti2(ti_int a);
+
+double
+__floattidf(ti_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(ti_int) * CHAR_BIT;
+ const ti_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __clzti2(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > DBL_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit DBL_MANT_DIG-1 bits to the right of 1
+ // Q = bit DBL_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = ((tu_int)a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
+ if (a & ((tu_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ double_bits fb;
+ fb.u.high = ((su_int)s & 0x80000000) | // sign
+ ((e + 1023) << 20) | // exponent
+ ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
+ fb.u.low = (su_int)a; // mantissa-low
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floattisf.c b/lib/floattisf.c
new file mode 100644
index 000000000..25bda9759
--- /dev/null
+++ b/lib/floattisf.c
@@ -0,0 +1,82 @@
+//===-- floattisf.c - Implement __floattisf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floattisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// ti_int is a 128 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+si_int __clzti2(ti_int a);
+
+float
+__floattisf(ti_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(ti_int) * CHAR_BIT;
+ const ti_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __clzti2(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > FLT_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit FLT_MANT_DIG-1 bits to the right of 1
+ // Q = bit FLT_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = ((tu_int)a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
+ if (a & ((tu_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ float_bits fb;
+ fb.u = ((su_int)s & 0x80000000) | // sign
+ ((e + 127) << 23) | // exponent
+ ((su_int)a & 0x007FFFFF); // mantissa
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floattixf.c b/lib/floattixf.c
new file mode 100644
index 000000000..520b6ed08
--- /dev/null
+++ b/lib/floattixf.c
@@ -0,0 +1,83 @@
+//===-- floattixf.c - Implement __floattixf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floattixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// ti_int is a 128 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+si_int __clzti2(ti_int a);
+
+long double
+__floattixf(ti_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(ti_int) * CHAR_BIT;
+ const ti_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __clzti2(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > LDBL_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit LDBL_MANT_DIG-1 bits to the right of 1
+ // Q = bit LDBL_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case LDBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case LDBL_MANT_DIG + 2:
+ break;
+ default:
+ a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
+ if (a & ((tu_int)1 << LDBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to LDBL_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (LDBL_MANT_DIG - sd);
+ // a is now rounded to LDBL_MANT_DIG bits
+ }
+ long_double_bits fb;
+ fb.u.high.low = ((su_int)s & 0x8000) | // sign
+ (e + 16383); // exponent
+ fb.u.low.all = (du_int)a; // mantissa
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatundidf.c b/lib/floatundidf.c
new file mode 100644
index 000000000..f019d693b
--- /dev/null
+++ b/lib/floatundidf.c
@@ -0,0 +1,101 @@
+//===-- floatundidf.c - Implement __floatundidf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// du_int is a 64 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+#ifndef __SOFT_FP__
+// Support for systems that have hardware floating-point; we'll set the inexact flag
+// as a side-effect of this computation.
+#include <stdint.h>
+
+double
+__floatundidf(du_int a)
+{
+ static const double twop52 = 0x1.0p52;
+ static const double twop84 = 0x1.0p84;
+ static const double twop84_plus_twop52 = 0x1.00000001p84;
+
+ union { uint64_t x; double d; } high = { .d = twop84 };
+ union { uint64_t x; double d; } low = { .d = twop52 };
+
+ high.x |= a >> 32;
+ low.x |= a & UINT64_C(0x00000000ffffffff);
+
+ const double result = (high.d - twop84_plus_twop52) + low.d;
+ return result;
+}
+
+#else
+// Support for systems that don't have hardware floating-point; there are no flags to
+// set, and we don't want to code-gen to an unknown soft-float implementation.
+
+double
+__floatundidf(du_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int sd = N - __builtin_clzll(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > DBL_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit DBL_MANT_DIG-1 bits to the right of 1
+ // Q = bit DBL_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
+ if (a & ((du_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ double_bits fb;
+ fb.u.high = ((e + 1023) << 20) | // exponent
+ ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
+ fb.u.low = (su_int)a; // mantissa-low
+ return fb.f;
+}
+#endif \ No newline at end of file
diff --git a/lib/floatundisf.c b/lib/floatundisf.c
new file mode 100644
index 000000000..66099e025
--- /dev/null
+++ b/lib/floatundisf.c
@@ -0,0 +1,73 @@
+//===-- floatundisf.c - Implement __floatundisf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// du_int is a 64 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+float
+__floatundisf(du_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int sd = N - __builtin_clzll(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > FLT_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit FLT_MANT_DIG-1 bits to the right of 1
+ // Q = bit FLT_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
+ if (a & ((du_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ float_bits fb;
+ fb.u = ((e + 127) << 23) | // exponent
+ ((su_int)a & 0x007FFFFF); // mantissa
+ return fb.f;
+}
diff --git a/lib/floatundixf.c b/lib/floatundixf.c
new file mode 100644
index 000000000..6e8c4839f
--- /dev/null
+++ b/lib/floatundixf.c
@@ -0,0 +1,40 @@
+//===-- floatundixf.c - Implement __floatundixf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// du_int is a 64 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+long double
+__floatundixf(du_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int clz = __builtin_clzll(a);
+ int e = (N - 1) - clz ; // exponent
+ long_double_bits fb;
+ fb.u.high.low = (e + 16383); // exponent
+ fb.u.low.all = a << clz; // mantissa
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatuntidf.c b/lib/floatuntidf.c
new file mode 100644
index 000000000..1b87fcfc4
--- /dev/null
+++ b/lib/floatuntidf.c
@@ -0,0 +1,80 @@
+//===-- floatuntidf.c - Implement __floatuntidf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatuntidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// tu_int is a 128 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+si_int __clzti2(ti_int a);
+
+double
+__floatuntidf(tu_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(tu_int) * CHAR_BIT;
+ int sd = N - __clzti2(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > DBL_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit DBL_MANT_DIG-1 bits to the right of 1
+ // Q = bit DBL_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
+ if (a & ((tu_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ // a is now rounded to DBL_MANT_DIG bits
+ }
+ double_bits fb;
+ fb.u.high = ((e + 1023) << 20) | // exponent
+ ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
+ fb.u.low = (su_int)a; // mantissa-low
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatuntisf.c b/lib/floatuntisf.c
new file mode 100644
index 000000000..e75d99571
--- /dev/null
+++ b/lib/floatuntisf.c
@@ -0,0 +1,79 @@
+//===-- floatuntisf.c - Implement __floatuntisf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatuntisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// tu_int is a 128 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+si_int __clzti2(ti_int a);
+
+float
+__floatuntisf(tu_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(tu_int) * CHAR_BIT;
+ int sd = N - __clzti2(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > FLT_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit FLT_MANT_DIG-1 bits to the right of 1
+ // Q = bit FLT_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
+ if (a & ((tu_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ // a is now rounded to FLT_MANT_DIG bits
+ }
+ float_bits fb;
+ fb.u = ((e + 127) << 23) | // exponent
+ ((su_int)a & 0x007FFFFF); // mantissa
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatuntixf.c b/lib/floatuntixf.c
new file mode 100644
index 000000000..a28db10f6
--- /dev/null
+++ b/lib/floatuntixf.c
@@ -0,0 +1,80 @@
+//===-- floatuntixf.c - Implement __floatuntixf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatuntixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// tu_int is a 128 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+si_int __clzti2(ti_int a);
+
+long double
+__floatuntixf(tu_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(tu_int) * CHAR_BIT;
+ int sd = N - __clzti2(a); // number of significant digits
+ int e = sd - 1; // exponent
+ if (sd > LDBL_MANT_DIG)
+ {
+ // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ // 12345678901234567890123456
+ // 1 = msb 1 bit
+ // P = bit LDBL_MANT_DIG-1 bits to the right of 1
+ // Q = bit LDBL_MANT_DIG bits to the right of 1
+ // R = "or" of all bits to the right of Q
+ switch (sd)
+ {
+ case LDBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case LDBL_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (LDBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
+ };
+ // finish:
+ a |= (a & 4) != 0; // Or P into R
+ ++a; // round - this step may add a significant bit
+ a >>= 2; // dump Q and R
+ // a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
+ if (a & ((tu_int)1 << LDBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ // a is now rounded to LDBL_MANT_DIG bits
+ }
+ else
+ {
+ a <<= (LDBL_MANT_DIG - sd);
+ // a is now rounded to LDBL_MANT_DIG bits
+ }
+ long_double_bits fb;
+ fb.u.high.low = (e + 16383); // exponent
+ fb.u.low.all = (du_int)a; // mantissa
+ return fb.f;
+}
+
+#endif
diff --git a/lib/gcc_personality_v0.c b/lib/gcc_personality_v0.c
new file mode 100644
index 000000000..55d1166b8
--- /dev/null
+++ b/lib/gcc_personality_v0.c
@@ -0,0 +1,237 @@
+//===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+//
+// _Unwind_* stuff based on C++ ABI public documentation
+// http://refspecs.freestandards.org/abi-eh-1.21.html
+//
+typedef enum {
+ _URC_NO_REASON = 0,
+ _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+ _URC_FATAL_PHASE2_ERROR = 2,
+ _URC_FATAL_PHASE1_ERROR = 3,
+ _URC_NORMAL_STOP = 4,
+ _URC_END_OF_STACK = 5,
+ _URC_HANDLER_FOUND = 6,
+ _URC_INSTALL_CONTEXT = 7,
+ _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef enum {
+ _UA_SEARCH_PHASE = 1,
+ _UA_CLEANUP_PHASE = 2,
+ _UA_HANDLER_FRAME = 4,
+ _UA_FORCE_UNWIND = 8,
+ _UA_END_OF_STACK = 16
+} _Unwind_Action;
+
+typedef struct _Unwind_Context* _Unwind_Context_t;
+
+struct _Unwind_Exception {
+ uint64_t exception_class;
+ _Unwind_Reason_Code (*exception_cleanup)(_Unwind_Reason_Code reason,
+ struct _Unwind_Exception* exc);
+ uintptr_t private_1;
+ uintptr_t private_2;
+};
+
+extern const uint8_t* _Unwind_GetLanguageSpecificData(_Unwind_Context_t c);
+extern void _Unwind_SetGR(_Unwind_Context_t c, int i, uintptr_t n);
+extern void _Unwind_SetIP(_Unwind_Context_t, uintptr_t new_value);
+extern uintptr_t _Unwind_GetIP(_Unwind_Context_t context);
+extern uintptr_t _Unwind_GetRegionStart(_Unwind_Context_t context);
+
+
+//
+// Pointer encodings documented at:
+// http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
+//
+#define DW_EH_PE_omit 0xff // no data follows
+
+#define DW_EH_PE_absptr 0x00
+#define DW_EH_PE_uleb128 0x01
+#define DW_EH_PE_udata2 0x02
+#define DW_EH_PE_udata4 0x03
+#define DW_EH_PE_udata8 0x04
+#define DW_EH_PE_sleb128 0x09
+#define DW_EH_PE_sdata2 0x0A
+#define DW_EH_PE_sdata4 0x0B
+#define DW_EH_PE_sdata8 0x0C
+
+#define DW_EH_PE_pcrel 0x10
+#define DW_EH_PE_textrel 0x20
+#define DW_EH_PE_datarel 0x30
+#define DW_EH_PE_funcrel 0x40
+#define DW_EH_PE_aligned 0x50
+#define DW_EH_PE_indirect 0x80 // gcc extension
+
+
+
+// read a uleb128 encoded value and advance pointer
+static uintptr_t readULEB128(const uint8_t** data)
+{
+ uintptr_t result = 0;
+ uintptr_t shift = 0;
+ unsigned char byte;
+ const uint8_t* p = *data;
+ do {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ } while (byte & 0x80);
+ *data = p;
+ return result;
+}
+
+// read a pointer encoded value and advance pointer
+static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)
+{
+ const uint8_t* p = *data;
+ uintptr_t result = 0;
+
+ if ( encoding == DW_EH_PE_omit )
+ return 0;
+
+ // first get value
+ switch (encoding & 0x0F) {
+ case DW_EH_PE_absptr:
+ result = *((uintptr_t*)p);
+ p += sizeof(uintptr_t);
+ break;
+ case DW_EH_PE_uleb128:
+ result = readULEB128(&p);
+ break;
+ case DW_EH_PE_udata2:
+ result = *((uint16_t*)p);
+ p += sizeof(uint16_t);
+ break;
+ case DW_EH_PE_udata4:
+ result = *((uint32_t*)p);
+ p += sizeof(uint32_t);
+ break;
+ case DW_EH_PE_udata8:
+ result = *((uint64_t*)p);
+ p += sizeof(uint64_t);
+ break;
+ case DW_EH_PE_sdata2:
+ result = *((int16_t*)p);
+ p += sizeof(int16_t);
+ break;
+ case DW_EH_PE_sdata4:
+ result = *((int32_t*)p);
+ p += sizeof(int32_t);
+ break;
+ case DW_EH_PE_sdata8:
+ result = *((int64_t*)p);
+ p += sizeof(int64_t);
+ break;
+ case DW_EH_PE_sleb128:
+ default:
+ // not supported
+ abort();
+ break;
+ }
+
+ // then add relative offset
+ switch ( encoding & 0x70 ) {
+ case DW_EH_PE_absptr:
+ // do nothing
+ break;
+ case DW_EH_PE_pcrel:
+ result += (uintptr_t)(*data);
+ break;
+ case DW_EH_PE_textrel:
+ case DW_EH_PE_datarel:
+ case DW_EH_PE_funcrel:
+ case DW_EH_PE_aligned:
+ default:
+ // not supported
+ abort();
+ break;
+ }
+
+ // then apply indirection
+ if (encoding & DW_EH_PE_indirect) {
+ result = *((uintptr_t*)result);
+ }
+
+ *data = p;
+ return result;
+}
+
+
+//
+// The C compiler makes references to __gcc_personality_v0 in
+// the dwarf unwind information for translation units that use
+// __attribute__((cleanup(xx))) on local variables.
+// This personality routine is called by the system unwinder
+// on each frame as the stack is unwound during a C++ exception
+// throw through a C function compiled with -fexceptions.
+//
+_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
+ uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
+ _Unwind_Context_t context)
+{
+ // Since C does not have catch clauses, there is nothing to do during
+ // phase 1 (the search phase).
+ if ( actions & _UA_SEARCH_PHASE )
+ return _URC_CONTINUE_UNWIND;
+
+ // There is nothing to do if there is no LSDA for this frame.
+ const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context);
+ if ( lsda == NULL )
+ return _URC_CONTINUE_UNWIND;
+
+ uintptr_t pc = _Unwind_GetIP(context)-1;
+ uintptr_t funcStart = _Unwind_GetRegionStart(context);
+ uintptr_t pcOffset = pc - funcStart;
+
+ // Parse LSDA header.
+ uint8_t lpStartEncoding = *lsda++;
+ if (lpStartEncoding != DW_EH_PE_omit) {
+ readEncodedPointer(&lsda, lpStartEncoding);
+ }
+ uint8_t ttypeEncoding = *lsda++;
+ if (ttypeEncoding != DW_EH_PE_omit) {
+ readULEB128(&lsda);
+ }
+ // Walk call-site table looking for range that includes current PC.
+ uint8_t callSiteEncoding = *lsda++;
+ uint32_t callSiteTableLength = readULEB128(&lsda);
+ const uint8_t* callSiteTableStart = lsda;
+ const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
+ const uint8_t* p=callSiteTableStart;
+ while (p < callSiteTableEnd) {
+ uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
+ uintptr_t length = readEncodedPointer(&p, callSiteEncoding);
+ uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding);
+ readULEB128(&p); // action value not used for C code
+ if ( landingPad == 0 )
+ continue; // no landing pad for this entry
+ if ( (start <= pcOffset) && (pcOffset < (start+length)) ) {
+ // Found landing pad for the PC.
+ // Set Instruction Pointer to so we re-enter function
+ // at landing pad. The landing pad is created by the compiler
+ // to take two parameters in registers.
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
+ (uintptr_t)exceptionObject);
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
+ _Unwind_SetIP(context, funcStart+landingPad);
+ return _URC_INSTALL_CONTEXT;
+ }
+ }
+
+ // No landing pad found, continue unwinding.
+ return _URC_CONTINUE_UNWIND;
+}
+
diff --git a/lib/i386/Makefile.mk b/lib/i386/Makefile.mk
new file mode 100644
index 000000000..140ee9977
--- /dev/null
+++ b/lib/i386/Makefile.mk
@@ -0,0 +1,22 @@
+#===- lib/i386/Makefile.mk ---------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+Dir := lib/i386
+SubDirs :=
+OnlyArchs := i386
+
+AsmSources := $(foreach file,$(wildcard $(Dir)/*.s),$(notdir $(file)))
+Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
+ObjNames := $(Sources:%.c=%.o) $(AsmSources:%.s=%.o)
+Target := Optimized
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
+
+include make/subdir.mk
diff --git a/lib/i386/ashldi3.s b/lib/i386/ashldi3.s
new file mode 100644
index 000000000..3de2dfc83
--- /dev/null
+++ b/lib/i386/ashldi3.s
@@ -0,0 +1,65 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// di_int __ashldi3(di_int input, int count);
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+#ifdef __i386__
+#ifdef __SSE2__
+
+.text
+.align 4
+.globl ___ashldi3
+___ashldi3:
+ movd 12(%esp), %xmm2 // Load count
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0 // Load input
+#else
+ movq 4(%esp), %xmm0 // Load input
+#endif
+ psllq %xmm2, %xmm0 // shift input by count
+ movd %xmm0, %eax
+ psrlq $32, %xmm0
+ movd %xmm0, %edx
+ ret
+
+#else // Use GPRs instead of SSE2 instructions, if they aren't available.
+
+.text
+.align 4
+.globl ___ashldi3
+___ashldi3:
+ movl 12(%esp), %ecx // Load count
+ movl 8(%esp), %edx // Load high
+ movl 4(%esp), %eax // Load low
+
+ testl $0x20, %ecx // If count >= 32
+ jnz 2f // goto 2
+ testl $0x1f, %ecx // If count == 0
+ jz 1f // goto 1
+
+ pushl %ebx
+ movl %eax, %ebx // copy low
+ shll %cl, %eax // left shift low by count
+ shll %cl, %edx // left shift high by count
+ neg %cl
+ shrl %cl, %ebx // right shift low by 32 - count
+ orl %ebx, %edx // or the result into the high word
+ popl %ebx
+1: ret
+
+2: movl %eax, %edx // Move low to high
+ xorl %eax, %eax // clear low
+ shll %cl, %edx // shift high by count - 32
+ ret
+
+#endif // __SSE2__
+#endif // __i386__
diff --git a/lib/i386/ashrdi3.s b/lib/i386/ashrdi3.s
new file mode 100644
index 000000000..db01f2132
--- /dev/null
+++ b/lib/i386/ashrdi3.s
@@ -0,0 +1,75 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// di_int __ashrdi3(di_int input, int count);
+
+#ifdef __i386__
+#ifdef __SSE2__
+
+.text
+.align 4
+.globl ___ashrdi3
+___ashrdi3:
+ movd 12(%esp), %xmm2 // Load count
+ movl 8(%esp), %eax
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0 // Load input
+#else
+ movq 4(%esp), %xmm0 // Load input
+#endif
+
+ psrlq %xmm2, %xmm0 // unsigned shift input by count
+
+ testl %eax, %eax // check the sign-bit of the input
+ jns 1f // early out for positive inputs
+
+ // If the input is negative, we need to construct the shifted sign bit
+ // to or into the result, as xmm does not have a signed right shift.
+ pcmpeqb %xmm1, %xmm1 // -1ULL
+ psrlq $58, %xmm1 // 0x3f
+ pandn %xmm1, %xmm2 // 63 - count
+ pcmpeqb %xmm1, %xmm1 // -1ULL
+ psubq %xmm1, %xmm2 // 64 - count
+ psllq %xmm2, %xmm1 // -1 << (64 - count) = leading sign bits
+ por %xmm1, %xmm0
+
+ // Move the result back to the general purpose registers and return
+1: movd %xmm0, %eax
+ psrlq $32, %xmm0
+ movd %xmm0, %edx
+ ret
+
+#else // Use GPRs instead of SSE2 instructions, if they aren't available.
+
+.text
+.align 4
+.globl ___ashrdi3
+___ashrdi3:
+ movl 12(%esp), %ecx // Load count
+ movl 8(%esp), %edx // Load high
+ movl 4(%esp), %eax // Load low
+
+ testl $0x20, %ecx // If count >= 32
+ jnz 2f // goto 2
+ testl $0x1f, %ecx // If count == 0
+ jz 1f // goto 1
+
+ pushl %ebx
+ movl %edx, %ebx // copy high
+ shrl %cl, %eax // right shift low by count
+ sarl %cl, %edx // right shift high by count
+ neg %cl
+ shll %cl, %ebx // left shift high by 32 - count
+ orl %ebx, %eax // or the result into the low word
+ popl %ebx
+1: ret
+
+2: movl %edx, %eax // Move high to low
+ sarl $31, %edx // clear high
+ sarl %cl, %eax // shift low by count - 32
+ ret
+
+#endif // __SSE2__
+#endif // __i386__
diff --git a/lib/i386/divdi3.s b/lib/i386/divdi3.s
new file mode 100644
index 000000000..3b50266d7
--- /dev/null
+++ b/lib/i386/divdi3.s
@@ -0,0 +1,160 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// di_int __divdi3(di_int a, di_int b);
+
+// result = a / b.
+// both inputs and the output are 64-bit signed integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+.globl ___divdi3
+___divdi3:
+
+/* This is currently implemented by wrapping the unsigned divide up in an absolute
+ value, then restoring the correct sign at the end of the computation. This could
+ certainly be improved upon. */
+
+ pushl %esi
+ movl 20(%esp), %edx // high word of b
+ movl 16(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (b < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (b < 0) ? not(b) : b
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(b)
+ movl %edx, 20(%esp)
+ movl %eax, 16(%esp) // store abs(b) back to stack
+ movl %ecx, %esi // set aside sign of b
+
+ movl 12(%esp), %edx // high word of b
+ movl 8(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (a < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (a < 0) ? not(a) : a
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(a)
+ movl %edx, 12(%esp)
+ movl %eax, 8(%esp) // store abs(a) back to stack
+ xorl %ecx, %esi // sign of result = (sign of a) ^ (sign of b)
+
+ pushl %ebx
+ movl 24(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 20(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 16(%esp), %edx // Load the high and low words of a, and jump
+ movl 12(%esp), %eax // to [1] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 1f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+
+1: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+
+9: /* High word of b is zero on this branch */
+
+ movl 16(%esp), %eax // Find qhi and rhi such that
+ movl 20(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 12(%esp), %eax // Find qlo such that
+ divl %ecx //
+ movl %ebx, %edx // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %ebx // Restore callee-save registers
+ popl %esi
+ retl // Return
+
+#endif // __i386__
diff --git a/lib/i386/floatdidf.s b/lib/i386/floatdidf.s
new file mode 100644
index 000000000..34736ac58
--- /dev/null
+++ b/lib/i386/floatdidf.s
@@ -0,0 +1,32 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// double __floatundidf(du_int a);
+
+#ifdef __i386__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop32: .quad 0x41f0000000000000
+
+#define REL_ADDR(_a) (_a)-0b(%eax)
+
+.text
+.align 4
+.globl ___floatdidf
+___floatdidf:
+ cvtsi2sd 8(%esp), %xmm1
+ movss 4(%esp), %xmm0 // low 32 bits of a
+ calll 0f
+0: popl %eax
+ mulsd REL_ADDR(twop32), %xmm1 // a_hi as a double (without rounding)
+ movsd REL_ADDR(twop52), %xmm2 // 0x1.0p52
+ subsd %xmm2, %xmm1 // a_hi - 0x1p52 (no rounding occurs)
+ orpd %xmm2, %xmm0 // 0x1p52 + a_lo (no rounding occurs)
+ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here)
+ movsd %xmm0, 4(%esp)
+ fldl 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatdisf.s b/lib/i386/floatdisf.s
new file mode 100644
index 000000000..20b80d1d8
--- /dev/null
+++ b/lib/i386/floatdisf.s
@@ -0,0 +1,30 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// float __floatdisf(di_int a);
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+#ifdef __i386__
+
+.text
+.align 4
+.globl ___floatdisf
+___floatdisf:
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0
+ movq %xmm0, 4(%esp)
+#endif
+ fildll 4(%esp)
+ fstps 4(%esp)
+ flds 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatdixf.s b/lib/i386/floatdixf.s
new file mode 100644
index 000000000..71e2d2abc
--- /dev/null
+++ b/lib/i386/floatdixf.s
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// float __floatdixf(di_int a);
+
+#ifdef __i386__
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+.text
+.align 4
+.globl ___floatdixf
+___floatdixf:
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0
+ movq %xmm0, 4(%esp)
+#endif
+ fildll 4(%esp)
+ ret
+
+#endif // __i386__ \ No newline at end of file
diff --git a/lib/i386/floatundidf.s b/lib/i386/floatundidf.s
new file mode 100644
index 000000000..d9be85343
--- /dev/null
+++ b/lib/i386/floatundidf.s
@@ -0,0 +1,43 @@
+//===-- floatundidf.s - Implement __floatundidf for i386 ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+// double __floatundidf(du_int a);
+
+#ifdef __i386__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52:
+ .quad 0x4530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)-0b(%eax)
+
+.text
+.align 4
+.globl ___floatundidf
+___floatundidf:
+ movss 8(%esp), %xmm1 // high 32 bits of a
+ movss 4(%esp), %xmm0 // low 32 bits of a
+ calll 0f
+0: popl %eax
+ orpd REL_ADDR(twop84), %xmm1 // 0x1p84 + a_hi (no rounding occurs)
+ subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs)
+ orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs)
+ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here)
+ movsd %xmm0, 4(%esp)
+ fldl 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatundisf.s b/lib/i386/floatundisf.s
new file mode 100644
index 000000000..a1b29667c
--- /dev/null
+++ b/lib/i386/floatundisf.s
@@ -0,0 +1,95 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// float __floatundisf(du_int a);
+
+// Note that there is a hardware instruction, fildll, that does most of what
+// this function needs to do. However, because of our ia32 ABI, it will take
+// a write-small read-large stall, so the software implementation here is
+// actually several cycles faster.
+
+// This is a branch-free implementation. A branchy implementation might be
+// faster for the common case if you know something a priori about the input
+// distribution.
+
+/* branch-free x87 implementation - one cycle slower than without x87.
+
+#ifdef __i386__
+
+.const
+.align 3
+
+ .quad 0x43f0000000000000
+twop64: .quad 0x0000000000000000
+
+#define TWOp64 twop64-0b(%ecx,%eax,8)
+
+.text
+.align 4
+.globl ___floatundisf
+___floatundisf:
+ movl 8(%esp), %eax
+ movd 8(%esp), %xmm1
+ movd 4(%esp), %xmm0
+ punpckldq %xmm1, %xmm0
+ calll 0f
+0: popl %ecx
+ sarl $31, %eax
+ movq %xmm0, 4(%esp)
+ fildll 4(%esp)
+ faddl TWOp64
+ fstps 4(%esp)
+ flds 4(%esp)
+ ret
+
+#endif // __i386__
+
+*/
+
+/* branch-free, x87-free implementation - faster at the expense of code size */
+
+#ifdef __i386__
+
+.const
+.align 3
+twop52: .quad 0x4330000000000000
+ .quad 0x0000000000000fff
+sticky: .quad 0x0000000000000000
+ .long 0x00000012
+twelve: .long 0x00000000
+
+#define TWOp52 twop52-0b(%ecx)
+#define STICKY sticky-0b(%ecx,%eax,8)
+
+.text
+.align 4
+.globl ___floatundisf
+___floatundisf:
+ movl 8(%esp), %eax
+ movd 8(%esp), %xmm1
+ movd 4(%esp), %xmm0
+ punpckldq %xmm1, %xmm0
+
+ calll 0f
+0: popl %ecx
+ shrl %eax // high 31 bits of input as sint32
+ addl $0x7ff80000, %eax
+ sarl $31, %eax // (big input) ? -1 : 0
+ movsd STICKY, %xmm1 // (big input) ? 0xfff : 0
+ movl $12, %edx
+ andl %eax, %edx // (big input) ? 12 : 0
+ movd %edx, %xmm3
+ andpd %xmm0, %xmm1 // (big input) ? input & 0xfff : 0
+ movsd TWOp52, %xmm2 // 0x1.0p52
+ psrlq %xmm3, %xmm0 // (big input) ? input >> 12 : input
+ orpd %xmm2, %xmm1 // 0x1.0p52 + ((big input) ? input & 0xfff : input)
+ orpd %xmm1, %xmm0 // 0x1.0p52 + ((big input) ? (input >> 12 | input & 0xfff) : input)
+ subsd %xmm2, %xmm0 // (double)((big input) ? (input >> 12 | input & 0xfff) : input)
+ cvtsd2ss %xmm0, %xmm0 // (float)((big input) ? (input >> 12 | input & 0xfff) : input)
+ pslld $23, %xmm3
+ paddd %xmm3, %xmm0 // (float)input
+ movd %xmm0, 4(%esp)
+ flds 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatundixf.s b/lib/i386/floatundixf.s
new file mode 100644
index 000000000..c24689aac
--- /dev/null
+++ b/lib/i386/floatundixf.s
@@ -0,0 +1,34 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __floatundixf(du_int a);16
+
+#ifdef __i386__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52_neg:
+ .quad 0xc530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)-0b(%eax)
+
+.text
+.align 4
+.globl ___floatundixf
+___floatundixf:
+ calll 0f
+0: popl %eax
+ movss 8(%esp), %xmm0 // hi 32 bits of input
+ movss 4(%esp), %xmm1 // lo 32 bits of input
+ orpd REL_ADDR(twop84), %xmm0 // 2^84 + hi (as a double)
+ orpd REL_ADDR(twop52), %xmm1 // 2^52 + lo (as a double)
+ addsd REL_ADDR(twop84_plus_twop52_neg), %xmm0 // hi - 2^52 (no rounding occurs)
+ movsd %xmm1, 4(%esp)
+ fldl 4(%esp)
+ movsd %xmm0, 4(%esp)
+ faddl 4(%esp)
+ ret
+
+#endif // __i386__ \ No newline at end of file
diff --git a/lib/i386/lshrdi3.s b/lib/i386/lshrdi3.s
new file mode 100644
index 000000000..5992c2131
--- /dev/null
+++ b/lib/i386/lshrdi3.s
@@ -0,0 +1,65 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// di_int __lshrdi3(di_int input, int count);
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+#ifdef __i386__
+#ifdef __SSE2__
+
+.text
+.align 4
+.globl ___lshrdi3
+___lshrdi3:
+ movd 12(%esp), %xmm2 // Load count
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0 // Load input
+#else
+ movq 4(%esp), %xmm0 // Load input
+#endif
+ psrlq %xmm2, %xmm0 // shift input by count
+ movd %xmm0, %eax
+ psrlq $32, %xmm0
+ movd %xmm0, %edx
+ ret
+
+#else // Use GPRs instead of SSE2 instructions, if they aren't available.
+
+.text
+.align 4
+.globl ___lshrdi3
+___lshrdi3:
+ movl 12(%esp), %ecx // Load count
+ movl 8(%esp), %edx // Load high
+ movl 4(%esp), %eax // Load low
+
+ testl $0x20, %ecx // If count >= 32
+ jnz 2f // goto 2
+ testl $0x1f, %ecx // If count == 0
+ jz 1f // goto 1
+
+ pushl %ebx
+ movl %edx, %ebx // copy high
+ shrl %cl, %eax // right shift low by count
+ shrl %cl, %edx // right shift high by count
+ neg %cl
+ shll %cl, %ebx // left shift high by 32 - count
+ orl %ebx, %eax // or the result into the low word
+ popl %ebx
+1: ret
+
+2: movl %edx, %eax // Move high to low
+ xorl %edx, %edx // clear high
+ shrl %cl, %eax // shift low by count - 32
+ ret
+
+#endif // __SSE2__
+#endif // __i386__
diff --git a/lib/i386/moddi3.s b/lib/i386/moddi3.s
new file mode 100644
index 000000000..af1f38a13
--- /dev/null
+++ b/lib/i386/moddi3.s
@@ -0,0 +1,165 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// di_int __moddi3(di_int a, di_int b);
+
+// result = remainder of a / b.
+// both inputs and the output are 64-bit signed integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+.globl ___moddi3
+___moddi3:
+
+/* This is currently implemented by wrapping the unsigned modulus up in an absolute
+ value. This could certainly be improved upon. */
+
+ pushl %esi
+ movl 20(%esp), %edx // high word of b
+ movl 16(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (b < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (b < 0) ? not(b) : b
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(b)
+ movl %edx, 20(%esp)
+ movl %eax, 16(%esp) // store abs(b) back to stack
+
+ movl 12(%esp), %edx // high word of b
+ movl 8(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (a < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (a < 0) ? not(a) : a
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(a)
+ movl %edx, 12(%esp)
+ movl %eax, 8(%esp) // store abs(a) back to stack
+ movl %ecx, %esi // set aside sign of a
+
+ pushl %ebx
+ movl 24(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 20(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 16(%esp), %edx // Load the high and low words of a, and jump
+ movl 12(%esp), %eax // to [2] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 2f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 1f // if positive, this is the result.
+ addl 24(%esp), %ebx // otherwise
+ adcl 28(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+1: movl %ebx, %eax
+ movl %ecx, %edx
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+2: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 3f // if positive, this is the result.
+ addl 24(%esp), %ebx // otherwise
+ adcl 28(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+3: movl %ebx, %eax
+ movl %ecx, %edx
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+9: /* High word of b is zero on this branch */
+
+ movl 16(%esp), %eax // Find qhi and rhi such that
+ movl 20(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 12(%esp), %eax // Find rlo such that
+ divl %ecx //
+ movl %edx, %eax // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+ popl %ebx //
+ xorl %edx, %edx // and return 0:rlo
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %esi
+ retl // Return
+
+
+#endif // __i386__
diff --git a/lib/i386/muldi3.s b/lib/i386/muldi3.s
new file mode 100644
index 000000000..9f29c3ced
--- /dev/null
+++ b/lib/i386/muldi3.s
@@ -0,0 +1,28 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// di_int __muldi3(di_int a, di_int b);
+
+#ifdef __i386__
+
+.text
+.align 4
+.globl ___muldi3
+___muldi3:
+ pushl %ebx
+ movl 16(%esp), %eax // b.lo
+ movl 12(%esp), %ecx // a.hi
+ imull %eax, %ecx // b.lo * a.hi
+
+ movl 8(%esp), %edx // a.lo
+ movl 20(%esp), %ebx // b.hi
+ imull %edx, %ebx // a.lo * b.hi
+
+ mull %edx // EDX:EAX = a.lo * b.lo
+ addl %ecx, %ebx // EBX = (a.lo*b.hi + a.hi*b.lo)
+ addl %ebx, %edx
+
+ popl %ebx
+ retl
+
+#endif // __i386__
diff --git a/lib/i386/udivdi3.s b/lib/i386/udivdi3.s
new file mode 100644
index 000000000..977cee36c
--- /dev/null
+++ b/lib/i386/udivdi3.s
@@ -0,0 +1,113 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// du_int __udivdi3(du_int a, du_int b);
+
+// result = a / b.
+// both inputs and the output are 64-bit unsigned integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+.globl ___udivdi3
+___udivdi3:
+
+ pushl %ebx
+ movl 20(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 16(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 12(%esp), %edx // Load the high and low words of a, and jump
+ movl 8(%esp), %eax // to [1] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 1f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+ popl %edi
+ popl %ebx
+ retl
+
+
+1: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+ popl %edi
+ popl %ebx
+ retl
+
+
+9: /* High word of b is zero on this branch */
+
+ movl 12(%esp), %eax // Find qhi and rhi such that
+ movl 16(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 8(%esp), %eax // Find qlo such that
+ divl %ecx //
+ movl %ebx, %edx // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+ popl %ebx //
+ retl // and return qhi:qlo
+
+#endif // __i386__
diff --git a/lib/i386/umoddi3.s b/lib/i386/umoddi3.s
new file mode 100644
index 000000000..2ddd71006
--- /dev/null
+++ b/lib/i386/umoddi3.s
@@ -0,0 +1,124 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// du_int __umoddi3(du_int a, du_int b);
+
+// result = remainder of a / b.
+// both inputs and the output are 64-bit unsigned integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+.globl ___umoddi3
+___umoddi3:
+
+ pushl %ebx
+ movl 20(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 16(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 12(%esp), %edx // Load the high and low words of a, and jump
+ movl 8(%esp), %eax // to [2] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 2f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 1f // if positive, this is the result.
+ addl 20(%esp), %ebx // otherwise
+ adcl 24(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+1: movl %ebx, %eax
+ movl %ecx, %edx
+
+ popl %edi
+ popl %ebx
+ retl
+
+
+2: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 3f // if positive, this is the result.
+ addl 20(%esp), %ebx // otherwise
+ adcl 24(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+3: movl %ebx, %eax
+ movl %ecx, %edx
+
+ popl %edi
+ popl %ebx
+ retl
+
+
+
+9: /* High word of b is zero on this branch */
+
+ movl 12(%esp), %eax // Find qhi and rhi such that
+ movl 16(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 8(%esp), %eax // Find rlo such that
+ divl %ecx //
+ movl %edx, %eax // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+ popl %ebx //
+ xorl %edx, %edx // and return 0:rlo
+ retl //
+
+#endif // __i386__
diff --git a/lib/int_lib.h b/lib/int_lib.h
new file mode 100644
index 000000000..7d09c856f
--- /dev/null
+++ b/lib/int_lib.h
@@ -0,0 +1,143 @@
+//===-- int_lib.h - configuration header for libgcc replacement -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a configuration header for libgcc replacement.
+// This file is not part of the interface of this library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INT_LIB_H
+#define INT_LIB_H
+
+// Assumption: signed integral is 2's complement
+// Assumption: right shift of signed negative is arithmetic shift
+
+#include <limits.h>
+
+#ifdef __LITTLE_ENDIAN__
+#if __LITTLE_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN 0
+#endif
+#endif
+
+#ifdef __BIG_ENDIAN__
+#if __BIG_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN 1
+#endif
+#endif
+
+#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
+#error unable to determine endian
+#endif
+
+typedef int si_int;
+typedef unsigned su_int;
+
+typedef long long di_int;
+typedef unsigned long long du_int;
+
+typedef union
+{
+ di_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ su_int low;
+ si_int high;
+#else
+ si_int high;
+ su_int low;
+#endif
+ };
+} dwords;
+
+typedef union
+{
+ du_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ su_int low;
+ su_int high;
+#else
+ su_int high;
+ su_int low;
+#endif
+ };
+} udwords;
+
+#if __x86_64
+
+typedef int ti_int __attribute__ ((mode (TI)));
+typedef unsigned tu_int __attribute__ ((mode (TI)));
+
+typedef union
+{
+ ti_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ du_int low;
+ di_int high;
+#else
+ di_int high;
+ du_int low;
+#endif
+ };
+} twords;
+
+typedef union
+{
+ tu_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ du_int low;
+ du_int high;
+#else
+ du_int high;
+ du_int low;
+#endif
+ };
+} utwords;
+
+#endif
+
+typedef union
+{
+ su_int u;
+ float f;
+} float_bits;
+
+typedef union
+{
+ udwords u;
+ double f;
+} double_bits;
+
+typedef struct
+{
+#if _YUGA_LITTLE_ENDIAN
+ udwords low;
+ udwords high;
+#else
+ udwords high;
+ udwords low;
+#endif
+} uqwords;
+
+typedef union
+{
+ uqwords u;
+ long double f;
+} long_double_bits;
+
+#endif
diff --git a/lib/lshrdi3.c b/lib/lshrdi3.c
new file mode 100644
index 000000000..62eb1a4a0
--- /dev/null
+++ b/lib/lshrdi3.c
@@ -0,0 +1,40 @@
+//===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __lshrdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: logical a >> b
+
+// Precondition: 0 <= b < bits_in_dword
+
+di_int
+__lshrdi3(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ udwords input;
+ udwords result;
+ input.all = a;
+ if (b & bits_in_word) // bits_in_word <= b < bits_in_dword
+ {
+ result.high = 0;
+ result.low = input.high >> (b - bits_in_word);
+ }
+ else // 0 <= b < bits_in_word
+ {
+ if (b == 0)
+ return a;
+ result.high = input.high >> b;
+ result.low = (input.high << (bits_in_word - b)) | (input.low >> b);
+ }
+ return result.all;
+}
diff --git a/lib/lshrti3.c b/lib/lshrti3.c
new file mode 100644
index 000000000..99258cee1
--- /dev/null
+++ b/lib/lshrti3.c
@@ -0,0 +1,44 @@
+//===-- lshrti3.c - Implement __lshrti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __lshrti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: logical a >> b
+
+// Precondition: 0 <= b < bits_in_tword
+
+ti_int
+__lshrti3(ti_int a, si_int b)
+{
+ const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
+ utwords input;
+ utwords result;
+ input.all = a;
+ if (b & bits_in_dword) // bits_in_dword <= b < bits_in_tword
+ {
+ result.high = 0;
+ result.low = input.high >> (b - bits_in_dword);
+ }
+ else // 0 <= b < bits_in_dword
+ {
+ if (b == 0)
+ return a;
+ result.high = input.high >> b;
+ result.low = (input.high << (bits_in_dword - b)) | (input.low >> b);
+ }
+ return result.all;
+}
+
+#endif
diff --git a/lib/moddi3.c b/lib/moddi3.c
new file mode 100644
index 000000000..5e903914a
--- /dev/null
+++ b/lib/moddi3.c
@@ -0,0 +1,31 @@
+//===-- moddi3.c - Implement __moddi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __moddi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+// Returns: a % b
+
+di_int
+__moddi3(di_int a, di_int b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+ di_int s = b >> bits_in_dword_m1; // s = b < 0 ? -1 : 0
+ b = (b ^ s) - s; // negate if s == -1
+ s = a >> bits_in_dword_m1; // s = a < 0 ? -1 : 0
+ a = (a ^ s) - s; // negate if s == -1
+ di_int r;
+ __udivmoddi4(a, b, (du_int*)&r);
+ return (r ^ s) - s; // negate if s == -1
+}
diff --git a/lib/modsi3.c b/lib/modsi3.c
new file mode 100644
index 000000000..d6dfe616d
--- /dev/null
+++ b/lib/modsi3.c
@@ -0,0 +1,22 @@
+//===-- modsi3.c - Implement __modsi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __modsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a % b
+
+si_int
+__modsi3(si_int a, si_int b)
+{
+ return a - (a / b) * b;
+}
diff --git a/lib/modti3.c b/lib/modti3.c
new file mode 100644
index 000000000..91ff8aa5d
--- /dev/null
+++ b/lib/modti3.c
@@ -0,0 +1,35 @@
+//===-- modti3.c - Implement __modti3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __modti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+// Returns: a % b
+
+ti_int
+__modti3(ti_int a, ti_int b)
+{
+ const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
+ ti_int s = b >> bits_in_tword_m1; // s = b < 0 ? -1 : 0
+ b = (b ^ s) - s; // negate if s == -1
+ s = a >> bits_in_tword_m1; // s = a < 0 ? -1 : 0
+ a = (a ^ s) - s; // negate if s == -1
+ ti_int r;
+ __udivmodti4(a, b, (tu_int*)&r);
+ return (r ^ s) - s; // negate if s == -1
+}
+
+#endif
diff --git a/lib/muldc3.c b/lib/muldc3.c
new file mode 100644
index 000000000..b945e8e38
--- /dev/null
+++ b/lib/muldc3.c
@@ -0,0 +1,73 @@
+//===-- muldc3.c - Implement __muldc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __muldc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+// Returns: the product of a + ib and c + id
+
+double _Complex
+__muldc3(double __a, double __b, double __c, double __d)
+{
+ double __ac = __a * __c;
+ double __bd = __b * __d;
+ double __ad = __a * __d;
+ double __bc = __b * __c;
+ double _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (isinf(__a) || isinf(__b))
+ {
+ __a = copysign(isinf(__a) ? 1 : 0, __a);
+ __b = copysign(isinf(__b) ? 1 : 0, __b);
+ if (isnan(__c))
+ __c = copysign(0, __c);
+ if (isnan(__d))
+ __d = copysign(0, __d);
+ __recalc = 1;
+ }
+ if (isinf(__c) || isinf(__d))
+ {
+ __c = copysign(isinf(__c) ? 1 : 0, __c);
+ __d = copysign(isinf(__d) ? 1 : 0, __d);
+ if (isnan(__a))
+ __a = copysign(0, __a);
+ if (isnan(__b))
+ __b = copysign(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+ isinf(__ad) || isinf(__bc)))
+ {
+ if (isnan(__a))
+ __a = copysign(0, __a);
+ if (isnan(__b))
+ __b = copysign(0, __b);
+ if (isnan(__c))
+ __c = copysign(0, __c);
+ if (isnan(__d))
+ __d = copysign(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = INFINITY * (__a * __c - __b * __d);
+ __imag__ z = INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}
diff --git a/lib/muldi3.c b/lib/muldi3.c
new file mode 100644
index 000000000..98299e6f0
--- /dev/null
+++ b/lib/muldi3.c
@@ -0,0 +1,53 @@
+//===-- muldi3.c - Implement __muldi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __muldi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a * b
+
+static
+di_int
+__muldsi3(su_int a, su_int b)
+{
+ dwords r;
+ const int bits_in_word_2 = (int)(sizeof(si_int) * CHAR_BIT) / 2;
+ const su_int lower_mask = (su_int)~0 >> bits_in_word_2;
+ r.low = (a & lower_mask) * (b & lower_mask);
+ su_int t = r.low >> bits_in_word_2;
+ r.low &= lower_mask;
+ t += (a >> bits_in_word_2) * (b & lower_mask);
+ r.low += (t & lower_mask) << bits_in_word_2;
+ r.high = t >> bits_in_word_2;
+ t = r.low >> bits_in_word_2;
+ r.low &= lower_mask;
+ t += (b >> bits_in_word_2) * (a & lower_mask);
+ r.low += (t & lower_mask) << bits_in_word_2;
+ r.high += t >> bits_in_word_2;
+ r.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);
+ return r.all;
+}
+
+// Returns: a * b
+
+di_int
+__muldi3(di_int a, di_int b)
+{
+ dwords x;
+ x.all = a;
+ dwords y;
+ y.all = b;
+ dwords r;
+ r.all = __muldsi3(x.low, y.low);
+ r.high += x.high * y.low + x.low * y.high;
+ return r.all;
+}
diff --git a/lib/mulsc3.c b/lib/mulsc3.c
new file mode 100644
index 000000000..bc47a47ea
--- /dev/null
+++ b/lib/mulsc3.c
@@ -0,0 +1,73 @@
+//===-- mulsc3.c - Implement __mulsc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __mulsc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+// Returns: the product of a + ib and c + id
+
+float _Complex
+__mulsc3(float __a, float __b, float __c, float __d)
+{
+ float __ac = __a * __c;
+ float __bd = __b * __d;
+ float __ad = __a * __d;
+ float __bc = __b * __c;
+ float _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (isinf(__a) || isinf(__b))
+ {
+ __a = copysignf(isinf(__a) ? 1 : 0, __a);
+ __b = copysignf(isinf(__b) ? 1 : 0, __b);
+ if (isnan(__c))
+ __c = copysignf(0, __c);
+ if (isnan(__d))
+ __d = copysignf(0, __d);
+ __recalc = 1;
+ }
+ if (isinf(__c) || isinf(__d))
+ {
+ __c = copysignf(isinf(__c) ? 1 : 0, __c);
+ __d = copysignf(isinf(__d) ? 1 : 0, __d);
+ if (isnan(__a))
+ __a = copysignf(0, __a);
+ if (isnan(__b))
+ __b = copysignf(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+ isinf(__ad) || isinf(__bc)))
+ {
+ if (isnan(__a))
+ __a = copysignf(0, __a);
+ if (isnan(__b))
+ __b = copysignf(0, __b);
+ if (isnan(__c))
+ __c = copysignf(0, __c);
+ if (isnan(__d))
+ __d = copysignf(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = INFINITY * (__a * __c - __b * __d);
+ __imag__ z = INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}
diff --git a/lib/multi3.c b/lib/multi3.c
new file mode 100644
index 000000000..8ba6550b6
--- /dev/null
+++ b/lib/multi3.c
@@ -0,0 +1,57 @@
+//===-- multi3.c - Implement __multi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __multi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: a * b
+
+static
+ti_int
+__mulddi3(du_int a, du_int b)
+{
+ twords r;
+ const int bits_in_dword_2 = (int)(sizeof(di_int) * CHAR_BIT) / 2;
+ const du_int lower_mask = (du_int)~0 >> bits_in_dword_2;
+ r.low = (a & lower_mask) * (b & lower_mask);
+ du_int t = r.low >> bits_in_dword_2;
+ r.low &= lower_mask;
+ t += (a >> bits_in_dword_2) * (b & lower_mask);
+ r.low += (t & lower_mask) << bits_in_dword_2;
+ r.high = t >> bits_in_dword_2;
+ t = r.low >> bits_in_dword_2;
+ r.low &= lower_mask;
+ t += (b >> bits_in_dword_2) * (a & lower_mask);
+ r.low += (t & lower_mask) << bits_in_dword_2;
+ r.high += t >> bits_in_dword_2;
+ r.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2);
+ return r.all;
+}
+
+// Returns: a * b
+
+ti_int
+__multi3(ti_int a, ti_int b)
+{
+ twords x;
+ x.all = a;
+ twords y;
+ y.all = b;
+ twords r;
+ r.all = __mulddi3(x.low, y.low);
+ r.high += x.high * y.low + x.low * y.high;
+ return r.all;
+}
+
+#endif
diff --git a/lib/mulvdi3.c b/lib/mulvdi3.c
new file mode 100644
index 000000000..862a8c006
--- /dev/null
+++ b/lib/mulvdi3.c
@@ -0,0 +1,56 @@
+//===-- mulvdi3.c - Implement __mulvdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __mulvdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a * b
+
+// Effects: aborts if a * b overflows
+
+di_int
+__mulvdi3(di_int a, di_int b)
+{
+ const int N = (int)(sizeof(di_int) * CHAR_BIT);
+ const di_int MIN = (di_int)1 << (N-1);
+ const di_int MAX = ~MIN;
+ if (a == MIN)
+ {
+ if (b == 0 || b == 1)
+ return a * b;
+ abort();
+ }
+ if (b == MIN)
+ {
+ if (a == 0 || a == 1)
+ return a * b;
+ abort();
+ }
+ di_int sa = a >> (N - 1);
+ di_int abs_a = (a ^ sa) - sa;
+ di_int sb = b >> (N - 1);
+ di_int abs_b = (b ^ sb) - sb;
+ if (abs_a < 2 || abs_b < 2)
+ return a * b;
+ if (sa == sb)
+ {
+ if (abs_a > MAX / abs_b)
+ abort();
+ }
+ else
+ {
+ if (abs_a > MIN / -abs_b)
+ abort();
+ }
+ return a * b;
+}
diff --git a/lib/mulvsi3.c b/lib/mulvsi3.c
new file mode 100644
index 000000000..cef0c3551
--- /dev/null
+++ b/lib/mulvsi3.c
@@ -0,0 +1,56 @@
+//===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __mulvsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a * b
+
+// Effects: aborts if a * b overflows
+
+si_int
+__mulvsi3(si_int a, si_int b)
+{
+ const int N = (int)(sizeof(si_int) * CHAR_BIT);
+ const si_int MIN = (si_int)1 << (N-1);
+ const si_int MAX = ~MIN;
+ if (a == MIN)
+ {
+ if (b == 0 || b == 1)
+ return a * b;
+ abort();
+ }
+ if (b == MIN)
+ {
+ if (a == 0 || a == 1)
+ return a * b;
+ abort();
+ }
+ si_int sa = a >> (N - 1);
+ si_int abs_a = (a ^ sa) - sa;
+ si_int sb = b >> (N - 1);
+ si_int abs_b = (b ^ sb) - sb;
+ if (abs_a < 2 || abs_b < 2)
+ return a * b;
+ if (sa == sb)
+ {
+ if (abs_a > MAX / abs_b)
+ abort();
+ }
+ else
+ {
+ if (abs_a > MIN / -abs_b)
+ abort();
+ }
+ return a * b;
+}
diff --git a/lib/mulvti3.c b/lib/mulvti3.c
new file mode 100644
index 000000000..82efe8caa
--- /dev/null
+++ b/lib/mulvti3.c
@@ -0,0 +1,60 @@
+//===-- mulvti3.c - Implement __mulvti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __mulvti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a * b
+
+// Effects: aborts if a * b overflows
+
+ti_int
+__mulvti3(ti_int a, ti_int b)
+{
+ const int N = (int)(sizeof(ti_int) * CHAR_BIT);
+ const ti_int MIN = (ti_int)1 << (N-1);
+ const ti_int MAX = ~MIN;
+ if (a == MIN)
+ {
+ if (b == 0 || b == 1)
+ return a * b;
+ abort();
+ }
+ if (b == MIN)
+ {
+ if (a == 0 || a == 1)
+ return a * b;
+ abort();
+ }
+ ti_int sa = a >> (N - 1);
+ ti_int abs_a = (a ^ sa) - sa;
+ ti_int sb = b >> (N - 1);
+ ti_int abs_b = (b ^ sb) - sb;
+ if (abs_a < 2 || abs_b < 2)
+ return a * b;
+ if (sa == sb)
+ {
+ if (abs_a > MAX / abs_b)
+ abort();
+ }
+ else
+ {
+ if (abs_a > MIN / -abs_b)
+ abort();
+ }
+ return a * b;
+}
+
+#endif
diff --git a/lib/mulxc3.c b/lib/mulxc3.c
new file mode 100644
index 000000000..e38ab0dcf
--- /dev/null
+++ b/lib/mulxc3.c
@@ -0,0 +1,77 @@
+//===-- mulxc3.c - Implement __mulxc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __mulxc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+// Returns: the product of a + ib and c + id
+
+long double _Complex
+__mulxc3(long double __a, long double __b, long double __c, long double __d)
+{
+ long double __ac = __a * __c;
+ long double __bd = __b * __d;
+ long double __ad = __a * __d;
+ long double __bc = __b * __c;
+ long double _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (isinf(__a) || isinf(__b))
+ {
+ __a = copysignl(isinf(__a) ? 1 : 0, __a);
+ __b = copysignl(isinf(__b) ? 1 : 0, __b);
+ if (isnan(__c))
+ __c = copysignl(0, __c);
+ if (isnan(__d))
+ __d = copysignl(0, __d);
+ __recalc = 1;
+ }
+ if (isinf(__c) || isinf(__d))
+ {
+ __c = copysignl(isinf(__c) ? 1 : 0, __c);
+ __d = copysignl(isinf(__d) ? 1 : 0, __d);
+ if (isnan(__a))
+ __a = copysignl(0, __a);
+ if (isnan(__b))
+ __b = copysignl(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+ isinf(__ad) || isinf(__bc)))
+ {
+ if (isnan(__a))
+ __a = copysignl(0, __a);
+ if (isnan(__b))
+ __b = copysignl(0, __b);
+ if (isnan(__c))
+ __c = copysignl(0, __c);
+ if (isnan(__d))
+ __d = copysignl(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = INFINITY * (__a * __c - __b * __d);
+ __imag__ z = INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}
+
+#endif
diff --git a/lib/negdi2.c b/lib/negdi2.c
new file mode 100644
index 000000000..db2d865bd
--- /dev/null
+++ b/lib/negdi2.c
@@ -0,0 +1,22 @@
+//===-- negdi2.c - Implement __negdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __negdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: -a
+
+di_int
+__negdi2(di_int a)
+{
+ return ~a + 1;
+}
diff --git a/lib/negti2.c b/lib/negti2.c
new file mode 100644
index 000000000..c1c8a1296
--- /dev/null
+++ b/lib/negti2.c
@@ -0,0 +1,26 @@
+//===-- negti2.c - Implement __negti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __negti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: -a
+
+ti_int
+__negti2(ti_int a)
+{
+ return ~a + 1;
+}
+
+#endif
diff --git a/lib/negvdi2.c b/lib/negvdi2.c
new file mode 100644
index 000000000..eb9f6e916
--- /dev/null
+++ b/lib/negvdi2.c
@@ -0,0 +1,28 @@
+//===-- negvdi2.c - Implement __negvdi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __negvdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: -a
+
+// Effects: aborts if -a overflows
+
+di_int
+__negvdi2(di_int a)
+{
+ const di_int MIN = (di_int)1 << ((int)(sizeof(di_int) * CHAR_BIT)-1);
+ if (a == MIN)
+ abort();
+ return -a;
+}
diff --git a/lib/negvsi2.c b/lib/negvsi2.c
new file mode 100644
index 000000000..7e42655e6
--- /dev/null
+++ b/lib/negvsi2.c
@@ -0,0 +1,28 @@
+//===-- negvsi2.c - Implement __negvsi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __negvsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: -a
+
+// Effects: aborts if -a overflows
+
+si_int
+__negvsi2(si_int a)
+{
+ const si_int MIN = (si_int)1 << ((int)(sizeof(si_int) * CHAR_BIT)-1);
+ if (a == MIN)
+ abort();
+ return -a;
+}
diff --git a/lib/negvti2.c b/lib/negvti2.c
new file mode 100644
index 000000000..ced05e885
--- /dev/null
+++ b/lib/negvti2.c
@@ -0,0 +1,32 @@
+//===-- negvti2.c - Implement __negvti2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __negvti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: -a
+
+// Effects: aborts if -a overflows
+
+ti_int
+__negvti2(ti_int a)
+{
+ const ti_int MIN = (ti_int)1 << ((int)(sizeof(ti_int) * CHAR_BIT)-1);
+ if (a == MIN)
+ abort();
+ return -a;
+}
+
+#endif
diff --git a/lib/paritydi2.c b/lib/paritydi2.c
new file mode 100644
index 000000000..ea7c56588
--- /dev/null
+++ b/lib/paritydi2.c
@@ -0,0 +1,26 @@
+//===-- paritydi2.c - Implement __paritydi2 -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __paritydi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: 1 if number of bits is odd else returns 0
+
+si_int __paritysi2(si_int a);
+
+si_int
+__paritydi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ return __paritysi2(x.high ^ x.low);
+}
diff --git a/lib/paritysi2.c b/lib/paritysi2.c
new file mode 100644
index 000000000..c38f9cf2a
--- /dev/null
+++ b/lib/paritysi2.c
@@ -0,0 +1,26 @@
+//===-- paritysi2.c - Implement __paritysi2 -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __paritysi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: 1 if number of bits is odd else returns 0
+
+si_int
+__paritysi2(si_int a)
+{
+ su_int x = (su_int)a;
+ x ^= x >> 16;
+ x ^= x >> 8;
+ x ^= x >> 4;
+ return (0x6996 >> (x & 0xF)) & 1;
+}
diff --git a/lib/parityti2.c b/lib/parityti2.c
new file mode 100644
index 000000000..6842a5192
--- /dev/null
+++ b/lib/parityti2.c
@@ -0,0 +1,30 @@
+//===-- parityti2.c - Implement __parityti2 -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __parityti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: 1 if number of bits is odd else returns 0
+
+si_int __paritydi2(di_int a);
+
+si_int
+__parityti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ return __paritydi2(x.high ^ x.low);
+}
+
+#endif
diff --git a/lib/popcountdi2.c b/lib/popcountdi2.c
new file mode 100644
index 000000000..338bbb3ca
--- /dev/null
+++ b/lib/popcountdi2.c
@@ -0,0 +1,35 @@
+//===-- popcountdi2.c - Implement __popcountdi2 ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __popcountdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: count of 1 bits
+
+si_int
+__popcountdi2(di_int a)
+{
+ du_int x2 = (du_int)a;
+ x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);
+ // Every 2 bits holds the sum of every pair of bits (32)
+ x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);
+ // Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16)
+ x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;
+ // Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8)
+ su_int x = (su_int)(x2 + (x2 >> 32));
+ // The lower 32 bits hold four 16 bit sums (5 significant bits).
+ // Upper 32 bits are garbage
+ x = x + (x >> 16);
+ // The lower 16 bits hold two 32 bit sums (6 significant bits).
+ // Upper 16 bits are garbage
+ return (x + (x >> 8)) & 0x0000007F; // (7 significant bits)
+}
diff --git a/lib/popcountsi2.c b/lib/popcountsi2.c
new file mode 100644
index 000000000..68220aef9
--- /dev/null
+++ b/lib/popcountsi2.c
@@ -0,0 +1,32 @@
+//===-- popcountsi2.c - Implement __popcountsi2 ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __popcountsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: count of 1 bits
+
+si_int
+__popcountsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ x = x - ((x >> 1) & 0x55555555);
+ // Every 2 bits holds the sum of every pair of bits
+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
+ // Every 4 bits holds the sum of every 4-set of bits (3 significant bits)
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ // Every 8 bits holds the sum of every 8-set of bits (4 significant bits)
+ x = (x + (x >> 16));
+ // The lower 16 bits hold two 8 bit sums (5 significant bits).
+ // Upper 16 bits are garbage
+ return (x + (x >> 8)) & 0x0000003F; // (6 significant bits)
+}
diff --git a/lib/popcountti2.c b/lib/popcountti2.c
new file mode 100644
index 000000000..9ac052d91
--- /dev/null
+++ b/lib/popcountti2.c
@@ -0,0 +1,43 @@
+//===-- popcountti2.c - Implement __popcountti2 ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __popcountti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: count of 1 bits
+
+si_int
+__popcountti2(ti_int a)
+{
+ tu_int x3 = (tu_int)a;
+ x3 = x3 - ((x3 >> 1) & (((tu_int)0x5555555555555555uLL << 64) |
+ 0x5555555555555555uLL));
+ // Every 2 bits holds the sum of every pair of bits (64)
+ x3 = ((x3 >> 2) & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL))
+ + (x3 & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL));
+ // Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (32)
+ x3 = (x3 + (x3 >> 4))
+ & (((tu_int)0x0F0F0F0F0F0F0F0FuLL << 64) | 0x0F0F0F0F0F0F0F0FuLL);
+ // Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (16)
+ du_int x2 = (du_int)(x3 + (x3 >> 64));
+ // Every 8 bits holds the sum of every 8-set of bits (5 significant bits) (8)
+ su_int x = (su_int)(x2 + (x2 >> 32));
+ // Every 8 bits holds the sum of every 8-set of bits (6 significant bits) (4)
+ x = x + (x >> 16);
+ // Every 8 bits holds the sum of every 8-set of bits (7 significant bits) (2)
+ // Upper 16 bits are garbage
+ return (x + (x >> 8)) & 0xFF; // (8 significant bits)
+}
+
+#endif
diff --git a/lib/powidf2.c b/lib/powidf2.c
new file mode 100644
index 000000000..3237e266d
--- /dev/null
+++ b/lib/powidf2.c
@@ -0,0 +1,33 @@
+//===-- powidf2.cpp - Implement __powidf2 ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __powidf2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a ^ b
+
+double
+__powidf2(double a, si_int b)
+{
+ const int recip = b < 0;
+ double r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
diff --git a/lib/powisf2.c b/lib/powisf2.c
new file mode 100644
index 000000000..fcaaa1f26
--- /dev/null
+++ b/lib/powisf2.c
@@ -0,0 +1,33 @@
+//===-- powisf2.cpp - Implement __powisf2 ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __powisf2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a ^ b
+
+float
+__powisf2(float a, si_int b)
+{
+ const int recip = b < 0;
+ float r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
diff --git a/lib/powitf2.c b/lib/powitf2.c
new file mode 100644
index 000000000..34aa2cb6a
--- /dev/null
+++ b/lib/powitf2.c
@@ -0,0 +1,37 @@
+//===-- powitf2.cpp - Implement __powitf2 ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __powitf2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if _ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: a ^ b
+
+long double
+__powitf2(long double a, si_int b)
+{
+ const int recip = b < 0;
+ long double r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
+
+#endif
diff --git a/lib/powixf2.c b/lib/powixf2.c
new file mode 100644
index 000000000..07e145a44
--- /dev/null
+++ b/lib/powixf2.c
@@ -0,0 +1,37 @@
+//===-- powixf2.cpp - Implement __powixf2 ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __powixf2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+// Returns: a ^ b
+
+long double
+__powixf2(long double a, si_int b)
+{
+ const int recip = b < 0;
+ long double r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
+
+#endif
diff --git a/lib/ppc/DD.h b/lib/ppc/DD.h
new file mode 100644
index 000000000..32acecd5f
--- /dev/null
+++ b/lib/ppc/DD.h
@@ -0,0 +1,46 @@
+#ifndef __DD_HEADER
+#define __DD_HEADER
+
+#include <stdint.h>
+
+typedef union {
+ long double ld;
+ struct {
+ double hi;
+ double lo;
+ };
+} DD;
+
+typedef union {
+ double d;
+ uint64_t x;
+} doublebits;
+
+#define LOWORDER(xy,xHi,xLo,yHi,yLo) \
+ (((((xHi)*(yHi) - (xy)) + (xHi)*(yLo)) + (xLo)*(yHi)) + (xLo)*(yLo))
+
+static inline double __attribute__((always_inline))
+fabs(double x)
+{
+ doublebits result = { .d = x };
+ result.x &= UINT64_C(0x7fffffffffffffff);
+ return result.d;
+}
+
+static inline double __attribute__((always_inline))
+high26bits(double x)
+{
+ doublebits result = { .d = x };
+ result.x &= UINT64_C(0xfffffffff8000000);
+ return result.d;
+}
+
+static inline int __attribute__((always_inline))
+different_sign(double x, double y)
+{
+ doublebits xsignbit = { .d = x }, ysignbit = { .d = y };
+ int result = (int)(xsignbit.x >> 63) ^ (int)(ysignbit.x >> 63);
+ return result;
+}
+
+#endif // __DD_HEADER
diff --git a/lib/ppc/Makefile.mk b/lib/ppc/Makefile.mk
new file mode 100644
index 000000000..5d0f2b3df
--- /dev/null
+++ b/lib/ppc/Makefile.mk
@@ -0,0 +1,22 @@
+#===- lib/ppc/Makefile.mk ----------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+Dir := lib/ppc
+SubDirs :=
+OnlyArchs := ppc
+
+AsmSources := $(foreach file,$(wildcard $(Dir)/*.s),$(notdir $(file)))
+Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
+ObjNames := $(Sources:%.c=%.o) $(AsmSources:%.s=%.o)
+Target := Optimized
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
+
+include make/subdir.mk
diff --git a/lib/ppc/divtc3.c b/lib/ppc/divtc3.c
new file mode 100644
index 000000000..bec6b5353
--- /dev/null
+++ b/lib/ppc/divtc3.c
@@ -0,0 +1,88 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "DD.h"
+#include <math.h>
+
+#define makeFinite(x) { \
+ (x).hi = __builtin_copysign(isinf((x).hi) ? 1.0 : 0.0, (x).hi); \
+ (x).lo = 0.0; \
+ }
+
+long double __gcc_qadd(long double, long double);
+long double __gcc_qsub(long double, long double);
+long double __gcc_qmul(long double, long double);
+long double __gcc_qdiv(long double, long double);
+
+long double _Complex
+__divtc3(long double a, long double b, long double c, long double d)
+{
+ DD cDD = { .ld = c };
+ DD dDD = { .ld = d };
+
+ int ilogbw = 0;
+ const double logbw = logb(__builtin_fmax( __builtin_fabs(cDD.hi), __builtin_fabs(dDD.hi) ));
+
+ if (isfinite(logbw))
+ {
+ ilogbw = (int)logbw;
+
+ cDD.hi = scalbn(cDD.hi, -ilogbw);
+ cDD.lo = scalbn(cDD.lo, -ilogbw);
+ dDD.hi = scalbn(dDD.hi, -ilogbw);
+ dDD.lo = scalbn(dDD.lo, -ilogbw);
+ }
+
+ const long double denom = __gcc_qadd(__gcc_qmul(cDD.ld, cDD.ld), __gcc_qmul(dDD.ld, dDD.ld));
+ const long double realNumerator = __gcc_qadd(__gcc_qmul(a,cDD.ld), __gcc_qmul(b,dDD.ld));
+ const long double imagNumerator = __gcc_qsub(__gcc_qmul(b,cDD.ld), __gcc_qmul(a,dDD.ld));
+
+ DD real = { .ld = __gcc_qdiv(realNumerator, denom) };
+ DD imag = { .ld = __gcc_qdiv(imagNumerator, denom) };
+
+ real.hi = scalbn(real.hi, -ilogbw);
+ real.lo = scalbn(real.lo, -ilogbw);
+ imag.hi = scalbn(imag.hi, -ilogbw);
+ imag.lo = scalbn(imag.lo, -ilogbw);
+
+ if (isnan(real.hi) && isnan(imag.hi))
+ {
+ DD aDD = { .ld = a };
+ DD bDD = { .ld = b };
+ DD rDD = { .ld = denom };
+
+ if ((rDD.hi == 0.0) && (!isnan(aDD.hi) || !isnan(bDD.hi)))
+ {
+ real.hi = __builtin_copysign(INFINITY,cDD.hi) * aDD.hi;
+ real.lo = 0.0;
+ imag.hi = __builtin_copysign(INFINITY,cDD.hi) * bDD.hi;
+ imag.lo = 0.0;
+ }
+
+ else if ((isinf(aDD.hi) || isinf(bDD.hi)) && isfinite(cDD.hi) && isfinite(dDD.hi))
+ {
+ makeFinite(aDD);
+ makeFinite(bDD);
+ real.hi = INFINITY * (aDD.hi*cDD.hi + bDD.hi*dDD.hi);
+ real.lo = 0.0;
+ imag.hi = INFINITY * (bDD.hi*cDD.hi - aDD.hi*dDD.hi);
+ imag.lo = 0.0;
+ }
+
+ else if ((isinf(cDD.hi) || isinf(dDD.hi)) && isfinite(aDD.hi) && isfinite(bDD.hi))
+ {
+ makeFinite(cDD);
+ makeFinite(dDD);
+ real.hi = __builtin_copysign(0.0,(aDD.hi*cDD.hi + bDD.hi*dDD.hi));
+ real.lo = 0.0;
+ imag.hi = __builtin_copysign(0.0,(bDD.hi*cDD.hi - aDD.hi*dDD.hi));
+ imag.lo = 0.0;
+ }
+ }
+
+ long double _Complex z;
+ __real__ z = real.ld;
+ __imag__ z = imag.ld;
+
+ return z;
+}
diff --git a/lib/ppc/fixtfdi.c b/lib/ppc/fixtfdi.c
new file mode 100644
index 000000000..c95241701
--- /dev/null
+++ b/lib/ppc/fixtfdi.c
@@ -0,0 +1,100 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// int64_t __fixunstfdi(long double x);
+// This file implements the PowerPC 128-bit double-double -> int64_t conversion
+
+#include "DD.h"
+#include <stdint.h>
+
+uint64_t __fixtfdi(long double input)
+{
+ const DD x = { .ld = input };
+ const doublebits hibits = { .d = x.hi };
+
+ const uint32_t absHighWord = (uint32_t)(hibits.x >> 32) & UINT32_C(0x7fffffff);
+ const uint32_t absHighWordMinusOne = absHighWord - UINT32_C(0x3ff00000);
+
+ // If (1.0 - tiny) <= input < 0x1.0p63:
+ if (UINT32_C(0x03f00000) > absHighWordMinusOne)
+ {
+ // Do an unsigned conversion of the absolute value, then restore the sign.
+ const int unbiasedHeadExponent = absHighWordMinusOne >> 20;
+
+ int64_t result = hibits.x & INT64_C(0x000fffffffffffff); // mantissa(hi)
+ result |= INT64_C(0x0010000000000000); // matissa(hi) with implicit bit
+ result <<= 10; // mantissa(hi) with one zero preceeding bit.
+
+ const int64_t hiNegationMask = ((int64_t)(hibits.x)) >> 63;
+
+ // If the tail is non-zero, we need to patch in the tail bits.
+ if (0.0 != x.lo)
+ {
+ const doublebits lobits = { .d = x.lo };
+ int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
+ tailMantissa |= INT64_C(0x0010000000000000);
+
+ // At this point we have the mantissa of |tail|
+ // We need to negate it if head and tail have different signs.
+ const int64_t loNegationMask = ((int64_t)(lobits.x)) >> 63;
+ const int64_t negationMask = loNegationMask ^ hiNegationMask;
+ tailMantissa = (tailMantissa ^ negationMask) - negationMask;
+
+ // Now we have the mantissa of tail as a signed 2s-complement integer
+
+ const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
+
+ // Shift the tail mantissa into the right position, accounting for the
+ // bias of 10 that we shifted the head mantissa by.
+ tailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 10)));
+
+ result += tailMantissa;
+ }
+
+ result >>= (62 - unbiasedHeadExponent);
+
+ // Restore the sign of the result and return
+ result = (result ^ hiNegationMask) - hiNegationMask;
+ return result;
+
+ }
+
+ // Edge cases handled here:
+
+ // |x| < 1, result is zero.
+ if (1.0 > __builtin_fabs(x.hi))
+ return INT64_C(0);
+
+ // x very close to INT64_MIN, care must be taken to see which side we are on.
+ if (x.hi == -0x1.0p63) {
+
+ int64_t result = INT64_MIN;
+
+ if (0.0 < x.lo)
+ {
+ // If the tail is positive, the correct result is something other than INT64_MIN.
+ // we'll need to figure out what it is.
+
+ const doublebits lobits = { .d = x.lo };
+ int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
+ tailMantissa |= INT64_C(0x0010000000000000);
+
+ // Now we negate the tailMantissa
+ tailMantissa = (tailMantissa ^ INT64_C(-1)) + INT64_C(1);
+
+ // And shift it by the appropriate amount
+ const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
+ tailMantissa >>= 1075 - biasedTailExponent;
+
+ result -= tailMantissa;
+ }
+
+ return result;
+ }
+
+ // Signed overflows, infinities, and NaNs
+ if (x.hi > 0.0)
+ return INT64_MAX;
+ else
+ return INT64_MIN;
+}
diff --git a/lib/ppc/fixunstfdi.c b/lib/ppc/fixunstfdi.c
new file mode 100644
index 000000000..35ce3a912
--- /dev/null
+++ b/lib/ppc/fixunstfdi.c
@@ -0,0 +1,58 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// uint64_t __fixunstfdi(long double x);
+// This file implements the PowerPC 128-bit double-double -> uint64_t conversion
+
+#include "DD.h"
+#include <stdint.h>
+
+uint64_t __fixunstfdi(long double input)
+{
+ const DD x = { .ld = input };
+ const doublebits hibits = { .d = x.hi };
+
+ const uint32_t highWordMinusOne = (uint32_t)(hibits.x >> 32) - UINT32_C(0x3ff00000);
+
+ // If (1.0 - tiny) <= input < 0x1.0p64:
+ if (UINT32_C(0x04000000) > highWordMinusOne)
+ {
+ const int unbiasedHeadExponent = highWordMinusOne >> 20;
+
+ uint64_t result = hibits.x & UINT64_C(0x000fffffffffffff); // mantissa(hi)
+ result |= UINT64_C(0x0010000000000000); // matissa(hi) with implicit bit
+ result <<= 11; // mantissa(hi) left aligned in the int64 field.
+
+ // If the tail is non-zero, we need to patch in the tail bits.
+ if (0.0 != x.lo)
+ {
+ const doublebits lobits = { .d = x.lo };
+ int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
+ tailMantissa |= INT64_C(0x0010000000000000);
+
+ // At this point we have the mantissa of |tail|
+
+ const int64_t negationMask = ((int64_t)(lobits.x)) >> 63;
+ tailMantissa = (tailMantissa ^ negationMask) - negationMask;
+
+ // Now we have the mantissa of tail as a signed 2s-complement integer
+
+ const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
+
+ // Shift the tail mantissa into the right position, accounting for the
+ // bias of 11 that we shifted the head mantissa by.
+ tailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 11)));
+
+ result += tailMantissa;
+ }
+
+ result >>= (63 - unbiasedHeadExponent);
+ return result;
+ }
+
+ // Edge cases are handled here, with saturation.
+ if (1.0 > x.hi)
+ return UINT64_C(0);
+ else
+ return UINT64_MAX;
+}
diff --git a/lib/ppc/floatditf.c b/lib/ppc/floatditf.c
new file mode 100644
index 000000000..081dc8cbe
--- /dev/null
+++ b/lib/ppc/floatditf.c
@@ -0,0 +1,34 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __floatditf(long long x);
+// This file implements the PowerPC long long -> long double conversion
+
+#include "DD.h"
+#include <stdint.h>
+
+long double __floatditf(int64_t a) {
+
+ static const double twop32 = 0x1.0p32;
+ static const double twop52 = 0x1.0p52;
+
+ doublebits low = { .d = twop52 };
+ low.x |= a & UINT64_C(0x00000000ffffffff); // 0x1.0p52 + low 32 bits of a.
+
+ const double high_addend = (double)((int32_t)(a >> 32))*twop32 - twop52;
+
+ // At this point, we have two double precision numbers
+ // high_addend and low.d, and we wish to return their sum
+ // as a canonicalized long double:
+
+ // This implementation sets the inexact flag spuriously.
+ // This could be avoided, but at some substantial cost.
+
+ DD result;
+
+ result.hi = high_addend + low.d;
+ result.lo = (high_addend - result.hi) + low.d;
+
+ return result.ld;
+
+}
diff --git a/lib/ppc/floatunditf.c b/lib/ppc/floatunditf.c
new file mode 100644
index 000000000..63f0b4467
--- /dev/null
+++ b/lib/ppc/floatunditf.c
@@ -0,0 +1,40 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __floatunditf(unsigned long long x);
+// This file implements the PowerPC unsigned long long -> long double conversion
+
+#include "DD.h"
+#include <stdint.h>
+
+long double __floatunditf(uint64_t a) {
+
+ // Begins with an exact copy of the code from __floatundidf
+
+ static const double twop52 = 0x1.0p52;
+ static const double twop84 = 0x1.0p84;
+ static const double twop84_plus_twop52 = 0x1.00000001p84;
+
+ doublebits high = { .d = twop84 };
+ doublebits low = { .d = twop52 };
+
+ high.x |= a >> 32; // 0x1.0p84 + high 32 bits of a
+ low.x |= a & UINT64_C(0x00000000ffffffff); // 0x1.0p52 + low 32 bits of a
+
+ const double high_addend = high.d - twop84_plus_twop52;
+
+ // At this point, we have two double precision numbers
+ // high_addend and low.d, and we wish to return their sum
+ // as a canonicalized long double:
+
+ // This implementation sets the inexact flag spuriously.
+ // This could be avoided, but at some substantial cost.
+
+ DD result;
+
+ result.hi = high_addend + low.d;
+ result.lo = (high_addend - result.hi) + low.d;
+
+ return result.ld;
+
+}
diff --git a/lib/ppc/gcc_qadd.c b/lib/ppc/gcc_qadd.c
new file mode 100644
index 000000000..eb3fdd11e
--- /dev/null
+++ b/lib/ppc/gcc_qadd.c
@@ -0,0 +1,74 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __gcc_qadd(long double x, long double y);
+// This file implements the PowerPC 128-bit double-double add operation.
+// This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+
+#include "DD.h"
+
+long double __gcc_qadd(long double x, long double y)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+
+ DD dst = { .ld = x }, src = { .ld = y };
+
+ register double A = dst.hi, a = dst.lo,
+ B = src.hi, b = src.lo;
+
+ // If both operands are zero:
+ if ((A == 0.0) && (B == 0.0)) {
+ dst.hi = A + B;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ // If either operand is NaN or infinity:
+ const doublebits abits = { .d = A };
+ const doublebits bbits = { .d = B };
+ if ((((uint32_t)(abits.x >> 32) & infinityHi) == infinityHi) ||
+ (((uint32_t)(bbits.x >> 32) & infinityHi) == infinityHi)) {
+ dst.hi = A + B;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ // If the computation overflows:
+ // This may be playing things a little bit fast and loose, but it will do for a start.
+ const double testForOverflow = A + (B + (a + b));
+ const doublebits testbits = { .d = testForOverflow };
+ if (((uint32_t)(testbits.x >> 32) & infinityHi) == infinityHi) {
+ dst.hi = testForOverflow;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ double H, h;
+ double T, t;
+ double W, w;
+ double Y;
+
+ H = B + (A - (A + B));
+ T = b + (a - (a + b));
+ h = A + (B - (A + B));
+ t = a + (b - (a + b));
+
+ if (fabs(A) <= fabs(B))
+ w = (a + b) + h;
+ else
+ w = (a + b) + H;
+
+ W = (A + B) + w;
+ Y = (A + B) - W;
+ Y += w;
+
+ if (fabs(a) <= fabs(b))
+ w = t + Y;
+ else
+ w = T + Y;
+
+ dst.hi = Y = W + w;
+ dst.lo = (W - Y) + w;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/gcc_qdiv.c b/lib/ppc/gcc_qdiv.c
new file mode 100644
index 000000000..53e6c55ec
--- /dev/null
+++ b/lib/ppc/gcc_qdiv.c
@@ -0,0 +1,53 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __gcc_qdiv(long double x, long double y);
+// This file implements the PowerPC 128-bit double-double division operation.
+// This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+
+#include "DD.h"
+
+long double __gcc_qdiv(long double a, long double b)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+ DD dst = { .ld = a }, src = { .ld = b };
+
+ register double x = dst.hi, x1 = dst.lo,
+ y = src.hi, y1 = src.lo;
+
+ double yHi, yLo, qHi, qLo;
+ double yq, tmp, q;
+
+ q = x / y;
+
+ // Detect special cases
+ if (q == 0.0) {
+ dst.hi = q;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ const doublebits qBits = { .d = q };
+ if (((uint32_t)(qBits.x >> 32) & infinityHi) == infinityHi) {
+ dst.hi = q;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ yHi = high26bits(y);
+ qHi = high26bits(q);
+
+ yq = y * q;
+ yLo = y - yHi;
+ qLo = q - qHi;
+
+ tmp = LOWORDER(yq, yHi, yLo, qHi, qLo);
+ tmp = (x - yq) - tmp;
+ tmp = ((tmp + x1) - y1 * q) / y;
+ x = q + tmp;
+
+ dst.lo = (q - x) + tmp;
+ dst.hi = x;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/gcc_qmul.c b/lib/ppc/gcc_qmul.c
new file mode 100644
index 000000000..26d899ee8
--- /dev/null
+++ b/lib/ppc/gcc_qmul.c
@@ -0,0 +1,51 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __gcc_qmul(long double x, long double y);
+// This file implements the PowerPC 128-bit double-double multiply operation.
+// This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+
+#include "DD.h"
+
+long double __gcc_qmul(long double x, long double y)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+ DD dst = { .ld = x }, src = { .ld = y };
+
+ register double A = dst.hi, a = dst.lo,
+ B = src.hi, b = src.lo;
+
+ double aHi, aLo, bHi, bLo;
+ double ab, tmp, tau;
+
+ ab = A * B;
+
+ // Detect special cases
+ if (ab == 0.0) {
+ dst.hi = ab;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ const doublebits abBits = { .d = ab };
+ if (((uint32_t)(abBits.x >> 32) & infinityHi) == infinityHi) {
+ dst.hi = ab;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ // Generic cases handled here.
+ aHi = high26bits(A);
+ bHi = high26bits(B);
+ aLo = A - aHi;
+ bLo = B - bHi;
+
+ tmp = LOWORDER(ab, aHi, aLo, bHi, bLo);
+ tmp += (A * b + a * B);
+ tau = ab + tmp;
+
+ dst.lo = (ab - tau) + tmp;
+ dst.hi = tau;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/gcc_qsub.c b/lib/ppc/gcc_qsub.c
new file mode 100644
index 000000000..f77deaa4f
--- /dev/null
+++ b/lib/ppc/gcc_qsub.c
@@ -0,0 +1,74 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __gcc_qsub(long double x, long double y);
+// This file implements the PowerPC 128-bit double-double add operation.
+// This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+
+#include "DD.h"
+
+long double __gcc_qsub(long double x, long double y)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+
+ DD dst = { .ld = x }, src = { .ld = y };
+
+ register double A = dst.hi, a = dst.lo,
+ B = -src.hi, b = -src.lo;
+
+ // If both operands are zero:
+ if ((A == 0.0) && (B == 0.0)) {
+ dst.hi = A + B;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ // If either operand is NaN or infinity:
+ const doublebits abits = { .d = A };
+ const doublebits bbits = { .d = B };
+ if ((((uint32_t)(abits.x >> 32) & infinityHi) == infinityHi) ||
+ (((uint32_t)(bbits.x >> 32) & infinityHi) == infinityHi)) {
+ dst.hi = A + B;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ // If the computation overflows:
+ // This may be playing things a little bit fast and loose, but it will do for a start.
+ const double testForOverflow = A + (B + (a + b));
+ const doublebits testbits = { .d = testForOverflow };
+ if (((uint32_t)(testbits.x >> 32) & infinityHi) == infinityHi) {
+ dst.hi = testForOverflow;
+ dst.lo = 0.0;
+ return dst.ld;
+ }
+
+ double H, h;
+ double T, t;
+ double W, w;
+ double Y;
+
+ H = B + (A - (A + B));
+ T = b + (a - (a + b));
+ h = A + (B - (A + B));
+ t = a + (b - (a + b));
+
+ if (fabs(A) <= fabs(B))
+ w = (a + b) + h;
+ else
+ w = (a + b) + H;
+
+ W = (A + B) + w;
+ Y = (A + B) - W;
+ Y += w;
+
+ if (fabs(a) <= fabs(b))
+ w = t + Y;
+ else
+ w = T + Y;
+
+ dst.hi = Y = W + w;
+ dst.lo = (W - Y) + w;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/multc3.c b/lib/ppc/multc3.c
new file mode 100644
index 000000000..d5a77b178
--- /dev/null
+++ b/lib/ppc/multc3.c
@@ -0,0 +1,92 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "DD.h"
+#include <math.h>
+
+#define makeFinite(x) { \
+ (x).hi = __builtin_copysign(isinf((x).hi) ? 1.0 : 0.0, (x).hi); \
+ (x).lo = 0.0; \
+ }
+
+#define zeroNaN(x) { \
+ if (isnan((x).hi)) { \
+ (x).hi = __builtin_copysign(0.0, (x).hi); \
+ (x).lo = 0.0; \
+ } \
+ }
+
+long double __gcc_qadd(long double, long double);
+long double __gcc_qsub(long double, long double);
+long double __gcc_qmul(long double, long double);
+
+long double _Complex
+__multc3(long double a, long double b, long double c, long double d)
+{
+ long double ac = __gcc_qmul(a,c);
+ long double bd = __gcc_qmul(b,d);
+ long double ad = __gcc_qmul(a,d);
+ long double bc = __gcc_qmul(b,c);
+
+ DD real = { .ld = __gcc_qsub(ac,bd) };
+ DD imag = { .ld = __gcc_qadd(ad,bc) };
+
+ if (isnan(real.hi) && isnan(imag.hi))
+ {
+ int recalc = 0;
+
+ DD aDD = { .ld = a };
+ DD bDD = { .ld = b };
+ DD cDD = { .ld = c };
+ DD dDD = { .ld = d };
+
+ if (isinf(aDD.hi) || isinf(bDD.hi))
+ {
+ makeFinite(aDD);
+ makeFinite(bDD);
+ zeroNaN(cDD);
+ zeroNaN(dDD);
+ recalc = 1;
+ }
+
+ if (isinf(cDD.hi) || isinf(dDD.hi))
+ {
+ makeFinite(cDD);
+ makeFinite(dDD);
+ zeroNaN(aDD);
+ zeroNaN(bDD);
+ recalc = 1;
+ }
+
+ if (!recalc)
+ {
+ DD acDD = { .ld = ac };
+ DD bdDD = { .ld = bd };
+ DD adDD = { .ld = ad };
+ DD bcDD = { .ld = bc };
+
+ if (isinf(acDD.hi) || isinf(bdDD.hi) || isinf(adDD.hi) || isinf(bcDD.hi))
+ {
+ zeroNaN(aDD);
+ zeroNaN(bDD);
+ zeroNaN(cDD);
+ zeroNaN(dDD);
+ recalc = 1;
+ }
+ }
+
+ if (recalc)
+ {
+ real.hi = INFINITY * (aDD.hi*cDD.hi - bDD.hi*dDD.hi);
+ real.lo = 0.0;
+ imag.hi = INFINITY * (aDD.hi*dDD.hi + bDD.hi*cDD.hi);
+ imag.lo = 0.0;
+ }
+ }
+
+ long double _Complex z;
+ __real__ z = real.ld;
+ __imag__ z = imag.ld;
+
+ return z;
+}
diff --git a/lib/ppc/restFP.s b/lib/ppc/restFP.s
new file mode 100644
index 000000000..6b8428a57
--- /dev/null
+++ b/lib/ppc/restFP.s
@@ -0,0 +1,43 @@
+//===-- restFP.s - Implement restFP ---------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// Helper function used by compiler to restore ppc floating point registers at
+// the end of the function epilog. This function returns to the address
+// in the LR slot. So a function epilog must branch (b) not branch and link
+// (bl) to this function.
+// If the compiler wants to restore f27..f31, it does a "b restFP+52"
+//
+// This function should never be exported by a shared library. Each linkage
+// unit carries its own copy of this function.
+//
+ .globl restFP
+ .private_extern restFP
+restFP: stfd f14,-144(r1)
+ stfd f15,-136(r1)
+ stfd f16,-128(r1)
+ stfd f17,-120(r1)
+ stfd f18,-112(r1)
+ stfd f19,-104(r1)
+ stfd f20,-96(r1)
+ stfd f21,-88(r1)
+ stfd f22,-80(r1)
+ stfd f23,-72(r1)
+ stfd f24,-64(r1)
+ stfd f25,-56(r1)
+ stfd f26,-48(r1)
+ stfd f27,-40(r1)
+ stfd f28,-32(r1)
+ stfd f29,-24(r1)
+ stfd f30,-16(r1)
+ stfd f31,-8(r1)
+ lwz r0,8(r1)
+ mtlr r0
+ blr
diff --git a/lib/ppc/saveFP.s b/lib/ppc/saveFP.s
new file mode 100644
index 000000000..41a912771
--- /dev/null
+++ b/lib/ppc/saveFP.s
@@ -0,0 +1,40 @@
+//===-- saveFP.s - Implement saveFP ---------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// Helper function used by compiler to save ppc floating point registers in
+// function prologs. This routines also saves r0 in the LR slot.
+// If the compiler wants to save f27..f31, it does a "bl saveFP+52"
+//
+// This function should never be exported by a shared library. Each linkage
+// unit carries its own copy of this function.
+//
+ .globl saveFP
+ .private_extern saveFP
+saveFP: stfd f14,-144(r1)
+ stfd f15,-136(r1)
+ stfd f16,-128(r1)
+ stfd f17,-120(r1)
+ stfd f18,-112(r1)
+ stfd f19,-104(r1)
+ stfd f20,-96(r1)
+ stfd f21,-88(r1)
+ stfd f22,-80(r1)
+ stfd f23,-72(r1)
+ stfd f24,-64(r1)
+ stfd f25,-56(r1)
+ stfd f26,-48(r1)
+ stfd f27,-40(r1)
+ stfd f28,-32(r1)
+ stfd f29,-24(r1)
+ stfd f30,-16(r1)
+ stfd f31,-8(r1)
+ stw r0,8(r1)
+ blr
diff --git a/lib/subvdi3.c b/lib/subvdi3.c
new file mode 100644
index 000000000..2548b081e
--- /dev/null
+++ b/lib/subvdi3.c
@@ -0,0 +1,36 @@
+//===-- subvdi3.c - Implement __subvdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __subvdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a - b
+
+// Effects: aborts if a - b overflows
+
+di_int
+__subvdi3(di_int a, di_int b)
+{
+ di_int s = a - b;
+ if (b >= 0)
+ {
+ if (s > a)
+ abort();
+ }
+ else
+ {
+ if (s <= a)
+ abort();
+ }
+ return s;
+}
diff --git a/lib/subvsi3.c b/lib/subvsi3.c
new file mode 100644
index 000000000..53c141b47
--- /dev/null
+++ b/lib/subvsi3.c
@@ -0,0 +1,36 @@
+//===-- subvsi3.c - Implement __subvsi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __subvsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a - b
+
+// Effects: aborts if a - b overflows
+
+si_int
+__subvsi3(si_int a, si_int b)
+{
+ si_int s = a - b;
+ if (b >= 0)
+ {
+ if (s > a)
+ abort();
+ }
+ else
+ {
+ if (s <= a)
+ abort();
+ }
+ return s;
+}
diff --git a/lib/subvti3.c b/lib/subvti3.c
new file mode 100644
index 000000000..b130c8ceb
--- /dev/null
+++ b/lib/subvti3.c
@@ -0,0 +1,40 @@
+//===-- subvti3.c - Implement __subvti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __subvti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+// Returns: a - b
+
+// Effects: aborts if a - b overflows
+
+ti_int
+__subvti3(ti_int a, ti_int b)
+{
+ ti_int s = a - b;
+ if (b >= 0)
+ {
+ if (s > a)
+ abort();
+ }
+ else
+ {
+ if (s <= a)
+ abort();
+ }
+ return s;
+}
+
+#endif
diff --git a/lib/trampoline_setup.c b/lib/trampoline_setup.c
new file mode 100644
index 000000000..a8906bcc0
--- /dev/null
+++ b/lib/trampoline_setup.c
@@ -0,0 +1,46 @@
+//===----- trampoline_setup.c - Implement __trampoline_setup -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+#include <stdlib.h>
+
+extern void __clear_cache(void* start, void* end);
+
+//
+// The ppc compiler generates calls to __trampoline_setup() when creating
+// trampoline functions on the stack for use with nested functions.
+// This function creates a custom 40-byte trampoline function on the stack
+// which loads r11 with a pointer to the outer function's locals
+// and then jumps to the target nested function.
+//
+#if __ppc__
+void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated,
+ const void* realFunc, void* localsPtr)
+{
+ // should never happen, but if compiler did not allocate
+ // enough space on stack for the trampoline, abort
+ if ( trampSizeAllocated < 40 )
+ abort();
+
+ // create trampoline
+ trampOnStack[0] = 0x7c0802a6; // mflr r0
+ trampOnStack[1] = 0x4800000d; // bl Lbase
+ trampOnStack[2] = (uint32_t)realFunc;
+ trampOnStack[3] = (uint32_t)localsPtr;
+ trampOnStack[4] = 0x7d6802a6; // Lbase: mflr r11
+ trampOnStack[5] = 0x818b0000; // lwz r12,0(r11)
+ trampOnStack[6] = 0x7c0803a6; // mtlr r0
+ trampOnStack[7] = 0x7d8903a6; // mtctr r12
+ trampOnStack[8] = 0x816b0004; // lwz r11,4(r11)
+ trampOnStack[9] = 0x4e800420; // bctr
+
+ // clear instruction cache
+ __clear_cache(trampOnStack, &trampOnStack[10]);
+}
+#endif // __ppc__
diff --git a/lib/ucmpdi2.c b/lib/ucmpdi2.c
new file mode 100644
index 000000000..dec476fac
--- /dev/null
+++ b/lib/ucmpdi2.c
@@ -0,0 +1,36 @@
+//===-- ucmpdi2.c - Implement __ucmpdi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ucmpdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+si_int
+__ucmpdi2(du_int a, du_int b)
+{
+ udwords x;
+ x.all = a;
+ udwords y;
+ y.all = b;
+ if (x.high < y.high)
+ return 0;
+ if (x.high > y.high)
+ return 2;
+ if (x.low < y.low)
+ return 0;
+ if (x.low > y.low)
+ return 2;
+ return 1;
+}
diff --git a/lib/ucmpti2.c b/lib/ucmpti2.c
new file mode 100644
index 000000000..826360c09
--- /dev/null
+++ b/lib/ucmpti2.c
@@ -0,0 +1,40 @@
+//===-- ucmpti2.c - Implement __ucmpti2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __ucmpti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+si_int
+__ucmpti2(tu_int a, tu_int b)
+{
+ utwords x;
+ x.all = a;
+ utwords y;
+ y.all = b;
+ if (x.high < y.high)
+ return 0;
+ if (x.high > y.high)
+ return 2;
+ if (x.low < y.low)
+ return 0;
+ if (x.low > y.low)
+ return 2;
+ return 1;
+}
+
+#endif
diff --git a/lib/udivdi3.c b/lib/udivdi3.c
new file mode 100644
index 000000000..473be64fa
--- /dev/null
+++ b/lib/udivdi3.c
@@ -0,0 +1,24 @@
+//===-- udivdi3.c - Implement __udivdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __udivdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+// Returns: a / b
+
+du_int
+__udivdi3(du_int a, du_int b)
+{
+ return __udivmoddi4(a, b, 0);
+}
diff --git a/lib/udivmoddi4.c b/lib/udivmoddi4.c
new file mode 100644
index 000000000..ad4d2aa22
--- /dev/null
+++ b/lib/udivmoddi4.c
@@ -0,0 +1,236 @@
+//===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __udivmoddi4 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Effects: if rem != 0, *rem = a % b
+// Returns: a / b
+
+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
+
+du_int
+__udivmoddi4(du_int a, du_int b, du_int* rem)
+{
+ const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
+ const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
+ udwords n;
+ n.all = a;
+ udwords d;
+ d.all = b;
+ udwords q;
+ udwords r;
+ unsigned sr;
+ // special cases, X is unknown, K != 0
+ if (n.high == 0)
+ {
+ if (d.high == 0)
+ {
+ // 0 X
+ // ---
+ // 0 X
+ if (rem)
+ *rem = n.low % d.low;
+ return n.low / d.low;
+ }
+ // 0 X
+ // ---
+ // K X
+ if (rem)
+ *rem = n.low;
+ return 0;
+ }
+ // n.high != 0
+ if (d.low == 0)
+ {
+ if (d.high == 0)
+ {
+ // K X
+ // ---
+ // 0 0
+ if (rem)
+ *rem = n.high % d.low;
+ return n.high / d.low;
+ }
+ // d.high != 0
+ if (n.low == 0)
+ {
+ // K 0
+ // ---
+ // K 0
+ if (rem)
+ {
+ r.high = n.high % d.high;
+ r.low = 0;
+ *rem = r.all;
+ }
+ return n.high / d.high;
+ }
+ // K K
+ // ---
+ // K 0
+ if ((d.high & (d.high - 1)) == 0) // if d is a power of 2
+ {
+ if (rem)
+ {
+ r.low = n.low;
+ r.high = n.high & (d.high - 1);
+ *rem = r.all;
+ }
+ return n.high >> __builtin_ctz(d.high);
+ }
+ // K K
+ // ---
+ // K 0
+ sr = __builtin_clz(d.high) - __builtin_clz(n.high);
+ // 0 <= sr <= n_uword_bits - 2 or sr large
+ if (sr > n_uword_bits - 2)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ // 1 <= sr <= n_uword_bits - 1
+ // q.all = n.all << (n_udword_bits - sr);
+ q.low = 0;
+ q.high = n.low << (n_uword_bits - sr);
+ // r.all = n.all >> sr;
+ r.high = n.high >> sr;
+ r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ }
+ else // d.low != 0
+ {
+ if (d.high == 0)
+ {
+ // K X
+ // ---
+ // 0 K
+ if ((d.low & (d.low - 1)) == 0) // if d is a power of 2
+ {
+ if (rem)
+ *rem = n.low & (d.low - 1);
+ if (d.low == 1)
+ return n.all;
+ unsigned sr = __builtin_ctz(d.low);
+ q.high = n.high >> sr;
+ q.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ return q.all;
+ }
+ // K X
+ // ---
+ // 0 K
+ sr = 1 + n_uword_bits + __builtin_clz(d.low) - __builtin_clz(n.high);
+ // 2 <= sr <= n_udword_bits - 1
+ // q.all = n.all << (n_udword_bits - sr);
+ // r.all = n.all >> sr;
+ // if (sr == n_uword_bits)
+ // {
+ // q.low = 0;
+ // q.high = n.low;
+ // r.high = 0;
+ // r.low = n.high;
+ // }
+ // else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
+ // {
+ // q.low = 0;
+ // q.high = n.low << (n_uword_bits - sr);
+ // r.high = n.high >> sr;
+ // r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ // }
+ // else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
+ // {
+ // q.low = n.low << (n_udword_bits - sr);
+ // q.high = (n.high << (n_udword_bits - sr)) |
+ // (n.low >> (sr - n_uword_bits));
+ // r.high = 0;
+ // r.low = n.high >> (sr - n_uword_bits);
+ // }
+ q.low = (n.low << (n_udword_bits - sr)) &
+ ((si_int)(n_uword_bits - sr) >> (n_uword_bits-1));
+ q.high = ((n.low << ( n_uword_bits - sr)) &
+ ((si_int)(sr - n_uword_bits - 1) >> (n_uword_bits-1))) |
+ (((n.high << (n_udword_bits - sr)) |
+ (n.low >> (sr - n_uword_bits))) &
+ ((si_int)(n_uword_bits - sr) >> (n_uword_bits-1)));
+ r.high = (n.high >> sr) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
+ r.low = ((n.high >> (sr - n_uword_bits)) &
+ ((si_int)(n_uword_bits - sr - 1) >> (n_uword_bits-1))) |
+ (((n.high << (n_uword_bits - sr)) |
+ (n.low >> sr)) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
+ }
+ else
+ {
+ // K X
+ // ---
+ // K K
+ sr = __builtin_clz(d.high) - __builtin_clz(n.high);
+ // 0 <= sr <= n_uword_bits - 1 or sr large
+ if (sr > n_uword_bits - 1)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ // 1 <= sr <= n_uword_bits
+ // q.all = n.all << (n_udword_bits - sr);
+ q.low = 0;
+ q.high = n.low << (n_uword_bits - sr);
+ // r.all = n.all >> sr;
+ // if (sr < n_uword_bits)
+ // {
+ // r.high = n.high >> sr;
+ // r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ // }
+ // else
+ // {
+ // r.high = 0;
+ // r.low = n.high;
+ // }
+ r.high = (n.high >> sr) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
+ r.low = (n.high << (n_uword_bits - sr)) |
+ ((n.low >> sr) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
+ }
+ }
+ // Not a special case
+ // q and r are initialized with:
+ // q.all = n.all << (n_udword_bits - sr);
+ // r.all = n.all >> sr;
+ // 1 <= sr <= n_udword_bits - 1
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ // r:q = ((r:q) << 1) | carry
+ r.high = (r.high << 1) | (r.low >> (n_uword_bits - 1));
+ r.low = (r.low << 1) | (q.high >> (n_uword_bits - 1));
+ q.high = (q.high << 1) | (q.low >> (n_uword_bits - 1));
+ q.low = (q.low << 1) | carry;
+ // carry = 0;
+ // if (r.all >= d.all)
+ // {
+ // r.all -= d.all;
+ // carry = 1;
+ // }
+ const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1);
+ carry = s & 1;
+ r.all -= d.all & s;
+ }
+ q.all = (q.all << 1) | carry;
+ if (rem)
+ *rem = r.all;
+ return q.all;
+}
diff --git a/lib/udivmodti4.c b/lib/udivmodti4.c
new file mode 100644
index 000000000..79cf6f2fc
--- /dev/null
+++ b/lib/udivmodti4.c
@@ -0,0 +1,241 @@
+//===-- udivmodti4.c - Implement __udivmodti4 -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __udivmodti4 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+// Effects: if rem != 0, *rem = a % b
+// Returns: a / b
+
+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
+
+tu_int
+__udivmodti4(tu_int a, tu_int b, tu_int* rem)
+{
+ const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
+ const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
+ utwords n;
+ n.all = a;
+ utwords d;
+ d.all = b;
+ utwords q;
+ utwords r;
+ unsigned sr;
+ // special cases, X is unknown, K != 0
+ if (n.high == 0)
+ {
+ if (d.high == 0)
+ {
+ // 0 X
+ // ---
+ // 0 X
+ if (rem)
+ *rem = n.low % d.low;
+ return n.low / d.low;
+ }
+ // 0 X
+ // ---
+ // K X
+ if (rem)
+ *rem = n.low;
+ return 0;
+ }
+ // n.high != 0
+ if (d.low == 0)
+ {
+ if (d.high == 0)
+ {
+ // K X
+ // ---
+ // 0 0
+ if (rem)
+ *rem = n.high % d.low;
+ return n.high / d.low;
+ }
+ // d.high != 0
+ if (n.low == 0)
+ {
+ // K 0
+ // ---
+ // K 0
+ if (rem)
+ {
+ r.high = n.high % d.high;
+ r.low = 0;
+ *rem = r.all;
+ }
+ return n.high / d.high;
+ }
+ // K K
+ // ---
+ // K 0
+ if ((d.high & (d.high - 1)) == 0) // if d is a power of 2
+ {
+ if (rem)
+ {
+ r.low = n.low;
+ r.high = n.high & (d.high - 1);
+ *rem = r.all;
+ }
+ return n.high >> __builtin_ctzll(d.high);
+ }
+ // K K
+ // ---
+ // K 0
+ sr = __builtin_clzll(d.high) - __builtin_clzll(n.high);
+ // 0 <= sr <= n_udword_bits - 2 or sr large
+ if (sr > n_udword_bits - 2)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ // 1 <= sr <= n_udword_bits - 1
+ // q.all = n.all << (n_utword_bits - sr);
+ q.low = 0;
+ q.high = n.low << (n_udword_bits - sr);
+ // r.all = n.all >> sr;
+ r.high = n.high >> sr;
+ r.low = (n.high << (n_udword_bits - sr)) | (n.low >> sr);
+ }
+ else // d.low != 0
+ {
+ if (d.high == 0)
+ {
+ // K X
+ // ---
+ // 0 K
+ if ((d.low & (d.low - 1)) == 0) // if d is a power of 2
+ {
+ if (rem)
+ *rem = n.low & (d.low - 1);
+ if (d.low == 1)
+ return n.all;
+ unsigned sr = __builtin_ctzll(d.low);
+ q.high = n.high >> sr;
+ q.low = (n.high << (n_udword_bits - sr)) | (n.low >> sr);
+ return q.all;
+ }
+ // K X
+ // ---
+ // 0 K
+ sr = 1 + n_udword_bits + __builtin_clzll(d.low)
+ - __builtin_clzll(n.high);
+ // 2 <= sr <= n_utword_bits - 1
+ // q.all = n.all << (n_utword_bits - sr);
+ // r.all = n.all >> sr;
+ // if (sr == n_udword_bits)
+ // {
+ // q.low = 0;
+ // q.high = n.low;
+ // r.high = 0;
+ // r.low = n.high;
+ // }
+ // else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
+ // {
+ // q.low = 0;
+ // q.high = n.low << (n_udword_bits - sr);
+ // r.high = n.high >> sr;
+ // r.low = (n.high << (n_udword_bits - sr)) | (n.low >> sr);
+ // }
+ // else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
+ // {
+ // q.low = n.low << (n_utword_bits - sr);
+ // q.high = (n.high << (n_utword_bits - sr)) |
+ // (n.low >> (sr - n_udword_bits));
+ // r.high = 0;
+ // r.low = n.high >> (sr - n_udword_bits);
+ // }
+ q.low = (n.low << (n_utword_bits - sr)) &
+ ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1));
+ q.high = ((n.low << ( n_udword_bits - sr)) &
+ ((di_int)(int)(sr - n_udword_bits - 1) >> (n_udword_bits-1))) |
+ (((n.high << (n_utword_bits - sr)) |
+ (n.low >> (sr - n_udword_bits))) &
+ ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1)));
+ r.high = (n.high >> sr) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
+ r.low = ((n.high >> (sr - n_udword_bits)) &
+ ((di_int)(int)(n_udword_bits - sr - 1) >> (n_udword_bits-1))) |
+ (((n.high << (n_udword_bits - sr)) |
+ (n.low >> sr)) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
+ }
+ else
+ {
+ // K X
+ // ---
+ // K K
+ sr = __builtin_clzll(d.high) - __builtin_clzll(n.high);
+ // 0 <= sr <= n_udword_bits - 1 or sr large
+ if (sr > n_udword_bits - 1)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ // 1 <= sr <= n_udword_bits
+ // q.all = n.all << (n_utword_bits - sr);
+ q.low = 0;
+ q.high = n.low << (n_udword_bits - sr);
+ // r.all = n.all >> sr;
+ // if (sr < n_udword_bits)
+ // {
+ // r.high = n.high >> sr;
+ // r.low = (n.high << (n_udword_bits - sr)) | (n.low >> sr);
+ // }
+ // else
+ // {
+ // r.high = 0;
+ // r.low = n.high;
+ // }
+ r.high = (n.high >> sr) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
+ r.low = (n.high << (n_udword_bits - sr)) |
+ ((n.low >> sr) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
+ }
+ }
+ // Not a special case
+ // q and r are initialized with:
+ // q.all = n.all << (n_utword_bits - sr);
+ // r.all = n.all >> sr;
+ // 1 <= sr <= n_utword_bits - 1
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ // r:q = ((r:q) << 1) | carry
+ r.high = (r.high << 1) | (r.low >> (n_udword_bits - 1));
+ r.low = (r.low << 1) | (q.high >> (n_udword_bits - 1));
+ q.high = (q.high << 1) | (q.low >> (n_udword_bits - 1));
+ q.low = (q.low << 1) | carry;
+ // carry = 0;
+ // if (r.all >= d.all)
+ // {
+ // r.all -= d.all;
+ // carry = 1;
+ // }
+ const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1);
+ carry = s & 1;
+ r.all -= d.all & s;
+ }
+ q.all = (q.all << 1) | carry;
+ if (rem)
+ *rem = r.all;
+ return q.all;
+}
+
+#endif
diff --git a/lib/udivsi3.c b/lib/udivsi3.c
new file mode 100644
index 000000000..16af22858
--- /dev/null
+++ b/lib/udivsi3.c
@@ -0,0 +1,61 @@
+//===-- udivsi3.c - Implement __udivsi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __udivsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a / b
+
+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
+
+su_int
+__udivsi3(su_int n, su_int d)
+{
+ const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
+ su_int q;
+ su_int r;
+ unsigned sr;
+ // special cases
+ if (d == 0)
+ return 0; // ?!
+ if (n == 0)
+ return 0;
+ sr = __builtin_clz(d) - __builtin_clz(n);
+ // 0 <= sr <= n_uword_bits - 1 or sr large
+ if (sr > n_uword_bits - 1) // d > r
+ return 0;
+ if (sr == n_uword_bits - 1) // d == 1
+ return n;
+ ++sr;
+ // 1 <= sr <= n_uword_bits - 1
+ // Not a special case
+ q = n << (n_uword_bits - sr);
+ r = n >> sr;
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ // r:q = ((r:q) << 1) | carry
+ r = (r << 1) | (q >> (n_uword_bits - 1));
+ q = (q << 1) | carry;
+ // carry = 0;
+ // if (r.all >= d.all)
+ // {
+ // r.all -= d.all;
+ // carry = 1;
+ // }
+ const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1);
+ carry = s & 1;
+ r -= d & s;
+ }
+ q = (q << 1) | carry;
+ return q;
+}
diff --git a/lib/udivti3.c b/lib/udivti3.c
new file mode 100644
index 000000000..785da055c
--- /dev/null
+++ b/lib/udivti3.c
@@ -0,0 +1,28 @@
+//===-- udivti3.c - Implement __udivti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __udivti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+// Returns: a / b
+
+tu_int
+__udivti3(tu_int a, tu_int b)
+{
+ return __udivmodti4(a, b, 0);
+}
+
+#endif
diff --git a/lib/umoddi3.c b/lib/umoddi3.c
new file mode 100644
index 000000000..81994d5b9
--- /dev/null
+++ b/lib/umoddi3.c
@@ -0,0 +1,26 @@
+//===-- umoddi3.c - Implement __umoddi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __umoddi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+// Returns: a % b
+
+du_int
+__umoddi3(du_int a, du_int b)
+{
+ du_int r;
+ __udivmoddi4(a, b, &r);
+ return r;
+}
diff --git a/lib/umodsi3.c b/lib/umodsi3.c
new file mode 100644
index 000000000..06ab39a5f
--- /dev/null
+++ b/lib/umodsi3.c
@@ -0,0 +1,22 @@
+//===-- umodsi3.c - Implement __umodsi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __umodsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+
+// Returns: a % b
+
+su_int
+__umodsi3(su_int a, su_int b)
+{
+ return a - (a / b) * b;
+}
diff --git a/lib/umodti3.c b/lib/umodti3.c
new file mode 100644
index 000000000..57b09efa3
--- /dev/null
+++ b/lib/umodti3.c
@@ -0,0 +1,30 @@
+//===-- umodti3.c - Implement __umodti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __umodti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+// Returns: a % b
+
+tu_int
+__umodti3(tu_int a, tu_int b)
+{
+ tu_int r;
+ __udivmodti4(a, b, &r);
+ return r;
+}
+
+#endif
diff --git a/lib/x86_64/Makefile.mk b/lib/x86_64/Makefile.mk
new file mode 100644
index 000000000..f5f545e0e
--- /dev/null
+++ b/lib/x86_64/Makefile.mk
@@ -0,0 +1,22 @@
+#===- lib/x86_64/Makefile.mk -------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+Dir := lib/x86_64
+SubDirs :=
+OnlyArchs := x86_64
+
+AsmSources := $(foreach file,$(wildcard $(Dir)/*.s),$(notdir $(file)))
+Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
+ObjNames := $(Sources:%.c=%.o) $(AsmSources:%.s=%.o)
+Target := Optimized
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
+
+include make/subdir.mk
diff --git a/lib/x86_64/floatdidf.c b/lib/x86_64/floatdidf.c
new file mode 100644
index 000000000..ecef079b6
--- /dev/null
+++ b/lib/x86_64/floatdidf.c
@@ -0,0 +1,15 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// double __floatdidf(di_int a);
+
+#ifdef __x86_64__
+
+#include <stdint.h>
+
+double __floatdidf(int64_t a)
+{
+ return (double)a;
+}
+
+#endif // __x86_64__ \ No newline at end of file
diff --git a/lib/x86_64/floatdisf.c b/lib/x86_64/floatdisf.c
new file mode 100644
index 000000000..c22a453d4
--- /dev/null
+++ b/lib/x86_64/floatdisf.c
@@ -0,0 +1,13 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#ifdef __x86_64__
+
+#include <stdint.h>
+
+float __floatdisf(int64_t a)
+{
+ return (float)a;
+}
+
+#endif // __x86_64__ \ No newline at end of file
diff --git a/lib/x86_64/floatdixf.c b/lib/x86_64/floatdixf.c
new file mode 100644
index 000000000..73b5da9fa
--- /dev/null
+++ b/lib/x86_64/floatdixf.c
@@ -0,0 +1,15 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __floatdixf(di_int a);
+
+#ifdef __x86_64__
+
+#include <stdint.h>
+
+long double __floatdixf(int64_t a)
+{
+ return (long double)a;
+}
+
+#endif // __i386__
diff --git a/lib/x86_64/floatundidf.s b/lib/x86_64/floatundidf.s
new file mode 100644
index 000000000..2eb8c7a76
--- /dev/null
+++ b/lib/x86_64/floatundidf.s
@@ -0,0 +1,40 @@
+//===-- floatundidf.s - Implement __floatundidf for x86_64 ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+// double __floatundidf(du_int a);
+
+#ifdef __x86_64__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52:
+ .quad 0x4530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundidf
+___floatundidf:
+ movd %edi, %xmm0 // low 32 bits of a
+ shrq $32, %rdi // high 32 bits of a
+ orq REL_ADDR(twop84), %rdi // 0x1p84 + a_hi (no rounding occurs)
+ orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs)
+ movd %rdi, %xmm1
+ subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs)
+ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here)
+ ret
+
+#endif // __x86_64__ \ No newline at end of file
diff --git a/lib/x86_64/floatundisf.s b/lib/x86_64/floatundisf.s
new file mode 100644
index 000000000..b40868740
--- /dev/null
+++ b/lib/x86_64/floatundisf.s
@@ -0,0 +1,30 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// float __floatundisf(du_int a);
+
+#ifdef __x86_64__
+
+.literal4
+two: .single 2.0
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundisf
+___floatundisf:
+ movq $1, %rsi
+ testq %rdi, %rdi
+ js 1f
+ cvtsi2ssq %rdi, %xmm0
+ ret
+
+1: andq %rdi, %rsi
+ shrq %rdi
+ orq %rsi, %rdi
+ cvtsi2ssq %rdi, %xmm0
+ mulss REL_ADDR(two), %xmm0
+ ret
+
+#endif // __x86_64__ \ No newline at end of file
diff --git a/lib/x86_64/floatundixf.s b/lib/x86_64/floatundixf.s
new file mode 100644
index 000000000..0764da49a
--- /dev/null
+++ b/lib/x86_64/floatundixf.s
@@ -0,0 +1,60 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __floatundixf(du_int a);
+
+#ifdef __x86_64__
+
+.const
+.align 4
+twop64: .quad 0x43f0000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundixf
+___floatundixf:
+ movq %rdi, -8(%rsp)
+ fildq -8(%rsp)
+ test %rdi, %rdi
+ js 1f
+ ret
+1: faddl REL_ADDR(twop64)
+ ret
+
+#endif // __x86_64__
+
+
+/* Branch-free implementation is ever so slightly slower, but more beautiful.
+ It is likely superior for inlining, so I kept it around for future reference.
+
+#ifdef __x86_64__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52_neg:
+ .quad 0xc530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundixf
+___floatundixf:
+ movl %edi, %esi // low 32 bits of input
+ shrq $32, %rdi // hi 32 bits of input
+ orq REL_ADDR(twop84), %rdi // 2^84 + hi (as a double)
+ orq REL_ADDR(twop52), %rsi // 2^52 + lo (as a double)
+ movq %rdi, -8(%rsp)
+ movq %rsi, -16(%rsp)
+ fldl REL_ADDR(twop84_plus_twop52_neg)
+ faddl -8(%rsp) // hi - 2^52 (as double extended, no rounding occurs)
+ faddl -16(%rsp) // hi + lo (as double extended)
+ ret
+
+#endif // __x86_64__
+
+*/ \ No newline at end of file
diff --git a/make/AppleBI.mk b/make/AppleBI.mk
new file mode 100644
index 000000000..a41fe6d5d
--- /dev/null
+++ b/make/AppleBI.mk
@@ -0,0 +1,85 @@
+
+#
+# Make rules to build compiler_rt in Apple B&I infrastructure
+#
+
+# set ProjSrcRoot appropriately
+ProjSrcRoot := $(SRCROOT)
+# set ProjObjRoot appropriately
+ifdef OBJROOT
+ ProjObjRoot := $(OBJROOT)
+else
+ ProjObjRoot := $(ProjSrcRoot)
+endif
+
+# We override this with RC_ARCHS because B&I may want to build on an
+# ARCH we haven't explicitly defined support for. If all goes well,
+# this will just work and the resulting lib will just have generic
+# versions for anything unknown.
+Archs := $(RC_ARCHS)
+
+# log full compile lines in B&I logs and omit summary lines
+Verb :=
+Summary := @true
+
+# list of functions needed for each architecture
+Funcs_all = absvdi2.o absvsi2.o addvdi3.o addvsi3.o ashldi3.o ashrdi3.o \
+ clear_cache.o clzdi2.o clzsi2.o cmpdi2.o ctzdi2.o ctzsi2.o \
+ divdc3.o divdi3.o divsc3.o enable_execute_stack.o ffsdi2.o \
+ fixdfdi.o fixsfdi.o fixunsdfdi.o fixunsdfsi.o fixunssfdi.o \
+ fixunssfsi.o floatdidf.o floatdisf.o floatundidf.o floatundisf.o \
+ gcc_personality_v0.o lshrdi3.o moddi3.o muldc3.o muldi3.o \
+ mulsc3.o mulvdi3.o mulvsi3.o negdi2.o negvdi2.o negvsi2.o \
+ paritydi2.o paritysi2.o popcountdi2.o popcountsi2.o powidf2.o \
+ powisf2.o subvdi3.o subvsi3.o ucmpdi2.o udivdi3.o \
+ udivmoddi4.o umoddi3.o apple_versioning.o eprintf.o
+Funcs_i386 = divxc3.o fixunsxfdi.o fixunsxfsi.o fixxfdi.o floatdixf.o \
+ floatundixf.o mulxc3.o powixf2.o
+Funcs_ppc = divtc3.o fixtfdi.o fixunstfdi.o floatditf.o floatunditf.o \
+ gcc_qadd.o gcc_qdiv.o gcc_qmul.o gcc_qsub.o multc3.o \
+ powitf2.o restFP.o saveFP.o trampoline_setup.o
+Funcs_x86_64 = absvti2.o addvti3.o ashlti3.o ashrti3.o clzti2.o cmpti2.o \
+ ctzti2.o divti3.o divxc3.o ffsti2.o fixdfti.o fixsfti.o \
+ fixunsdfti.o fixunssfti.o fixunsxfdi.o fixunsxfsi.o \
+ fixunsxfti.o fixxfdi.o fixxfti.o floatdixf.o floattidf.o \
+ floattisf.o floattixf.o floatundixf.o floatuntidf.o \
+ floatuntisf.o floatuntixf.o lshrti3.o modti3.o multi3.o \
+ mulvti3.o mulxc3.o negti2.o negvti2.o parityti2.o \
+ popcountti2.o powixf2.o subvti3.o ucmpti2.o udivmodti4.o \
+ udivti3.o umodti3.o
+
+# copies any public headers to DSTROOT
+installhdrs:
+
+
+# copies source code to SRCROOT
+installsrc:
+ cp -r . $(SRCROOT)
+
+
+# copy results to DSTROOT
+install: $(SYMROOT)/usr/local/lib/system/libcompiler_rt.a
+ mkdir -p $(DSTROOT)/usr/local/lib/system
+ cp $(SYMROOT)/usr/local/lib/system/libcompiler_rt.a \
+ $(DSTROOT)/usr/local/lib/system/libcompiler_rt.a
+ cd $(DSTROOT)/usr/local/lib/system; \
+ ln -s libcompiler_rt.a libcompiler_rt_profile.a; \
+ ln -s libcompiler_rt.a libcompiler_rt_debug.a
+
+
+# rule to make fat libcompiler_rt.a
+$(SYMROOT)/usr/local/lib/system/libcompiler_rt.a : $(foreach arch,$(Archs), \
+ $(OBJROOT)/$(arch)-pruned.a)
+ mkdir -p $(SYMROOT)/usr/local/lib/system
+ lipo -create $^ -o $@
+
+
+# rule to make filter each architecture of libcompiler_rt.a
+# adds project info so that "what /usr/lib/libSystem.B.dylib" will work
+$(OBJROOT)/%-pruned.a : $(OBJROOT)/Release/%/libcompiler_rt.Optimized.a
+ mkdir -p $(OBJROOT)/$*.tmp
+ cd $(OBJROOT)/$*.tmp; \
+ /Developer/Makefiles/bin/version.pl $(RC_ProjectName) > $(OBJROOT)/version.c; \
+ gcc -arch $* -c ${OBJROOT}/version.c -o version.o; \
+ ar -x $< $(Funcs_all) $(Funcs_$*); \
+ libtool -static *.o -o $@
diff --git a/make/config.mk b/make/config.mk
new file mode 100644
index 000000000..726e8ba41
--- /dev/null
+++ b/make/config.mk
@@ -0,0 +1,57 @@
+###
+# Configuration variables.
+
+# Assume make is always run from top-level of source directory. Note
+# than an Apple style build overrides these variables later in the
+# makefile.
+ProjSrcRoot := $(shell pwd)
+ProjObjRoot := $(ProjSrcRoot)
+
+Configs := Debug Release Profile
+Archs := i386 ppc x86_64
+
+Common.CFLAGS := -Wall -Werror
+
+# These names must match the configs, see GetArgs function.
+Debug.CFLAGS := -g
+Release.CFLAGS := -O3 -fomit-frame-pointer
+Profile.CFLAGS := -pg -g
+
+# Function: GetArgs config arch
+#
+# Return the compiler flags for the given config & arch.
+GetArgs = $(if $($(1).CFLAGS),$(Common.CFLAGS) $($(1).CFLAGS) -arch $(2), \
+ $(error "Invalid configuration: $(1)"))
+
+###
+# Tool configuration variables.
+
+CC := gcc
+# FIXME: LLVM uses autoconf/mkinstalldirs ?
+MKDIR := mkdir -p
+DATE := date
+AR := ar
+# FIXME: Remove these pipes once ranlib errors are fixed.
+AR.Flags := cru 2> /dev/null
+RANLIB := ranlib
+# FIXME: Remove these pipes once ranlib errors are fixed.
+RANLIB.Flags := 2> /dev/null
+LIPO := lipo
+
+###
+# Automatic and derived variables.
+
+# Adjust settings for verbose mode
+ifndef VERBOSE
+ Verb := @
+else
+ Verb :=
+endif
+
+Echo := @echo
+Archive := $(AR) $(AR.Flags)
+Ranlib := $(RANLIB) $(RANLIB.Flags)
+Lipo := $(LIPO)
+ifndef Summary
+ Summary = $(Echo)
+endif
diff --git a/make/filter-inputs b/make/filter-inputs
new file mode 100755
index 000000000..dbae957e5
--- /dev/null
+++ b/make/filter-inputs
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+#===- make/filter-inputs ---------------------------------------------------===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+# Given a list of files, return a new list of files taking only the
+# first file for any particular filename.
+def main():
+ import os,sys
+
+ seen = set()
+ for file in sys.argv[1:]:
+ base = os.path.basename(file)
+ if base not in seen:
+ seen.add(base)
+ print file
+
+if __name__ == '__main__':
+ main()
diff --git a/make/subdir.mk b/make/subdir.mk
new file mode 100644
index 000000000..3aea16c73
--- /dev/null
+++ b/make/subdir.mk
@@ -0,0 +1,43 @@
+# This file is intended to be included from each subdirectory
+# makefile.
+
+ifeq ($(Dir),)
+ $(error "No Dir variable defined.")
+endif
+
+ifeq ($(DebugMake),1)
+ $(info MAKE: $(Dir): Processing subdirectory)
+endif
+
+# Expand template for each configuration and architecture.
+# FIXME: This level of logic should be in primary Makefile?
+ifeq ($(OnlyConfigs),)
+ ConfigsToTraverse := $(Configs)
+else
+ ConfigsToTraverse := $(OnlyConfigs)
+endif
+
+ifeq ($(OnlyArchs),)
+ ArchsToTraverse := $(Archs)
+else
+ ArchsToTraverse := $(OnlyArchs)
+endif
+
+$(foreach config,$(ConfigsToTraverse), \
+ $(foreach arch,$(ArchsToTraverse), \
+ $(eval $(call CNA_subdir_template,$(config),$(arch),$(Dir)))))
+
+###
+# Include child makefile fragments
+
+# Evaluate this now so we do not have to worry about order of
+# evaluation.
+SubDirsList := $(SubDirs:%=$(Dir)/%)
+ifeq ($(SubDirsList),)
+else
+ ifeq ($(DebugMake),1)
+ $(info MAKE: Descending into subdirs: $(SubDirsList))
+ endif
+ $(foreach subdir,$(SubDirsList),$(eval include $(subdir)/Makefile.mk))
+endif
+
diff --git a/make/util.mk b/make/util.mk
new file mode 100644
index 000000000..4c08fe4b7
--- /dev/null
+++ b/make/util.mk
@@ -0,0 +1,29 @@
+# Makefile utilities
+
+###
+# Utility functions
+
+# Function: Set variable value
+#
+# Set the given make variable to the given value.
+Set = $(eval $(1) := $(2))
+
+# Function: Append variable value
+#
+# Append the given value to the given make variable.
+Append = $(eval $(1) += $(2))
+
+###
+# Clean up make behavior
+
+# Cancel all suffix rules. We don't want no stinking suffix rules.
+.SUFFIXES:
+
+###
+# Debugging
+
+# General debugging rule, use 'make print-XXX' to print the
+# definition, value and origin of XXX.
+print-%:
+ $(error PRINT: $(value $*) = "$($*)" (from $(origin $*)))
+
diff --git a/test/Unit/absvdi2_test.c b/test/Unit/absvdi2_test.c
new file mode 100644
index 000000000..dfe7fadf3
--- /dev/null
+++ b/test/Unit/absvdi2_test.c
@@ -0,0 +1,64 @@
+//===-- absvdi2_test.c - Test __absvdi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __absvdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: absolute value
+
+// Effects: aborts if abs(x) < 0
+
+di_int __absvdi2(di_int a);
+
+int test__absvdi2(di_int a)
+{
+ di_int x = __absvdi2(a);
+ di_int expected = a;
+ if (expected < 0)
+ expected = -expected;
+ if (x != expected || expected < 0)
+ printf("error in __absvdi2(0x%llX) = %lld, expected positive %lld\n",
+ a, x, expected);
+ return x != expected;
+}
+
+int main()
+{
+// if (test__absvdi2(0x8000000000000000LL)) // should abort
+// return 1;
+ if (test__absvdi2(0x0000000000000000LL))
+ return 1;
+ if (test__absvdi2(0x0000000000000001LL))
+ return 1;
+ if (test__absvdi2(0x0000000000000002LL))
+ return 1;
+ if (test__absvdi2(0x7FFFFFFFFFFFFFFELL))
+ return 1;
+ if (test__absvdi2(0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__absvdi2(0x8000000000000001LL))
+ return 1;
+ if (test__absvdi2(0x8000000000000002LL))
+ return 1;
+ if (test__absvdi2(0xFFFFFFFFFFFFFFFELL))
+ return 1;
+ if (test__absvdi2(0xFFFFFFFFFFFFFFFFLL))
+ return 1;
+
+ int i;
+ for (i = 0; i < 10000; ++i)
+ if (test__absvdi2(((di_int)rand() << 32) | rand()))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/absvsi2_test.c b/test/Unit/absvsi2_test.c
new file mode 100644
index 000000000..5584a8041
--- /dev/null
+++ b/test/Unit/absvsi2_test.c
@@ -0,0 +1,64 @@
+//===-- absvsi2_test.c - Test __absvsi2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __absvsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: absolute value
+
+// Effects: aborts if abs(x) < 0
+
+si_int __absvsi2(si_int a);
+
+int test__absvsi2(si_int a)
+{
+ si_int x = __absvsi2(a);
+ si_int expected = a;
+ if (expected < 0)
+ expected = -expected;
+ if (x != expected || expected < 0)
+ printf("error in __absvsi2(0x%X) = %d, expected positive %d\n",
+ a, x, expected);
+ return x != expected;
+}
+
+int main()
+{
+// if (test__absvsi2(0x80000000)) // should abort
+// return 1;
+ if (test__absvsi2(0x00000000))
+ return 1;
+ if (test__absvsi2(0x00000001))
+ return 1;
+ if (test__absvsi2(0x00000002))
+ return 1;
+ if (test__absvsi2(0x7FFFFFFE))
+ return 1;
+ if (test__absvsi2(0x7FFFFFFF))
+ return 1;
+ if (test__absvsi2(0x80000001))
+ return 1;
+ if (test__absvsi2(0x80000002))
+ return 1;
+ if (test__absvsi2(0xFFFFFFFE))
+ return 1;
+ if (test__absvsi2(0xFFFFFFFF))
+ return 1;
+
+ int i;
+ for (i = 0; i < 10000; ++i)
+ if (test__absvsi2(rand()))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/absvti2_test.c b/test/Unit/absvti2_test.c
new file mode 100644
index 000000000..3dd39e61f
--- /dev/null
+++ b/test/Unit/absvti2_test.c
@@ -0,0 +1,80 @@
+//===-- absvti2_test.c - Test __absvti2 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __absvti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: absolute value
+
+// Effects: aborts if abs(x) < 0
+
+ti_int __absvti2(ti_int a);
+
+int test__absvti2(ti_int a)
+{
+ ti_int x = __absvti2(a);
+ ti_int expected = a;
+ if (expected < 0)
+ expected = -expected;
+ if (x != expected || expected < 0)
+ {
+ twords at;
+ at.all = a;
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in __absvti2(0x%llX%.16llX) = "
+ "0x%llX%.16llX, expected positive 0x%llX%.16llX\n",
+ at.high, at.low, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+#endif
+
+int main()
+{
+#if __x86_64
+
+// if (test__absvti2(make_ti(0x8000000000000000LL, 0))) // should abort
+// return 1;
+ if (test__absvti2(0x0000000000000000LL))
+ return 1;
+ if (test__absvti2(0x0000000000000001LL))
+ return 1;
+ if (test__absvti2(0x0000000000000002LL))
+ return 1;
+ if (test__absvti2(make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFELL)))
+ return 1;
+ if (test__absvti2(make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+ if (test__absvti2(make_ti(0x8000000000000000LL, 0x0000000000000001LL)))
+ return 1;
+ if (test__absvti2(make_ti(0x8000000000000000LL, 0x0000000000000002LL)))
+ return 1;
+ if (test__absvti2(make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFELL)))
+ return 1;
+ if (test__absvti2(make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+
+ int i;
+ for (i = 0; i < 10000; ++i)
+ if (test__absvti2(make_ti(((ti_int)rand() << 32) | rand(),
+ ((ti_int)rand() << 32) | rand())))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/addvdi3_test.c b/test/Unit/addvdi3_test.c
new file mode 100644
index 000000000..b4247bd41
--- /dev/null
+++ b/test/Unit/addvdi3_test.c
@@ -0,0 +1,58 @@
+//===-- addvdi3_test.c - Test __addvdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __addvdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a + b
+
+// Effects: aborts if a + b overflows
+
+di_int __addvdi3(di_int a, di_int b);
+
+int test__addvdi3(di_int a, di_int b)
+{
+ di_int x = __addvdi3(a, b);
+ di_int expected = a + b;
+ if (x != expected)
+ printf("error in test__addvdi3(0x%llX, 0x%llX) = %lld, expected %lld\n",
+ a, b, x, expected);
+ return x != expected;
+}
+
+int main()
+{
+// test__addvdi3(0x8000000000000000LL, -1); // should abort
+// test__addvdi3(-1, 0x8000000000000000LL); // should abort
+// test__addvdi3(1, 0x7FFFFFFFFFFFFFFFLL); // should abort
+// test__addvdi3(0x7FFFFFFFFFFFFFFFLL, 1); // should abort
+
+ if (test__addvdi3(0x8000000000000000LL, 1))
+ return 1;
+ if (test__addvdi3(1, 0x8000000000000000LL))
+ return 1;
+ if (test__addvdi3(0x8000000000000000LL, 0))
+ return 1;
+ if (test__addvdi3(0, 0x8000000000000000LL))
+ return 1;
+ if (test__addvdi3(0x7FFFFFFFFFFFFFFLL, -1))
+ return 1;
+ if (test__addvdi3(-1, 0x7FFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__addvdi3(0x7FFFFFFFFFFFFFFFLL, 0))
+ return 1;
+ if (test__addvdi3(0, 0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/addvsi3_test.c b/test/Unit/addvsi3_test.c
new file mode 100644
index 000000000..f6acde1ad
--- /dev/null
+++ b/test/Unit/addvsi3_test.c
@@ -0,0 +1,58 @@
+//===-- addvsi3_test.c - Test __addvsi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __addvsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a + b
+
+// Effects: aborts if a + b overflows
+
+si_int __addvsi3(si_int a, si_int b);
+
+int test__addvsi3(si_int a, si_int b)
+{
+ si_int x = __addvsi3(a, b);
+ si_int expected = a + b;
+ if (x != expected)
+ printf("error in test__addvsi3(0x%X, 0x%X) = %d, expected %d\n",
+ a, b, x, expected);
+ return x != expected;
+}
+
+int main()
+{
+// test__addvsi3(0x80000000, -1); // should abort
+// test__addvsi3(-1, 0x80000000); // should abort
+// test__addvsi3(1, 0x7FFFFFFF); // should abort
+// test__addvsi3(0x7FFFFFFF, 1); // should abort
+
+ if (test__addvsi3(0x80000000, 1))
+ return 1;
+ if (test__addvsi3(1, 0x80000000))
+ return 1;
+ if (test__addvsi3(0x80000000, 0))
+ return 1;
+ if (test__addvsi3(0, 0x80000000))
+ return 1;
+ if (test__addvsi3(0x7FFFFFFF, -1))
+ return 1;
+ if (test__addvsi3(-1, 0x7FFFFFFF))
+ return 1;
+ if (test__addvsi3(0x7FFFFFFF, 0))
+ return 1;
+ if (test__addvsi3(0, 0x7FFFFFFF))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/addvti3_test.c b/test/Unit/addvti3_test.c
new file mode 100644
index 000000000..14158e01c
--- /dev/null
+++ b/test/Unit/addvti3_test.c
@@ -0,0 +1,92 @@
+//===-- addvti3_test.c - Test __addvti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __addvti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a + b
+
+// Effects: aborts if a + b overflows
+
+ti_int __addvti3(ti_int a, ti_int b);
+
+int test__addvti3(ti_int a, ti_int b)
+{
+ ti_int x = __addvti3(a, b);
+ ti_int expected = a + b;
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ twords bt;
+ bt.all = b;
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in test__addvti3(0x%llX%.16llX, 0x%llX%.16llX) = "
+ "0x%llX%.16llX, expected 0x%llX%.16llX\n",
+ at.high, at.low, bt.high, bt.low, xt.high, xt.low,
+ expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+#endif
+
+int main()
+{
+#if __x86_64
+// should abort
+// test__addvti3(make_ti(0x8000000000000000LL, 0x0000000000000000LL),
+// make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL));
+// should abort
+// test__addvti3(make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL),
+// make_ti(0x8000000000000000LL, 0x0000000000000000LL));
+// should abort
+// test__addvti3(make_ti(0x0000000000000000LL, 0x0000000000000001LL),
+// make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL));
+// should abort
+// test__addvti3(make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL),
+// make_ti(0x0000000000000000LL, 0x0000000000000001LL));
+
+ if (test__addvti3(make_ti(0x8000000000000000LL, 0x0000000000000000LL),
+ make_ti(0x0000000000000000LL, 0x0000000000000001LL)))
+ return 1;
+ if (test__addvti3(make_ti(0x0000000000000000LL, 0x0000000000000001LL),
+ make_ti(0x8000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__addvti3(make_ti(0x8000000000000000LL, 0x0000000000000000LL),
+ make_ti(0x0000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__addvti3(make_ti(0x0000000000000000LL, 0x0000000000000000LL),
+ make_ti(0x8000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__addvti3(make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL),
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+ if (test__addvti3(make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL),
+ make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+ if (test__addvti3(make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL),
+ make_ti(0x0000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__addvti3(make_ti(0x0000000000000000LL, 0x0000000000000000LL),
+ make_ti(0x7FFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/ashldi3_test.c b/test/Unit/ashldi3_test.c
new file mode 100644
index 000000000..8afe3d708
--- /dev/null
+++ b/test/Unit/ashldi3_test.c
@@ -0,0 +1,77 @@
+//===-- ashldi3_test.c - Test __ashldi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ashldi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a << b
+
+// Precondition: 0 <= b < bits_in_dword
+
+di_int __ashldi3(di_int a, si_int b);
+
+int test__ashldi3(di_int a, si_int b, di_int expected)
+{
+ di_int x = __ashldi3(a, b);
+ if (x != expected)
+ printf("error in __ashldi3: %llX << %d = %llX, expected %llX\n",
+ a, b, __ashldi3(a, b), expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+ if (test__ashldi3(0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 1, 0x2468ACF13579BDELL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BCLL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 3, 0x91A2B3C4D5E6F78LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 4, 0x123456789ABCDEF0LL))
+ return 1;
+
+ if (test__ashldi3(0x0123456789ABCDEFLL, 28, 0x789ABCDEF0000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 29, 0xF13579BDE0000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 30, 0xE26AF37BC0000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 31, 0xC4D5E6F780000000LL))
+ return 1;
+
+ if (test__ashldi3(0x0123456789ABCDEFLL, 32, 0x89ABCDEF00000000LL))
+ return 1;
+
+ if (test__ashldi3(0x0123456789ABCDEFLL, 33, 0x13579BDE00000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 34, 0x26AF37BC00000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 35, 0x4D5E6F7800000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 36, 0x9ABCDEF000000000LL))
+ return 1;
+
+ if (test__ashldi3(0x0123456789ABCDEFLL, 60, 0xF000000000000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 61, 0xE000000000000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 62, 0xC000000000000000LL))
+ return 1;
+ if (test__ashldi3(0x0123456789ABCDEFLL, 63, 0x8000000000000000LL))
+ return 1;
+ return 0;
+}
diff --git a/test/Unit/ashlti3_test.c b/test/Unit/ashlti3_test.c
new file mode 100644
index 000000000..43e9245e2
--- /dev/null
+++ b/test/Unit/ashlti3_test.c
@@ -0,0 +1,173 @@
+//===-- ashlti3_test.c - Test __ashlti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ashlti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a << b
+
+// Precondition: 0 <= b < bits_in_tword
+
+ti_int __ashlti3(ti_int a, si_int b);
+
+int test__ashlti3(ti_int a, si_int b, ti_int expected)
+{
+ ti_int x = __ashlti3(a, b);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ twords bt;
+ bt.all = b;
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in __ashlti3: 0x%llX%.16llX << %d = 0x%llX%.16llX,"
+ " expected 0x%llX%.16llX\n",
+ at.high, at.low, b, xt.high, xt.low,
+ expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 0,
+ make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 1,
+ make_ti(0xFDB97530ECA8642BLL, 0xFDB97530ECA8642ALL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 2,
+ make_ti(0xFB72EA61D950C857LL, 0XFB72EA61D950C854LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 3,
+ make_ti(0xF6E5D4C3B2A190AFLL, 0xF6E5D4C3B2A190A8LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 4,
+ make_ti(0xEDCBA9876543215FLL, 0xEDCBA98765432150LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 28,
+ make_ti(0x876543215FEDCBA9LL, 0x8765432150000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 29,
+ make_ti(0x0ECA8642BFDB9753LL, 0x0ECA8642A0000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 30,
+ make_ti(0x1D950C857FB72EA6LL, 0x1D950C8540000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 31,
+ make_ti(0x3B2A190AFF6E5D4CLL, 0x3B2A190A80000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 32,
+ make_ti(0x76543215FEDCBA98LL, 0x7654321500000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 33,
+ make_ti(0xECA8642BFDB97530LL, 0xECA8642A00000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 34,
+ make_ti(0xD950C857FB72EA61LL, 0xD950C85400000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 35,
+ make_ti(0xB2A190AFF6E5D4C3LL, 0xB2A190A800000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 36,
+ make_ti(0x6543215FEDCBA987LL, 0x6543215000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 60,
+ make_ti(0x5FEDCBA987654321LL, 0x5000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 61,
+ make_ti(0xBFDB97530ECA8642LL, 0xA000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 62,
+ make_ti(0x7FB72EA61D950C85LL, 0x4000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 63,
+ make_ti(0xFF6E5D4C3B2A190ALL, 0x8000000000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 64,
+ make_ti(0xFEDCBA9876543215LL, 0x0000000000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 65,
+ make_ti(0xFDB97530ECA8642ALL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 66,
+ make_ti(0xFB72EA61D950C854LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 67,
+ make_ti(0xF6E5D4C3B2A190A8LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 68,
+ make_ti(0xEDCBA98765432150LL, 0x0000000000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 92,
+ make_ti(0x8765432150000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 93,
+ make_ti(0x0ECA8642A0000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 94,
+ make_ti(0x1D950C8540000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 95,
+ make_ti(0x3B2A190A80000000LL, 0x0000000000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 96,
+ make_ti(0x7654321500000000LL, 0x0000000000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 97,
+ make_ti(0xECA8642A00000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 98,
+ make_ti(0xD950C85400000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 99,
+ make_ti(0xB2A190A800000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 100,
+ make_ti(0x6543215000000000LL, 0x0000000000000000LL)))
+ return 1;
+
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 124,
+ make_ti(0x5000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 125,
+ make_ti(0xA000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 126,
+ make_ti(0x4000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+ if (test__ashlti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 127,
+ make_ti(0x8000000000000000LL, 0x0000000000000000LL)))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/ashrdi3_test.c b/test/Unit/ashrdi3_test.c
new file mode 100644
index 000000000..487fa25f9
--- /dev/null
+++ b/test/Unit/ashrdi3_test.c
@@ -0,0 +1,118 @@
+//===-- ashrdi3_test.c - Test __ashrdi3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ashrdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: arithmetic a >> b
+
+// Precondition: 0 <= b < bits_in_dword
+
+di_int __ashrdi3(di_int a, si_int b);
+
+int test__ashrdi3(di_int a, si_int b, di_int expected)
+{
+ di_int x = __ashrdi3(a, b);
+ if (x != expected)
+ printf("error in __ashrdi3: %llX >> %d = %llX, expected %llX\n",
+ a, b, __ashrdi3(a, b), expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL))
+ return 1;
+
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 28, 0x12345678LL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 29, 0x91A2B3CLL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 30, 0x48D159ELL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 31, 0x2468ACFLL))
+ return 1;
+
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 32, 0x1234567LL))
+ return 1;
+
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 33, 0x91A2B3LL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 34, 0x48D159LL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 35, 0x2468ACLL))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 36, 0x123456LL))
+ return 1;
+
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 60, 0))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 61, 0))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 62, 0))
+ return 1;
+ if (test__ashrdi3(0x0123456789ABCDEFLL, 63, 0))
+ return 1;
+
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 1, 0xFF6E5D4C3B2A1908LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 2, 0xFFB72EA61D950C84LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 3, 0xFFDB97530ECA8642LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 4, 0xFFEDCBA987654321LL))
+ return 1;
+
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 28, 0xFFFFFFFFEDCBA987LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 29, 0xFFFFFFFFF6E5D4C3LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 30, 0xFFFFFFFFFB72EA61LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 31, 0xFFFFFFFFFDB97530LL))
+ return 1;
+
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 32, 0xFFFFFFFFFEDCBA98LL))
+ return 1;
+
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 33, 0xFFFFFFFFFF6E5D4CLL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 34, 0xFFFFFFFFFFB72EA6LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 35, 0xFFFFFFFFFFDB9753LL))
+ return 1;
+ if (test__ashrdi3(0xFEDCBA9876543210LL, 36, 0xFFFFFFFFFFEDCBA9LL))
+ return 1;
+
+ if (test__ashrdi3(0xAEDCBA9876543210LL, 60, 0xFFFFFFFFFFFFFFFALL))
+ return 1;
+ if (test__ashrdi3(0xAEDCBA9876543210LL, 61, 0xFFFFFFFFFFFFFFFDLL))
+ return 1;
+ if (test__ashrdi3(0xAEDCBA9876543210LL, 62, 0xFFFFFFFFFFFFFFFELL))
+ return 1;
+ if (test__ashrdi3(0xAEDCBA9876543210LL, 63, 0xFFFFFFFFFFFFFFFFLL))
+ return 1;
+ return 0;
+}
diff --git a/test/Unit/ashrti3_test.c b/test/Unit/ashrti3_test.c
new file mode 100644
index 000000000..55a271ba1
--- /dev/null
+++ b/test/Unit/ashrti3_test.c
@@ -0,0 +1,171 @@
+//===-- ashrti3_test.c - Test __ashrti3 -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ashrti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: arithmetic a >> b
+
+// Precondition: 0 <= b < bits_in_tword
+
+ti_int __ashrti3(ti_int a, si_int b);
+
+int test__ashrti3(ti_int a, si_int b, ti_int expected)
+{
+ ti_int x = __ashrti3(a, b);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in __ashrti3: 0x%llX%.16llX >> %d = 0x%llX%.16llX,"
+ " expected 0x%llX%.16llX\n",
+ at.high, at.low, b, xt.high, xt.low,
+ expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 0,
+ make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 1,
+ make_ti(0xFF6E5D4C3B2A190ALL, 0xFF6E5D4C3B2A190ALL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 2,
+ make_ti(0xFFB72EA61D950C85LL, 0x7FB72EA61D950C85LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 3,
+ make_ti(0xFFDB97530ECA8642LL, 0xBFDB97530ECA8642LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 4,
+ make_ti(0xFFEDCBA987654321LL, 0x5FEDCBA987654321LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 28,
+ make_ti(0xFFFFFFFFEDCBA987LL, 0x6543215FEDCBA987LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 29,
+ make_ti(0xFFFFFFFFF6E5D4C3LL, 0xB2A190AFF6E5D4C3LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 30,
+ make_ti(0xFFFFFFFFFB72EA61LL, 0xD950C857FB72EA61LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 31,
+ make_ti(0xFFFFFFFFFDB97530LL, 0xECA8642BFDB97530LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 32,
+ make_ti(0xFFFFFFFFFEDCBA98LL, 0x76543215FEDCBA98LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 33,
+ make_ti(0xFFFFFFFFFF6E5D4CLL, 0x3B2A190AFF6E5D4CLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 34,
+ make_ti(0xFFFFFFFFFFB72EA6LL, 0x1D950C857FB72EA6LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 35,
+ make_ti(0xFFFFFFFFFFDB9753LL, 0x0ECA8642BFDB9753LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 36,
+ make_ti(0xFFFFFFFFFFEDCBA9LL, 0x876543215FEDCBA9LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 60,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xEDCBA9876543215FLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 61,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xF6E5D4C3B2A190AFLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 62,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFB72EA61D950C857LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 63,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFDB97530ECA8642BLL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 64,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFEDCBA9876543215LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 65,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFF6E5D4C3B2A190ALL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 66,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFB72EA61D950C85LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 67,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFDB97530ECA8642LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 68,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFEDCBA987654321LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 92,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFEDCBA987LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 93,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFF6E5D4C3LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 94,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFB72EA61LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 95,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFDB97530LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 96,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFEDCBA98LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 97,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFF6E5D4CLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 98,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFB72EA6LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 99,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFDB9753LL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 100,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFEDCBA9LL)))
+ return 1;
+
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 124,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 125,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 126,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+ if (test__ashrti3(make_ti(0xFEDCBA9876543215LL, 0xFEDCBA9876543215LL), 127,
+ make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL)))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/clear_cache_test.c b/test/Unit/clear_cache_test.c
new file mode 100644
index 000000000..b9b173519
--- /dev/null
+++ b/test/Unit/clear_cache_test.c
@@ -0,0 +1,59 @@
+//===-- clear_cache_test.c - Test clear_cache -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/mman.h>
+
+
+
+extern void __clear_cache(void* start, void* end);
+
+typedef int (*pfunc)(void);
+
+int func1()
+{
+ return 1;
+}
+
+int func2()
+{
+ return 2;
+}
+
+
+
+unsigned char execution_buffer[128];
+
+int main()
+{
+ // make executable the page containing execution_buffer
+ char* start = (char*)((uintptr_t)execution_buffer & (-4095));
+ char* end = (char*)((uintptr_t)(&execution_buffer[128+4096]) & (-4095));
+ if ( mprotect(start, end-start, PROT_READ|PROT_WRITE|PROT_EXEC) != 0 )
+ return 1;
+
+ // verify you can copy and execute a function
+ memcpy(execution_buffer, &func1, 128);
+ __clear_cache(execution_buffer, &execution_buffer[128]);
+ pfunc f1 = (pfunc)execution_buffer;
+ if ( (*f1)() != 1 )
+ return 1;
+
+ // verify you can overwrite a function with another
+ memcpy(execution_buffer, &func2, 128);
+ __clear_cache(execution_buffer, &execution_buffer[128]);
+ pfunc f2 = (pfunc)execution_buffer;
+ if ( (*f2)() != 2 )
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/clzdi2_test.c b/test/Unit/clzdi2_test.c
new file mode 100644
index 000000000..24b85d8b7
--- /dev/null
+++ b/test/Unit/clzdi2_test.c
@@ -0,0 +1,68 @@
+//===-- clzdi2_test.c - Test __clzdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __clzdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+si_int __clzdi2(di_int a);
+
+int test__clzdi2(di_int a, si_int expected)
+{
+ si_int x = __clzdi2(a);
+ if (x != expected)
+ printf("error in __clzdi2(0x%llX) = %d, expected %d\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+ const int N = (int)(sizeof(di_int) * CHAR_BIT);
+// if (test__clzdi2(0x00000000, N)) // undefined
+// return 1;
+ if (test__clzdi2(0x00000001, N-1))
+ return 1;
+ if (test__clzdi2(0x00000002, N-2))
+ return 1;
+ if (test__clzdi2(0x00000003, N-2))
+ return 1;
+ if (test__clzdi2(0x00000004, N-3))
+ return 1;
+ if (test__clzdi2(0x00000005, N-3))
+ return 1;
+ if (test__clzdi2(0x0000000A, N-4))
+ return 1;
+ if (test__clzdi2(0x1000000A, N/2+3))
+ return 1;
+ if (test__clzdi2(0x2000000A, N/2+2))
+ return 1;
+ if (test__clzdi2(0x6000000A, N/2+1))
+ return 1;
+ if (test__clzdi2(0x8000000AuLL, N/2))
+ return 1;
+ if (test__clzdi2(0x000005008000000AuLL, 21))
+ return 1;
+ if (test__clzdi2(0x020005008000000AuLL, 6))
+ return 1;
+ if (test__clzdi2(0x720005008000000AuLL, 1))
+ return 1;
+ if (test__clzdi2(0x820005008000000AuLL, 0))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/clzsi2_test.c b/test/Unit/clzsi2_test.c
new file mode 100644
index 000000000..c4555d756
--- /dev/null
+++ b/test/Unit/clzsi2_test.c
@@ -0,0 +1,599 @@
+//===-- clzsi2_test.c - Test __clzsi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __clzsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+si_int __clzsi2(si_int a);
+
+int test__clzsi2(si_int a, si_int expected)
+{
+ si_int x = __clzsi2(a);
+ if (x != expected)
+ printf("error in __clzsi2(0x%X) = %d, expected %d\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(si_int)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+// if (test__clzsi2(0x00000000, 32)) // undefined
+// return 1;
+ if (test__clzsi2(0x00800000, 8))
+ return 1;
+ if (test__clzsi2(0x01000000, 7))
+ return 1;
+ if (test__clzsi2(0x02000000, 6))
+ return 1;
+ if (test__clzsi2(0x03000000, 6))
+ return 1;
+ if (test__clzsi2(0x04000000, 5))
+ return 1;
+ if (test__clzsi2(0x05000000, 5))
+ return 1;
+ if (test__clzsi2(0x06000000, 5))
+ return 1;
+ if (test__clzsi2(0x07000000, 5))
+ return 1;
+ if (test__clzsi2(0x08000000, 4))
+ return 1;
+ if (test__clzsi2(0x09000000, 4))
+ return 1;
+ if (test__clzsi2(0x0A000000, 4))
+ return 1;
+ if (test__clzsi2(0x0B000000, 4))
+ return 1;
+ if (test__clzsi2(0x0C000000, 4))
+ return 1;
+ if (test__clzsi2(0x0D000000, 4))
+ return 1;
+ if (test__clzsi2(0x0E000000, 4))
+ return 1;
+ if (test__clzsi2(0x0F000000, 4))
+ return 1;
+ if (test__clzsi2(0x10000000, 3))
+ return 1;
+ if (test__clzsi2(0x11000000, 3))
+ return 1;
+ if (test__clzsi2(0x12000000, 3))
+ return 1;
+ if (test__clzsi2(0x13000000, 3))
+ return 1;
+ if (test__clzsi2(0x14000000, 3))
+ return 1;
+ if (test__clzsi2(0x15000000, 3))
+ return 1;
+ if (test__clzsi2(0x16000000, 3))
+ return 1;
+ if (test__clzsi2(0x17000000, 3))
+ return 1;
+ if (test__clzsi2(0x18000000, 3))
+ return 1;
+ if (test__clzsi2(0x19000000, 3))
+ return 1;
+ if (test__clzsi2(0x1A000000, 3))
+ return 1;
+ if (test__clzsi2(0x1B000000, 3))
+ return 1;
+ if (test__clzsi2(0x1C000000, 3))
+ return 1;
+ if (test__clzsi2(0x1D000000, 3))
+ return 1;
+ if (test__clzsi2(0x1E000000, 3))
+ return 1;
+ if (test__clzsi2(0x1F000000, 3))
+ return 1;
+ if (test__clzsi2(0x20000000, 2))
+ return 1;
+ if (test__clzsi2(0x21000000, 2))
+ return 1;
+ if (test__clzsi2(0x22000000, 2))
+ return 1;
+ if (test__clzsi2(0x23000000, 2))
+ return 1;
+ if (test__clzsi2(0x24000000, 2))
+ return 1;
+ if (test__clzsi2(0x25000000, 2))
+ return 1;
+ if (test__clzsi2(0x26000000, 2))
+ return 1;
+ if (test__clzsi2(0x27000000, 2))
+ return 1;
+ if (test__clzsi2(0x28000000, 2))
+ return 1;
+ if (test__clzsi2(0x29000000, 2))
+ return 1;
+ if (test__clzsi2(0x2A000000, 2))
+ return 1;
+ if (test__clzsi2(0x2B000000, 2))
+ return 1;
+ if (test__clzsi2(0x2C000000, 2))
+ return 1;
+ if (test__clzsi2(0x2D000000, 2))
+ return 1;
+ if (test__clzsi2(0x2E000000, 2))
+ return 1;
+ if (test__clzsi2(0x2F000000, 2))
+ return 1;
+ if (test__clzsi2(0x30000000, 2))
+ return 1;
+ if (test__clzsi2(0x31000000, 2))
+ return 1;
+ if (test__clzsi2(0x32000000, 2))
+ return 1;
+ if (test__clzsi2(0x33000000, 2))
+ return 1;
+ if (test__clzsi2(0x34000000, 2))
+ return 1;
+ if (test__clzsi2(0x35000000, 2))
+ return 1;
+ if (test__clzsi2(0x36000000, 2))
+ return 1;
+ if (test__clzsi2(0x37000000, 2))
+ return 1;
+ if (test__clzsi2(0x38000000, 2))
+ return 1;
+ if (test__clzsi2(0x39000000, 2))
+ return 1;
+ if (test__clzsi2(0x3A000000, 2))
+ return 1;
+ if (test__clzsi2(0x3B000000, 2))
+ return 1;
+ if (test__clzsi2(0x3C000000, 2))
+ return 1;
+ if (test__clzsi2(0x3D000000, 2))
+ return 1;
+ if (test__clzsi2(0x3E000000, 2))
+ return 1;
+ if (test__clzsi2(0x3F000000, 2))
+ return 1;
+ if (test__clzsi2(0x40000000, 1))
+ return 1;
+ if (test__clzsi2(0x41000000, 1))
+ return 1;
+ if (test__clzsi2(0x42000000, 1))
+ return 1;
+ if (test__clzsi2(0x43000000, 1))
+ return 1;
+ if (test__clzsi2(0x44000000, 1))
+ return 1;
+ if (test__clzsi2(0x45000000, 1))
+ return 1;
+ if (test__clzsi2(0x46000000, 1))
+ return 1;
+ if (test__clzsi2(0x47000000, 1))
+ return 1;
+ if (test__clzsi2(0x48000000, 1))
+ return 1;
+ if (test__clzsi2(0x49000000, 1))
+ return 1;
+ if (test__clzsi2(0x4A000000, 1))
+ return 1;
+ if (test__clzsi2(0x4B000000, 1))
+ return 1;
+ if (test__clzsi2(0x4C000000, 1))
+ return 1;
+ if (test__clzsi2(0x4D000000, 1))
+ return 1;
+ if (test__clzsi2(0x4E000000, 1))
+ return 1;
+ if (test__clzsi2(0x4F000000, 1))
+ return 1;
+ if (test__clzsi2(0x50000000, 1))
+ return 1;
+ if (test__clzsi2(0x51000000, 1))
+ return 1;
+ if (test__clzsi2(0x52000000, 1))
+ return 1;
+ if (test__clzsi2(0x53000000, 1))
+ return 1;
+ if (test__clzsi2(0x54000000, 1))
+ return 1;
+ if (test__clzsi2(0x55000000, 1))
+ return 1;
+ if (test__clzsi2(0x56000000, 1))
+ return 1;
+ if (test__clzsi2(0x57000000, 1))
+ return 1;
+ if (test__clzsi2(0x58000000, 1))
+ return 1;
+ if (test__clzsi2(0x59000000, 1))
+ return 1;
+ if (test__clzsi2(0x5A000000, 1))
+ return 1;
+ if (test__clzsi2(0x5B000000, 1))
+ return 1;
+ if (test__clzsi2(0x5C000000, 1))
+ return 1;
+ if (test__clzsi2(0x5D000000, 1))
+ return 1;
+ if (test__clzsi2(0x5E000000, 1))
+ return 1;
+ if (test__clzsi2(0x5F000000, 1))
+ return 1;
+ if (test__clzsi2(0x60000000, 1))
+ return 1;
+ if (test__clzsi2(0x61000000, 1))
+ return 1;
+ if (test__clzsi2(0x62000000, 1))
+ return 1;
+ if (test__clzsi2(0x63000000, 1))
+ return 1;
+ if (test__clzsi2(0x64000000, 1))
+ return 1;
+ if (test__clzsi2(0x65000000, 1))
+ return 1;
+ if (test__clzsi2(0x66000000, 1))
+ return 1;
+ if (test__clzsi2(0x67000000, 1))
+ return 1;
+ if (test__clzsi2(0x68000000, 1))
+ return 1;
+ if (test__clzsi2(0x69000000, 1))
+ return 1;
+ if (test__clzsi2(0x6A000000, 1))
+ return 1;
+ if (test__clzsi2(0x6B000000, 1))
+ return 1;
+ if (test__clzsi2(0x6C000000, 1))
+ return 1;
+ if (test__clzsi2(0x6D000000, 1))
+ return 1;
+ if (test__clzsi2(0x6E000000, 1))
+ return 1;
+ if (test__clzsi2(0x6F000000, 1))
+ return 1;
+ if (test__clzsi2(0x70000000, 1))
+ return 1;
+ if (test__clzsi2(0x71000000, 1))
+ return 1;
+ if (test__clzsi2(0x72000000, 1))
+ return 1;
+ if (test__clzsi2(0x73000000, 1))
+ return 1;
+ if (test__clzsi2(0x74000000, 1))
+ return 1;
+ if (test__clzsi2(0x75000000, 1))
+ return 1;
+ if (test__clzsi2(0x76000000, 1))
+ return 1;
+ if (test__clzsi2(0x77000000, 1))
+ return 1;
+ if (test__clzsi2(0x78000000, 1))
+ return 1;
+ if (test__clzsi2(0x79000000, 1))
+ return 1;
+ if (test__clzsi2(0x7A000000, 1))
+ return 1;
+ if (test__clzsi2(0x7B000000, 1))
+ return 1;
+ if (test__clzsi2(0x7C000000, 1))
+ return 1;
+ if (test__clzsi2(0x7D000000, 1))
+ return 1;
+ if (test__clzsi2(0x7E000000, 1))
+ return 1;
+ if (test__clzsi2(0x7F000000, 1))
+ return 1;
+ if (test__clzsi2(0x80000000, 0))
+ return 1;
+ if (test__clzsi2(0x81000000, 0))
+ return 1;
+ if (test__clzsi2(0x82000000, 0))
+ return 1;
+ if (test__clzsi2(0x83000000, 0))
+ return 1;
+ if (test__clzsi2(0x84000000, 0))
+ return 1;
+ if (test__clzsi2(0x85000000, 0))
+ return 1;
+ if (test__clzsi2(0x86000000, 0))
+ return 1;
+ if (test__clzsi2(0x87000000, 0))
+ return 1;
+ if (test__clzsi2(0x88000000, 0))
+ return 1;
+ if (test__clzsi2(0x89000000, 0))
+ return 1;
+ if (test__clzsi2(0x8A000000, 0))
+ return 1;
+ if (test__clzsi2(0x8B000000, 0))
+ return 1;
+ if (test__clzsi2(0x8C000000, 0))
+ return 1;
+ if (test__clzsi2(0x8D000000, 0))
+ return 1;
+ if (test__clzsi2(0x8E000000, 0))
+ return 1;
+ if (test__clzsi2(0x8F000000, 0))
+ return 1;
+ if (test__clzsi2(0x90000000, 0))
+ return 1;
+ if (test__clzsi2(0x91000000, 0))
+ return 1;
+ if (test__clzsi2(0x92000000, 0))
+ return 1;
+ if (test__clzsi2(0x93000000, 0))
+ return 1;
+ if (test__clzsi2(0x94000000, 0))
+ return 1;
+ if (test__clzsi2(0x95000000, 0))
+ return 1;
+ if (test__clzsi2(0x96000000, 0))
+ return 1;
+ if (test__clzsi2(0x97000000, 0))
+ return 1;
+ if (test__clzsi2(0x98000000, 0))
+ return 1;
+ if (test__clzsi2(0x99000000, 0))
+ return 1;
+ if (test__clzsi2(0x9A000000, 0))
+ return 1;
+ if (test__clzsi2(0x9B000000, 0))
+ return 1;
+ if (test__clzsi2(0x9C000000, 0))
+ return 1;
+ if (test__clzsi2(0x9D000000, 0))
+ return 1;
+ if (test__clzsi2(0x9E000000, 0))
+ return 1;
+ if (test__clzsi2(0x9F000000, 0))
+ return 1;
+ if (test__clzsi2(0xA0000000, 0))
+ return 1;
+ if (test__clzsi2(0xA1000000, 0))
+ return 1;
+ if (test__clzsi2(0xA2000000, 0))
+ return 1;
+ if (test__clzsi2(0xA3000000, 0))
+ return 1;
+ if (test__clzsi2(0xA4000000, 0))
+ return 1;
+ if (test__clzsi2(0xA5000000, 0))
+ return 1;
+ if (test__clzsi2(0xA6000000, 0))
+ return 1;
+ if (test__clzsi2(0xA7000000, 0))
+ return 1;
+ if (test__clzsi2(0xA8000000, 0))
+ return 1;
+ if (test__clzsi2(0xA9000000, 0))
+ return 1;
+ if (test__clzsi2(0xAA000000, 0))
+ return 1;
+ if (test__clzsi2(0xAB000000, 0))
+ return 1;
+ if (test__clzsi2(0xAC000000, 0))
+ return 1;
+ if (test__clzsi2(0xAD000000, 0))
+ return 1;
+ if (test__clzsi2(0xAE000000, 0))
+ return 1;
+ if (test__clzsi2(0xAF000000, 0))
+ return 1;
+ if (test__clzsi2(0xB0000000, 0))
+ return 1;
+ if (test__clzsi2(0xB1000000, 0))
+ return 1;
+ if (test__clzsi2(0xB2000000, 0))
+ return 1;
+ if (test__clzsi2(0xB3000000, 0))
+ return 1;
+ if (test__clzsi2(0xB4000000, 0))
+ return 1;
+ if (test__clzsi2(0xB5000000, 0))
+ return 1;
+ if (test__clzsi2(0xB6000000, 0))
+ return 1;
+ if (test__clzsi2(0xB7000000, 0))
+ return 1;
+ if (test__clzsi2(0xB8000000, 0))
+ return 1;
+ if (test__clzsi2(0xB9000000, 0))
+ return 1;
+ if (test__clzsi2(0xBA000000, 0))
+ return 1;
+ if (test__clzsi2(0xBB000000, 0))
+ return 1;
+ if (test__clzsi2(0xBC000000, 0))
+ return 1;
+ if (test__clzsi2(0xBD000000, 0))
+ return 1;
+ if (test__clzsi2(0xBE000000, 0))
+ return 1;
+ if (test__clzsi2(0xBF000000, 0))
+ return 1;
+ if (test__clzsi2(0xC0000000, 0))
+ return 1;
+ if (test__clzsi2(0xC1000000, 0))
+ return 1;
+ if (test__clzsi2(0xC2000000, 0))
+ return 1;
+ if (test__clzsi2(0xC3000000, 0))
+ return 1;
+ if (test__clzsi2(0xC4000000, 0))
+ return 1;
+ if (test__clzsi2(0xC5000000, 0))
+ return 1;
+ if (test__clzsi2(0xC6000000, 0))
+ return 1;
+ if (test__clzsi2(0xC7000000, 0))
+ return 1;
+ if (test__clzsi2(0xC8000000, 0))
+ return 1;
+ if (test__clzsi2(0xC9000000, 0))
+ return 1;
+ if (test__clzsi2(0xCA000000, 0))
+ return 1;
+ if (test__clzsi2(0xCB000000, 0))
+ return 1;
+ if (test__clzsi2(0xCC000000, 0))
+ return 1;
+ if (test__clzsi2(0xCD000000, 0))
+ return 1;
+ if (test__clzsi2(0xCE000000, 0))
+ return 1;
+ if (test__clzsi2(0xCF000000, 0))
+ return 1;
+ if (test__clzsi2(0xD0000000, 0))
+ return 1;
+ if (test__clzsi2(0xD1000000, 0))
+ return 1;
+ if (test__clzsi2(0xD2000000, 0))
+ return 1;
+ if (test__clzsi2(0xD3000000, 0))
+ return 1;
+ if (test__clzsi2(0xD4000000, 0))
+ return 1;
+ if (test__clzsi2(0xD5000000, 0))
+ return 1;
+ if (test__clzsi2(0xD6000000, 0))
+ return 1;
+ if (test__clzsi2(0xD7000000, 0))
+ return 1;
+ if (test__clzsi2(0xD8000000, 0))
+ return 1;
+ if (test__clzsi2(0xD9000000, 0))
+ return 1;
+ if (test__clzsi2(0xDA000000, 0))
+ return 1;
+ if (test__clzsi2(0xDB000000, 0))
+ return 1;
+ if (test__clzsi2(0xDC000000, 0))
+ return 1;
+ if (test__clzsi2(0xDD000000, 0))
+ return 1;
+ if (test__clzsi2(0xDE000000, 0))
+ return 1;
+ if (test__clzsi2(0xDF000000, 0))
+ return 1;
+ if (test__clzsi2(0xE0000000, 0))
+ return 1;
+ if (test__clzsi2(0xE1000000, 0))
+ return 1;
+ if (test__clzsi2(0xE2000000, 0))
+ return 1;
+ if (test__clzsi2(0xE3000000, 0))
+ return 1;
+ if (test__clzsi2(0xE4000000, 0))
+ return 1;
+ if (test__clzsi2(0xE5000000, 0))
+ return 1;
+ if (test__clzsi2(0xE6000000, 0))
+ return 1;
+ if (test__clzsi2(0xE7000000, 0))
+ return 1;
+ if (test__clzsi2(0xE8000000, 0))
+ return 1;
+ if (test__clzsi2(0xE9000000, 0))
+ return 1;
+ if (test__clzsi2(0xEA000000, 0))
+ return 1;
+ if (test__clzsi2(0xEB000000, 0))
+ return 1;
+ if (test__clzsi2(0xEC000000, 0))
+ return 1;
+ if (test__clzsi2(0xED000000, 0))
+ return 1;
+ if (test__clzsi2(0xEE000000, 0))
+ return 1;
+ if (test__clzsi2(0xEF000000, 0))
+ return 1;
+ if (test__clzsi2(0xF0000000, 0))
+ return 1;
+ if (test__clzsi2(0xF1000000, 0))
+ return 1;
+ if (test__clzsi2(0xF2000000, 0))
+ return 1;
+ if (test__clzsi2(0xF3000000, 0))
+ return 1;
+ if (test__clzsi2(0xF4000000, 0))
+ return 1;
+ if (test__clzsi2(0xF5000000, 0))
+ return 1;
+ if (test__clzsi2(0xF6000000, 0))
+ return 1;
+ if (test__clzsi2(0xF7000000, 0))
+ return 1;
+ if (test__clzsi2(0xF8000000, 0))
+ return 1;
+ if (test__clzsi2(0xF9000000, 0))
+ return 1;
+ if (test__clzsi2(0xFA000000, 0))
+ return 1;
+ if (test__clzsi2(0xFB000000, 0))
+ return 1;
+ if (test__clzsi2(0xFC000000, 0))
+ return 1;
+ if (test__clzsi2(0xFD000000, 0))
+ return 1;
+ if (test__clzsi2(0xFE000000, 0))
+ return 1;
+ if (test__clzsi2(0xFF000000, 0))
+ return 1;
+
+ if (test__clzsi2(0x00000001, 31))
+ return 1;
+ if (test__clzsi2(0x00000002, 30))
+ return 1;
+ if (test__clzsi2(0x00000004, 29))
+ return 1;
+ if (test__clzsi2(0x00000008, 28))
+ return 1;
+ if (test__clzsi2(0x00000010, 27))
+ return 1;
+ if (test__clzsi2(0x00000020, 26))
+ return 1;
+ if (test__clzsi2(0x00000040, 25))
+ return 1;
+ if (test__clzsi2(0x00000080, 24))
+ return 1;
+ if (test__clzsi2(0x00000100, 23))
+ return 1;
+ if (test__clzsi2(0x00000200, 22))
+ return 1;
+ if (test__clzsi2(0x00000400, 21))
+ return 1;
+ if (test__clzsi2(0x00000800, 20))
+ return 1;
+ if (test__clzsi2(0x00001000, 19))
+ return 1;
+ if (test__clzsi2(0x00002000, 18))
+ return 1;
+ if (test__clzsi2(0x00004000, 17))
+ return 1;
+ if (test__clzsi2(0x00008000, 16))
+ return 1;
+ if (test__clzsi2(0x00010000, 15))
+ return 1;
+ if (test__clzsi2(0x00020000, 14))
+ return 1;
+ if (test__clzsi2(0x00040000, 13))
+ return 1;
+ if (test__clzsi2(0x00080000, 12))
+ return 1;
+ if (test__clzsi2(0x00100000, 11))
+ return 1;
+ if (test__clzsi2(0x00200000, 10))
+ return 1;
+ if (test__clzsi2(0x00400000, 9))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/clzti2_test.c b/test/Unit/clzti2_test.c
new file mode 100644
index 000000000..5aa2eb76b
--- /dev/null
+++ b/test/Unit/clzti2_test.c
@@ -0,0 +1,88 @@
+//===-- clzti2_test.c - Test __clzti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __clzti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+si_int __clzti2(ti_int a);
+
+int test__clzti2(ti_int a, si_int expected)
+{
+ si_int x = __clzti2(a);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ printf("error in __clzti2(0x%llX%.16llX) = %d, expected %d\n",
+ at.high, at.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ const int N = (int)(sizeof(ti_int) * CHAR_BIT);
+
+ if (test__clzti2(0x00000001, N-1))
+ return 1;
+ if (test__clzti2(0x00000002, N-2))
+ return 1;
+ if (test__clzti2(0x00000003, N-2))
+ return 1;
+ if (test__clzti2(0x00000004, N-3))
+ return 1;
+ if (test__clzti2(0x00000005, N-3))
+ return 1;
+ if (test__clzti2(0x0000000A, N-4))
+ return 1;
+ if (test__clzti2(0x1000000A, N*3/4+3))
+ return 1;
+ if (test__clzti2(0x2000000A, N*3/4+2))
+ return 1;
+ if (test__clzti2(0x6000000A, N*3/4+1))
+ return 1;
+ if (test__clzti2(0x8000000AuLL, N*3/4))
+ return 1;
+ if (test__clzti2(0x000005008000000AuLL, 85))
+ return 1;
+ if (test__clzti2(0x020005008000000AuLL, 70))
+ return 1;
+ if (test__clzti2(0x720005008000000AuLL, 65))
+ return 1;
+ if (test__clzti2(0x820005008000000AuLL, 64))
+ return 1;
+
+ if (test__clzti2(make_ti(0x0000000080000000LL, 0x8000000800000000LL), 32))
+ return 1;
+ if (test__clzti2(make_ti(0x0000000100000000LL, 0x8000000800000000LL), 31))
+ return 1;
+ if (test__clzti2(make_ti(0x1000000100000000LL, 0x8000000800000000LL), 3))
+ return 1;
+ if (test__clzti2(make_ti(0x7000000100000000LL, 0x8000000800000000LL), 1))
+ return 1;
+ if (test__clzti2(make_ti(0x8000000100000000LL, 0x8000000800000000LL), 0))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/cmpdi2_test.c b/test/Unit/cmpdi2_test.c
new file mode 100644
index 000000000..459a5d50b
--- /dev/null
+++ b/test/Unit/cmpdi2_test.c
@@ -0,0 +1,77 @@
+//===-- cmpdi2_test.c - Test __cmpdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __cmpdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+si_int __cmpdi2(di_int a, di_int b);
+
+int test__cmpdi2(di_int a, di_int b, si_int expected)
+{
+ si_int x = __cmpdi2(a, b);
+ if (x != expected)
+ printf("error in __cmpdi2(0x%llX, 0x%llX) = %d, expected %d\n",
+ a, b, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+ if (test__cmpdi2(0, 0, 1))
+ return 1;
+ if (test__cmpdi2(1, 1, 1))
+ return 1;
+ if (test__cmpdi2(2, 2, 1))
+ return 1;
+ if (test__cmpdi2(0x7FFFFFFF, 0x7FFFFFFF, 1))
+ return 1;
+ if (test__cmpdi2(0x80000000, 0x80000000, 1))
+ return 1;
+ if (test__cmpdi2(0x80000001, 0x80000001, 1))
+ return 1;
+ if (test__cmpdi2(0xFFFFFFFF, 0xFFFFFFFF, 1))
+ return 1;
+ if (test__cmpdi2(0x000000010000000LL, 0x000000010000000LL, 1))
+ return 1;
+ if (test__cmpdi2(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL, 1))
+ return 1;
+
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000300000001LL, 0))
+ return 1;
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000300000002LL, 0))
+ return 1;
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000300000003LL, 0))
+ return 1;
+
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000100000001LL, 2))
+ return 1;
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000100000002LL, 2))
+ return 1;
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000100000003LL, 2))
+ return 1;
+
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000200000001LL, 2))
+ return 1;
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000200000002LL, 1))
+ return 1;
+ if (test__cmpdi2(0x0000000200000002LL, 0x0000000200000003LL, 0))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/cmpti2_test.c b/test/Unit/cmpti2_test.c
new file mode 100644
index 000000000..ef0e1923f
--- /dev/null
+++ b/test/Unit/cmpti2_test.c
@@ -0,0 +1,110 @@
+//===-- cmpti2_test.c - Test __cmpti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __cmpti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+si_int __cmpti2(ti_int a, ti_int b);
+
+int test__cmpti2(ti_int a, ti_int b, si_int expected)
+{
+ si_int x = __cmpti2(a, b);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ twords bt;
+ bt.all = b;
+ printf("error in __cmpti2(0x%llX%.16llX, 0x%llX%.16llX) = %d, expected %d\n",
+ at.high, at.low, bt.high, bt.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__cmpti2(0, 0, 1))
+ return 1;
+ if (test__cmpti2(1, 1, 1))
+ return 1;
+ if (test__cmpti2(2, 2, 1))
+ return 1;
+ if (test__cmpti2(0x7FFFFFFF, 0x7FFFFFFF, 1))
+ return 1;
+ if (test__cmpti2(0x80000000, 0x80000000, 1))
+ return 1;
+ if (test__cmpti2(0x80000001, 0x80000001, 1))
+ return 1;
+ if (test__cmpti2(0xFFFFFFFF, 0xFFFFFFFF, 1))
+ return 1;
+ if (test__cmpti2(0x000000010000000LL, 0x000000010000000LL, 1))
+ return 1;
+ if (test__cmpti2(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL, 1))
+ return 1;
+
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000300000001LL, 0))
+ return 1;
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000300000002LL, 0))
+ return 1;
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000300000003LL, 0))
+ return 1;
+
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000100000001LL, 2))
+ return 1;
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000100000002LL, 2))
+ return 1;
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000100000003LL, 2))
+ return 1;
+
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000200000001LL, 2))
+ return 1;
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000200000002LL, 1))
+ return 1;
+ if (test__cmpti2(0x0000000200000002LL, 0x0000000200000003LL, 0))
+ return 1;
+
+ if (test__cmpti2(make_ti(2, 2), make_ti(3, 1), 0))
+ return 1;
+ if (test__cmpti2(make_ti(2, 2), make_ti(3, 2), 0))
+ return 1;
+ if (test__cmpti2(make_ti(2, 2), make_ti(3, 3), 0))
+ return 1;
+
+ if (test__cmpti2(make_ti(2, 2), make_ti(1, 1), 2))
+ return 1;
+ if (test__cmpti2(make_ti(2, 2), make_ti(1, 2), 2))
+ return 1;
+ if (test__cmpti2(make_ti(2, 2), make_ti(1, 3), 2))
+ return 1;
+
+ if (test__cmpti2(make_ti(2, 2), make_ti(2, 1), 2))
+ return 1;
+ if (test__cmpti2(make_ti(2, 2), make_ti(2, 2), 1))
+ return 1;
+ if (test__cmpti2(make_ti(2, 2), make_ti(2, 3), 0))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/ctzdi2_test.c b/test/Unit/ctzdi2_test.c
new file mode 100644
index 000000000..b72fdb307
--- /dev/null
+++ b/test/Unit/ctzdi2_test.c
@@ -0,0 +1,67 @@
+//===-- ctzdi2_test.c - Test __ctzdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ctzdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+si_int __ctzdi2(di_int a);
+
+int test__ctzdi2(di_int a, si_int expected)
+{
+ si_int x = __ctzdi2(a);
+ if (x != expected)
+ printf("error in __ctzdi2(0x%llX) = %d, expected %d\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+// if (test__ctzdi2(0x00000000, N)) // undefined
+// return 1;
+ if (test__ctzdi2(0x00000001, 0))
+ return 1;
+ if (test__ctzdi2(0x00000002, 1))
+ return 1;
+ if (test__ctzdi2(0x00000003, 0))
+ return 1;
+ if (test__ctzdi2(0x00000004, 2))
+ return 1;
+ if (test__ctzdi2(0x00000005, 0))
+ return 1;
+ if (test__ctzdi2(0x0000000A, 1))
+ return 1;
+ if (test__ctzdi2(0x10000000, 28))
+ return 1;
+ if (test__ctzdi2(0x20000000, 29))
+ return 1;
+ if (test__ctzdi2(0x60000000, 29))
+ return 1;
+ if (test__ctzdi2(0x80000000uLL, 31))
+ return 1;
+ if (test__ctzdi2(0x0000050000000000uLL, 40))
+ return 1;
+ if (test__ctzdi2(0x0200080000000000uLL, 43))
+ return 1;
+ if (test__ctzdi2(0x7200000000000000uLL, 57))
+ return 1;
+ if (test__ctzdi2(0x8000000000000000uLL, 63))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/ctzsi2_test.c b/test/Unit/ctzsi2_test.c
new file mode 100644
index 000000000..2c6fd0e91
--- /dev/null
+++ b/test/Unit/ctzsi2_test.c
@@ -0,0 +1,569 @@
+//===-- ctzsi2_test.c - Test __ctzsi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ctzsi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+si_int __ctzsi2(si_int a);
+
+int test__ctzsi2(si_int a, si_int expected)
+{
+ si_int x = __ctzsi2(a);
+ if (x != expected)
+ printf("error in __ctzsi2(0x%X) = %d, expected %d\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(si_int)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+// if (test__ctzsi2(0x00000000, 32)) // undefined
+// return 1;
+ if (test__ctzsi2(0x00000001, 0))
+ return 1;
+ if (test__ctzsi2(0x00000002, 1))
+ return 1;
+ if (test__ctzsi2(0x00000003, 0))
+ return 1;
+ if (test__ctzsi2(0x00000004, 2))
+ return 1;
+ if (test__ctzsi2(0x00000005, 0))
+ return 1;
+ if (test__ctzsi2(0x00000006, 1))
+ return 1;
+ if (test__ctzsi2(0x00000007, 0))
+ return 1;
+ if (test__ctzsi2(0x00000008, 3))
+ return 1;
+ if (test__ctzsi2(0x00000009, 0))
+ return 1;
+ if (test__ctzsi2(0x0000000A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000000B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000000C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000000D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000000E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000000F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000010, 4))
+ return 1;
+ if (test__ctzsi2(0x00000012, 1))
+ return 1;
+ if (test__ctzsi2(0x00000013, 0))
+ return 1;
+ if (test__ctzsi2(0x00000014, 2))
+ return 1;
+ if (test__ctzsi2(0x00000015, 0))
+ return 1;
+ if (test__ctzsi2(0x00000016, 1))
+ return 1;
+ if (test__ctzsi2(0x00000017, 0))
+ return 1;
+ if (test__ctzsi2(0x00000018, 3))
+ return 1;
+ if (test__ctzsi2(0x00000019, 0))
+ return 1;
+ if (test__ctzsi2(0x0000001A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000001B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000001C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000001D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000001E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000001F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000020, 5))
+ return 1;
+ if (test__ctzsi2(0x00000022, 1))
+ return 1;
+ if (test__ctzsi2(0x00000023, 0))
+ return 1;
+ if (test__ctzsi2(0x00000024, 2))
+ return 1;
+ if (test__ctzsi2(0x00000025, 0))
+ return 1;
+ if (test__ctzsi2(0x00000026, 1))
+ return 1;
+ if (test__ctzsi2(0x00000027, 0))
+ return 1;
+ if (test__ctzsi2(0x00000028, 3))
+ return 1;
+ if (test__ctzsi2(0x00000029, 0))
+ return 1;
+ if (test__ctzsi2(0x0000002A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000002B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000002C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000002D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000002E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000002F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000030, 4))
+ return 1;
+ if (test__ctzsi2(0x00000032, 1))
+ return 1;
+ if (test__ctzsi2(0x00000033, 0))
+ return 1;
+ if (test__ctzsi2(0x00000034, 2))
+ return 1;
+ if (test__ctzsi2(0x00000035, 0))
+ return 1;
+ if (test__ctzsi2(0x00000036, 1))
+ return 1;
+ if (test__ctzsi2(0x00000037, 0))
+ return 1;
+ if (test__ctzsi2(0x00000038, 3))
+ return 1;
+ if (test__ctzsi2(0x00000039, 0))
+ return 1;
+ if (test__ctzsi2(0x0000003A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000003B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000003C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000003D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000003E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000003F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000040, 6))
+ return 1;
+ if (test__ctzsi2(0x00000042, 1))
+ return 1;
+ if (test__ctzsi2(0x00000043, 0))
+ return 1;
+ if (test__ctzsi2(0x00000044, 2))
+ return 1;
+ if (test__ctzsi2(0x00000045, 0))
+ return 1;
+ if (test__ctzsi2(0x00000046, 1))
+ return 1;
+ if (test__ctzsi2(0x00000047, 0))
+ return 1;
+ if (test__ctzsi2(0x00000048, 3))
+ return 1;
+ if (test__ctzsi2(0x00000049, 0))
+ return 1;
+ if (test__ctzsi2(0x0000004A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000004B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000004C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000004D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000004E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000004F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000050, 4))
+ return 1;
+ if (test__ctzsi2(0x00000052, 1))
+ return 1;
+ if (test__ctzsi2(0x00000053, 0))
+ return 1;
+ if (test__ctzsi2(0x00000054, 2))
+ return 1;
+ if (test__ctzsi2(0x00000055, 0))
+ return 1;
+ if (test__ctzsi2(0x00000056, 1))
+ return 1;
+ if (test__ctzsi2(0x00000057, 0))
+ return 1;
+ if (test__ctzsi2(0x00000058, 3))
+ return 1;
+ if (test__ctzsi2(0x00000059, 0))
+ return 1;
+ if (test__ctzsi2(0x0000005A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000005B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000005C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000005D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000005E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000005F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000060, 5))
+ return 1;
+ if (test__ctzsi2(0x00000062, 1))
+ return 1;
+ if (test__ctzsi2(0x00000063, 0))
+ return 1;
+ if (test__ctzsi2(0x00000064, 2))
+ return 1;
+ if (test__ctzsi2(0x00000065, 0))
+ return 1;
+ if (test__ctzsi2(0x00000066, 1))
+ return 1;
+ if (test__ctzsi2(0x00000067, 0))
+ return 1;
+ if (test__ctzsi2(0x00000068, 3))
+ return 1;
+ if (test__ctzsi2(0x00000069, 0))
+ return 1;
+ if (test__ctzsi2(0x0000006A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000006B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000006C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000006D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000006E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000006F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000070, 4))
+ return 1;
+ if (test__ctzsi2(0x00000072, 1))
+ return 1;
+ if (test__ctzsi2(0x00000073, 0))
+ return 1;
+ if (test__ctzsi2(0x00000074, 2))
+ return 1;
+ if (test__ctzsi2(0x00000075, 0))
+ return 1;
+ if (test__ctzsi2(0x00000076, 1))
+ return 1;
+ if (test__ctzsi2(0x00000077, 0))
+ return 1;
+ if (test__ctzsi2(0x00000078, 3))
+ return 1;
+ if (test__ctzsi2(0x00000079, 0))
+ return 1;
+ if (test__ctzsi2(0x0000007A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000007B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000007C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000007D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000007E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000007F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000080, 7))
+ return 1;
+ if (test__ctzsi2(0x00000082, 1))
+ return 1;
+ if (test__ctzsi2(0x00000083, 0))
+ return 1;
+ if (test__ctzsi2(0x00000084, 2))
+ return 1;
+ if (test__ctzsi2(0x00000085, 0))
+ return 1;
+ if (test__ctzsi2(0x00000086, 1))
+ return 1;
+ if (test__ctzsi2(0x00000087, 0))
+ return 1;
+ if (test__ctzsi2(0x00000088, 3))
+ return 1;
+ if (test__ctzsi2(0x00000089, 0))
+ return 1;
+ if (test__ctzsi2(0x0000008A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000008B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000008C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000008D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000008E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000008F, 0))
+ return 1;
+ if (test__ctzsi2(0x00000090, 4))
+ return 1;
+ if (test__ctzsi2(0x00000092, 1))
+ return 1;
+ if (test__ctzsi2(0x00000093, 0))
+ return 1;
+ if (test__ctzsi2(0x00000094, 2))
+ return 1;
+ if (test__ctzsi2(0x00000095, 0))
+ return 1;
+ if (test__ctzsi2(0x00000096, 1))
+ return 1;
+ if (test__ctzsi2(0x00000097, 0))
+ return 1;
+ if (test__ctzsi2(0x00000098, 3))
+ return 1;
+ if (test__ctzsi2(0x00000099, 0))
+ return 1;
+ if (test__ctzsi2(0x0000009A, 1))
+ return 1;
+ if (test__ctzsi2(0x0000009B, 0))
+ return 1;
+ if (test__ctzsi2(0x0000009C, 2))
+ return 1;
+ if (test__ctzsi2(0x0000009D, 0))
+ return 1;
+ if (test__ctzsi2(0x0000009E, 1))
+ return 1;
+ if (test__ctzsi2(0x0000009F, 0))
+ return 1;
+ if (test__ctzsi2(0x000000A0, 5))
+ return 1;
+ if (test__ctzsi2(0x000000A2, 1))
+ return 1;
+ if (test__ctzsi2(0x000000A3, 0))
+ return 1;
+ if (test__ctzsi2(0x000000A4, 2))
+ return 1;
+ if (test__ctzsi2(0x000000A5, 0))
+ return 1;
+ if (test__ctzsi2(0x000000A6, 1))
+ return 1;
+ if (test__ctzsi2(0x000000A7, 0))
+ return 1;
+ if (test__ctzsi2(0x000000A8, 3))
+ return 1;
+ if (test__ctzsi2(0x000000A9, 0))
+ return 1;
+ if (test__ctzsi2(0x000000AA, 1))
+ return 1;
+ if (test__ctzsi2(0x000000AB, 0))
+ return 1;
+ if (test__ctzsi2(0x000000AC, 2))
+ return 1;
+ if (test__ctzsi2(0x000000AD, 0))
+ return 1;
+ if (test__ctzsi2(0x000000AE, 1))
+ return 1;
+ if (test__ctzsi2(0x000000AF, 0))
+ return 1;
+ if (test__ctzsi2(0x000000B0, 4))
+ return 1;
+ if (test__ctzsi2(0x000000B2, 1))
+ return 1;
+ if (test__ctzsi2(0x000000B3, 0))
+ return 1;
+ if (test__ctzsi2(0x000000B4, 2))
+ return 1;
+ if (test__ctzsi2(0x000000B5, 0))
+ return 1;
+ if (test__ctzsi2(0x000000B6, 1))
+ return 1;
+ if (test__ctzsi2(0x000000B7, 0))
+ return 1;
+ if (test__ctzsi2(0x000000B8, 3))
+ return 1;
+ if (test__ctzsi2(0x000000B9, 0))
+ return 1;
+ if (test__ctzsi2(0x000000BA, 1))
+ return 1;
+ if (test__ctzsi2(0x000000BB, 0))
+ return 1;
+ if (test__ctzsi2(0x000000BC, 2))
+ return 1;
+ if (test__ctzsi2(0x000000BD, 0))
+ return 1;
+ if (test__ctzsi2(0x000000BE, 1))
+ return 1;
+ if (test__ctzsi2(0x000000BF, 0))
+ return 1;
+ if (test__ctzsi2(0x000000C0, 6))
+ return 1;
+ if (test__ctzsi2(0x000000C2, 1))
+ return 1;
+ if (test__ctzsi2(0x000000C3, 0))
+ return 1;
+ if (test__ctzsi2(0x000000C4, 2))
+ return 1;
+ if (test__ctzsi2(0x000000C5, 0))
+ return 1;
+ if (test__ctzsi2(0x000000C6, 1))
+ return 1;
+ if (test__ctzsi2(0x000000C7, 0))
+ return 1;
+ if (test__ctzsi2(0x000000C8, 3))
+ return 1;
+ if (test__ctzsi2(0x000000C9, 0))
+ return 1;
+ if (test__ctzsi2(0x000000CA, 1))
+ return 1;
+ if (test__ctzsi2(0x000000CB, 0))
+ return 1;
+ if (test__ctzsi2(0x000000CC, 2))
+ return 1;
+ if (test__ctzsi2(0x000000CD, 0))
+ return 1;
+ if (test__ctzsi2(0x000000CE, 1))
+ return 1;
+ if (test__ctzsi2(0x000000CF, 0))
+ return 1;
+ if (test__ctzsi2(0x000000D0, 4))
+ return 1;
+ if (test__ctzsi2(0x000000D2, 1))
+ return 1;
+ if (test__ctzsi2(0x000000D3, 0))
+ return 1;
+ if (test__ctzsi2(0x000000D4, 2))
+ return 1;
+ if (test__ctzsi2(0x000000D5, 0))
+ return 1;
+ if (test__ctzsi2(0x000000D6, 1))
+ return 1;
+ if (test__ctzsi2(0x000000D7, 0))
+ return 1;
+ if (test__ctzsi2(0x000000D8, 3))
+ return 1;
+ if (test__ctzsi2(0x000000D9, 0))
+ return 1;
+ if (test__ctzsi2(0x000000DA, 1))
+ return 1;
+ if (test__ctzsi2(0x000000DB, 0))
+ return 1;
+ if (test__ctzsi2(0x000000DC, 2))
+ return 1;
+ if (test__ctzsi2(0x000000DD, 0))
+ return 1;
+ if (test__ctzsi2(0x000000DE, 1))
+ return 1;
+ if (test__ctzsi2(0x000000DF, 0))
+ return 1;
+ if (test__ctzsi2(0x000000E0, 5))
+ return 1;
+ if (test__ctzsi2(0x000000E2, 1))
+ return 1;
+ if (test__ctzsi2(0x000000E3, 0))
+ return 1;
+ if (test__ctzsi2(0x000000E4, 2))
+ return 1;
+ if (test__ctzsi2(0x000000E5, 0))
+ return 1;
+ if (test__ctzsi2(0x000000E6, 1))
+ return 1;
+ if (test__ctzsi2(0x000000E7, 0))
+ return 1;
+ if (test__ctzsi2(0x000000E8, 3))
+ return 1;
+ if (test__ctzsi2(0x000000E9, 0))
+ return 1;
+ if (test__ctzsi2(0x000000EA, 1))
+ return 1;
+ if (test__ctzsi2(0x000000EB, 0))
+ return 1;
+ if (test__ctzsi2(0x000000EC, 2))
+ return 1;
+ if (test__ctzsi2(0x000000ED, 0))
+ return 1;
+ if (test__ctzsi2(0x000000EE, 1))
+ return 1;
+ if (test__ctzsi2(0x000000EF, 0))
+ return 1;
+ if (test__ctzsi2(0x000000F0, 4))
+ return 1;
+ if (test__ctzsi2(0x000000F2, 1))
+ return 1;
+ if (test__ctzsi2(0x000000F3, 0))
+ return 1;
+ if (test__ctzsi2(0x000000F4, 2))
+ return 1;
+ if (test__ctzsi2(0x000000F5, 0))
+ return 1;
+ if (test__ctzsi2(0x000000F6, 1))
+ return 1;
+ if (test__ctzsi2(0x000000F7, 0))
+ return 1;
+ if (test__ctzsi2(0x000000F8, 3))
+ return 1;
+ if (test__ctzsi2(0x000000F9, 0))
+ return 1;
+ if (test__ctzsi2(0x000000FA, 1))
+ return 1;
+ if (test__ctzsi2(0x000000FB, 0))
+ return 1;
+ if (test__ctzsi2(0x000000FC, 2))
+ return 1;
+ if (test__ctzsi2(0x000000FD, 0))
+ return 1;
+ if (test__ctzsi2(0x000000FE, 1))
+ return 1;
+ if (test__ctzsi2(0x000000FF, 0))
+ return 1;
+
+ if (test__ctzsi2(0x00000100, 8))
+ return 1;
+ if (test__ctzsi2(0x00000200, 9))
+ return 1;
+ if (test__ctzsi2(0x00000400, 10))
+ return 1;
+ if (test__ctzsi2(0x00000800, 11))
+ return 1;
+ if (test__ctzsi2(0x00001000, 12))
+ return 1;
+ if (test__ctzsi2(0x00002000, 13))
+ return 1;
+ if (test__ctzsi2(0x00004000, 14))
+ return 1;
+ if (test__ctzsi2(0x00008000, 15))
+ return 1;
+ if (test__ctzsi2(0x00010000, 16))
+ return 1;
+ if (test__ctzsi2(0x00020000, 17))
+ return 1;
+ if (test__ctzsi2(0x00040000, 18))
+ return 1;
+ if (test__ctzsi2(0x00080000, 19))
+ return 1;
+ if (test__ctzsi2(0x00100000, 20))
+ return 1;
+ if (test__ctzsi2(0x00200000, 21))
+ return 1;
+ if (test__ctzsi2(0x00400000, 22))
+ return 1;
+ if (test__ctzsi2(0x00800000, 23))
+ return 1;
+ if (test__ctzsi2(0x01000000, 24))
+ return 1;
+ if (test__ctzsi2(0x02000000, 25))
+ return 1;
+ if (test__ctzsi2(0x04000000, 26))
+ return 1;
+ if (test__ctzsi2(0x08000000, 27))
+ return 1;
+ if (test__ctzsi2(0x10000000, 28))
+ return 1;
+ if (test__ctzsi2(0x20000000, 29))
+ return 1;
+ if (test__ctzsi2(0x40000000, 30))
+ return 1;
+ if (test__ctzsi2(0x80000000, 31))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/ctzti2_test.c b/test/Unit/ctzti2_test.c
new file mode 100644
index 000000000..cbad510e4
--- /dev/null
+++ b/test/Unit/ctzti2_test.c
@@ -0,0 +1,82 @@
+//===-- ctzti2_test.c - Test __ctzti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ctzti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+si_int __ctzti2(ti_int a);
+
+int test__ctzti2(ti_int a, si_int expected)
+{
+ si_int x = __ctzti2(a);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ printf("error in __ctzti2(0x%llX%.16llX) = %d, expected %d\n",
+ at.high, at.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__ctzti2(0x00000001, 0))
+ return 1;
+ if (test__ctzti2(0x00000002, 1))
+ return 1;
+ if (test__ctzti2(0x00000003, 0))
+ return 1;
+ if (test__ctzti2(0x00000004, 2))
+ return 1;
+ if (test__ctzti2(0x00000005, 0))
+ return 1;
+ if (test__ctzti2(0x0000000A, 1))
+ return 1;
+ if (test__ctzti2(0x10000000, 28))
+ return 1;
+ if (test__ctzti2(0x20000000, 29))
+ return 1;
+ if (test__ctzti2(0x60000000, 29))
+ return 1;
+ if (test__ctzti2(0x80000000uLL, 31))
+ return 1;
+ if (test__ctzti2(0x0000050000000000uLL, 40))
+ return 1;
+ if (test__ctzti2(0x0200080000000000uLL, 43))
+ return 1;
+ if (test__ctzti2(0x7200000000000000uLL, 57))
+ return 1;
+ if (test__ctzti2(0x8000000000000000uLL, 63))
+ return 1;
+ if (test__ctzti2(make_ti(0x00000000A0000000LL, 0x0000000000000000LL), 93))
+ return 1;
+ if (test__ctzti2(make_ti(0xF000000000000000LL, 0x0000000000000000LL), 124))
+ return 1;
+ if (test__ctzti2(make_ti(0x8000000000000000LL, 0x0000000000000000LL), 127))
+ return 1;
+#endif
+
+ return 0;
+}
diff --git a/test/Unit/divdc3_test.c b/test/Unit/divdc3_test.c
new file mode 100644
index 000000000..c44eb5c4a
--- /dev/null
+++ b/test/Unit/divdc3_test.c
@@ -0,0 +1,370 @@
+//===-- divdc3_test.c - Test __divdc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divdc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+#include <stdio.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+double _Complex __divdc3(double __a, double __b, double __c, double __d);
+
+enum {zero, non_zero, inf, NaN, non_zero_nan};
+
+int
+classify(double _Complex x)
+{
+ if (x == 0)
+ return zero;
+ if (isinf(creal(x)) || isinf(cimag(x)))
+ return inf;
+ if (isnan(creal(x)) && isnan(cimag(x)))
+ return NaN;
+ if (isnan(creal(x)))
+ {
+ if (cimag(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ if (isnan(cimag(x)))
+ {
+ if (creal(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ return non_zero;
+}
+
+int test__divdc3(double a, double b, double c, double d)
+{
+ double _Complex r = __divdc3(a, b, c, d);
+// printf("test__divdc3(%f, %f, %f, %f) = %f + I%f\n",
+// a, b, c, d, creal(r), cimag(r));
+ double _Complex dividend;
+ double _Complex divisor;
+
+ __real__ dividend = a;
+ __imag__ dividend = b;
+ __real__ divisor = c;
+ __imag__ divisor = d;
+
+ switch (classify(dividend))
+ {
+ case zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != non_zero)
+ return 1;
+ {
+ double _Complex z = (a * c + b * d) / (c * c + d * d)
+ + (b * c - a * d) / (c * c + d * d) * _Complex_I;
+ if (cabs((r-z)/r) > 1.e-6)
+ return 1;
+ }
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case inf:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case NaN:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero_nan:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+double x[][2] =
+{
+ { 1.e-6, 1.e-6},
+ {-1.e-6, 1.e-6},
+ {-1.e-6, -1.e-6},
+ { 1.e-6, -1.e-6},
+
+ { 1.e+6, 1.e-6},
+ {-1.e+6, 1.e-6},
+ {-1.e+6, -1.e-6},
+ { 1.e+6, -1.e-6},
+
+ { 1.e-6, 1.e+6},
+ {-1.e-6, 1.e+6},
+ {-1.e-6, -1.e+6},
+ { 1.e-6, -1.e+6},
+
+ { 1.e+6, 1.e+6},
+ {-1.e+6, 1.e+6},
+ {-1.e+6, -1.e+6},
+ { 1.e+6, -1.e+6},
+
+ {NAN, NAN},
+ {-INFINITY, NAN},
+ {-2, NAN},
+ {-1, NAN},
+ {-0.5, NAN},
+ {-0., NAN},
+ {+0., NAN},
+ {0.5, NAN},
+ {1, NAN},
+ {2, NAN},
+ {INFINITY, NAN},
+
+ {NAN, -INFINITY},
+ {-INFINITY, -INFINITY},
+ {-2, -INFINITY},
+ {-1, -INFINITY},
+ {-0.5, -INFINITY},
+ {-0., -INFINITY},
+ {+0., -INFINITY},
+ {0.5, -INFINITY},
+ {1, -INFINITY},
+ {2, -INFINITY},
+ {INFINITY, -INFINITY},
+
+ {NAN, -2},
+ {-INFINITY, -2},
+ {-2, -2},
+ {-1, -2},
+ {-0.5, -2},
+ {-0., -2},
+ {+0., -2},
+ {0.5, -2},
+ {1, -2},
+ {2, -2},
+ {INFINITY, -2},
+
+ {NAN, -1},
+ {-INFINITY, -1},
+ {-2, -1},
+ {-1, -1},
+ {-0.5, -1},
+ {-0., -1},
+ {+0., -1},
+ {0.5, -1},
+ {1, -1},
+ {2, -1},
+ {INFINITY, -1},
+
+ {NAN, -0.5},
+ {-INFINITY, -0.5},
+ {-2, -0.5},
+ {-1, -0.5},
+ {-0.5, -0.5},
+ {-0., -0.5},
+ {+0., -0.5},
+ {0.5, -0.5},
+ {1, -0.5},
+ {2, -0.5},
+ {INFINITY, -0.5},
+
+ {NAN, -0.},
+ {-INFINITY, -0.},
+ {-2, -0.},
+ {-1, -0.},
+ {-0.5, -0.},
+ {-0., -0.},
+ {+0., -0.},
+ {0.5, -0.},
+ {1, -0.},
+ {2, -0.},
+ {INFINITY, -0.},
+
+ {NAN, 0.},
+ {-INFINITY, 0.},
+ {-2, 0.},
+ {-1, 0.},
+ {-0.5, 0.},
+ {-0., 0.},
+ {+0., 0.},
+ {0.5, 0.},
+ {1, 0.},
+ {2, 0.},
+ {INFINITY, 0.},
+
+ {NAN, 0.5},
+ {-INFINITY, 0.5},
+ {-2, 0.5},
+ {-1, 0.5},
+ {-0.5, 0.5},
+ {-0., 0.5},
+ {+0., 0.5},
+ {0.5, 0.5},
+ {1, 0.5},
+ {2, 0.5},
+ {INFINITY, 0.5},
+
+ {NAN, 1},
+ {-INFINITY, 1},
+ {-2, 1},
+ {-1, 1},
+ {-0.5, 1},
+ {-0., 1},
+ {+0., 1},
+ {0.5, 1},
+ {1, 1},
+ {2, 1},
+ {INFINITY, 1},
+
+ {NAN, 2},
+ {-INFINITY, 2},
+ {-2, 2},
+ {-1, 2},
+ {-0.5, 2},
+ {-0., 2},
+ {+0., 2},
+ {0.5, 2},
+ {1, 2},
+ {2, 2},
+ {INFINITY, 2},
+
+ {NAN, INFINITY},
+ {-INFINITY, INFINITY},
+ {-2, INFINITY},
+ {-1, INFINITY},
+ {-0.5, INFINITY},
+ {-0., INFINITY},
+ {+0., INFINITY},
+ {0.5, INFINITY},
+ {1, INFINITY},
+ {2, INFINITY},
+ {INFINITY, INFINITY}
+
+};
+
+int main()
+{
+ const unsigned N = sizeof(x) / sizeof(x[0]);
+ unsigned i, j;
+ for (i = 0; i < N; ++i)
+ {
+ for (j = 0; j < N; ++j)
+ {
+ if (test__divdc3(x[i][0], x[i][1], x[j][0], x[j][1]))
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/test/Unit/divdi3_test.c b/test/Unit/divdi3_test.c
new file mode 100644
index 000000000..0566a7850
--- /dev/null
+++ b/test/Unit/divdi3_test.c
@@ -0,0 +1,58 @@
+//===-- divdi3_test.c - Test __divdi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divdi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a / b
+
+di_int __divdi3(di_int a, di_int b);
+
+int test__divdi3(di_int a, di_int b, di_int expected)
+{
+ di_int x = __divdi3(a, b);
+ if (x != expected)
+ printf("error in __divdi3: %lld / %lld = %lld, expected %lld\n",
+ a, b, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+ if (test__divdi3(0, 1, 0))
+ return 1;
+ if (test__divdi3(0, -1, 0))
+ return 1;
+
+ if (test__divdi3(2, 1, 2))
+ return 1;
+ if (test__divdi3(2, -1, -2))
+ return 1;
+ if (test__divdi3(-2, 1, -2))
+ return 1;
+ if (test__divdi3(-2, -1, 2))
+ return 1;
+
+ if (test__divdi3(0x8000000000000000LL, 1, 0x8000000000000000LL))
+ return 1;
+ if (test__divdi3(0x8000000000000000LL, -1, 0x8000000000000000LL))
+ return 1;
+ if (test__divdi3(0x8000000000000000LL, -2, 0x4000000000000000LL))
+ return 1;
+ if (test__divdi3(0x8000000000000000LL, 2, 0xC000000000000000LL))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/divsc3_test.c b/test/Unit/divsc3_test.c
new file mode 100644
index 000000000..50979abf2
--- /dev/null
+++ b/test/Unit/divsc3_test.c
@@ -0,0 +1,370 @@
+//===-- divsc3_test.c - Test __divsc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divsc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+#include <stdio.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+float _Complex __divsc3(float __a, float __b, float __c, float __d);
+
+enum {zero, non_zero, inf, NaN, non_zero_nan};
+
+int
+classify(float _Complex x)
+{
+ if (x == 0)
+ return zero;
+ if (isinf(crealf(x)) || isinf(cimagf(x)))
+ return inf;
+ if (isnan(crealf(x)) && isnan(cimagf(x)))
+ return NaN;
+ if (isnan(crealf(x)))
+ {
+ if (cimagf(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ if (isnan(cimagf(x)))
+ {
+ if (crealf(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ return non_zero;
+}
+
+int test__divsc3(float a, float b, float c, float d)
+{
+ float _Complex r = __divsc3(a, b, c, d);
+// printf("test__divsc3(%f, %f, %f, %f) = %f + I%f\n",
+// a, b, c, d, crealf(r), cimagf(r));
+ float _Complex dividend;
+ float _Complex divisor;
+
+ __real__ dividend = a;
+ __imag__ dividend = b;
+ __real__ divisor = c;
+ __imag__ divisor = d;
+
+ switch (classify(dividend))
+ {
+ case zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != non_zero)
+ return 1;
+ {
+ float _Complex z = (a * c + b * d) / (c * c + d * d)
+ + (b * c - a * d) / (c * c + d * d) * _Complex_I;
+ if (r != z)
+ return 1;
+ }
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case inf:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case NaN:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero_nan:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+float x[][2] =
+{
+ { 1.e-6, 1.e-6},
+ {-1.e-6, 1.e-6},
+ {-1.e-6, -1.e-6},
+ { 1.e-6, -1.e-6},
+
+ { 1.e+6, 1.e-6},
+ {-1.e+6, 1.e-6},
+ {-1.e+6, -1.e-6},
+ { 1.e+6, -1.e-6},
+
+ { 1.e-6, 1.e+6},
+ {-1.e-6, 1.e+6},
+ {-1.e-6, -1.e+6},
+ { 1.e-6, -1.e+6},
+
+ { 1.e+6, 1.e+6},
+ {-1.e+6, 1.e+6},
+ {-1.e+6, -1.e+6},
+ { 1.e+6, -1.e+6},
+
+ {NAN, NAN},
+ {-INFINITY, NAN},
+ {-2, NAN},
+ {-1, NAN},
+ {-0.5, NAN},
+ {-0., NAN},
+ {+0., NAN},
+ {0.5, NAN},
+ {1, NAN},
+ {2, NAN},
+ {INFINITY, NAN},
+
+ {NAN, -INFINITY},
+ {-INFINITY, -INFINITY},
+ {-2, -INFINITY},
+ {-1, -INFINITY},
+ {-0.5, -INFINITY},
+ {-0., -INFINITY},
+ {+0., -INFINITY},
+ {0.5, -INFINITY},
+ {1, -INFINITY},
+ {2, -INFINITY},
+ {INFINITY, -INFINITY},
+
+ {NAN, -2},
+ {-INFINITY, -2},
+ {-2, -2},
+ {-1, -2},
+ {-0.5, -2},
+ {-0., -2},
+ {+0., -2},
+ {0.5, -2},
+ {1, -2},
+ {2, -2},
+ {INFINITY, -2},
+
+ {NAN, -1},
+ {-INFINITY, -1},
+ {-2, -1},
+ {-1, -1},
+ {-0.5, -1},
+ {-0., -1},
+ {+0., -1},
+ {0.5, -1},
+ {1, -1},
+ {2, -1},
+ {INFINITY, -1},
+
+ {NAN, -0.5},
+ {-INFINITY, -0.5},
+ {-2, -0.5},
+ {-1, -0.5},
+ {-0.5, -0.5},
+ {-0., -0.5},
+ {+0., -0.5},
+ {0.5, -0.5},
+ {1, -0.5},
+ {2, -0.5},
+ {INFINITY, -0.5},
+
+ {NAN, -0.},
+ {-INFINITY, -0.},
+ {-2, -0.},
+ {-1, -0.},
+ {-0.5, -0.},
+ {-0., -0.},
+ {+0., -0.},
+ {0.5, -0.},
+ {1, -0.},
+ {2, -0.},
+ {INFINITY, -0.},
+
+ {NAN, 0.},
+ {-INFINITY, 0.},
+ {-2, 0.},
+ {-1, 0.},
+ {-0.5, 0.},
+ {-0., 0.},
+ {+0., 0.},
+ {0.5, 0.},
+ {1, 0.},
+ {2, 0.},
+ {INFINITY, 0.},
+
+ {NAN, 0.5},
+ {-INFINITY, 0.5},
+ {-2, 0.5},
+ {-1, 0.5},
+ {-0.5, 0.5},
+ {-0., 0.5},
+ {+0., 0.5},
+ {0.5, 0.5},
+ {1, 0.5},
+ {2, 0.5},
+ {INFINITY, 0.5},
+
+ {NAN, 1},
+ {-INFINITY, 1},
+ {-2, 1},
+ {-1, 1},
+ {-0.5, 1},
+ {-0., 1},
+ {+0., 1},
+ {0.5, 1},
+ {1, 1},
+ {2, 1},
+ {INFINITY, 1},
+
+ {NAN, 2},
+ {-INFINITY, 2},
+ {-2, 2},
+ {-1, 2},
+ {-0.5, 2},
+ {-0., 2},
+ {+0., 2},
+ {0.5, 2},
+ {1, 2},
+ {2, 2},
+ {INFINITY, 2},
+
+ {NAN, INFINITY},
+ {-INFINITY, INFINITY},
+ {-2, INFINITY},
+ {-1, INFINITY},
+ {-0.5, INFINITY},
+ {-0., INFINITY},
+ {+0., INFINITY},
+ {0.5, INFINITY},
+ {1, INFINITY},
+ {2, INFINITY},
+ {INFINITY, INFINITY}
+
+};
+
+int main()
+{
+ const unsigned N = sizeof(x) / sizeof(x[0]);
+ unsigned i, j;
+ for (i = 0; i < N; ++i)
+ {
+ for (j = 0; j < N; ++j)
+ {
+ if (test__divsc3(x[i][0], x[i][1], x[j][0], x[j][1]))
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/test/Unit/divsi3_test.c b/test/Unit/divsi3_test.c
new file mode 100644
index 000000000..425c5798f
--- /dev/null
+++ b/test/Unit/divsi3_test.c
@@ -0,0 +1,56 @@
+//===-- divsi3_test.c - Test __divsi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a / b
+
+si_int __divsi3(si_int a, si_int b);
+
+int test__divsi3(si_int a, si_int b, si_int expected)
+{
+ si_int x = __divsi3(a, b);
+ if (x != expected)
+ printf("error in __divsi3: %d / %d = %d, expected %d\n",
+ a, b, x, expected);
+ return x != expected;
+}
+
+int main()
+{
+ if (test__divsi3(0, 1, 0))
+ return 1;
+ if (test__divsi3(0, -1, 0))
+ return 1;
+
+ if (test__divsi3(2, 1, 2))
+ return 1;
+ if (test__divsi3(2, -1, -2))
+ return 1;
+ if (test__divsi3(-2, 1, -2))
+ return 1;
+ if (test__divsi3(-2, -1, 2))
+ return 1;
+
+ if (test__divsi3(0x80000000, 1, 0x80000000))
+ return 1;
+ if (test__divsi3(0x80000000, -1, 0x80000000))
+ return 1;
+ if (test__divsi3(0x80000000, -2, 0x40000000))
+ return 1;
+ if (test__divsi3(0x80000000, 2, 0xC0000000))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/divtc3_test.c b/test/Unit/divtc3_test.c
new file mode 100644
index 000000000..3fa608500
--- /dev/null
+++ b/test/Unit/divtc3_test.c
@@ -0,0 +1,380 @@
+//===-- divtc3_test.c - Test __divtc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divtc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if _ARCH_PPC
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+#include <stdio.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+long double _Complex
+__divtc3(long double __a, long double __b, long double __c, long double __d);
+
+enum {zero, non_zero, inf, NaN, non_zero_nan};
+
+int
+classify(long double _Complex x)
+{
+ if (x == 0)
+ return zero;
+ if (isinf(creall(x)) || isinf(cimagl(x)))
+ return inf;
+ if (isnan(creall(x)) && isnan(cimagl(x)))
+ return NaN;
+ if (isnan(creall(x)))
+ {
+ if (cimagl(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ if (isnan(cimagl(x)))
+ {
+ if (creall(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ return non_zero;
+}
+
+int test__divtc3(long double a, long double b, long double c, long double d)
+{
+ long double _Complex r = __divtc3(a, b, c, d);
+// printf("test__divtc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
+// a, b, c, d, creall(r), cimagl(r));
+
+ long double _Complex dividend;
+ long double _Complex divisor;
+
+ __real__ dividend = a;
+ __imag__ dividend = b;
+ __real__ divisor = c;
+ __imag__ divisor = d;
+
+ switch (classify(dividend))
+ {
+ case zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != non_zero)
+ return 1;
+ {
+ long double _Complex z = (a * c + b * d) / (c * c + d * d)
+ + (b * c - a * d) / (c * c + d * d) * _Complex_I;
+ if (cabs((r - z)/r) > 1.e-6)
+ return 1;
+ }
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case inf:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case NaN:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero_nan:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+long double x[][2] =
+{
+ { 1.e-6, 1.e-6},
+ {-1.e-6, 1.e-6},
+ {-1.e-6, -1.e-6},
+ { 1.e-6, -1.e-6},
+
+ { 1.e+6, 1.e-6},
+ {-1.e+6, 1.e-6},
+ {-1.e+6, -1.e-6},
+ { 1.e+6, -1.e-6},
+
+ { 1.e-6, 1.e+6},
+ {-1.e-6, 1.e+6},
+ {-1.e-6, -1.e+6},
+ { 1.e-6, -1.e+6},
+
+ { 1.e+6, 1.e+6},
+ {-1.e+6, 1.e+6},
+ {-1.e+6, -1.e+6},
+ { 1.e+6, -1.e+6},
+
+ {NAN, NAN},
+ {-INFINITY, NAN},
+ {-2, NAN},
+ {-1, NAN},
+ {-0.5, NAN},
+ {-0., NAN},
+ {+0., NAN},
+ {0.5, NAN},
+ {1, NAN},
+ {2, NAN},
+ {INFINITY, NAN},
+
+ {NAN, -INFINITY},
+ {-INFINITY, -INFINITY},
+ {-2, -INFINITY},
+ {-1, -INFINITY},
+ {-0.5, -INFINITY},
+ {-0., -INFINITY},
+ {+0., -INFINITY},
+ {0.5, -INFINITY},
+ {1, -INFINITY},
+ {2, -INFINITY},
+ {INFINITY, -INFINITY},
+
+ {NAN, -2},
+ {-INFINITY, -2},
+ {-2, -2},
+ {-1, -2},
+ {-0.5, -2},
+ {-0., -2},
+ {+0., -2},
+ {0.5, -2},
+ {1, -2},
+ {2, -2},
+ {INFINITY, -2},
+
+ {NAN, -1},
+ {-INFINITY, -1},
+ {-2, -1},
+ {-1, -1},
+ {-0.5, -1},
+ {-0., -1},
+ {+0., -1},
+ {0.5, -1},
+ {1, -1},
+ {2, -1},
+ {INFINITY, -1},
+
+ {NAN, -0.5},
+ {-INFINITY, -0.5},
+ {-2, -0.5},
+ {-1, -0.5},
+ {-0.5, -0.5},
+ {-0., -0.5},
+ {+0., -0.5},
+ {0.5, -0.5},
+ {1, -0.5},
+ {2, -0.5},
+ {INFINITY, -0.5},
+
+ {NAN, -0.},
+ {-INFINITY, -0.},
+ {-2, -0.},
+ {-1, -0.},
+ {-0.5, -0.},
+ {-0., -0.},
+ {+0., -0.},
+ {0.5, -0.},
+ {1, -0.},
+ {2, -0.},
+ {INFINITY, -0.},
+
+ {NAN, 0.},
+ {-INFINITY, 0.},
+ {-2, 0.},
+ {-1, 0.},
+ {-0.5, 0.},
+ {-0., 0.},
+ {+0., 0.},
+ {0.5, 0.},
+ {1, 0.},
+ {2, 0.},
+ {INFINITY, 0.},
+
+ {NAN, 0.5},
+ {-INFINITY, 0.5},
+ {-2, 0.5},
+ {-1, 0.5},
+ {-0.5, 0.5},
+ {-0., 0.5},
+ {+0., 0.5},
+ {0.5, 0.5},
+ {1, 0.5},
+ {2, 0.5},
+ {INFINITY, 0.5},
+
+ {NAN, 1},
+ {-INFINITY, 1},
+ {-2, 1},
+ {-1, 1},
+ {-0.5, 1},
+ {-0., 1},
+ {+0., 1},
+ {0.5, 1},
+ {1, 1},
+ {2, 1},
+ {INFINITY, 1},
+
+ {NAN, 2},
+ {-INFINITY, 2},
+ {-2, 2},
+ {-1, 2},
+ {-0.5, 2},
+ {-0., 2},
+ {+0., 2},
+ {0.5, 2},
+ {1, 2},
+ {2, 2},
+ {INFINITY, 2},
+
+ {NAN, INFINITY},
+ {-INFINITY, INFINITY},
+ {-2, INFINITY},
+ {-1, INFINITY},
+ {-0.5, INFINITY},
+ {-0., INFINITY},
+ {+0., INFINITY},
+ {0.5, INFINITY},
+ {1, INFINITY},
+ {2, INFINITY},
+ {INFINITY, INFINITY}
+
+};
+
+#endif
+
+int main()
+{
+#if _ARCH_PPC
+ const unsigned N = sizeof(x) / sizeof(x[0]);
+ unsigned i, j;
+ for (i = 0; i < N; ++i)
+ {
+ for (j = 0; j < N; ++j)
+ {
+ if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1]))
+ return 1;
+ }
+ }
+
+// printf("No errors found.\n");
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/divti3_test.c b/test/Unit/divti3_test.c
new file mode 100644
index 000000000..891927bb0
--- /dev/null
+++ b/test/Unit/divti3_test.c
@@ -0,0 +1,76 @@
+//===-- divti3_test.c - Test __divti3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divti3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: a / b
+
+ti_int __divti3(ti_int a, ti_int b);
+
+int test__divti3(ti_int a, ti_int b, ti_int expected)
+{
+ ti_int x = __divti3(a, b);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ twords bt;
+ bt.all = b;
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in __divti3: 0x%llX%.16llX / 0x%llX%.16llX = "
+ "0x%llX%.16llX, expected 0x%llX%.16llX\n",
+ at.high, at.low, bt.high, bt.low, xt.high, xt.low,
+ expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__divti3(0, 1, 0))
+ return 1;
+ if (test__divti3(0, -1, 0))
+ return 1;
+
+ if (test__divti3(2, 1, 2))
+ return 1;
+ if (test__divti3(2, -1, -2))
+ return 1;
+ if (test__divti3(-2, 1, -2))
+ return 1;
+ if (test__divti3(-2, -1, 2))
+ return 1;
+
+ if (test__divti3(make_ti(0x8000000000000000LL, 0), 1, make_ti(0x8000000000000000LL, 0)))
+ return 1;
+ if (test__divti3(make_ti(0x8000000000000000LL, 0), -1, make_ti(0x8000000000000000LL, 0)))
+ return 1;
+ if (test__divti3(make_ti(0x8000000000000000LL, 0), -2, make_ti(0x4000000000000000LL, 0)))
+ return 1;
+ if (test__divti3(make_ti(0x8000000000000000LL, 0), 2, make_ti(0xC000000000000000LL, 0)))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/divxc3_test.c b/test/Unit/divxc3_test.c
new file mode 100644
index 000000000..6c64d342e
--- /dev/null
+++ b/test/Unit/divxc3_test.c
@@ -0,0 +1,377 @@
+//===-- divxc3_test.c - Test __divxc3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divxc3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+#include <stdio.h>
+
+// Returns: the quotient of (a + ib) / (c + id)
+
+long double _Complex
+__divxc3(long double __a, long double __b, long double __c, long double __d);
+
+enum {zero, non_zero, inf, NaN, non_zero_nan};
+
+int
+classify(long double _Complex x)
+{
+ if (x == 0)
+ return zero;
+ if (isinf(creall(x)) || isinf(cimagl(x)))
+ return inf;
+ if (isnan(creall(x)) && isnan(cimagl(x)))
+ return NaN;
+ if (isnan(creall(x)))
+ {
+ if (cimagl(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ if (isnan(cimagl(x)))
+ {
+ if (creall(x) == 0)
+ return NaN;
+ return non_zero_nan;
+ }
+ return non_zero;
+}
+
+int test__divxc3(long double a, long double b, long double c, long double d)
+{
+ long double _Complex r = __divxc3(a, b, c, d);
+// printf("test__divxc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
+// a, b, c, d, creall(r), cimagl(r));
+ long double _Complex dividend;
+ long double _Complex divisor;
+
+ __real__ dividend = a;
+ __imag__ dividend = b;
+ __real__ divisor = c;
+ __imag__ divisor = d;
+
+ switch (classify(dividend))
+ {
+ case zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != non_zero)
+ return 1;
+ {
+ long double _Complex z = (a * c + b * d) / (c * c + d * d)
+ + (b * c - a * d) / (c * c + d * d) * _Complex_I;
+ if (cabs((r - z)/r) > 1.e-6)
+ return 1;
+ }
+ break;
+ case inf:
+ if (classify(r) != zero)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case inf:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case NaN:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ case non_zero_nan:
+ switch (classify(divisor))
+ {
+ case zero:
+ if (classify(r) != inf)
+ return 1;
+ break;
+ case non_zero:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case inf:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case NaN:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ case non_zero_nan:
+ if (classify(r) != NaN)
+ return 1;
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+long double x[][2] =
+{
+ { 1.e-6, 1.e-6},
+ {-1.e-6, 1.e-6},
+ {-1.e-6, -1.e-6},
+ { 1.e-6, -1.e-6},
+
+ { 1.e+6, 1.e-6},
+ {-1.e+6, 1.e-6},
+ {-1.e+6, -1.e-6},
+ { 1.e+6, -1.e-6},
+
+ { 1.e-6, 1.e+6},
+ {-1.e-6, 1.e+6},
+ {-1.e-6, -1.e+6},
+ { 1.e-6, -1.e+6},
+
+ { 1.e+6, 1.e+6},
+ {-1.e+6, 1.e+6},
+ {-1.e+6, -1.e+6},
+ { 1.e+6, -1.e+6},
+
+ {NAN, NAN},
+ {-INFINITY, NAN},
+ {-2, NAN},
+ {-1, NAN},
+ {-0.5, NAN},
+ {-0., NAN},
+ {+0., NAN},
+ {0.5, NAN},
+ {1, NAN},
+ {2, NAN},
+ {INFINITY, NAN},
+
+ {NAN, -INFINITY},
+ {-INFINITY, -INFINITY},
+ {-2, -INFINITY},
+ {-1, -INFINITY},
+ {-0.5, -INFINITY},
+ {-0., -INFINITY},
+ {+0., -INFINITY},
+ {0.5, -INFINITY},
+ {1, -INFINITY},
+ {2, -INFINITY},
+ {INFINITY, -INFINITY},
+
+ {NAN, -2},
+ {-INFINITY, -2},
+ {-2, -2},
+ {-1, -2},
+ {-0.5, -2},
+ {-0., -2},
+ {+0., -2},
+ {0.5, -2},
+ {1, -2},
+ {2, -2},
+ {INFINITY, -2},
+
+ {NAN, -1},
+ {-INFINITY, -1},
+ {-2, -1},
+ {-1, -1},
+ {-0.5, -1},
+ {-0., -1},
+ {+0., -1},
+ {0.5, -1},
+ {1, -1},
+ {2, -1},
+ {INFINITY, -1},
+
+ {NAN, -0.5},
+ {-INFINITY, -0.5},
+ {-2, -0.5},
+ {-1, -0.5},
+ {-0.5, -0.5},
+ {-0., -0.5},
+ {+0., -0.5},
+ {0.5, -0.5},
+ {1, -0.5},
+ {2, -0.5},
+ {INFINITY, -0.5},
+
+ {NAN, -0.},
+ {-INFINITY, -0.},
+ {-2, -0.},
+ {-1, -0.},
+ {-0.5, -0.},
+ {-0., -0.},
+ {+0., -0.},
+ {0.5, -0.},
+ {1, -0.},
+ {2, -0.},
+ {INFINITY, -0.},
+
+ {NAN, 0.},
+ {-INFINITY, 0.},
+ {-2, 0.},
+ {-1, 0.},
+ {-0.5, 0.},
+ {-0., 0.},
+ {+0., 0.},
+ {0.5, 0.},
+ {1, 0.},
+ {2, 0.},
+ {INFINITY, 0.},
+
+ {NAN, 0.5},
+ {-INFINITY, 0.5},
+ {-2, 0.5},
+ {-1, 0.5},
+ {-0.5, 0.5},
+ {-0., 0.5},
+ {+0., 0.5},
+ {0.5, 0.5},
+ {1, 0.5},
+ {2, 0.5},
+ {INFINITY, 0.5},
+
+ {NAN, 1},
+ {-INFINITY, 1},
+ {-2, 1},
+ {-1, 1},
+ {-0.5, 1},
+ {-0., 1},
+ {+0., 1},
+ {0.5, 1},
+ {1, 1},
+ {2, 1},
+ {INFINITY, 1},
+
+ {NAN, 2},
+ {-INFINITY, 2},
+ {-2, 2},
+ {-1, 2},
+ {-0.5, 2},
+ {-0., 2},
+ {+0., 2},
+ {0.5, 2},
+ {1, 2},
+ {2, 2},
+ {INFINITY, 2},
+
+ {NAN, INFINITY},
+ {-INFINITY, INFINITY},
+ {-2, INFINITY},
+ {-1, INFINITY},
+ {-0.5, INFINITY},
+ {-0., INFINITY},
+ {+0., INFINITY},
+ {0.5, INFINITY},
+ {1, INFINITY},
+ {2, INFINITY},
+ {INFINITY, INFINITY}
+
+};
+
+#endif
+
+int main()
+{
+#if !_ARCH_PPC
+ const unsigned N = sizeof(x) / sizeof(x[0]);
+ unsigned i, j;
+ for (i = 0; i < N; ++i)
+ {
+ for (j = 0; j < N; ++j)
+ {
+ if (test__divxc3(x[i][0], x[i][1], x[j][0], x[j][1]))
+ return 1;
+ }
+ }
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/enable_execute_stack_test.c b/test/Unit/enable_execute_stack_test.c
new file mode 100644
index 000000000..2e0a6c227
--- /dev/null
+++ b/test/Unit/enable_execute_stack_test.c
@@ -0,0 +1,57 @@
+//===-- enable_execute_stack_test.c - Test __enable_execute_stack ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/mman.h>
+
+
+
+extern void __clear_cache(void* start, void* end);
+extern void __enable_execute_stack(void* addr);
+
+typedef int (*pfunc)(void);
+
+int func1()
+{
+ return 1;
+}
+
+int func2()
+{
+ return 2;
+}
+
+
+
+
+int main()
+{
+ unsigned char execution_buffer[128];
+ // mark stack page containing execution_buffer to be executable
+ __enable_execute_stack(execution_buffer);
+
+ // verify you can copy and execute a function
+ memcpy(execution_buffer, &func1, 128);
+ __clear_cache(execution_buffer, &execution_buffer[128]);
+ pfunc f1 = (pfunc)execution_buffer;
+ if ( (*f1)() != 1 )
+ return 1;
+
+ // verify you can overwrite a function with another
+ memcpy(execution_buffer, &func2, 128);
+ __clear_cache(execution_buffer, &execution_buffer[128]);
+ pfunc f2 = (pfunc)execution_buffer;
+ if ( (*f2)() != 2 )
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/ffsdi2_test.c b/test/Unit/ffsdi2_test.c
new file mode 100644
index 000000000..8713c4f6a
--- /dev/null
+++ b/test/Unit/ffsdi2_test.c
@@ -0,0 +1,66 @@
+//===-- ffsdi2_test.c - Test __ffsdi2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ffsdi2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the index of the least significant 1-bit in a, or
+// the value zero if a is zero. The least significant bit is index one.
+
+si_int __ffsdi2(di_int a);
+
+int test__ffsdi2(di_int a, si_int expected)
+{
+ si_int x = __ffsdi2(a);
+ if (x != expected)
+ printf("error in __ffsdi2(0x%llX) = %d, expected %d\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+
+int main()
+{
+ if (test__ffsdi2(0x00000000, 0))
+ return 1;
+ if (test__ffsdi2(0x00000001, 1))
+ return 1;
+ if (test__ffsdi2(0x00000002, 2))
+ return 1;
+ if (test__ffsdi2(0x00000003, 1))
+ return 1;
+ if (test__ffsdi2(0x00000004, 3))
+ return 1;
+ if (test__ffsdi2(0x00000005, 1))
+ return 1;
+ if (test__ffsdi2(0x0000000A, 2))
+ return 1;
+ if (test__ffsdi2(0x10000000, 29))
+ return 1;
+ if (test__ffsdi2(0x20000000, 30))
+ return 1;
+ if (test__ffsdi2(0x60000000, 30))
+ return 1;
+ if (test__ffsdi2(0x80000000uLL, 32))
+ return 1;
+ if (test__ffsdi2(0x0000050000000000uLL, 41))
+ return 1;
+ if (test__ffsdi2(0x0200080000000000uLL, 44))
+ return 1;
+ if (test__ffsdi2(0x7200000000000000uLL, 58))
+ return 1;
+ if (test__ffsdi2(0x8000000000000000uLL, 64))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/ffsti2_test.c b/test/Unit/ffsti2_test.c
new file mode 100644
index 000000000..5d9b7d5be
--- /dev/null
+++ b/test/Unit/ffsti2_test.c
@@ -0,0 +1,81 @@
+//===-- ffsti2_test.c - Test __ffsti2 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __ffsti2 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: the index of the least significant 1-bit in a, or
+// the value zero if a is zero. The least significant bit is index one.
+
+si_int __ffsti2(ti_int a);
+
+int test__ffsti2(ti_int a, si_int expected)
+{
+ si_int x = __ffsti2(a);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ printf("error in __ffsti2(0x%llX%.16llX) = %d, expected %d\n",
+ at.high, at.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__ffsti2(0x00000000, 0))
+ return 1;
+ if (test__ffsti2(0x00000001, 1))
+ return 1;
+ if (test__ffsti2(0x00000002, 2))
+ return 1;
+ if (test__ffsti2(0x00000003, 1))
+ return 1;
+ if (test__ffsti2(0x00000004, 3))
+ return 1;
+ if (test__ffsti2(0x00000005, 1))
+ return 1;
+ if (test__ffsti2(0x0000000A, 2))
+ return 1;
+ if (test__ffsti2(0x10000000, 29))
+ return 1;
+ if (test__ffsti2(0x20000000, 30))
+ return 1;
+ if (test__ffsti2(0x60000000, 30))
+ return 1;
+ if (test__ffsti2(0x80000000uLL, 32))
+ return 1;
+ if (test__ffsti2(0x0000050000000000uLL, 41))
+ return 1;
+ if (test__ffsti2(0x0200080000000000uLL, 44))
+ return 1;
+ if (test__ffsti2(0x7200000000000000uLL, 58))
+ return 1;
+ if (test__ffsti2(0x8000000000000000uLL, 64))
+ return 1;
+ if (test__ffsti2(make_ti(0x8000000800000000uLL, 0), 100))
+ return 1;
+ if (test__ffsti2(make_ti(0x8000000000000000uLL, 0), 128))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixdfdi_test.c b/test/Unit/fixdfdi_test.c
new file mode 100644
index 000000000..d84d26d4b
--- /dev/null
+++ b/test/Unit/fixdfdi_test.c
@@ -0,0 +1,94 @@
+//===-- fixdfdi_test.c - Test __fixdfdi -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixdfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// su_int is a 32 bit integral type
+// value in double is representable in di_int (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+di_int __fixdfdi(double a);
+
+int test__fixdfdi(double a, di_int expected)
+{
+ di_int x = __fixdfdi(a);
+ if (x != expected)
+ printf("error in __fixdfdi(%A) = %llX, expected %llX\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+int main()
+{
+ if (test__fixdfdi(0.0, 0))
+ return 1;
+
+ if (test__fixdfdi(0.5, 0))
+ return 1;
+ if (test__fixdfdi(0.99, 0))
+ return 1;
+ if (test__fixdfdi(1.0, 1))
+ return 1;
+ if (test__fixdfdi(1.5, 1))
+ return 1;
+ if (test__fixdfdi(1.99, 1))
+ return 1;
+ if (test__fixdfdi(2.0, 2))
+ return 1;
+ if (test__fixdfdi(2.01, 2))
+ return 1;
+ if (test__fixdfdi(-0.5, 0))
+ return 1;
+ if (test__fixdfdi(-0.99, 0))
+ return 1;
+ if (test__fixdfdi(-1.0, -1))
+ return 1;
+ if (test__fixdfdi(-1.5, -1))
+ return 1;
+ if (test__fixdfdi(-1.99, -1))
+ return 1;
+ if (test__fixdfdi(-2.0, -2))
+ return 1;
+ if (test__fixdfdi(-2.01, -2))
+ return 1;
+
+ if (test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixdfdi(-0x1.FFFFFEp+62, 0x8000008000000000LL))
+ return 1;
+ if (test__fixdfdi(-0x1.FFFFFCp+62, 0x8000010000000000LL))
+ return 1;
+
+ if (test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, 0x8000000000000400LL))
+ return 1;
+ if (test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, 0x8000000000000800LL))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/fixdfti_test.c b/test/Unit/fixdfti_test.c
new file mode 100644
index 000000000..d8276f91e
--- /dev/null
+++ b/test/Unit/fixdfti_test.c
@@ -0,0 +1,121 @@
+//===-- fixdfti_test.c - Test __fixdfti -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixdfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// su_int is a 32 bit integral type
+// value in double is representable in ti_int (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+ti_int __fixdfti(double a);
+
+int test__fixdfti(double a, ti_int expected)
+{
+ ti_int x = __fixdfti(a);
+ if (x != expected)
+ {
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in __fixdfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ a, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__fixdfti(0.0, 0))
+ return 1;
+
+ if (test__fixdfti(0.5, 0))
+ return 1;
+ if (test__fixdfti(0.99, 0))
+ return 1;
+ if (test__fixdfti(1.0, 1))
+ return 1;
+ if (test__fixdfti(1.5, 1))
+ return 1;
+ if (test__fixdfti(1.99, 1))
+ return 1;
+ if (test__fixdfti(2.0, 2))
+ return 1;
+ if (test__fixdfti(2.01, 2))
+ return 1;
+ if (test__fixdfti(-0.5, 0))
+ return 1;
+ if (test__fixdfti(-0.99, 0))
+ return 1;
+ if (test__fixdfti(-1.0, -1))
+ return 1;
+ if (test__fixdfti(-1.5, -1))
+ return 1;
+ if (test__fixdfti(-1.99, -1))
+ return 1;
+ if (test__fixdfti(-2.0, -2))
+ return 1;
+ if (test__fixdfti(-2.01, -2))
+ return 1;
+
+ if (test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixdfti(-0x1.FFFFFEp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000008000000000LL)))
+ return 1;
+ if (test__fixdfti(-0x1.FFFFFCp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000010000000000LL)))
+ return 1;
+
+ if (test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000400LL)))
+ return 1;
+ if (test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000800LL)))
+ return 1;
+
+ if (test__fixdfti(0x1.FFFFFFFFFFFFFp+126, make_ti(0x7FFFFFFFFFFFFC00LL, 0)))
+ return 1;
+ if (test__fixdfti(0x1.FFFFFFFFFFFFEp+126, make_ti(0x7FFFFFFFFFFFF800LL, 0)))
+ return 1;
+
+ if (test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, make_ti(0x8000000000000400LL, 0)))
+ return 1;
+ if (test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, make_ti(0x8000000000000800LL, 0)))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixsfdi_test.c b/test/Unit/fixsfdi_test.c
new file mode 100644
index 000000000..434e1a9e0
--- /dev/null
+++ b/test/Unit/fixsfdi_test.c
@@ -0,0 +1,84 @@
+//===-- fixsfdi_test.c - Test __fixsfdi -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixsfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// su_int is a 32 bit integral type
+// value in float is representable in di_int (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+di_int __fixsfdi(float a);
+
+int test__fixsfdi(float a, di_int expected)
+{
+ di_int x = __fixsfdi(a);
+ if (x != expected)
+ printf("error in __fixsfdi(%A) = %llX, expected %llX\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+ if (test__fixsfdi(0.0F, 0))
+ return 1;
+
+ if (test__fixsfdi(0.5F, 0))
+ return 1;
+ if (test__fixsfdi(0.99F, 0))
+ return 1;
+ if (test__fixsfdi(1.0F, 1))
+ return 1;
+ if (test__fixsfdi(1.5F, 1))
+ return 1;
+ if (test__fixsfdi(1.99F, 1))
+ return 1;
+ if (test__fixsfdi(2.0F, 2))
+ return 1;
+ if (test__fixsfdi(2.01F, 2))
+ return 1;
+ if (test__fixsfdi(-0.5F, 0))
+ return 1;
+ if (test__fixsfdi(-0.99F, 0))
+ return 1;
+ if (test__fixsfdi(-1.0F, -1))
+ return 1;
+ if (test__fixsfdi(-1.5F, -1))
+ return 1;
+ if (test__fixsfdi(-1.99F, -1))
+ return 1;
+ if (test__fixsfdi(-2.0F, -2))
+ return 1;
+ if (test__fixsfdi(-2.01F, -2))
+ return 1;
+
+ if (test__fixsfdi(0x1.FFFFFEp+62F, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixsfdi(0x1.FFFFFCp+62F, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixsfdi(-0x1.FFFFFEp+62F, 0x8000008000000000LL))
+ return 1;
+ if (test__fixsfdi(-0x1.FFFFFCp+62F, 0x8000010000000000LL))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/fixsfti_test.c b/test/Unit/fixsfti_test.c
new file mode 100644
index 000000000..a8c0d563b
--- /dev/null
+++ b/test/Unit/fixsfti_test.c
@@ -0,0 +1,109 @@
+//===-- fixsfti_test.c - Test __fixsfti -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixsfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// su_int is a 32 bit integral type
+// value in float is representable in ti_int (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+ti_int __fixsfti(float a);
+
+int test__fixsfti(float a, ti_int expected)
+{
+ ti_int x = __fixsfti(a);
+ if (x != expected)
+ {
+ twords xt;
+ xt.all = x;
+ twords expectedt;
+ expectedt.all = expected;
+ printf("error in __fixsfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ a, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__fixsfti(0.0F, 0))
+ return 1;
+
+ if (test__fixsfti(0.5F, 0))
+ return 1;
+ if (test__fixsfti(0.99F, 0))
+ return 1;
+ if (test__fixsfti(1.0F, 1))
+ return 1;
+ if (test__fixsfti(1.5F, 1))
+ return 1;
+ if (test__fixsfti(1.99F, 1))
+ return 1;
+ if (test__fixsfti(2.0F, 2))
+ return 1;
+ if (test__fixsfti(2.01F, 2))
+ return 1;
+ if (test__fixsfti(-0.5F, 0))
+ return 1;
+ if (test__fixsfti(-0.99F, 0))
+ return 1;
+ if (test__fixsfti(-1.0F, -1))
+ return 1;
+ if (test__fixsfti(-1.5F, -1))
+ return 1;
+ if (test__fixsfti(-1.99F, -1))
+ return 1;
+ if (test__fixsfti(-2.0F, -2))
+ return 1;
+ if (test__fixsfti(-2.01F, -2))
+ return 1;
+
+ if (test__fixsfti(0x1.FFFFFEp+62F, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixsfti(0x1.FFFFFCp+62F, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixsfti(-0x1.FFFFFEp+62F, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000008000000000LL)))
+ return 1;
+ if (test__fixsfti(-0x1.FFFFFCp+62F, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000010000000000LL)))
+ return 1;
+
+ if (test__fixsfti(0x1.FFFFFEp+126F, make_ti(0x7FFFFF8000000000LL, 0)))
+ return 1;
+ if (test__fixsfti(0x1.FFFFFCp+126F, make_ti(0x7FFFFF0000000000LL, 0)))
+ return 1;
+
+ if (test__fixsfti(-0x1.FFFFFEp+126F, make_ti(0x8000008000000000LL, 0)))
+ return 1;
+ if (test__fixsfti(-0x1.FFFFFCp+126F, make_ti(0x8000010000000000LL, 0)))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixunsdfdi_test.c b/test/Unit/fixunsdfdi_test.c
new file mode 100644
index 000000000..fbdf3682f
--- /dev/null
+++ b/test/Unit/fixunsdfdi_test.c
@@ -0,0 +1,106 @@
+//===-- fixunsdfdi_test.c - Test __fixunsdfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunsdfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// du_int is a 64 bit integral type
+// value in double is representable in du_int or is negative
+// (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+du_int __fixunsdfdi(double a);
+
+int test__fixunsdfdi(double a, du_int expected)
+{
+ du_int x = __fixunsdfdi(a);
+ if (x != expected)
+ printf("error in __fixunsdfdi(%A) = %llX, expected %llX\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(du_int) == 2*sizeof(su_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+int main()
+{
+ if (test__fixunsdfdi(0.0, 0))
+ return 1;
+
+ if (test__fixunsdfdi(0.5, 0))
+ return 1;
+ if (test__fixunsdfdi(0.99, 0))
+ return 1;
+ if (test__fixunsdfdi(1.0, 1))
+ return 1;
+ if (test__fixunsdfdi(1.5, 1))
+ return 1;
+ if (test__fixunsdfdi(1.99, 1))
+ return 1;
+ if (test__fixunsdfdi(2.0, 2))
+ return 1;
+ if (test__fixunsdfdi(2.01, 2))
+ return 1;
+ if (test__fixunsdfdi(-0.5, 0))
+ return 1;
+ if (test__fixunsdfdi(-0.99, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunsdfdi(-1.0, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunsdfdi(-1.5, 0))
+ return 1;
+ if (test__fixunsdfdi(-1.99, 0))
+ return 1;
+ if (test__fixunsdfdi(-2.0, 0))
+ return 1;
+ if (test__fixunsdfdi(-2.01, 0))
+ return 1;
+#endif
+
+ if (test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunsdfdi(-0x1.FFFFFEp+62, 0))
+ return 1;
+ if (test__fixunsdfdi(-0x1.FFFFFCp+62, 0))
+ return 1;
+#endif
+
+ if (test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800LL))
+ return 1;
+ if (test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0))
+ return 1;
+ if (test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0))
+ return 1;
+#endif
+
+ return 0;
+}
diff --git a/test/Unit/fixunsdfsi_test.c b/test/Unit/fixunsdfsi_test.c
new file mode 100644
index 000000000..9e6b95d55
--- /dev/null
+++ b/test/Unit/fixunsdfsi_test.c
@@ -0,0 +1,100 @@
+//===-- fixunsdfsi_test.c - Test __fixunsdfsi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunsdfsi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned int, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// su_int is a 32 bit integral type
+// value in double is representable in su_int or is negative
+// (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+su_int __fixunsdfsi(double a);
+
+int test__fixunsdfsi(double a, su_int expected)
+{
+ su_int x = __fixunsdfsi(a);
+ if (x != expected)
+ printf("error in __fixunsdfsi(%A) = %X, expected %X\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+int main()
+{
+ if (test__fixunsdfsi(0.0, 0))
+ return 1;
+
+ if (test__fixunsdfsi(0.5, 0))
+ return 1;
+ if (test__fixunsdfsi(0.99, 0))
+ return 1;
+ if (test__fixunsdfsi(1.0, 1))
+ return 1;
+ if (test__fixunsdfsi(1.5, 1))
+ return 1;
+ if (test__fixunsdfsi(1.99, 1))
+ return 1;
+ if (test__fixunsdfsi(2.0, 2))
+ return 1;
+ if (test__fixunsdfsi(2.01, 2))
+ return 1;
+ if (test__fixunsdfsi(-0.5, 0))
+ return 1;
+ if (test__fixunsdfsi(-0.99, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunsdfsi(-1.0, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunsdfsi(-1.5, 0))
+ return 1;
+ if (test__fixunsdfsi(-1.99, 0))
+ return 1;
+ if (test__fixunsdfsi(-2.0, 0))
+ return 1;
+ if (test__fixunsdfsi(-2.01, 0))
+ return 1;
+#endif
+
+ if (test__fixunsdfsi(0x1.000000p+31, 0x80000000))
+ return 1;
+ if (test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00))
+ return 1;
+ if (test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80))
+ return 1;
+ if (test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunsdfsi(-0x1.FFFFFEp+30, 0))
+ return 1;
+ if (test__fixunsdfsi(-0x1.FFFFFCp+30, 0))
+ return 1;
+#endif
+
+ if (test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF))
+ return 1;
+ if (test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF))
+ return 1;
+ if (test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/fixunsdfti_test.c b/test/Unit/fixunsdfti_test.c
new file mode 100644
index 000000000..24452b348
--- /dev/null
+++ b/test/Unit/fixunsdfti_test.c
@@ -0,0 +1,128 @@
+//===-- fixunsdfti_test.c - Test __fixunsdfti -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunsdfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// tu_int is a 64 bit integral type
+// value in double is representable in tu_int or is negative
+// (no range checking performed)
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+#if __x86_64
+
+tu_int __fixunsdfti(double a);
+
+int test__fixunsdfti(double a, tu_int expected)
+{
+ tu_int x = __fixunsdfti(a);
+ if (x != expected)
+ {
+ utwords xt;
+ xt.all = x;
+ utwords expectedt;
+ expectedt.all = expected;
+ printf("error in __fixunsdfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ a, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(tu_int) == 2*sizeof(du_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__fixunsdfti(0.0, 0))
+ return 1;
+
+ if (test__fixunsdfti(0.5, 0))
+ return 1;
+ if (test__fixunsdfti(0.99, 0))
+ return 1;
+ if (test__fixunsdfti(1.0, 1))
+ return 1;
+ if (test__fixunsdfti(1.5, 1))
+ return 1;
+ if (test__fixunsdfti(1.99, 1))
+ return 1;
+ if (test__fixunsdfti(2.0, 2))
+ return 1;
+ if (test__fixunsdfti(2.01, 2))
+ return 1;
+ if (test__fixunsdfti(-0.5, 0))
+ return 1;
+ if (test__fixunsdfti(-0.99, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunsdfti(-1.0, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunsdfti(-1.5, 0))
+ return 1;
+ if (test__fixunsdfti(-1.99, 0))
+ return 1;
+ if (test__fixunsdfti(-2.0, 0))
+ return 1;
+ if (test__fixunsdfti(-2.01, 0))
+ return 1;
+#endif
+
+ if (test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunsdfti(-0x1.FFFFFEp+62, 0))
+ return 1;
+ if (test__fixunsdfti(-0x1.FFFFFCp+62, 0))
+ return 1;
+#endif
+
+ if (test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800LL))
+ return 1;
+ if (test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, make_ti(0xFFFFFFFFFFFFF800LL, 0)))
+ return 1;
+ if (test__fixunsdfti(0x1.0000000000000p+127, make_ti(0x8000000000000000LL, 0)))
+ return 1;
+ if (test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, make_ti(0x7FFFFFFFFFFFFC00LL, 0)))
+ return 1;
+ if (test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, make_ti(0x7FFFFFFFFFFFF800LL, 0)))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0))
+ return 1;
+ if (test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0))
+ return 1;
+#endif
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixunssfdi_test.c b/test/Unit/fixunssfdi_test.c
new file mode 100644
index 000000000..cde3c22a7
--- /dev/null
+++ b/test/Unit/fixunssfdi_test.c
@@ -0,0 +1,95 @@
+//===-- fixunssfdi_test.c - Test __fixunssfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunssfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// du_int is a 64 bit integral type
+// value in float is representable in du_int or is negative
+// (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+du_int __fixunssfdi(float a);
+
+int test__fixunssfdi(float a, du_int expected)
+{
+ du_int x = __fixunssfdi(a);
+ if (x != expected)
+ printf("error in __fixunssfdi(%A) = %llX, expected %llX\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(du_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+ if (test__fixunssfdi(0.0F, 0))
+ return 1;
+
+ if (test__fixunssfdi(0.5F, 0))
+ return 1;
+ if (test__fixunssfdi(0.99F, 0))
+ return 1;
+ if (test__fixunssfdi(1.0F, 1))
+ return 1;
+ if (test__fixunssfdi(1.5F, 1))
+ return 1;
+ if (test__fixunssfdi(1.99F, 1))
+ return 1;
+ if (test__fixunssfdi(2.0F, 2))
+ return 1;
+ if (test__fixunssfdi(2.01F, 2))
+ return 1;
+ if (test__fixunssfdi(-0.5F, 0))
+ return 1;
+ if (test__fixunssfdi(-0.99F, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunssfdi(-1.0F, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunssfdi(-1.5F, 0))
+ return 1;
+ if (test__fixunssfdi(-1.99F, 0))
+ return 1;
+ if (test__fixunssfdi(-2.0F, 0))
+ return 1;
+ if (test__fixunssfdi(-2.01F, 0))
+ return 1;
+#endif
+
+ if (test__fixunssfdi(0x1.FFFFFEp+63F, 0xFFFFFF0000000000LL))
+ return 1;
+ if (test__fixunssfdi(0x1.000000p+63F, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunssfdi(0x1.FFFFFEp+62F, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunssfdi(0x1.FFFFFCp+62F, 0x7FFFFF0000000000LL))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunssfdi(-0x1.FFFFFEp+62F, 0x0000000000000000LL))
+ return 1;
+ if (test__fixunssfdi(-0x1.FFFFFCp+62F, 0x0000000000000000LL))
+ return 1;
+#endif
+
+ return 0;
+}
diff --git a/test/Unit/fixunssfsi_test.c b/test/Unit/fixunssfsi_test.c
new file mode 100644
index 000000000..c8995b08a
--- /dev/null
+++ b/test/Unit/fixunssfsi_test.c
@@ -0,0 +1,93 @@
+//===-- fixunssfsi_test.c - Test __fixunssfsi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunssfsi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned int, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// su_int is a 32 bit integral type
+// value in float is representable in su_int or is negative
+// (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+su_int __fixunssfsi(float a);
+
+int test__fixunssfsi(float a, su_int expected)
+{
+ su_int x = __fixunssfsi(a);
+ if (x != expected)
+ printf("error in __fixunssfsi(%A) = %X, expected %X\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+ if (test__fixunssfsi(0.0F, 0))
+ return 1;
+
+ if (test__fixunssfsi(0.5F, 0))
+ return 1;
+ if (test__fixunssfsi(0.99F, 0))
+ return 1;
+ if (test__fixunssfsi(1.0F, 1))
+ return 1;
+ if (test__fixunssfsi(1.5F, 1))
+ return 1;
+ if (test__fixunssfsi(1.99F, 1))
+ return 1;
+ if (test__fixunssfsi(2.0F, 2))
+ return 1;
+ if (test__fixunssfsi(2.01F, 2))
+ return 1;
+ if (test__fixunssfsi(-0.5F, 0))
+ return 1;
+ if (test__fixunssfsi(-0.99F, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunssfsi(-1.0F, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunssfsi(-1.5F, 0))
+ return 1;
+ if (test__fixunssfsi(-1.99F, 0))
+ return 1;
+ if (test__fixunssfsi(-2.0F, 0))
+ return 1;
+ if (test__fixunssfsi(-2.01F, 0))
+ return 1;
+#endif
+
+ if (test__fixunssfsi(0x1.000000p+31F, 0x80000000))
+ return 1;
+ if (test__fixunssfsi(0x1.FFFFFEp+31F, 0xFFFFFF00))
+ return 1;
+ if (test__fixunssfsi(0x1.FFFFFEp+30F, 0x7FFFFF80))
+ return 1;
+ if (test__fixunssfsi(0x1.FFFFFCp+30F, 0x7FFFFF00))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunssfsi(-0x1.FFFFFEp+30F, 0))
+ return 1;
+ if (test__fixunssfsi(-0x1.FFFFFCp+30F, 0))
+ return 1;
+#endif
+
+ return 0;
+}
diff --git a/test/Unit/fixunssfti_test.c b/test/Unit/fixunssfti_test.c
new file mode 100644
index 000000000..39bef8b33
--- /dev/null
+++ b/test/Unit/fixunssfti_test.c
@@ -0,0 +1,120 @@
+//===-- fixunssfti_test.c - Test __fixunssfti -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunssfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// tu_int is a 64 bit integral type
+// value in float is representable in tu_int or is negative
+// (no range checking performed)
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+tu_int __fixunssfti(float a);
+
+int test__fixunssfti(float a, tu_int expected)
+{
+ tu_int x = __fixunssfti(a);
+ if (x != expected)
+ {
+ utwords xt;
+ xt.all = x;
+ utwords expectedt;
+ expectedt.all = expected;
+ printf("error in __fixunssfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ a, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(tu_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__fixunssfti(0.0F, 0))
+ return 1;
+
+ if (test__fixunssfti(0.5F, 0))
+ return 1;
+ if (test__fixunssfti(0.99F, 0))
+ return 1;
+ if (test__fixunssfti(1.0F, 1))
+ return 1;
+ if (test__fixunssfti(1.5F, 1))
+ return 1;
+ if (test__fixunssfti(1.99F, 1))
+ return 1;
+ if (test__fixunssfti(2.0F, 2))
+ return 1;
+ if (test__fixunssfti(2.01F, 2))
+ return 1;
+ if (test__fixunssfti(-0.5F, 0))
+ return 1;
+ if (test__fixunssfti(-0.99F, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunssfti(-1.0F, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunssfti(-1.5F, 0))
+ return 1;
+ if (test__fixunssfti(-1.99F, 0))
+ return 1;
+ if (test__fixunssfti(-2.0F, 0))
+ return 1;
+ if (test__fixunssfti(-2.01F, 0))
+ return 1;
+#endif
+
+ if (test__fixunssfti(0x1.FFFFFEp+63F, 0xFFFFFF0000000000LL))
+ return 1;
+ if (test__fixunssfti(0x1.000000p+63F, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunssfti(0x1.FFFFFEp+62F, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunssfti(0x1.FFFFFCp+62F, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixunssfti(0x1.FFFFFEp+127F, make_ti(0xFFFFFF0000000000LL, 0)))
+ return 1;
+ if (test__fixunssfti(0x1.000000p+127F, make_ti(0x8000000000000000LL, 0)))
+ return 1;
+ if (test__fixunssfti(0x1.FFFFFEp+126F, make_ti(0x7FFFFF8000000000LL, 0)))
+ return 1;
+ if (test__fixunssfti(0x1.FFFFFCp+126F, make_ti(0x7FFFFF0000000000LL, 0)))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunssfti(-0x1.FFFFFEp+62F, 0x0000000000000000LL))
+ return 1;
+ if (test__fixunssfti(-0x1.FFFFFCp+62F, 0x0000000000000000LL))
+ return 1;
+ if (test__fixunssfti(-0x1.FFFFFEp+126F, 0x0000000000000000LL))
+ return 1;
+ if (test__fixunssfti(-0x1.FFFFFCp+126F, 0x0000000000000000LL))
+ return 1;
+#endif
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixunstfdi_test.c b/test/Unit/fixunstfdi_test.c
new file mode 100644
index 000000000..d96b0ea29
--- /dev/null
+++ b/test/Unit/fixunstfdi_test.c
@@ -0,0 +1,119 @@
+//===-- fixunstfdi_test.c - Test __fixunstfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunstfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if _ARCH_PPC
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is a ppc 128 bit floating point type
+// du_int is a 64 bit integral type
+// value in long double is representable in du_int or is negative
+// (no range checking performed)
+
+du_int __fixunstfdi(long double a);
+
+int test__fixunstfdi(long double a, du_int expected)
+{
+ du_int x = __fixunstfdi(a);
+ if (x != expected)
+ printf("error in __fixunstfdi(%LA) = %llX, expected %llX\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(du_int) == 2*sizeof(su_int)] = {0};
+char assumption_2[sizeof(du_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if _ARCH_PPC
+ if (test__fixunstfdi(0.0, 0))
+ return 1;
+
+ if (test__fixunstfdi(0.5, 0))
+ return 1;
+ if (test__fixunstfdi(0.99, 0))
+ return 1;
+ if (test__fixunstfdi(1.0, 1))
+ return 1;
+ if (test__fixunstfdi(1.5, 1))
+ return 1;
+ if (test__fixunstfdi(1.99, 1))
+ return 1;
+ if (test__fixunstfdi(2.0, 2))
+ return 1;
+ if (test__fixunstfdi(2.01, 2))
+ return 1;
+ if (test__fixunstfdi(-0.5, 0))
+ return 1;
+ if (test__fixunstfdi(-0.99, 0))
+ return 1;
+ if (test__fixunstfdi(-1.0, 0))
+ return 1;
+ if (test__fixunstfdi(-1.5, 0))
+ return 1;
+ if (test__fixunstfdi(-1.99, 0))
+ return 1;
+ if (test__fixunstfdi(-2.0, 0))
+ return 1;
+ if (test__fixunstfdi(-2.01, 0))
+ return 1;
+
+ if (test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixunstfdi(-0x1.FFFFFEp+62, 0))
+ return 1;
+ if (test__fixunstfdi(-0x1.FFFFFCp+62, 0))
+ return 1;
+
+ if (test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0))
+ return 1;
+ if (test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0))
+ return 1;
+
+ if (test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63L, 0xFFFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixunstfdi(0x1.0000000000000002p+63L, 0x8000000000000001LL))
+ return 1;
+ if (test__fixunstfdi(0x1.0000000000000000p+63L, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62L, 0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62L, 0x7FFFFFFFFFFFFFFELL))
+ return 1;
+
+ if (test__fixunstfdi(-0x1.0000000000000000p+63L, 0))
+ return 1;
+ if (test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62L, 0))
+ return 1;
+ if (test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62L, 0))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixunsxfdi_test.c b/test/Unit/fixunsxfdi_test.c
new file mode 100644
index 000000000..c839a361a
--- /dev/null
+++ b/test/Unit/fixunsxfdi_test.c
@@ -0,0 +1,122 @@
+//===-- fixunsxfdi_test.c - Test __fixunsxfdi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunsxfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// du_int is a 64 bit integral type
+// value in long double is representable in du_int or is negative
+// (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+du_int __fixunsxfdi(long double a);
+
+int test__fixunsxfdi(long double a, du_int expected)
+{
+ du_int x = __fixunsxfdi(a);
+ if (x != expected)
+ printf("error in __fixunsxfdi(%LA) = %llX, expected %llX\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(du_int) == 2*sizeof(su_int)] = {0};
+char assumption_2[sizeof(du_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if !_ARCH_PPC
+ if (test__fixunsxfdi(0.0, 0))
+ return 1;
+
+ if (test__fixunsxfdi(0.5, 0))
+ return 1;
+ if (test__fixunsxfdi(0.99, 0))
+ return 1;
+ if (test__fixunsxfdi(1.0, 1))
+ return 1;
+ if (test__fixunsxfdi(1.5, 1))
+ return 1;
+ if (test__fixunsxfdi(1.99, 1))
+ return 1;
+ if (test__fixunsxfdi(2.0, 2))
+ return 1;
+ if (test__fixunsxfdi(2.01, 2))
+ return 1;
+ if (test__fixunsxfdi(-0.5, 0))
+ return 1;
+ if (test__fixunsxfdi(-0.99, 0))
+ return 1;
+ if (test__fixunsxfdi(-1.0, 0))
+ return 1;
+ if (test__fixunsxfdi(-1.5, 0))
+ return 1;
+ if (test__fixunsxfdi(-1.99, 0))
+ return 1;
+ if (test__fixunsxfdi(-2.0, 0))
+ return 1;
+ if (test__fixunsxfdi(-2.01, 0))
+ return 1;
+
+ if (test__fixunsxfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunsxfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixunsxfdi(-0x1.FFFFFEp+62, 0))
+ return 1;
+ if (test__fixunsxfdi(-0x1.FFFFFCp+62, 0))
+ return 1;
+
+ if (test__fixunsxfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixunsxfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixunsxfdi(-0x1.FFFFFFFFFFFFFp+62, 0))
+ return 1;
+ if (test__fixunsxfdi(-0x1.FFFFFFFFFFFFEp+62, 0))
+ return 1;
+
+ if (test__fixunsxfdi(0x1.FFFFFFFFFFFFFFFEp+63L, 0xFFFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixunsxfdi(0x1.0000000000000002p+63L, 0x8000000000000001LL))
+ return 1;
+ if (test__fixunsxfdi(0x1.0000000000000000p+63L, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunsxfdi(0x1.FFFFFFFFFFFFFFFCp+62L, 0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixunsxfdi(0x1.FFFFFFFFFFFFFFF8p+62L, 0x7FFFFFFFFFFFFFFELL))
+ return 1;
+
+ if (test__fixunsxfdi(-0x1.0000000000000000p+63L, 0))
+ return 1;
+ if (test__fixunsxfdi(-0x1.FFFFFFFFFFFFFFFCp+62L, 0))
+ return 1;
+ if (test__fixunsxfdi(-0x1.FFFFFFFFFFFFFFF8p+62L, 0))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixunsxfsi_test.c b/test/Unit/fixunsxfsi_test.c
new file mode 100644
index 000000000..2b516d5b6
--- /dev/null
+++ b/test/Unit/fixunsxfsi_test.c
@@ -0,0 +1,107 @@
+//===-- fixunsxfsi_test.c - Test __fixunsxfsi -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunsxfsi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned int, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// su_int is a 32 bit integral type
+// value in long double is representable in su_int or is negative
+// (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+su_int __fixunsxfsi(long double a);
+
+int test__fixunsxfsi(long double a, su_int expected)
+{
+ su_int x = __fixunsxfsi(a);
+ if (x != expected)
+ printf("error in __fixunsxfsi(%LA) = %X, expected %X\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if !_ARCH_PPC
+ if (test__fixunsxfsi(0.0, 0))
+ return 1;
+
+ if (test__fixunsxfsi(0.5, 0))
+ return 1;
+ if (test__fixunsxfsi(0.99, 0))
+ return 1;
+ if (test__fixunsxfsi(1.0, 1))
+ return 1;
+ if (test__fixunsxfsi(1.5, 1))
+ return 1;
+ if (test__fixunsxfsi(1.99, 1))
+ return 1;
+ if (test__fixunsxfsi(2.0, 2))
+ return 1;
+ if (test__fixunsxfsi(2.01, 2))
+ return 1;
+ if (test__fixunsxfsi(-0.5, 0))
+ return 1;
+ if (test__fixunsxfsi(-0.99, 0))
+ return 1;
+#if !TARGET_LIBGCC
+ if (test__fixunsxfsi(-1.0, 0)) // libgcc ignores "returns 0 for negative input" spec
+ return 1;
+ if (test__fixunsxfsi(-1.5, 0))
+ return 1;
+ if (test__fixunsxfsi(-1.99, 0))
+ return 1;
+ if (test__fixunsxfsi(-2.0, 0))
+ return 1;
+ if (test__fixunsxfsi(-2.01, 0))
+ return 1;
+#endif
+
+ if (test__fixunsxfsi(0x1.000000p+31, 0x80000000))
+ return 1;
+ if (test__fixunsxfsi(0x1.FFFFFEp+31, 0xFFFFFF00))
+ return 1;
+ if (test__fixunsxfsi(0x1.FFFFFEp+30, 0x7FFFFF80))
+ return 1;
+ if (test__fixunsxfsi(0x1.FFFFFCp+30, 0x7FFFFF00))
+ return 1;
+
+#if !TARGET_LIBGCC
+ if (test__fixunsxfsi(-0x1.FFFFFEp+30, 0))
+ return 1;
+ if (test__fixunsxfsi(-0x1.FFFFFCp+30, 0))
+ return 1;
+#endif
+
+ if (test__fixunsxfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF))
+ return 1;
+ if (test__fixunsxfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF))
+ return 1;
+ if (test__fixunsxfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixunsxfti_test.c b/test/Unit/fixunsxfti_test.c
new file mode 100644
index 000000000..ccbcbb049
--- /dev/null
+++ b/test/Unit/fixunsxfti_test.c
@@ -0,0 +1,139 @@
+//===-- fixunsxfti_test.c - Test __fixunsxfti -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixunsxfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a unsigned long long, rounding toward zero.
+// Negative values all become zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// tu_int is a 64 bit integral type
+// value in long double is representable in tu_int or is negative
+// (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+tu_int __fixunsxfti(long double a);
+
+int test__fixunsxfti(long double a, tu_int expected)
+{
+ tu_int x = __fixunsxfti(a);
+ if (x != expected)
+ {
+ utwords xt;
+ xt.all = x;
+ utwords expectedt;
+ expectedt.all = expected;
+ printf("error in __fixunsxfti(%LA) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ a, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(tu_int) == 2*sizeof(du_int)] = {0};
+char assumption_2[sizeof(tu_int)*CHAR_BIT == 128] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__fixunsxfti(0.0, 0))
+ return 1;
+
+ if (test__fixunsxfti(0.5, 0))
+ return 1;
+ if (test__fixunsxfti(0.99, 0))
+ return 1;
+ if (test__fixunsxfti(1.0, 1))
+ return 1;
+ if (test__fixunsxfti(1.5, 1))
+ return 1;
+ if (test__fixunsxfti(1.99, 1))
+ return 1;
+ if (test__fixunsxfti(2.0, 2))
+ return 1;
+ if (test__fixunsxfti(2.01, 2))
+ return 1;
+ if (test__fixunsxfti(-0.5, 0))
+ return 1;
+ if (test__fixunsxfti(-0.99, 0))
+ return 1;
+ if (test__fixunsxfti(-1.0, 0))
+ return 1;
+ if (test__fixunsxfti(-1.5, 0))
+ return 1;
+ if (test__fixunsxfti(-1.99, 0))
+ return 1;
+ if (test__fixunsxfti(-2.0, 0))
+ return 1;
+ if (test__fixunsxfti(-2.01, 0))
+ return 1;
+
+ if (test__fixunsxfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixunsxfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixunsxfti(-0x1.FFFFFEp+62, 0))
+ return 1;
+ if (test__fixunsxfti(-0x1.FFFFFCp+62, 0))
+ return 1;
+
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixunsxfti(-0x1.FFFFFFFFFFFFFp+62, 0))
+ return 1;
+ if (test__fixunsxfti(-0x1.FFFFFFFFFFFFEp+62, 0))
+ return 1;
+
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFFFEp+63L, 0xFFFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixunsxfti(0x1.0000000000000002p+63L, 0x8000000000000001LL))
+ return 1;
+ if (test__fixunsxfti(0x1.0000000000000000p+63L, 0x8000000000000000LL))
+ return 1;
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFFFCp+62L, 0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFFF8p+62L, 0x7FFFFFFFFFFFFFFELL))
+ return 1;
+
+ if (test__fixunsxfti(-0x1.0000000000000000p+63L, 0))
+ return 1;
+ if (test__fixunsxfti(-0x1.FFFFFFFFFFFFFFFCp+62L, 0))
+ return 1;
+ if (test__fixunsxfti(-0x1.FFFFFFFFFFFFFFF8p+62L, 0))
+ return 1;
+
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFFFEp+127L, make_ti(0xFFFFFFFFFFFFFFFFLL, 0)))
+ return 1;
+ if (test__fixunsxfti(0x1.0000000000000002p+127L, make_ti(0x8000000000000001LL, 0)))
+ return 1;
+ if (test__fixunsxfti(0x1.0000000000000000p+127L, make_ti(0x8000000000000000LL, 0)))
+ return 1;
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFFFCp+126L, make_ti(0x7FFFFFFFFFFFFFFFLL, 0)))
+ return 1;
+ if (test__fixunsxfti(0x1.FFFFFFFFFFFFFFF8p+126L, make_ti(0x7FFFFFFFFFFFFFFELL, 0)))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixxfdi_test.c b/test/Unit/fixxfdi_test.c
new file mode 100644
index 000000000..9fe4e0a7c
--- /dev/null
+++ b/test/Unit/fixxfdi_test.c
@@ -0,0 +1,114 @@
+//===-- fixxfdi_test.c - Test __fixxfdi -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixxfdi for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// su_int is a 32 bit integral type
+// value in long double is representable in di_int (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+di_int __fixxfdi(long double a);
+
+int test__fixxfdi(long double a, di_int expected)
+{
+ di_int x = __fixxfdi(a);
+ if (x != expected)
+ printf("error in __fixxfdi(%LA) = %llX, expected %llX\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if !_ARCH_PPC
+ if (test__fixxfdi(0.0, 0))
+ return 1;
+
+ if (test__fixxfdi(0.5, 0))
+ return 1;
+ if (test__fixxfdi(0.99, 0))
+ return 1;
+ if (test__fixxfdi(1.0, 1))
+ return 1;
+ if (test__fixxfdi(1.5, 1))
+ return 1;
+ if (test__fixxfdi(1.99, 1))
+ return 1;
+ if (test__fixxfdi(2.0, 2))
+ return 1;
+ if (test__fixxfdi(2.01, 2))
+ return 1;
+ if (test__fixxfdi(-0.5, 0))
+ return 1;
+ if (test__fixxfdi(-0.99, 0))
+ return 1;
+ if (test__fixxfdi(-1.0, -1))
+ return 1;
+ if (test__fixxfdi(-1.5, -1))
+ return 1;
+ if (test__fixxfdi(-1.99, -1))
+ return 1;
+ if (test__fixxfdi(-2.0, -2))
+ return 1;
+ if (test__fixxfdi(-2.01, -2))
+ return 1;
+
+ if (test__fixxfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixxfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixxfdi(-0x1.FFFFFEp+62, 0x8000008000000000LL))
+ return 1;
+ if (test__fixxfdi(-0x1.FFFFFCp+62, 0x8000010000000000LL))
+ return 1;
+
+ if (test__fixxfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixxfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixxfdi(-0x1.FFFFFFFFFFFFFp+62, 0x8000000000000400LL))
+ return 1;
+ if (test__fixxfdi(-0x1.FFFFFFFFFFFFEp+62, 0x8000000000000800LL))
+ return 1;
+
+ if (test__fixxfdi(0x1.FFFFFFFFFFFFFFFCp+62L, 0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixxfdi(0x1.FFFFFFFFFFFFFFF8p+62L, 0x7FFFFFFFFFFFFFFELL))
+ return 1;
+
+ if (test__fixxfdi(-0x1.0000000000000000p+63L, 0x8000000000000000LL))
+ return 1;
+ if (test__fixxfdi(-0x1.FFFFFFFFFFFFFFFCp+62L, 0x8000000000000001LL))
+ return 1;
+ if (test__fixxfdi(-0x1.FFFFFFFFFFFFFFF8p+62L, 0x8000000000000002LL))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/fixxfti_test.c b/test/Unit/fixxfti_test.c
new file mode 100644
index 000000000..86fdcc08b
--- /dev/null
+++ b/test/Unit/fixxfti_test.c
@@ -0,0 +1,144 @@
+//===-- fixxfti_test.c - Test __fixxfti -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __fixxfti for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a signed long long, rounding toward zero.
+
+// Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+// su_int is a 32 bit integral type
+// value in long double is representable in ti_int (no range checking performed)
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+ti_int __fixxfti(long double a);
+
+int test__fixxfti(long double a, ti_int expected)
+{
+ ti_int x = __fixxfti(a);
+ if (x != expected)
+ {
+ utwords xt;
+ xt.all = x;
+ utwords expectedt;
+ expectedt.all = expected;
+ printf("error in __fixxfti(%LA) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ a, xt.high, xt.low, expectedt.high, expectedt.low);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(su_int)*CHAR_BIT == 32] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__fixxfti(0.0, 0))
+ return 1;
+
+ if (test__fixxfti(0.5, 0))
+ return 1;
+ if (test__fixxfti(0.99, 0))
+ return 1;
+ if (test__fixxfti(1.0, 1))
+ return 1;
+ if (test__fixxfti(1.5, 1))
+ return 1;
+ if (test__fixxfti(1.99, 1))
+ return 1;
+ if (test__fixxfti(2.0, 2))
+ return 1;
+ if (test__fixxfti(2.01, 2))
+ return 1;
+ if (test__fixxfti(-0.5, 0))
+ return 1;
+ if (test__fixxfti(-0.99, 0))
+ return 1;
+ if (test__fixxfti(-1.0, -1))
+ return 1;
+ if (test__fixxfti(-1.5, -1))
+ return 1;
+ if (test__fixxfti(-1.99, -1))
+ return 1;
+ if (test__fixxfti(-2.0, -2))
+ return 1;
+ if (test__fixxfti(-2.01, -2))
+ return 1;
+
+ if (test__fixxfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000LL))
+ return 1;
+ if (test__fixxfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000LL))
+ return 1;
+
+ if (test__fixxfti(-0x1.FFFFFEp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000008000000000LL)))
+ return 1;
+ if (test__fixxfti(-0x1.FFFFFCp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000010000000000LL)))
+ return 1;
+
+ if (test__fixxfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00LL))
+ return 1;
+ if (test__fixxfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL))
+ return 1;
+
+ if (test__fixxfti(-0x1.FFFFFFFFFFFFFp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000400LL)))
+ return 1;
+ if (test__fixxfti(-0x1.FFFFFFFFFFFFEp+62, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000800LL)))
+ return 1;
+
+ if (test__fixxfti(0x1.FFFFFFFFFFFFFFFCp+62L, 0x7FFFFFFFFFFFFFFFLL))
+ return 1;
+ if (test__fixxfti(0x1.FFFFFFFFFFFFFFF8p+62L, 0x7FFFFFFFFFFFFFFELL))
+ return 1;
+
+ if (test__fixxfti(-0x1.0000000000000000p+63L, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000000LL)))
+ return 1;
+ if (test__fixxfti(-0x1.FFFFFFFFFFFFFFFCp+62L, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000001LL)))
+ return 1;
+ if (test__fixxfti(-0x1.FFFFFFFFFFFFFFF8p+62L, make_ti(0xFFFFFFFFFFFFFFFFLL,
+ 0x8000000000000002LL)))
+ return 1;
+
+ if (test__fixxfti(0x1.FFFFFFFFFFFFFFFEp+126L, make_ti(0x7FFFFFFFFFFFFFFFLL,
+ 0x8000000000000000LL)))
+ return 1;
+ if (test__fixxfti(0x1.FFFFFFFFFFFFFFFCp+126L, make_ti(0x7FFFFFFFFFFFFFFFLL,
+ 0x0000000000000000LL)))
+
+ return 1;
+
+ if (test__fixxfti(-0x1.0000000000000000p+127L, make_ti(0x8000000000000000LL,
+ 0x0000000000000000LL)))
+ return 1;
+ if (test__fixxfti(-0x1.FFFFFFFFFFFFFFFEp+126L, make_ti(0x8000000000000000LL,
+ 0x8000000000000000LL)))
+ return 1;
+ if (test__fixxfti(-0x1.FFFFFFFFFFFFFFFCp+126L, make_ti(0x8000000000000001LL,
+ 0x0000000000000000LL)))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/floatdidf_test.c b/test/Unit/floatdidf_test.c
new file mode 100644
index 000000000..d207f5584
--- /dev/null
+++ b/test/Unit/floatdidf_test.c
@@ -0,0 +1,137 @@
+//===-- floatdidf.c - Test __floatdidf ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatdidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// di_int is a 64 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+double __floatdidf(di_int a);
+
+int test__floatdidf(di_int a, double expected)
+{
+ double x = __floatdidf(a);
+ if (x != expected)
+ printf("error in __floatdidf(%llX) = %a, expected %a\n", a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(di_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+int main()
+{
+ if (test__floatdidf(0, 0.0))
+ return 1;
+
+ if (test__floatdidf(1, 1.0))
+ return 1;
+ if (test__floatdidf(2, 2.0))
+ return 1;
+ if (test__floatdidf(20, 20.0))
+ return 1;
+ if (test__floatdidf(-1, -1.0))
+ return 1;
+ if (test__floatdidf(-2, -2.0))
+ return 1;
+ if (test__floatdidf(-20, -20.0))
+ return 1;
+
+ if (test__floatdidf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
+ return 1;
+ if (test__floatdidf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floatdidf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
+ return 1;
+ if (test__floatdidf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floatdidf(0x8000008000000000LL, -0x1.FFFFFEp+62))
+ return 1;
+ if (test__floatdidf(0x8000000000000800LL, -0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floatdidf(0x8000010000000000LL, -0x1.FFFFFCp+62))
+ return 1;
+ if (test__floatdidf(0x8000000000001000LL, -0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floatdidf(0x8000000000000000LL, -0x1.000000p+63))
+ return 1;
+ if (test__floatdidf(0x8000000000000001LL, -0x1.000000p+63))
+ return 1;
+
+ if (test__floatdidf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ return 1;
+
+ if (test__floatdidf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ return 1;
+
+ if (test__floatdidf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ return 1;
+ if (test__floatdidf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ return 1;
+
+ if (test__floatdidf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DA1LL, 0x1.1A3CFE870496Dp+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DB0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DB8LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DB6LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DBFLL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DC1LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DC7LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DC8LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DCFLL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DD0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DD1LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DD8LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DDFLL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floatdidf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/floatdisf_test.c b/test/Unit/floatdisf_test.c
new file mode 100644
index 000000000..91e098daf
--- /dev/null
+++ b/test/Unit/floatdisf_test.c
@@ -0,0 +1,95 @@
+//===-- floatdisf_test.c - Test __floatdisf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatdisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// di_int is a 64 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+float __floatdisf(di_int a);
+
+int test__floatdisf(di_int a, float expected)
+{
+ float x = __floatdisf(a);
+ if (x != expected)
+ printf("error in __floatdisf(%llX) = %a, expected %a\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(di_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+ if (test__floatdisf(0, 0.0F))
+ return 1;
+
+ if (test__floatdisf(1, 1.0F))
+ return 1;
+ if (test__floatdisf(2, 2.0F))
+ return 1;
+ if (test__floatdisf(-1, -1.0F))
+ return 1;
+ if (test__floatdisf(-2, -2.0F))
+ return 1;
+
+ if (test__floatdisf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62F))
+ return 1;
+ if (test__floatdisf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62F))
+ return 1;
+
+ if (test__floatdisf(0x8000008000000000LL, -0x1.FFFFFEp+62F))
+ return 1;
+ if (test__floatdisf(0x8000010000000000LL, -0x1.FFFFFCp+62F))
+ return 1;
+
+ if (test__floatdisf(0x8000000000000000LL, -0x1.000000p+63F))
+ return 1;
+ if (test__floatdisf(0x8000000000000001LL, -0x1.000000p+63F))
+ return 1;
+
+ if (test__floatdisf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+
+ if (test__floatdisf(0x0007FB72EA000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72EB000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72EC000000LL, 0x1.FEDCBCp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72E8000001LL, 0x1.FEDCBAp+50F))
+ return 1;
+
+ if (test__floatdisf(0x0007FB72E6000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72E7000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72E7FFFFFFLL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72E4000001LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatdisf(0x0007FB72E4000000LL, 0x1.FEDCB8p+50F))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/floatdixf_test.c b/test/Unit/floatdixf_test.c
new file mode 100644
index 000000000..cb3f5e0a3
--- /dev/null
+++ b/test/Unit/floatdixf_test.c
@@ -0,0 +1,144 @@
+//===-- floatdixf_test.c - Test __floatdixf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatdixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// di_int is a 64 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+long double __floatdixf(di_int a);
+
+int test__floatdixf(di_int a, long double expected)
+{
+ long double x = __floatdixf(a);
+ if (x != expected)
+ printf("error in __floatdixf(%llX) = %LA, expected %LA\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(di_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if !_ARCH_PPC
+ if (test__floatdixf(0, 0.0))
+ return 1;
+
+ if (test__floatdixf(1, 1.0))
+ return 1;
+ if (test__floatdixf(2, 2.0))
+ return 1;
+ if (test__floatdixf(20, 20.0))
+ return 1;
+ if (test__floatdixf(-1, -1.0))
+ return 1;
+ if (test__floatdixf(-2, -2.0))
+ return 1;
+ if (test__floatdixf(-20, -20.0))
+ return 1;
+
+ if (test__floatdixf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
+ return 1;
+ if (test__floatdixf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floatdixf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
+ return 1;
+ if (test__floatdixf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floatdixf(0x8000008000000000LL, -0x1.FFFFFEp+62))
+ return 1;
+ if (test__floatdixf(0x8000000000000800LL, -0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floatdixf(0x8000010000000000LL, -0x1.FFFFFCp+62))
+ return 1;
+ if (test__floatdixf(0x8000000000001000LL, -0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floatdixf(0x8000000000000000LL, -0x1.000000p+63))
+ return 1;
+ if (test__floatdixf(0x8000000000000001LL, -0x1.FFFFFFFFFFFFFFFCp+62L))
+ return 1;
+
+ if (test__floatdixf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ return 1;
+
+ if (test__floatdixf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ return 1;
+
+ if (test__floatdixf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ return 1;
+ if (test__floatdixf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ return 1;
+
+ if (test__floatdixf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DA1LL, 0x8.D1E7F43824B684p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DB0LL, 0x8.D1E7f43824B6Cp+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DB8LL, 0x8.D1E7F43824B6Ep+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DB6LL, 0x8.D1E7F43824B6D8p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DBFLL, 0x8.D1E7F43824B6FCp+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DC1LL, 0x8.D1E7F43824B704p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DC7LL, 0x8.D1E7F43824B71Cp+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DC8LL, 0x8.D1E7F43824B72p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DCFLL, 0x8.D1E7F43824B73Cp+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DD0LL, 0x8.D1E7F43824B74p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DD1LL, 0x8.D1E7F43824B744p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DD8LL, 0x8.D1E7F43824B76p+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DDFLL, 0x8.D1E7F43824B77Cp+54L))
+ return 1;
+ if (test__floatdixf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/floattidf_test.c b/test/Unit/floattidf_test.c
new file mode 100644
index 000000000..5d001c50a
--- /dev/null
+++ b/test/Unit/floattidf_test.c
@@ -0,0 +1,178 @@
+//===-- floattidf.c - Test __floattidf ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floattidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// ti_int is a 64 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+double __floattidf(ti_int a);
+
+int test__floattidf(ti_int a, double expected)
+{
+ double x = __floattidf(a);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ printf("error in __floattidf(0x%.16llX%.16llX) = %a, expected %a\n",
+ at.high, at.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(ti_int)*CHAR_BIT == 128] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__floattidf(0, 0.0))
+ return 1;
+
+ if (test__floattidf(1, 1.0))
+ return 1;
+ if (test__floattidf(2, 2.0))
+ return 1;
+ if (test__floattidf(20, 20.0))
+ return 1;
+ if (test__floattidf(-1, -1.0))
+ return 1;
+ if (test__floattidf(-2, -2.0))
+ return 1;
+ if (test__floattidf(-20, -20.0))
+ return 1;
+
+ if (test__floattidf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
+ return 1;
+ if (test__floattidf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floattidf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
+ return 1;
+ if (test__floattidf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floattidf(make_ti(0x8000008000000000LL, 0), -0x1.FFFFFEp+126))
+ return 1;
+ if (test__floattidf(make_ti(0x8000000000000800LL, 0), -0x1.FFFFFFFFFFFFEp+126))
+ return 1;
+ if (test__floattidf(make_ti(0x8000010000000000LL, 0), -0x1.FFFFFCp+126))
+ return 1;
+ if (test__floattidf(make_ti(0x8000000000001000LL, 0), -0x1.FFFFFFFFFFFFCp+126))
+ return 1;
+
+ if (test__floattidf(make_ti(0x8000000000000000LL, 0), -0x1.000000p+127))
+ return 1;
+ if (test__floattidf(make_ti(0x8000000000000001LL, 0), -0x1.000000p+127))
+ return 1;
+
+ if (test__floattidf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ return 1;
+
+ if (test__floattidf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ return 1;
+ if (test__floattidf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ return 1;
+ if (test__floattidf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ return 1;
+ if (test__floattidf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ return 1;
+ if (test__floattidf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ return 1;
+
+ if (test__floattidf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ return 1;
+ if (test__floattidf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ return 1;
+ if (test__floattidf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ return 1;
+ if (test__floattidf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ return 1;
+ if (test__floattidf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ return 1;
+
+ if (test__floattidf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DA1LL, 0x1.1A3CFE870496Dp+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DB0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DB8LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DB6LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DBFLL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DC1LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DC7LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DC8LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DCFLL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DD0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DD1LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DD8LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DDFLL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floattidf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+
+ if (test__floattidf(make_ti(0x023479FD0E092DC0LL, 0), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DA1LL, 1), 0x1.1A3CFE870496Dp+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DB0LL, 2), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DB8LL, 3), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DB6LL, 4), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DBFLL, 5), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DC1LL, 6), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DC7LL, 7), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DC8LL, 8), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DCFLL, 9), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DD0LL, 0), 0x1.1A3CFE870496Ep+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DD1LL, 11), 0x1.1A3CFE870496Fp+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DD8LL, 12), 0x1.1A3CFE870496Fp+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DDFLL, 13), 0x1.1A3CFE870496Fp+121))
+ return 1;
+ if (test__floattidf(make_ti(0x023479FD0E092DE0LL, 14), 0x1.1A3CFE870496Fp+121))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/floattisf_test.c b/test/Unit/floattisf_test.c
new file mode 100644
index 000000000..403dd6104
--- /dev/null
+++ b/test/Unit/floattisf_test.c
@@ -0,0 +1,134 @@
+//===-- floattisf_test.c - Test __floattisf -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floattisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// ti_int is a 64 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+float __floattisf(ti_int a);
+
+int test__floattisf(ti_int a, float expected)
+{
+ float x = __floattisf(a);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ printf("error in __floattisf(0x%.16llX%.16llX) = %a, expected %a\n",
+ at.high, at.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(ti_int)*CHAR_BIT == 128] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__floattisf(0, 0.0F))
+ return 1;
+
+ if (test__floattisf(1, 1.0F))
+ return 1;
+ if (test__floattisf(2, 2.0F))
+ return 1;
+ if (test__floattisf(-1, -1.0F))
+ return 1;
+ if (test__floattisf(-2, -2.0F))
+ return 1;
+
+ if (test__floattisf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62F))
+ return 1;
+ if (test__floattisf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62F))
+ return 1;
+
+ if (test__floattisf(make_ti(0xFFFFFFFFFFFFFFFFLL, 0x8000008000000000LL),
+ -0x1.FFFFFEp+62F))
+ return 1;
+ if (test__floattisf(make_ti(0xFFFFFFFFFFFFFFFFLL, 0x8000010000000000LL),
+ -0x1.FFFFFCp+62F))
+ return 1;
+
+ if (test__floattisf(make_ti(0xFFFFFFFFFFFFFFFFLL, 0x8000000000000000LL),
+ -0x1.000000p+63F))
+ return 1;
+ if (test__floattisf(make_ti(0xFFFFFFFFFFFFFFFFLL, 0x8000000000000001LL),
+ -0x1.000000p+63F))
+ return 1;
+
+ if (test__floattisf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+
+ if (test__floattisf(0x0007FB72EA000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72EB000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72EC000000LL, 0x1.FEDCBCp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72E8000001LL, 0x1.FEDCBAp+50F))
+ return 1;
+
+ if (test__floattisf(0x0007FB72E6000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72E7000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72E7FFFFFFLL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72E4000001LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floattisf(0x0007FB72E4000000LL, 0x1.FEDCB8p+50F))
+ return 1;
+
+ if (test__floattisf(make_ti(0x0007FB72E8000000LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+
+ if (test__floattisf(make_ti(0x0007FB72EA000000LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72EB000000LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72EBFFFFFFLL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72EC000000LL, 0), 0x1.FEDCBCp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72E8000001LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+
+ if (test__floattisf(make_ti(0x0007FB72E6000000LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72E7000000LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72E7FFFFFFLL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72E4000001LL, 0), 0x1.FEDCBAp+114F))
+ return 1;
+ if (test__floattisf(make_ti(0x0007FB72E4000000LL, 0), 0x1.FEDCB8p+114F))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/floattixf_test.c b/test/Unit/floattixf_test.c
new file mode 100644
index 000000000..a96f15d5d
--- /dev/null
+++ b/test/Unit/floattixf_test.c
@@ -0,0 +1,210 @@
+//===-- floattixf.c - Test __floattixf ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floattixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// ti_int is a 128 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+long double __floattixf(ti_int a);
+
+int test__floattixf(ti_int a, long double expected)
+{
+ long double x = __floattixf(a);
+ if (x != expected)
+ {
+ twords at;
+ at.all = a;
+ printf("error in __floattixf(0x%.16llX%.16llX) = %LA, expected %LA\n",
+ at.high, at.low, x, expected);
+ }
+ return x != expected;
+}
+
+char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0};
+char assumption_2[sizeof(ti_int)*CHAR_BIT == 128] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __x86_64
+ if (test__floattixf(0, 0.0))
+ return 1;
+
+ if (test__floattixf(1, 1.0))
+ return 1;
+ if (test__floattixf(2, 2.0))
+ return 1;
+ if (test__floattixf(20, 20.0))
+ return 1;
+ if (test__floattixf(-1, -1.0))
+ return 1;
+ if (test__floattixf(-2, -2.0))
+ return 1;
+ if (test__floattixf(-20, -20.0))
+ return 1;
+
+ if (test__floattixf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
+ return 1;
+ if (test__floattixf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floattixf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
+ return 1;
+ if (test__floattixf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floattixf(make_ti(0x8000008000000000LL, 0), -0x1.FFFFFEp+126))
+ return 1;
+ if (test__floattixf(make_ti(0x8000000000000800LL, 0), -0x1.FFFFFFFFFFFFEp+126))
+ return 1;
+ if (test__floattixf(make_ti(0x8000010000000000LL, 0), -0x1.FFFFFCp+126))
+ return 1;
+ if (test__floattixf(make_ti(0x8000000000001000LL, 0), -0x1.FFFFFFFFFFFFCp+126))
+ return 1;
+
+ if (test__floattixf(make_ti(0x8000000000000000LL, 0), -0x1.000000p+127))
+ return 1;
+ if (test__floattixf(make_ti(0x8000000000000001LL, 0), -0x1.FFFFFFFFFFFFFFFCp+126L))
+ return 1;
+
+ if (test__floattixf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ return 1;
+
+ if (test__floattixf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ return 1;
+ if (test__floattixf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ return 1;
+ if (test__floattixf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ return 1;
+ if (test__floattixf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ return 1;
+ if (test__floattixf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ return 1;
+
+ if (test__floattixf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ return 1;
+ if (test__floattixf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ return 1;
+ if (test__floattixf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ return 1;
+ if (test__floattixf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ return 1;
+ if (test__floattixf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ return 1;
+
+ if (test__floattixf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DA1LL, 0x1.1A3CFE870496D08p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DB0LL, 0x1.1A3CFE870496D8p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DB8LL, 0x1.1A3CFE870496DCp+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DB6LL, 0x1.1A3CFE870496DBp+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DBFLL, 0x1.1A3CFE870496DF8p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DC1LL, 0x1.1A3CFE870496E08p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DC7LL, 0x1.1A3CFE870496E38p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DC8LL, 0x1.1A3CFE870496E4p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DCFLL, 0x1.1A3CFE870496E78p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DD0LL, 0x1.1A3CFE870496E8p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DD1LL, 0x1.1A3CFE870496E88p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DD8LL, 0x1.1A3CFE870496ECp+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DDFLL, 0x1.1A3CFE870496EF8p+57L))
+ return 1;
+ if (test__floattixf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+
+ if (test__floattixf(make_ti(0x023479FD0E092DC0LL, 0), 0x1.1A3CFE870496Ep+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DA1LL, 1), 0x1.1A3CFE870496D08p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DB0LL, 2), 0x1.1A3CFE870496D8p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DB8LL, 3), 0x1.1A3CFE870496DCp+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DB6LL, 4), 0x1.1A3CFE870496DBp+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DBFLL, 5), 0x1.1A3CFE870496DF8p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DC1LL, 6), 0x1.1A3CFE870496E08p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DC7LL, 7), 0x1.1A3CFE870496E38p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DC8LL, 8), 0x1.1A3CFE870496E4p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DCFLL, 9), 0x1.1A3CFE870496E78p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DD0LL, 0), 0x1.1A3CFE870496E8p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DD1LL, 11), 0x1.1A3CFE870496E88p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DD8LL, 12), 0x1.1A3CFE870496ECp+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DDFLL, 13), 0x1.1A3CFE870496EF8p+121L))
+ return 1;
+ if (test__floattixf(make_ti(0x023479FD0E092DE0LL, 14), 0x1.1A3CFE870496Fp+121L))
+ return 1;
+
+ if (test__floattixf(make_ti(0, 0xFFFFFFFFFFFFFFFFLL), 0x1.FFFFFFFFFFFFFFFEp+63L))
+ return 1;
+
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x3456100000000001LL),
+ 0x1.2345678901234562p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x3456200000000000LL),
+ 0x1.2345678901234562p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x34562FFFFFFFFFFFLL),
+ 0x1.2345678901234562p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x3456300000000000LL),
+ 0x1.2345678901234564p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x3456400000000000LL),
+ 0x1.2345678901234564p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x34564FFFFFFFFFFFLL),
+ 0x1.2345678901234564p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x3456500000000000LL),
+ 0x1.2345678901234564p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x3456500000000001LL),
+ 0x1.2345678901234566p+108L))
+ return 1;
+ if (test__floattixf(make_ti(0x0000123456789012LL, 0x34566FFFFFFFFFFFLL),
+ 0x1.2345678901234566p+108L))
+ return 1;
+#endif
+ return 0;
+}
diff --git a/test/Unit/floatundidf_test.c b/test/Unit/floatundidf_test.c
new file mode 100644
index 000000000..5a8dcbfe1
--- /dev/null
+++ b/test/Unit/floatundidf_test.c
@@ -0,0 +1,132 @@
+//===-- floatundidf_test.c - Test __floatundidf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// du_int is a 64 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+double __floatundidf(du_int a);
+
+int test__floatundidf(di_int a, double expected)
+{
+ double x = __floatundidf(a);
+ if (x != expected)
+ printf("error in __floatundidf(%llX) = %a, expected %a\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(di_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(di_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(double)*CHAR_BIT == 64] = {0};
+
+int main()
+{
+ if (test__floatundidf(0, 0.0))
+ return 1;
+
+ if (test__floatundidf(1, 1.0))
+ return 1;
+ if (test__floatundidf(2, 2.0))
+ return 1;
+ if (test__floatundidf(20, 20.0))
+ return 1;
+
+ if (test__floatundidf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
+ return 1;
+ if (test__floatundidf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floatundidf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
+ return 1;
+ if (test__floatundidf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+
+ if (test__floatundidf(0x8000008000000000LL, 0x1.000001p+63))
+ return 1;
+ if (test__floatundidf(0x8000000000000800LL, 0x1.0000000000001p+63))
+ return 1;
+ if (test__floatundidf(0x8000010000000000LL, 0x1.000002p+63))
+ return 1;
+ if (test__floatundidf(0x8000000000001000LL, 0x1.0000000000002p+63))
+ return 1;
+
+ if (test__floatundidf(0x8000000000000000LL, 0x1p+63))
+ return 1;
+ if (test__floatundidf(0x8000000000000001LL, 0x1p+63))
+ return 1;
+
+ if (test__floatundidf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ return 1;
+
+ if (test__floatundidf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ return 1;
+
+ if (test__floatundidf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ return 1;
+ if (test__floatundidf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ return 1;
+
+ if (test__floatundidf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DA1LL, 0x1.1A3CFE870496Dp+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DB0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DB8LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DB6LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DBFLL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DC1LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DC7LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DC8LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DCFLL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DD0LL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DD1LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DD8LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DDFLL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+ if (test__floatundidf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/floatundisf_test.c b/test/Unit/floatundisf_test.c
new file mode 100644
index 000000000..782db6d40
--- /dev/null
+++ b/test/Unit/floatundisf_test.c
@@ -0,0 +1,96 @@
+//===-- floatundisf_test.c - Test __floatundisf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatundisf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a float, rounding toward even.
+
+// Assumption: float is a IEEE 32 bit floating point type
+// du_int is a 64 bit integral type
+
+// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
+
+float __floatundisf(du_int a);
+
+int test__floatundisf(du_int a, float expected)
+{
+ float x = __floatundisf(a);
+ if (x != expected)
+ printf("error in __floatundisf(%llX) = %a, expected %a\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(du_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(du_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(float)*CHAR_BIT == 32] = {0};
+
+int main()
+{
+ if (test__floatundisf(0, 0.0F))
+ return 1;
+
+ if (test__floatundisf(1, 1.0F))
+ return 1;
+ if (test__floatundisf(2, 2.0F))
+ return 1;
+
+ if (test__floatundisf(0x7FFFFF8000000000ULL, 0x1.FFFFFEp+62F))
+ return 1;
+ if (test__floatundisf(0x7FFFFF0000000000ULL, 0x1.FFFFFCp+62F))
+ return 1;
+
+ if (test__floatundisf(0x8000008000000000ULL, 0x1p+63F))
+ return 1;
+ if (test__floatundisf(0x8000010000000000LL, 0x1.000002p+63F))
+ return 1;
+
+ if (test__floatundisf(0x8000000000000000LL, 0x1p+63F))
+ return 1;
+ if (test__floatundisf(0x8000000000000001LL, 0x1p+63F))
+ return 1;
+
+ if (test__floatundisf(0xFFFFFFFFFFFFFFFELL, 0x1p+64F))
+ return 1;
+ if (test__floatundisf(0xFFFFFFFFFFFFFFFFLL, 0x1p+64F))
+ return 1;
+
+ if (test__floatundisf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+
+ if (test__floatundisf(0x0007FB72EA000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72EB000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72EC000000LL, 0x1.FEDCBCp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72E8000001LL, 0x1.FEDCBAp+50F))
+ return 1;
+
+ if (test__floatundisf(0x0007FB72E6000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72E7000000LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72E7FFFFFFLL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72E4000001LL, 0x1.FEDCBAp+50F))
+ return 1;
+ if (test__floatundisf(0x0007FB72E4000000LL, 0x1.FEDCB8p+50F))
+ return 1;
+
+ return 0;
+}
diff --git a/test/Unit/floatundixf_test.c b/test/Unit/floatundixf_test.c
new file mode 100644
index 000000000..112634827
--- /dev/null
+++ b/test/Unit/floatundixf_test.c
@@ -0,0 +1,144 @@
+//===-- floatundixf_test.c - Test __floatundixf ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatundixf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <stdio.h>
+
+// Returns: convert a to a long double, rounding toward even.
+
+// Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+// du_int is a 64 bit integral type
+
+// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+// 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+long double __floatundixf(du_int a);
+
+int test__floatundixf(du_int a, long double expected)
+{
+ long double x = __floatundixf(a);
+ if (x != expected)
+ printf("error in __floatundixf(%llX) = %LA, expected %LA\n",
+ a, x, expected);
+ return x != expected;
+}
+
+char assumption_1[sizeof(du_int) == 2*sizeof(si_int)] = {0};
+char assumption_2[sizeof(du_int)*CHAR_BIT == 64] = {0};
+char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if !_ARCH_PPC
+ if (test__floatundixf(0, 0.0))
+ return 1;
+
+ if (test__floatundixf(1, 1.0))
+ return 1;
+ if (test__floatundixf(2, 2.0))
+ return 1;
+ if (test__floatundixf(20, 20.0))
+ return 1;
+
+ if (test__floatundixf(0x7FFFFF8000000000ULL, 0x1.FFFFFEp+62))
+ return 1;
+ if (test__floatundixf(0x7FFFFFFFFFFFF800ULL, 0x1.FFFFFFFFFFFFEp+62))
+ return 1;
+ if (test__floatundixf(0x7FFFFF0000000000ULL, 0x1.FFFFFCp+62))
+ return 1;
+ if (test__floatundixf(0x7FFFFFFFFFFFF000ULL, 0x1.FFFFFFFFFFFFCp+62))
+ return 1;
+ if (test__floatundixf(0x7FFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFEp+59L))
+ return 1;
+ if (test__floatundixf(0xFFFFFFFFFFFFFFFEULL, 0xF.FFFFFFFFFFFFFFEp+60L))
+ return 1;
+ if (test__floatundixf(0xFFFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFFp+60L))
+ return 1;
+
+ if (test__floatundixf(0x8000008000000000ULL, 0x8.000008p+60))
+ return 1;
+ if (test__floatundixf(0x8000000000000800ULL, 0x8.0000000000008p+60))
+ return 1;
+ if (test__floatundixf(0x8000010000000000ULL, 0x8.00001p+60))
+ return 1;
+ if (test__floatundixf(0x8000000000001000ULL, 0x8.000000000001p+60))
+ return 1;
+
+ if (test__floatundixf(0x8000000000000000ULL, 0x8p+60))
+ return 1;
+ if (test__floatundixf(0x8000000000000001ULL, 0x8.000000000000001p+60L))
+ return 1;
+
+ if (test__floatundixf(0x0007FB72E8000000ULL, 0x1.FEDCBAp+50))
+ return 1;
+
+ if (test__floatundixf(0x0007FB72EA000000ULL, 0x1.FEDCBA8p+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72EB000000ULL, 0x1.FEDCBACp+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72EBFFFFFFULL, 0x1.FEDCBAFFFFFFCp+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72EC000000ULL, 0x1.FEDCBBp+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72E8000001ULL, 0x1.FEDCBA0000004p+50))
+ return 1;
+
+ if (test__floatundixf(0x0007FB72E6000000ULL, 0x1.FEDCB98p+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72E7000000ULL, 0x1.FEDCB9Cp+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72E7FFFFFFULL, 0x1.FEDCB9FFFFFFCp+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72E4000001ULL, 0x1.FEDCB90000004p+50))
+ return 1;
+ if (test__floatundixf(0x0007FB72E4000000ULL, 0x1.FEDCB9p+50))
+ return 1;
+
+ if (test__floatundixf(0x023479FD0E092DC0ULL, 0x1.1A3CFE870496Ep+57))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DA1ULL, 0x8.D1E7F43824B684p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DB0ULL, 0x8.D1E7f43824B6Cp+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DB8ULL, 0x8.D1E7F43824B6Ep+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DB6ULL, 0x8.D1E7F43824B6D8p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DBFULL, 0x8.D1E7F43824B6FCp+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DC1ULL, 0x8.D1E7F43824B704p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DC7ULL, 0x8.D1E7F43824B71Cp+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DC8ULL, 0x8.D1E7F43824B72p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DCFULL, 0x8.D1E7F43824B73Cp+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DD0ULL, 0x8.D1E7F43824B74p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DD1ULL, 0x8.D1E7F43824B744p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DD8ULL, 0x8.D1E7F43824B76p+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DDFULL, 0x8.D1E7F43824B77Cp+54L))
+ return 1;
+ if (test__floatundixf(0x023479FD0E092DE0ULL, 0x1.1A3CFE870496Fp+57))
+ return 1;
+
+#endif
+ return 0;
+}
diff --git a/test/Unit/floatuntidf_test.c b/test/Unit/floatuntidf_test.c
new file mode 100644
index 000000000..82c6006ed
--- /dev/null
+++ b/test/Unit/floatuntidf_test.c
@@ -0,0 +1,172 @@
+//===-- floatuntidf.c - Test __floatuntidf --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatuntidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+#include <stdio.h>
+
+// Returns: convert a to a double, rounding toward even.
+
+// Assumption: double is a IEEE 64 bit floating point type
+// tu_int is a 64 bit integral type
+
+// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+
+double __floatuntidf(tu_int a);
+
+int test__floatuntidf(tu_int a, double expected)
+{
+ double x = __floatuntidf(a);
+ if (x != expected)
+ {
+ utwords at;
+ at.all = a;
+ printf("error in __floatuntidf(0x%.16llX%.16llX) = %a, expected %a\n",
+ at.high, at.low, x, expected);
+ }<