Initial import of compiler-rt.

-

llvm-svn: 74292
This commit is contained in:
Daniel Dunbar 2009-06-26 16:47:03 +00:00
parent 455df54003
commit fd089990f7
282 changed files with 171808 additions and 36 deletions

View File

@ -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.
*
*/

View File

@ -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_

View File

@ -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.
*/
/********************

View File

@ -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"

63
compiler-rt/LICENSE.TXT Normal file
View File

@ -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
------- ---------

194
compiler-rt/Makefile Normal file
View File

@ -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)))))

133
compiler-rt/README.txt Normal file
View File

@ -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.

View File

@ -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

29
compiler-rt/lib/absvdi2.c Normal file
View File

@ -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;
}

29
compiler-rt/lib/absvsi2.c Normal file
View File

@ -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;
}

33
compiler-rt/lib/absvti2.c Normal file
View File

@ -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

36
compiler-rt/lib/addvdi3.c Normal file
View File

@ -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;
}

36
compiler-rt/lib/addvsi3.c Normal file
View File

@ -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;
}

40
compiler-rt/lib/addvti3.c Normal file
View File

@ -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

View File

@ -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__

40
compiler-rt/lib/ashldi3.c Normal file
View File

@ -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;
}

44
compiler-rt/lib/ashlti3.c Normal file
View File

@ -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

41
compiler-rt/lib/ashrdi3.c Normal file
View File

@ -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;
}

45
compiler-rt/lib/ashrti3.c Normal file
View File

@ -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

View File

@ -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
}

28
compiler-rt/lib/clzdi2.c Normal file
View File

@ -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)));
}

51
compiler-rt/lib/clzsi2.c Normal file
View File

@ -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));
}

32
compiler-rt/lib/clzti2.c Normal file
View File

@ -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

36
compiler-rt/lib/cmpdi2.c Normal file
View File

@ -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;
}

40
compiler-rt/lib/cmpti2.c Normal file
View File

@ -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

28
compiler-rt/lib/ctzdi2.c Normal file
View File

@ -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)));
}

54
compiler-rt/lib/ctzsi2.c Normal file
View File

@ -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));
}

32
compiler-rt/lib/ctzti2.c Normal file
View File

@ -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

58
compiler-rt/lib/divdc3.c Normal file
View File

@ -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;
}

30
compiler-rt/lib/divdi3.c Normal file
View File

@ -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
}

58
compiler-rt/lib/divsc3.c Normal file
View File

@ -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;
}

30
compiler-rt/lib/divsi3.c Normal file
View File

@ -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
}

34
compiler-rt/lib/divti3.c Normal file
View File

@ -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

62
compiler-rt/lib/divxc3.c Normal file
View File

@ -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

View File

@ -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);
}

31
compiler-rt/lib/eprintf.c Normal file
View File

@ -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();
}

31
compiler-rt/lib/ffsdi2.c Normal file
View File

@ -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;
}

35
compiler-rt/lib/ffsti2.c Normal file
View File

@ -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

41
compiler-rt/lib/fixdfdi.c Normal file
View File

@ -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;
}

43
compiler-rt/lib/fixdfti.c Normal file
View File

@ -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

39
compiler-rt/lib/fixsfdi.c Normal file
View File

@ -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;
}

43
compiler-rt/lib/fixsfti.c Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

41
compiler-rt/lib/fixxfdi.c Normal file
View File

@ -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

44
compiler-rt/lib/fixxfti.c Normal file
View File

@ -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

102
compiler-rt/lib/floatdidf.c Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

143
compiler-rt/lib/int_lib.h Normal file
View File

@ -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

40
compiler-rt/lib/lshrdi3.c Normal file
View File

@ -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;
}

44
compiler-rt/lib/lshrti3.c Normal file
View File

@ -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

31
compiler-rt/lib/moddi3.c Normal file
View File

@ -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
}

22
compiler-rt/lib/modsi3.c Normal file
View File

@ -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;
}

35
compiler-rt/lib/modti3.c Normal file
View File

@ -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

73
compiler-rt/lib/muldc3.c Normal file
View File

@ -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;
}

53
compiler-rt/lib/muldi3.c Normal file
View File

@ -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;
}

73
compiler-rt/lib/mulsc3.c Normal file
View File

@ -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;
}

57
compiler-rt/lib/multi3.c Normal file
View File

@ -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

56
compiler-rt/lib/mulvdi3.c Normal file
View File

@ -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;
}

56
compiler-rt/lib/mulvsi3.c Normal file
View File

@ -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;
}

60
compiler-rt/lib/mulvti3.c Normal file
View File

@ -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

77
compiler-rt/lib/mulxc3.c Normal file
View File

@ -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

22
compiler-rt/lib/negdi2.c Normal file
View File

@ -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;
}

26
compiler-rt/lib/negti2.c Normal file
View File

@ -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

28
compiler-rt/lib/negvdi2.c Normal file
View File

@ -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;
}

28
compiler-rt/lib/negvsi2.c Normal file
View File

@ -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;
}

32
compiler-rt/lib/negvti2.c Normal file
View File

@ -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

Some files were not shown because too many files have changed in this diff Show More