Compare commits
36 Commits
direct_gpu
...
llvmorg-2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18665516ad | ||
|
|
079a588dd1 | ||
|
|
c529f00553 | ||
|
|
2026b3fd03 | ||
|
|
3810f02f45 | ||
|
|
b466918a8c | ||
|
|
a52223b574 | ||
|
|
b76aad9fc0 | ||
|
|
e9e7d08fc6 | ||
|
|
25e67eda53 | ||
|
|
1df1d40e9f | ||
|
|
3a2ed724e3 | ||
|
|
8ab7ded56f | ||
|
|
d6db52d9b1 | ||
|
|
2db982c41f | ||
|
|
650437f2ef | ||
|
|
3e7b991362 | ||
|
|
95e705dba6 | ||
|
|
18d41baa16 | ||
|
|
6fa2343443 | ||
|
|
16b1f648f4 | ||
|
|
3c8d9e3967 | ||
|
|
406d24b588 | ||
|
|
6fdd777171 | ||
|
|
c268488db7 | ||
|
|
859d4167a0 | ||
|
|
93d8c22608 | ||
|
|
45400fd182 | ||
|
|
105e1edc48 | ||
|
|
48bc24b58e | ||
|
|
122bda50ba | ||
|
|
6e1a72fe08 | ||
|
|
2e7c26b02e | ||
|
|
acd2efdbc3 | ||
|
|
f498a646c7 | ||
|
|
e35b1819ad |
@@ -39,19 +39,19 @@ cscope.files:
|
||||
|
||||
install-local::
|
||||
$(Echo) Installing include files
|
||||
$(Verb) $(MKDIR) $(PROJ_includedir)
|
||||
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
|
||||
$(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include" ; then \
|
||||
cd $(PROJ_SRC_ROOT)/tools/clang/include && \
|
||||
for hdr in `find . -type f '!' '(' -name '*~' \
|
||||
-o -name '.#*' -o -name '*.in' -o -name '*.txt' \
|
||||
-o -name 'Makefile' -o -name '*.td' ')' -print \
|
||||
| grep -v CVS | grep -v .svn | grep -v .dir` ; do \
|
||||
instdir=`dirname "$(PROJ_includedir)/$$hdr"` ; \
|
||||
instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
|
||||
if test \! -d "$$instdir" ; then \
|
||||
$(EchoCmd) Making install directory $$instdir ; \
|
||||
$(MKDIR) $$instdir ;\
|
||||
fi ; \
|
||||
$(DataInstall) $$hdr $(PROJ_includedir)/$$hdr ; \
|
||||
$(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
|
||||
done ; \
|
||||
fi
|
||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
@@ -59,7 +59,7 @@ ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
|
||||
for hdr in `find . -type f '!' '(' -name 'Makefile' ')' -print \
|
||||
| grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
|
||||
$(DataInstall) $$hdr $(PROJ_includedir)/$$hdr ; \
|
||||
$(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
|
||||
done ; \
|
||||
fi
|
||||
endif
|
||||
|
||||
@@ -40,7 +40,7 @@ BugReporterContext::~BugReporterContext() {
|
||||
// Helper routines for walking the ExplodedGraph and fetching statements.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static inline const Stmt* GetStmt(ProgramPoint P) {
|
||||
static inline const Stmt* GetStmt(const ProgramPoint &P) {
|
||||
if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
|
||||
return SP->getStmt();
|
||||
else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P))
|
||||
|
||||
@@ -662,6 +662,16 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're initializing the whole aggregate, just do it in place.
|
||||
// FIXME: This is a hack around an AST bug (PR6537).
|
||||
if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) {
|
||||
EmitInitializationToLValue(E->getInit(0),
|
||||
LValue::MakeAddr(DestPtr, Qualifiers()),
|
||||
E->getType());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Here we iterate over the fields; this makes it simpler to both
|
||||
// default-initialize fields and skip over unnamed fields.
|
||||
@@ -680,8 +690,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
|
||||
// We never generate write-barries for initialized fields.
|
||||
LValue::SetObjCNonGC(FieldLoc, true);
|
||||
if (CurInitVal < NumInitElements) {
|
||||
// Store the initializer into the field
|
||||
EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
|
||||
// Store the initializer into the field.
|
||||
EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
|
||||
Field->getType());
|
||||
} else {
|
||||
// We're out of initalizers; default-initialize to null
|
||||
|
||||
@@ -230,7 +230,7 @@ class ConstStructBuilder {
|
||||
if (NumBytes > 1)
|
||||
Ty = llvm::ArrayType::get(Ty, NumBytes);
|
||||
|
||||
llvm::Constant *C = llvm::UndefValue::get(Ty);
|
||||
llvm::Constant *C = llvm::Constant::getNullValue(Ty);
|
||||
Elements.push_back(C);
|
||||
assert(getAlignment(C) == 1 && "Padding must have 1 byte alignment!");
|
||||
|
||||
@@ -268,7 +268,7 @@ class ConstStructBuilder {
|
||||
if (NumBytes > 1)
|
||||
Ty = llvm::ArrayType::get(Ty, NumBytes);
|
||||
|
||||
llvm::Constant *Padding = llvm::UndefValue::get(Ty);
|
||||
llvm::Constant *Padding = llvm::Constant::getNullValue(Ty);
|
||||
PackedElements.push_back(Padding);
|
||||
ElementOffsetInBytes += getSizeInBytes(Padding);
|
||||
}
|
||||
@@ -508,7 +508,7 @@ public:
|
||||
if (NumPadBytes > 1)
|
||||
Ty = llvm::ArrayType::get(Ty, NumPadBytes);
|
||||
|
||||
Elts.push_back(llvm::UndefValue::get(Ty));
|
||||
Elts.push_back(llvm::Constant::getNullValue(Ty));
|
||||
Types.push_back(Ty);
|
||||
}
|
||||
|
||||
|
||||
@@ -1147,8 +1147,8 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
||||
|
||||
// Collect the names of referenced protocols
|
||||
llvm::SmallVector<std::string, 16> Protocols;
|
||||
const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface();
|
||||
const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
|
||||
const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
|
||||
const ObjCList<ObjCProtocolDecl> &Protos = CatDecl->getReferencedProtocols();
|
||||
for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
|
||||
E = Protos.end(); I != E; ++I)
|
||||
Protocols.push_back((*I)->getNameAsString());
|
||||
|
||||
@@ -268,16 +268,15 @@ llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
|
||||
ASTContext &Context,
|
||||
llvm::LLVMContext &VMContext) const {
|
||||
if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
||||
if (CodeGenFunction::hasAggregateLLVMType(Ty))
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
} else {
|
||||
// Treat an enum type as its underlying type.
|
||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||
Ty = EnumTy->getDecl()->getIntegerType();
|
||||
|
||||
// Treat an enum type as its underlying type.
|
||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||
Ty = EnumTy->getDecl()->getIntegerType();
|
||||
|
||||
return (Ty->isPromotableIntegerType() ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
}
|
||||
return (Ty->isPromotableIntegerType() ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
}
|
||||
|
||||
/// X86_32ABIInfo - The X86-32 ABI information.
|
||||
@@ -1367,6 +1366,8 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
// i8* reg_save_area;
|
||||
// };
|
||||
unsigned neededInt, neededSSE;
|
||||
|
||||
Ty = CGF.getContext().getCanonicalType(Ty);
|
||||
ABIArgInfo AI = classifyArgumentType(Ty, CGF.getContext(), VMContext,
|
||||
neededInt, neededSSE);
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -w -emit-llvm < %s | FileCheck %s
|
||||
|
||||
// CHECK: @test1.x = internal constant [12 x i32] [i32 1
|
||||
// CHECK: @test2.x = internal constant [13 x i32] [i32 1,
|
||||
// CHECK: @test5w = global %0 { i32 2, [4 x i8] undef }
|
||||
// CHECK: @test5w = global %0 { i32 2, [4 x i8] zeroinitializer }
|
||||
// CHECK: @test5y = global %union.test5u { double 7.300000e+0{{[0]*}}1 }
|
||||
|
||||
// CHECK: @test6.x = internal constant %1 { i8 1, i8 2, i32 3, [4 x i8] zeroinitializer }
|
||||
void test1() {
|
||||
// This should codegen as a "@test1.x" global.
|
||||
const int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23 };
|
||||
@@ -59,3 +60,17 @@ void test5() {
|
||||
union test5u test5w = (union test5u)2;
|
||||
union test5u test5y = (union test5u)73.0;
|
||||
|
||||
|
||||
|
||||
// PR6660 - sqlite miscompile
|
||||
struct SelectDest {
|
||||
unsigned char eDest;
|
||||
unsigned char affinity;
|
||||
int iParm;
|
||||
int iMem;
|
||||
};
|
||||
|
||||
void test6() {
|
||||
struct SelectDest x = {1, 2, 3};
|
||||
test6f(&x);
|
||||
}
|
||||
|
||||
@@ -29,3 +29,14 @@ int f4() {
|
||||
static const int g4 = 12;
|
||||
return g4;
|
||||
}
|
||||
|
||||
// PR6537
|
||||
typedef union vec3 {
|
||||
struct { double x, y, z; };
|
||||
double component[3];
|
||||
} vec3;
|
||||
vec3 f5(vec3 value) {
|
||||
return (vec3) {{
|
||||
.x = value.x
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | grep "bitcast (%0\* @r to %union.x\*), \[4 x i8\] undef"
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
|
||||
|
||||
// Make sure we generate something sane instead of a ptrtoint
|
||||
union x {long long b;union x* a;} r = {.a = &r};
|
||||
|
||||
|
||||
// CHECK: bitcast (%0* @r to %union.x*), [4 x i8] zero
|
||||
11
clang/test/CodeGen/varargs.c
Normal file
11
clang/test/CodeGen/varargs.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// RUN: %clang_cc1 -emit-llvm -o - %s
|
||||
|
||||
|
||||
// PR6433 - Don't crash on va_arg(typedef).
|
||||
typedef double gdouble;
|
||||
void focus_changed_cb () {
|
||||
__builtin_va_list pa;
|
||||
double mfloat;
|
||||
mfloat = __builtin_va_arg((pa), gdouble);
|
||||
}
|
||||
|
||||
@@ -382,9 +382,7 @@ my %UniqueOptions = (
|
||||
|
||||
my %LangsAccepted = (
|
||||
"objective-c" => 1,
|
||||
"c" => 1,
|
||||
"c++" => 1,
|
||||
"objective-c++" => 1
|
||||
"c" => 1
|
||||
);
|
||||
|
||||
##----------------------------------------------------------------------------##
|
||||
|
||||
4
compiler-rt/.gitignore
vendored
4
compiler-rt/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
*~
|
||||
Debug
|
||||
Release
|
||||
Profile
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BLOCK_H_
|
||||
#define _BLOCK_H_
|
||||
|
||||
#if !defined(BLOCK_EXPORT)
|
||||
# if defined(__cplusplus)
|
||||
# define BLOCK_EXPORT extern "C"
|
||||
# else
|
||||
# define BLOCK_EXPORT extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Create a heap based copy of a Block or simply add a reference to an existing one.
|
||||
* This must be paired with Block_release to recover memory, even when running
|
||||
* under Objective-C Garbage Collection.
|
||||
*/
|
||||
BLOCK_EXPORT void *_Block_copy(const void *aBlock);
|
||||
|
||||
/* Lose the reference, and if heap based and last reference, recover the memory. */
|
||||
BLOCK_EXPORT void _Block_release(const void *aBlock);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Type correct macros. */
|
||||
|
||||
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
|
||||
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Block_private.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BLOCK_PRIVATE_H_
|
||||
#define _BLOCK_PRIVATE_H_
|
||||
|
||||
#if !defined(BLOCK_EXPORT)
|
||||
# if defined(__cplusplus)
|
||||
# define BLOCK_EXPORT extern "C"
|
||||
# else
|
||||
# define BLOCK_EXPORT extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
BLOCK_REFCOUNT_MASK = (0xffff),
|
||||
BLOCK_NEEDS_FREE = (1 << 24),
|
||||
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
|
||||
BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */
|
||||
BLOCK_IS_GC = (1 << 27),
|
||||
BLOCK_IS_GLOBAL = (1 << 28),
|
||||
BLOCK_HAS_DESCRIPTOR = (1 << 29)
|
||||
};
|
||||
|
||||
|
||||
/* Revised new layout. */
|
||||
struct Block_descriptor {
|
||||
unsigned long int reserved;
|
||||
unsigned long int size;
|
||||
void (*copy)(void *dst, void *src);
|
||||
void (*dispose)(void *);
|
||||
};
|
||||
|
||||
|
||||
struct Block_layout {
|
||||
void *isa;
|
||||
int flags;
|
||||
int reserved;
|
||||
void (*invoke)(void *, ...);
|
||||
struct Block_descriptor *descriptor;
|
||||
/* Imported variables. */
|
||||
};
|
||||
|
||||
|
||||
struct Block_byref {
|
||||
void *isa;
|
||||
struct Block_byref *forwarding;
|
||||
int flags; /* refcount; */
|
||||
int size;
|
||||
void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
|
||||
void (*byref_destroy)(struct Block_byref *);
|
||||
/* long shared[0]; */
|
||||
};
|
||||
|
||||
|
||||
struct Block_byref_header {
|
||||
void *isa;
|
||||
struct Block_byref *forwarding;
|
||||
int flags;
|
||||
int size;
|
||||
};
|
||||
|
||||
|
||||
/* Runtime support functions used by compiler when generating copy/dispose helpers. */
|
||||
|
||||
enum {
|
||||
/* See function implementation for a more complete description of these fields and combinations */
|
||||
BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */
|
||||
BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
|
||||
BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */
|
||||
BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */
|
||||
BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */
|
||||
};
|
||||
|
||||
/* Runtime entry point called by compiler when assigning objects inside copy helper routines */
|
||||
BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
|
||||
/* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */
|
||||
|
||||
|
||||
/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */
|
||||
BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
|
||||
|
||||
|
||||
|
||||
/* Other support functions */
|
||||
|
||||
/* Runtime entry to get total size of a closure */
|
||||
BLOCK_EXPORT unsigned long int Block_size(void *block_basic);
|
||||
|
||||
|
||||
|
||||
/* the raw data space for runtime classes for blocks */
|
||||
/* class+meta used for stack, malloc, and collectable based blocks */
|
||||
BLOCK_EXPORT void * _NSConcreteStackBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
|
||||
|
||||
|
||||
/* the intercept routines that must be used under GC */
|
||||
BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign_strong)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *),
|
||||
void (*gc_memmove)(void *, void *, unsigned long));
|
||||
|
||||
/* earlier version, now simply transitional */
|
||||
BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign_strong)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *));
|
||||
|
||||
BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
|
||||
void (*release)(const void *));
|
||||
|
||||
/* make a collectable GC heap based Block. Not useful under non-GC. */
|
||||
BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
|
||||
|
||||
/* thread-unsafe diagnostic */
|
||||
BLOCK_EXPORT const char *_Block_dump(const void *block);
|
||||
|
||||
|
||||
/* Obsolete */
|
||||
|
||||
/* first layout */
|
||||
struct Block_basic {
|
||||
void *isa;
|
||||
int Block_flags; /* int32_t */
|
||||
int Block_size; /* XXX should be packed into Block_flags */
|
||||
void (*Block_invoke)(void *);
|
||||
void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */
|
||||
void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */
|
||||
/* long params[0]; // where const imports, __block storage references, etc. get laid down */
|
||||
};
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _BLOCK_PRIVATE_H_ */
|
||||
@@ -1,13 +0,0 @@
|
||||
PROJECT( BlocksRuntime C )
|
||||
|
||||
SET( SRCS
|
||||
runtime.c
|
||||
data.c
|
||||
)
|
||||
|
||||
ADD_LIBRARY( ${PROJECT_NAME} SHARED ${SRCS})
|
||||
SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES
|
||||
INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib )
|
||||
|
||||
INSTALL( TARGETS ${PROJECT_NAME} DESTINATION lib )
|
||||
INSTALL( FILES Block.h Block_private.h DESTINATION include )
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/********************
|
||||
NSBlock support
|
||||
|
||||
We allocate space and export a symbol to be used as the Class for the on-stack and malloc'ed copies until ObjC arrives on the scene. These data areas are set up by Foundation to link in as real classes post facto.
|
||||
|
||||
We keep these in a separate file so that we can include the runtime code in test subprojects but not include the data so that compiled code that sees the data in libSystem doesn't get confused by a second copy. Somehow these don't get unified in a common block.
|
||||
**********************/
|
||||
|
||||
void * _NSConcreteStackBlock[32] = { 0 };
|
||||
void * _NSConcreteMallocBlock[32] = { 0 };
|
||||
void * _NSConcreteAutoBlock[32] = { 0 };
|
||||
void * _NSConcreteFinalizingBlock[32] = { 0 };
|
||||
void * _NSConcreteGlobalBlock[32] = { 0 };
|
||||
void * _NSConcreteWeakBlockVariable[32] = { 0 };
|
||||
|
||||
void _Block_copy_error(void) {
|
||||
}
|
||||
@@ -1,701 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Block_private.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_AVAILABILITY_MACROS_H
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif /* HAVE_AVAILABILITY_MACROS_H */
|
||||
|
||||
#ifdef HAVE_TARGET_CONDITIONALS_H
|
||||
#include <TargetConditionals.h>
|
||||
#endif /* HAVE_TARGET_CONDITIONALS_H */
|
||||
|
||||
#if defined(HAVE_OSATOMIC_COMPARE_AND_SWAP_INT) && defined(HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG)
|
||||
|
||||
#ifdef HAVE_LIBKERN_OSATOMIC_H
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif /* HAVE_LIBKERN_OSATOMIC_H */
|
||||
|
||||
#elif defined(__WIN32__)
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#include <windows.h>
|
||||
|
||||
static __inline bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst) {
|
||||
/* fixme barrier is overkill -- see objc-os.h */
|
||||
long original = InterlockedCompareExchange(dst, newl, oldl);
|
||||
return (original == oldl);
|
||||
}
|
||||
|
||||
static __inline bool OSAtomicCompareAndSwapInt(int oldi, int newi, int volatile *dst) {
|
||||
/* fixme barrier is overkill -- see objc-os.h */
|
||||
int original = InterlockedCompareExchange(dst, newi, oldi);
|
||||
return (original == oldi);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if the GCC atomic built-ins are available. If we're on
|
||||
* a 64-bit system, make sure we have an 8-byte atomic function
|
||||
* available.
|
||||
*
|
||||
*/
|
||||
|
||||
#elif defined(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT) && defined(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG)
|
||||
|
||||
static __inline bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst) {
|
||||
return __sync_bool_compare_and_swap(dst, oldl, newl);
|
||||
}
|
||||
|
||||
static __inline bool OSAtomicCompareAndSwapInt(int oldi, int newi, int volatile *dst) {
|
||||
return __sync_bool_compare_and_swap(dst, oldi, newi);
|
||||
}
|
||||
|
||||
#else
|
||||
#error unknown atomic compare-and-swap primitive
|
||||
#endif /* HAVE_OSATOMIC_COMPARE_AND_SWAP_INT && HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG */
|
||||
|
||||
|
||||
/*
|
||||
* Globals:
|
||||
*/
|
||||
|
||||
static void *_Block_copy_class = _NSConcreteMallocBlock;
|
||||
static void *_Block_copy_finalizing_class = _NSConcreteMallocBlock;
|
||||
static int _Block_copy_flag = BLOCK_NEEDS_FREE;
|
||||
static int _Byref_flag_initial_value = BLOCK_NEEDS_FREE | 2;
|
||||
|
||||
static const int WANTS_ONE = (1 << 16);
|
||||
|
||||
static bool isGC = false;
|
||||
|
||||
/*
|
||||
* Internal Utilities:
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static unsigned long int latching_incr_long(unsigned long int *where) {
|
||||
while (1) {
|
||||
unsigned long int old_value = *(volatile unsigned long int *)where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return BLOCK_REFCOUNT_MASK;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapLong(old_value, old_value+1, (volatile long int *)where)) {
|
||||
return old_value+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* if 0 */
|
||||
|
||||
static int latching_incr_int(int *where) {
|
||||
while (1) {
|
||||
int old_value = *(volatile int *)where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return BLOCK_REFCOUNT_MASK;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapInt(old_value, old_value+1, (volatile int *)where)) {
|
||||
return old_value+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int latching_decr_long(unsigned long int *where) {
|
||||
while (1) {
|
||||
unsigned long int old_value = *(volatile int *)where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return BLOCK_REFCOUNT_MASK;
|
||||
}
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapLong(old_value, old_value-1, (volatile long int *)where)) {
|
||||
return old_value-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* if 0 */
|
||||
|
||||
static int latching_decr_int(int *where) {
|
||||
while (1) {
|
||||
int old_value = *(volatile int *)where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return BLOCK_REFCOUNT_MASK;
|
||||
}
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapInt(old_value, old_value-1, (volatile int *)where)) {
|
||||
return old_value-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GC support stub routines:
|
||||
*/
|
||||
#if 0
|
||||
#pragma mark GC Support Routines
|
||||
#endif /* if 0 */
|
||||
|
||||
|
||||
static void *_Block_alloc_default(const unsigned long size, const bool initialCountIsOne, const bool isObject) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void _Block_assign_default(void *value, void **destptr) {
|
||||
*destptr = value;
|
||||
}
|
||||
|
||||
static void _Block_setHasRefcount_default(const void *ptr, const bool hasRefcount) {
|
||||
}
|
||||
|
||||
static void _Block_do_nothing(const void *aBlock) { }
|
||||
|
||||
static void _Block_retain_object_default(const void *ptr) {
|
||||
if (!ptr) return;
|
||||
}
|
||||
|
||||
static void _Block_release_object_default(const void *ptr) {
|
||||
if (!ptr) return;
|
||||
}
|
||||
|
||||
static void _Block_assign_weak_default(const void *ptr, void *dest) {
|
||||
*(void **)dest = (void *)ptr;
|
||||
}
|
||||
|
||||
static void _Block_memmove_default(void *dst, void *src, unsigned long size) {
|
||||
memmove(dst, src, (size_t)size);
|
||||
}
|
||||
|
||||
static void _Block_memmove_gc_broken(void *dest, void *src, unsigned long size) {
|
||||
void **destp = (void **)dest;
|
||||
void **srcp = (void **)src;
|
||||
while (size) {
|
||||
_Block_assign_default(*srcp, destp);
|
||||
destp++;
|
||||
srcp++;
|
||||
size -= sizeof(void *);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GC support callout functions - initially set to stub routines:
|
||||
*/
|
||||
|
||||
static void *(*_Block_allocator)(const unsigned long, const bool isOne, const bool isObject) = _Block_alloc_default;
|
||||
static void (*_Block_deallocator)(const void *) = (void (*)(const void *))free;
|
||||
static void (*_Block_assign)(void *value, void **destptr) = _Block_assign_default;
|
||||
static void (*_Block_setHasRefcount)(const void *ptr, const bool hasRefcount) = _Block_setHasRefcount_default;
|
||||
static void (*_Block_retain_object)(const void *ptr) = _Block_retain_object_default;
|
||||
static void (*_Block_release_object)(const void *ptr) = _Block_release_object_default;
|
||||
static void (*_Block_assign_weak)(const void *dest, void *ptr) = _Block_assign_weak_default;
|
||||
static void (*_Block_memmove)(void *dest, void *src, unsigned long size) = _Block_memmove_default;
|
||||
|
||||
|
||||
/*
|
||||
* GC support SPI functions - called from ObjC runtime and CoreFoundation:
|
||||
*/
|
||||
|
||||
/* Public SPI
|
||||
* Called from objc-auto to turn on GC.
|
||||
* version 3, 4 arg, but changed 1st arg
|
||||
*/
|
||||
void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *),
|
||||
void (*gc_memmove)(void *, void *, unsigned long)) {
|
||||
|
||||
isGC = true;
|
||||
_Block_allocator = alloc;
|
||||
_Block_deallocator = _Block_do_nothing;
|
||||
_Block_assign = gc_assign;
|
||||
_Block_copy_flag = BLOCK_IS_GC;
|
||||
_Block_copy_class = _NSConcreteAutoBlock;
|
||||
/* blocks with ctors & dtors need to have the dtor run from a class with a finalizer */
|
||||
_Block_copy_finalizing_class = _NSConcreteFinalizingBlock;
|
||||
_Block_setHasRefcount = setHasRefcount;
|
||||
_Byref_flag_initial_value = BLOCK_IS_GC; // no refcount
|
||||
_Block_retain_object = _Block_do_nothing;
|
||||
_Block_release_object = _Block_do_nothing;
|
||||
_Block_assign_weak = gc_assign_weak;
|
||||
_Block_memmove = gc_memmove;
|
||||
}
|
||||
|
||||
/* transitional */
|
||||
void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *)) {
|
||||
/* until objc calls _Block_use_GC it will call us; supply a broken internal memmove implementation until then */
|
||||
_Block_use_GC(alloc, setHasRefcount, gc_assign, gc_assign_weak, _Block_memmove_gc_broken);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called from objc-auto to alternatively turn on retain/release.
|
||||
* Prior to this the only "object" support we can provide is for those
|
||||
* super special objects that live in libSystem, namely dispatch queues.
|
||||
* Blocks and Block_byrefs have their own special entry points.
|
||||
*
|
||||
*/
|
||||
void _Block_use_RR( void (*retain)(const void *),
|
||||
void (*release)(const void *)) {
|
||||
_Block_retain_object = retain;
|
||||
_Block_release_object = release;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Support routines for copying:
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#pragma mark Copy/Release support
|
||||
#endif /* if 0 */
|
||||
|
||||
/* Copy, or bump refcount, of a block. If really copying, call the copy helper if present. */
|
||||
static void *_Block_copy_internal(const void *arg, const int flags) {
|
||||
struct Block_layout *aBlock;
|
||||
const bool wantsOne = (WANTS_ONE & flags) == WANTS_ONE;
|
||||
|
||||
//printf("_Block_copy_internal(%p, %x)\n", arg, flags);
|
||||
if (!arg) return NULL;
|
||||
|
||||
|
||||
// The following would be better done as a switch statement
|
||||
aBlock = (struct Block_layout *)arg;
|
||||
if (aBlock->flags & BLOCK_NEEDS_FREE) {
|
||||
// latches on high
|
||||
latching_incr_int(&aBlock->flags);
|
||||
return aBlock;
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_IS_GC) {
|
||||
// GC refcounting is expensive so do most refcounting here.
|
||||
if (wantsOne && ((latching_incr_int(&aBlock->flags) & BLOCK_REFCOUNT_MASK) == 1)) {
|
||||
// Tell collector to hang on this - it will bump the GC refcount version
|
||||
_Block_setHasRefcount(aBlock, true);
|
||||
}
|
||||
return aBlock;
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_IS_GLOBAL) {
|
||||
return aBlock;
|
||||
}
|
||||
|
||||
// Its a stack block. Make a copy.
|
||||
if (!isGC) {
|
||||
struct Block_layout *result = malloc(aBlock->descriptor->size);
|
||||
if (!result) return (void *)0;
|
||||
memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first
|
||||
// reset refcount
|
||||
result->flags &= ~(BLOCK_REFCOUNT_MASK); // XXX not needed
|
||||
result->flags |= BLOCK_NEEDS_FREE | 1;
|
||||
result->isa = _NSConcreteMallocBlock;
|
||||
if (result->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
//printf("calling block copy helper %p(%p, %p)...\n", aBlock->descriptor->copy, result, aBlock);
|
||||
(*aBlock->descriptor->copy)(result, aBlock); // do fixup
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
// Under GC want allocation with refcount 1 so we ask for "true" if wantsOne
|
||||
// This allows the copy helper routines to make non-refcounted block copies under GC
|
||||
unsigned long int flags = aBlock->flags;
|
||||
bool hasCTOR = (flags & BLOCK_HAS_CTOR) != 0;
|
||||
struct Block_layout *result = _Block_allocator(aBlock->descriptor->size, wantsOne, hasCTOR);
|
||||
if (!result) return (void *)0;
|
||||
memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first
|
||||
// reset refcount
|
||||
// if we copy a malloc block to a GC block then we need to clear NEEDS_FREE.
|
||||
flags &= ~(BLOCK_NEEDS_FREE|BLOCK_REFCOUNT_MASK); // XXX not needed
|
||||
if (wantsOne)
|
||||
flags |= BLOCK_IS_GC | 1;
|
||||
else
|
||||
flags |= BLOCK_IS_GC;
|
||||
result->flags = flags;
|
||||
if (flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
//printf("calling block copy helper...\n");
|
||||
(*aBlock->descriptor->copy)(result, aBlock); // do fixup
|
||||
}
|
||||
if (hasCTOR) {
|
||||
result->isa = _NSConcreteFinalizingBlock;
|
||||
}
|
||||
else {
|
||||
result->isa = _NSConcreteAutoBlock;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Runtime entry points for maintaining the sharing knowledge of byref data blocks.
|
||||
*
|
||||
* A closure has been copied and its fixup routine is asking us to fix up the reference to the shared byref data
|
||||
* Closures that aren't copied must still work, so everyone always accesses variables after dereferencing the forwarding ptr.
|
||||
* We ask if the byref pointer that we know about has already been copied to the heap, and if so, increment it.
|
||||
* Otherwise we need to copy it and update the stack forwarding pointer
|
||||
* XXX We need to account for weak/nonretained read-write barriers.
|
||||
*/
|
||||
|
||||
static void _Block_byref_assign_copy(void *dest, const void *arg, const int flags) {
|
||||
struct Block_byref **destp = (struct Block_byref **)dest;
|
||||
struct Block_byref *src = (struct Block_byref *)arg;
|
||||
|
||||
//printf("_Block_byref_assign_copy called, byref destp %p, src %p, flags %x\n", destp, src, flags);
|
||||
//printf("src dump: %s\n", _Block_byref_dump(src));
|
||||
if (src->forwarding->flags & BLOCK_IS_GC) {
|
||||
; // don't need to do any more work
|
||||
}
|
||||
else if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
//printf("making copy\n");
|
||||
// src points to stack
|
||||
bool isWeak = ((flags & (BLOCK_FIELD_IS_BYREF|BLOCK_FIELD_IS_WEAK)) == (BLOCK_FIELD_IS_BYREF|BLOCK_FIELD_IS_WEAK));
|
||||
// if its weak ask for an object (only matters under GC)
|
||||
struct Block_byref *copy = (struct Block_byref *)_Block_allocator(src->size, false, isWeak);
|
||||
copy->flags = src->flags | _Byref_flag_initial_value; // non-GC one for caller, one for stack
|
||||
copy->forwarding = copy; // patch heap copy to point to itself (skip write-barrier)
|
||||
src->forwarding = copy; // patch stack to point to heap copy
|
||||
copy->size = src->size;
|
||||
if (isWeak) {
|
||||
copy->isa = &_NSConcreteWeakBlockVariable; // mark isa field so it gets weak scanning
|
||||
}
|
||||
if (src->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
// Trust copy helper to copy everything of interest
|
||||
// If more than one field shows up in a byref block this is wrong XXX
|
||||
copy->byref_keep = src->byref_keep;
|
||||
copy->byref_destroy = src->byref_destroy;
|
||||
(*src->byref_keep)(copy, src);
|
||||
}
|
||||
else {
|
||||
// just bits. Blast 'em using _Block_memmove in case they're __strong
|
||||
_Block_memmove(
|
||||
(void *)©->byref_keep,
|
||||
(void *)&src->byref_keep,
|
||||
src->size - sizeof(struct Block_byref_header));
|
||||
}
|
||||
}
|
||||
// already copied to heap
|
||||
else if ((src->forwarding->flags & BLOCK_NEEDS_FREE) == BLOCK_NEEDS_FREE) {
|
||||
latching_incr_int(&src->forwarding->flags);
|
||||
}
|
||||
// assign byref data block pointer into new Block
|
||||
_Block_assign(src->forwarding, (void **)destp);
|
||||
}
|
||||
|
||||
// Old compiler SPI
|
||||
static void _Block_byref_release(const void *arg) {
|
||||
struct Block_byref *shared_struct = (struct Block_byref *)arg;
|
||||
int refcount;
|
||||
|
||||
// dereference the forwarding pointer since the compiler isn't doing this anymore (ever?)
|
||||
shared_struct = shared_struct->forwarding;
|
||||
|
||||
//printf("_Block_byref_release %p called, flags are %x\n", shared_struct, shared_struct->flags);
|
||||
// To support C++ destructors under GC we arrange for there to be a finalizer for this
|
||||
// by using an isa that directs the code to a finalizer that calls the byref_destroy method.
|
||||
if ((shared_struct->flags & BLOCK_NEEDS_FREE) == 0) {
|
||||
return; // stack or GC or global
|
||||
}
|
||||
refcount = shared_struct->flags & BLOCK_REFCOUNT_MASK;
|
||||
if (refcount <= 0) {
|
||||
printf("_Block_byref_release: Block byref data structure at %p underflowed\n", arg);
|
||||
}
|
||||
else if ((latching_decr_int(&shared_struct->flags) & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
//printf("disposing of heap based byref block\n");
|
||||
if (shared_struct->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
//printf("calling out to helper\n");
|
||||
(*shared_struct->byref_destroy)(shared_struct);
|
||||
}
|
||||
_Block_deallocator((struct Block_layout *)shared_struct);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* API supporting SPI
|
||||
* _Block_copy, _Block_release, and (old) _Block_destroy
|
||||
*
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#pragma mark SPI/API
|
||||
#endif /* if 0 */
|
||||
|
||||
void *_Block_copy(const void *arg) {
|
||||
return _Block_copy_internal(arg, WANTS_ONE);
|
||||
}
|
||||
|
||||
|
||||
// API entry point to release a copied Block
|
||||
void _Block_release(void *arg) {
|
||||
struct Block_layout *aBlock = (struct Block_layout *)arg;
|
||||
int32_t newCount;
|
||||
if (!aBlock) return;
|
||||
newCount = latching_decr_int(&aBlock->flags) & BLOCK_REFCOUNT_MASK;
|
||||
if (newCount > 0) return;
|
||||
// Hit zero
|
||||
if (aBlock->flags & BLOCK_IS_GC) {
|
||||
// Tell GC we no longer have our own refcounts. GC will decr its refcount
|
||||
// and unless someone has done a CFRetain or marked it uncollectable it will
|
||||
// now be subject to GC reclamation.
|
||||
_Block_setHasRefcount(aBlock, false);
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_NEEDS_FREE) {
|
||||
if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE)(*aBlock->descriptor->dispose)(aBlock);
|
||||
_Block_deallocator(aBlock);
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_IS_GLOBAL) {
|
||||
;
|
||||
}
|
||||
else {
|
||||
printf("Block_release called upon a stack Block: %p, ignored\n", (void *)aBlock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Old Compiler SPI point to release a copied Block used by the compiler in dispose helpers
|
||||
static void _Block_destroy(const void *arg) {
|
||||
struct Block_layout *aBlock;
|
||||
if (!arg) return;
|
||||
aBlock = (struct Block_layout *)arg;
|
||||
if (aBlock->flags & BLOCK_IS_GC) {
|
||||
// assert(aBlock->Block_flags & BLOCK_HAS_CTOR);
|
||||
return; // ignore, we are being called because of a DTOR
|
||||
}
|
||||
_Block_release(aBlock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* SPI used by other layers
|
||||
*
|
||||
*/
|
||||
|
||||
// SPI, also internal. Called from NSAutoBlock only under GC
|
||||
void *_Block_copy_collectable(const void *aBlock) {
|
||||
return _Block_copy_internal(aBlock, 0);
|
||||
}
|
||||
|
||||
|
||||
// SPI
|
||||
unsigned long int Block_size(void *arg) {
|
||||
return ((struct Block_layout *)arg)->descriptor->size;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark Compiler SPI entry points
|
||||
#endif /* if 0 */
|
||||
|
||||
|
||||
/*******************************************************
|
||||
|
||||
Entry points used by the compiler - the real API!
|
||||
|
||||
|
||||
A Block can reference four different kinds of things that require help when the Block is copied to the heap.
|
||||
1) C++ stack based objects
|
||||
2) References to Objective-C objects
|
||||
3) Other Blocks
|
||||
4) __block variables
|
||||
|
||||
In these cases helper functions are synthesized by the compiler for use in Block_copy and Block_release, called the copy and dispose helpers. The copy helper emits a call to the C++ const copy constructor for C++ stack based objects and for the rest calls into the runtime support function _Block_object_assign. The dispose helper has a call to the C++ destructor for case 1 and a call into _Block_object_dispose for the rest.
|
||||
|
||||
The flags parameter of _Block_object_assign and _Block_object_dispose is set to
|
||||
* BLOCK_FIELD_IS_OBJECT (3), for the case of an Objective-C Object,
|
||||
* BLOCK_FIELD_IS_BLOCK (7), for the case of another Block, and
|
||||
* BLOCK_FIELD_IS_BYREF (8), for the case of a __block variable.
|
||||
If the __block variable is marked weak the compiler also or's in BLOCK_FIELD_IS_WEAK (16).
|
||||
|
||||
So the Block copy/dispose helpers should only ever generate the four flag values of 3, 7, 8, and 24.
|
||||
|
||||
When a __block variable is either a C++ object, an Objective-C object, or another Block then the compiler also generates copy/dispose helper functions. Similarly to the Block copy helper, the "__block" copy helper (formerly and still a.k.a. "byref" copy helper) will do a C++ copy constructor (not a const one though!) and the dispose helper will do the destructor. And similarly the helpers will call into the same two support functions with the same values for objects and Blocks with the additional BLOCK_BYREF_CALLER (128) bit of information supplied.
|
||||
|
||||
So the __block copy/dispose helpers will generate flag values of 3 or 7 for objects and Blocks respectively, with BLOCK_FIELD_IS_WEAK (16) or'ed as appropriate and always 128 or'd in, for the following set of possibilities:
|
||||
__block id 128+3
|
||||
__weak block id 128+3+16
|
||||
__block (^Block) 128+7
|
||||
__weak __block (^Block) 128+7+16
|
||||
|
||||
The implementation of the two routines would be improved by switch statements enumerating the eight cases.
|
||||
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* When Blocks or Block_byrefs hold objects then their copy routine helpers use this entry point
|
||||
* to do the assignment.
|
||||
*/
|
||||
void _Block_object_assign(void *destAddr, const void *object, const int flags) {
|
||||
//printf("_Block_object_assign(*%p, %p, %x)\n", destAddr, object, flags);
|
||||
if ((flags & BLOCK_BYREF_CALLER) == BLOCK_BYREF_CALLER) {
|
||||
if ((flags & BLOCK_FIELD_IS_WEAK) == BLOCK_FIELD_IS_WEAK) {
|
||||
_Block_assign_weak(object, destAddr);
|
||||
}
|
||||
else {
|
||||
// do *not* retain or *copy* __block variables whatever they are
|
||||
_Block_assign((void *)object, destAddr);
|
||||
}
|
||||
}
|
||||
else if ((flags & BLOCK_FIELD_IS_BYREF) == BLOCK_FIELD_IS_BYREF) {
|
||||
// copying a __block reference from the stack Block to the heap
|
||||
// flags will indicate if it holds a __weak reference and needs a special isa
|
||||
_Block_byref_assign_copy(destAddr, object, flags);
|
||||
}
|
||||
// (this test must be before next one)
|
||||
else if ((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK) {
|
||||
// copying a Block declared variable from the stack Block to the heap
|
||||
_Block_assign(_Block_copy_internal(object, flags), destAddr);
|
||||
}
|
||||
// (this test must be after previous one)
|
||||
else if ((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT) {
|
||||
//printf("retaining object at %p\n", object);
|
||||
_Block_retain_object(object);
|
||||
//printf("done retaining object at %p\n", object);
|
||||
_Block_assign((void *)object, destAddr);
|
||||
}
|
||||
}
|
||||
|
||||
// When Blocks or Block_byrefs hold objects their destroy helper routines call this entry point
|
||||
// to help dispose of the contents
|
||||
// Used initially only for __attribute__((NSObject)) marked pointers.
|
||||
void _Block_object_dispose(const void *object, const int flags) {
|
||||
//printf("_Block_object_dispose(%p, %x)\n", object, flags);
|
||||
if (flags & BLOCK_FIELD_IS_BYREF) {
|
||||
// get rid of the __block data structure held in a Block
|
||||
_Block_byref_release(object);
|
||||
}
|
||||
else if ((flags & (BLOCK_FIELD_IS_BLOCK|BLOCK_BYREF_CALLER)) == BLOCK_FIELD_IS_BLOCK) {
|
||||
// get rid of a referenced Block held by this Block
|
||||
// (ignore __block Block variables, compiler doesn't need to call us)
|
||||
_Block_destroy(object);
|
||||
}
|
||||
else if ((flags & (BLOCK_FIELD_IS_WEAK|BLOCK_FIELD_IS_BLOCK|BLOCK_BYREF_CALLER)) == BLOCK_FIELD_IS_OBJECT) {
|
||||
// get rid of a referenced object held by this Block
|
||||
// (ignore __block object variables, compiler doesn't need to call us)
|
||||
_Block_release_object(object);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debugging support:
|
||||
*/
|
||||
#if 0
|
||||
#pragma mark Debugging
|
||||
#endif /* if 0 */
|
||||
|
||||
|
||||
const char *_Block_dump(const void *block) {
|
||||
struct Block_layout *closure = (struct Block_layout *)block;
|
||||
static char buffer[512];
|
||||
char *cp = buffer;
|
||||
if (closure == NULL) {
|
||||
sprintf(cp, "NULL passed to _Block_dump\n");
|
||||
return buffer;
|
||||
}
|
||||
if (! (closure->flags & BLOCK_HAS_DESCRIPTOR)) {
|
||||
printf("Block compiled by obsolete compiler, please recompile source for this Block\n");
|
||||
exit(1);
|
||||
}
|
||||
cp += sprintf(cp, "^%p (new layout) =\n", (void *)closure);
|
||||
if (closure->isa == NULL) {
|
||||
cp += sprintf(cp, "isa: NULL\n");
|
||||
}
|
||||
else if (closure->isa == _NSConcreteStackBlock) {
|
||||
cp += sprintf(cp, "isa: stack Block\n");
|
||||
}
|
||||
else if (closure->isa == _NSConcreteMallocBlock) {
|
||||
cp += sprintf(cp, "isa: malloc heap Block\n");
|
||||
}
|
||||
else if (closure->isa == _NSConcreteAutoBlock) {
|
||||
cp += sprintf(cp, "isa: GC heap Block\n");
|
||||
}
|
||||
else if (closure->isa == _NSConcreteGlobalBlock) {
|
||||
cp += sprintf(cp, "isa: global Block\n");
|
||||
}
|
||||
else if (closure->isa == _NSConcreteFinalizingBlock) {
|
||||
cp += sprintf(cp, "isa: finalizing Block\n");
|
||||
}
|
||||
else {
|
||||
cp += sprintf(cp, "isa?: %p\n", (void *)closure->isa);
|
||||
}
|
||||
cp += sprintf(cp, "flags:");
|
||||
if (closure->flags & BLOCK_HAS_DESCRIPTOR) {
|
||||
cp += sprintf(cp, " HASDESCRIPTOR");
|
||||
}
|
||||
if (closure->flags & BLOCK_NEEDS_FREE) {
|
||||
cp += sprintf(cp, " FREEME");
|
||||
}
|
||||
if (closure->flags & BLOCK_IS_GC) {
|
||||
cp += sprintf(cp, " ISGC");
|
||||
}
|
||||
if (closure->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
cp += sprintf(cp, " HASHELP");
|
||||
}
|
||||
if (closure->flags & BLOCK_HAS_CTOR) {
|
||||
cp += sprintf(cp, " HASCTOR");
|
||||
}
|
||||
cp += sprintf(cp, "\nrefcount: %u\n", closure->flags & BLOCK_REFCOUNT_MASK);
|
||||
cp += sprintf(cp, "invoke: %p\n", (void *)(uintptr_t)closure->invoke);
|
||||
{
|
||||
struct Block_descriptor *dp = closure->descriptor;
|
||||
cp += sprintf(cp, "descriptor: %p\n", (void *)dp);
|
||||
cp += sprintf(cp, "descriptor->reserved: %lu\n", dp->reserved);
|
||||
cp += sprintf(cp, "descriptor->size: %lu\n", dp->size);
|
||||
|
||||
if (closure->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
cp += sprintf(cp, "descriptor->copy helper: %p\n", (void *)(uintptr_t)dp->copy);
|
||||
cp += sprintf(cp, "descriptor->dispose helper: %p\n", (void *)(uintptr_t)dp->dispose);
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
const char *_Block_byref_dump(struct Block_byref *src) {
|
||||
static char buffer[256];
|
||||
char *cp = buffer;
|
||||
cp += sprintf(cp, "byref data block %p contents:\n", (void *)src);
|
||||
cp += sprintf(cp, " forwarding: %p\n", (void *)src->forwarding);
|
||||
cp += sprintf(cp, " flags: 0x%x\n", src->flags);
|
||||
cp += sprintf(cp, " size: %d\n", src->size);
|
||||
if (src->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
cp += sprintf(cp, " copy helper: %p\n", (void *)(uintptr_t)src->byref_keep);
|
||||
cp += sprintf(cp, " dispose helper: %p\n", (void *)(uintptr_t)src->byref_destroy);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# See docs/CMake.html for instructions about how to build Compiler-RT with CMake.
|
||||
|
||||
PROJECT( CompilerRT C )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
|
||||
|
||||
set(PACKAGE_NAME compiler-rt)
|
||||
set(PACKAGE_VERSION 1.0svn)
|
||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu")
|
||||
|
||||
SET( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules )
|
||||
|
||||
# add definitions
|
||||
include(DefineCompilerFlags)
|
||||
|
||||
# Disallow in-source build
|
||||
INCLUDE( MacroEnsureOutOfSourceBuild )
|
||||
MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
|
||||
"${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
|
||||
)
|
||||
|
||||
INCLUDE( ${CMAKE_SOURCE_DIR}/cmake/ConfigureChecks.cmake )
|
||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/cmake/config.h.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h )
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
SET( Achitectures
|
||||
i386 x86_64 ppc arm
|
||||
)
|
||||
|
||||
SET( Configurations
|
||||
Debug Release Profile
|
||||
)
|
||||
|
||||
# Only build Blocks Runtime if the compiler has enough support
|
||||
IF( WIN32 OR MSVC OR HAVE_OSATOMIC_COMPARE_AND_SWAP_INT OR HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT )
|
||||
SET(BUILD_BLOCKS_RUNTIME TRUE)
|
||||
ELSE( WIN32 OR MSVC OR HAVE_OSATOMIC_COMPARE_AND_SWAP_INT OR HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT )
|
||||
SET(BUILD_BLOCKS_RUNTIME FALSE)
|
||||
ENDIF( WIN32 OR MSVC OR HAVE_OSATOMIC_COMPARE_AND_SWAP_INT OR HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT )
|
||||
|
||||
IF( BUILD_BLOCKS_RUNTIME )
|
||||
ADD_SUBDIRECTORY( BlocksRuntime )
|
||||
ELSE( BUILD_BLOCKS_RUNTIME )
|
||||
MESSAGE(STATUS "No suitable atomic operation routines detected, skipping Blocks Runtime")
|
||||
ENDIF( BUILD_BLOCKS_RUNTIME )
|
||||
|
||||
ADD_SUBDIRECTORY( lib )
|
||||
|
||||
# Enable Test Suit:
|
||||
INCLUDE( MacroAddCheckTest )
|
||||
ADD_SUBDIRECTORY( test )
|
||||
@@ -1,21 +0,0 @@
|
||||
This file is a partial list of people who have contributed to the LLVM/CompilerRT
|
||||
project. If you have contributed a patch or made some other contribution to
|
||||
LLVM/CompilerRT, please submit a patch to this file to add yourself, and it will be
|
||||
done!
|
||||
|
||||
The list is sorted by surname and formatted to allow easy grepping and
|
||||
beautification by scripts. The fields are: name (N), email (E), web-address
|
||||
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
|
||||
(S).
|
||||
|
||||
N: Craig van Vliet
|
||||
E: cvanvliet@auroraux.org
|
||||
W: http://www.auroraux.org
|
||||
D: Code style and Readability fixes.
|
||||
|
||||
N: Edward O'Callaghan
|
||||
E: eocallaghan@auroraux.org
|
||||
W: http://www.auroraux.org
|
||||
D: CMake'ify Compiler-RT build system
|
||||
D: Maintain Solaris & AuroraUX ports of Compiler-RT
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
==============================================================================
|
||||
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
|
||||
------- ---------
|
||||
@@ -1,237 +0,0 @@
|
||||
SubDirs := lib
|
||||
|
||||
# Set default rule before anything else.
|
||||
all: help
|
||||
|
||||
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
|
||||
|
||||
# FIXME: Document the available subtargets.
|
||||
help:
|
||||
@echo "usage: make [{VARIABLE=VALUE}*] target"
|
||||
@echo
|
||||
@echo "User variables:"
|
||||
@echo " VERBOSE=1: Use to show all commands [default=0]"
|
||||
@echo
|
||||
@echo "Available targets:"
|
||||
@echo " <platform name>: build the libraries for 'platform'"
|
||||
@echo " clean: clean all configurations"
|
||||
@echo " test: run unit tests"
|
||||
@echo
|
||||
@echo " info-platforms: list available platforms"
|
||||
@echo " help-devel: print additional help for developers"
|
||||
@echo
|
||||
|
||||
help-devel: help
|
||||
@echo "Development targets:"
|
||||
@echo " <platform name>-<config name>:"
|
||||
@echo " build the libraries for a single platform config"
|
||||
@echo " <platform name>-<config name>-<arch name>:"
|
||||
@echo " build the libraries for a single config and arch"
|
||||
@echo " info-functions: list available compiler-rt functions"
|
||||
@echo " help-hidden: print help for Makefile debugging"
|
||||
@echo
|
||||
|
||||
help-hidden: help-devel
|
||||
@echo "Debugging variables:"
|
||||
@echo " DEBUGMAKE=1: enable some Makefile logging [default=]"
|
||||
@echo " =2: enable more Makefile logging"
|
||||
@echo
|
||||
@echo "Debugging targets:"
|
||||
@echo " make-print-FOO: print information on the variable 'FOO'"
|
||||
@echo
|
||||
|
||||
info-functions:
|
||||
@echo "compiler-rt Available Functions"
|
||||
@echo
|
||||
@echo "All Functions: $(AvailableFunctions)"
|
||||
@$(foreach fn,$(AvailableFunctions),\
|
||||
printf " %-20s - available in (%s)\n" $(fn)\
|
||||
"$(foreach key,$(AvailableIn.$(fn)),$($(key).Dir))";)
|
||||
|
||||
info-platforms:
|
||||
@echo "compiler-rt Available Platforms"
|
||||
@echo
|
||||
@echo "Platforms:"
|
||||
@$(foreach key,$(PlatformKeys),\
|
||||
printf " %s - from '%s'\n" $($(key).Name) $($(key).Path);\
|
||||
printf " %s\n" "$($(key).Description)";\
|
||||
printf " Configurations: %s\n\n" "$($(key).Configs)";)
|
||||
|
||||
# Provide default clean target which is extended by other templates.
|
||||
.PHONY: clean
|
||||
clean::
|
||||
|
||||
# Test
|
||||
.PHONY: test
|
||||
test:
|
||||
cd test/Unit && ./test
|
||||
|
||||
###
|
||||
# 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
|
||||
|
||||
Dir := .
|
||||
include make/subdir.mk
|
||||
include make/lib_info.mk
|
||||
include make/lib_util.mk
|
||||
include make/lib_platforms.mk
|
||||
|
||||
###
|
||||
# Define Platform Rules
|
||||
|
||||
define PerPlatform_template
|
||||
$(call Set,Tmp.Key,$(1))
|
||||
$(call Set,Tmp.Name,$($(Tmp.Key).Name))
|
||||
$(call Set,Tmp.Configs,$($(Tmp.Key).Configs))
|
||||
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name))
|
||||
|
||||
# Top-Level Platform Target
|
||||
$(Tmp.Name):: $(Tmp.Configs:%=$(Tmp.ObjPath)/%/libcompiler_rt.a)
|
||||
.PHONY: $(Tmp.Name)
|
||||
|
||||
clean::
|
||||
$(Verb) rm -rf $(Tmp.ObjPath)
|
||||
|
||||
# Per-Config Libraries
|
||||
$(foreach config,$(Tmp.Configs),\
|
||||
$(call PerPlatformConfig_template,$(config)))
|
||||
endef
|
||||
|
||||
define PerPlatformConfig_template
|
||||
$(call Set,Tmp.Config,$(1))
|
||||
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config))
|
||||
|
||||
# Compute the archs to build, depending on whether this is a universal build or
|
||||
# not.
|
||||
$(call Set,Tmp.ArchsToBuild,\
|
||||
$(if $(call IsDefined,$(Tmp.Key).UniversalArchs),\
|
||||
$(strip \
|
||||
$(or $($(Tmp.Key).UniversalArchs.$(Tmp.Config)),\
|
||||
$($(Tmp.Key).UniversalArchs))),\
|
||||
$(call VarOrDefault,$(Tmp.Key).Arch.$(Tmp.Config),$($(Tmp.Key).Arch))))
|
||||
|
||||
# Copy or lipo to create the per-config library.
|
||||
$(call Set,Tmp.Inputs,$(Tmp.ArchsToBuild:%=$(Tmp.ObjPath)/%/libcompiler_rt.a))
|
||||
$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
|
||||
$(Summary) " FINAL-ARCHIVE: $(Tmp.Name)/$(Tmp.Config): $$@"
|
||||
-$(Verb) $(RM) $$@
|
||||
$(if $(call streq,1,$(words $(Tmp.ArchsToBuild))), \
|
||||
$(Verb) $(CP) $(Tmp.Inputs) $$@, \
|
||||
$(Verb) $(LIPO) -create -output $$@ $(Tmp.Inputs))
|
||||
.PRECIOUS: $(Tmp.ObjPath)/.dir
|
||||
|
||||
# Per-Config Targets
|
||||
$(Tmp.Name)-$(Tmp.Config):: $(Tmp.ObjPath)/libcompiler_rt.a
|
||||
.PHONY: $(Tmp.Name)-$(Tmp.Config)
|
||||
|
||||
# Per-Config-Arch Libraries
|
||||
$(foreach arch,$(Tmp.ArchsToBuild),\
|
||||
$(call PerPlatformConfigArch_template,$(arch)))
|
||||
endef
|
||||
|
||||
define PerPlatformConfigArch_template
|
||||
$(call Set,Tmp.Arch,$(1))
|
||||
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch))
|
||||
$(call Set,Tmp.Functions,$(strip \
|
||||
$(call GetCNAVar,FUNCTIONS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
$(call Set,Tmp.Optimized,$(strip \
|
||||
$(call GetCNAVar,OPTIMIZED,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
$(call Set,Tmp.AR,$(strip \
|
||||
$(call GetCNAVar,AR,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
$(call Set,Tmp.ARFLAGS,$(strip \
|
||||
$(call GetCNAVar,ARFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
$(call Set,Tmp.RANLIB,$(strip \
|
||||
$(call GetCNAVar,RANLIB,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
$(call Set,Tmp.RANLIBFLAGS,$(strip \
|
||||
$(call GetCNAVar,RANLIBFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
|
||||
# Compute the object inputs for this library.
|
||||
$(call Set,Tmp.Inputs,\
|
||||
$(foreach fn,$(sort $(Tmp.Functions)),\
|
||||
$(call Set,Tmp.FnDir,\
|
||||
$(call SelectFunctionDir,$(Tmp.Config),$(Tmp.Arch),$(fn),$(Tmp.Optimized)))\
|
||||
$(Tmp.ObjPath)/$(Tmp.FnDir)/$(fn).o))
|
||||
$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
|
||||
$(Summary) " ARCHIVE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@"
|
||||
-$(Verb) $(RM) $$@
|
||||
$(Verb) $(Tmp.AR) $(Tmp.ARFLAGS) $$@ $(Tmp.Inputs)
|
||||
$(Verb) $(Tmp.RANLIB) $(Tmp.RANLIBFLAGS) $$@
|
||||
.PRECIOUS: $(Tmp.ObjPath)/.dir
|
||||
|
||||
# Per-Config-Arch Targets
|
||||
$(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch):: $(Tmp.ObjPath)/libcompiler_rt.a
|
||||
.PHONY: $(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch)
|
||||
|
||||
# Per-Config-Arch-SubDir Objects
|
||||
$(foreach key,$(SubDirKeys),\
|
||||
$(call PerPlatformConfigArchSubDir_template,$(key)))
|
||||
endef
|
||||
|
||||
define PerPlatformConfigArchSubDir_template
|
||||
$(call Set,Tmp.SubDirKey,$(1))
|
||||
$(call Set,Tmp.SubDir,$($(Tmp.SubDirKey).Dir))
|
||||
$(call Set,Tmp.SrcPath,$(ProjSrcRoot)/$(Tmp.SubDir))
|
||||
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch)/$(Tmp.SubDirKey))
|
||||
$(call Set,Tmp.Dependencies,$($(Tmp.SubDirKey).Dependencies))
|
||||
$(call Set,Tmp.CC,$(strip \
|
||||
$(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
$(call Set,Tmp.CFLAGS,$(strip \
|
||||
$(if $(call IsDefined,$(Tmp.Key).UniversalArchs),-arch $(Tmp.Arch),)\
|
||||
$(if $(call streq,$($(Tmp.Key).VISIBILITY_HIDDEN),1),\
|
||||
-fvisibility=hidden -DVISIBILITY_HIDDEN,)\
|
||||
$(call GetCNAVar,CFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
|
||||
|
||||
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.s $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
|
||||
$(Summary) " ASSEMBLE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
|
||||
$(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c -o $$@ $$<
|
||||
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.S $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
|
||||
$(Summary) " ASSEMBLE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
|
||||
$(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c -o $$@ $$<
|
||||
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.c $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
|
||||
$(Summary) " COMPILE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
|
||||
$(Verb) $(Tmp.CC) $(Tmp.CFLAGS) -c -o $$@ $$<
|
||||
.PRECIOUS: $(Tmp.ObjPath)/.dir
|
||||
|
||||
endef
|
||||
|
||||
# Run templates.
|
||||
$(foreach key,$(PlatformKeys),\
|
||||
$(eval $(call PerPlatform_template,$(key))))
|
||||
|
||||
###
|
||||
|
||||
ifneq ($(DEBUGMAKE),)
|
||||
$(info MAKE: Done processing Makefile)
|
||||
$(info )
|
||||
endif
|
||||
@@ -1,331 +0,0 @@
|
||||
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 replacement 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
|
||||
ti_int __ashlti3(ti_int a, si_int b); // a << b
|
||||
|
||||
di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill)
|
||||
ti_int __ashrti3(ti_int a, si_int b); // a >> b arithmetic (sign fill)
|
||||
di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill)
|
||||
ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill)
|
||||
|
||||
si_int __clzsi2(si_int a); // count leading zeros
|
||||
si_int __clzdi2(di_int a); // count leading zeros
|
||||
si_int __clzti2(ti_int a); // count leading zeros
|
||||
si_int __ctzsi2(si_int a); // count trailing zeros
|
||||
si_int __ctzdi2(di_int a); // count trailing zeros
|
||||
si_int __ctzti2(ti_int a); // count trailing zeros
|
||||
|
||||
si_int __ffsdi2(di_int a); // find least significant 1 bit
|
||||
si_int __ffsti2(ti_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 __parityti2(ti_int a); // bit parity
|
||||
|
||||
si_int __popcountsi2(si_int a); // bit population
|
||||
si_int __popcountdi2(di_int a); // bit population
|
||||
si_int __popcountti2(ti_int a); // bit population
|
||||
|
||||
uint32_t __bswapsi2(uint32_t a); // a byteswapped, arm only
|
||||
uint64_t __bswapdi2(uint64_t a); // a byteswapped, arm only
|
||||
|
||||
// Integral arithmetic
|
||||
|
||||
di_int __negdi2 (di_int a); // -a
|
||||
ti_int __negti2 (ti_int a); // -a
|
||||
di_int __muldi3 (di_int a, di_int b); // a * b
|
||||
ti_int __multi3 (ti_int a, ti_int b); // a * b
|
||||
si_int __divsi3 (si_int a, si_int b); // a / b signed
|
||||
di_int __divdi3 (di_int a, di_int b); // a / b signed
|
||||
ti_int __divti3 (ti_int a, ti_int b); // a / b signed
|
||||
su_int __udivsi3 (su_int n, su_int d); // a / b unsigned
|
||||
du_int __udivdi3 (du_int a, du_int b); // a / b unsigned
|
||||
tu_int __udivti3 (tu_int a, tu_int b); // a / b unsigned
|
||||
si_int __modsi3 (si_int a, si_int b); // a % b signed
|
||||
di_int __moddi3 (di_int a, di_int b); // a % b signed
|
||||
ti_int __modti3 (ti_int a, ti_int b); // a % b signed
|
||||
su_int __umodsi3 (su_int a, su_int b); // a % b unsigned
|
||||
du_int __umoddi3 (du_int a, du_int b); // a % b unsigned
|
||||
tu_int __umodti3 (tu_int a, tu_int b); // a % b unsigned
|
||||
du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b
|
||||
tu_int __udivmodti4(tu_int a, tu_int b, tu_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)
|
||||
ti_int __absvti2(ti_int a); // abs(a)
|
||||
|
||||
si_int __negvsi2(si_int a); // -a
|
||||
di_int __negvdi2(di_int a); // -a
|
||||
ti_int __negvti2(ti_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
|
||||
ti_int __addvti3(ti_int a, ti_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
|
||||
ti_int __subvti3(ti_int a, ti_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
|
||||
ti_int __mulvti3(ti_int a, ti_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 __cmpti2 (ti_int a, ti_int b);
|
||||
si_int __ucmpdi2(du_int a, du_int b);
|
||||
si_int __ucmpti2(tu_int a, tu_int b);
|
||||
|
||||
// Integral / floating point conversion
|
||||
|
||||
di_int __fixsfdi( float a);
|
||||
di_int __fixdfdi( double a);
|
||||
di_int __fixxfdi(long double a);
|
||||
|
||||
ti_int __fixsfti( float a);
|
||||
ti_int __fixdfti( double a);
|
||||
ti_int __fixxfti(long double a);
|
||||
uint64_t __fixtfdi(long double input); // ppc only, doesn't match documentation
|
||||
|
||||
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);
|
||||
|
||||
tu_int __fixunssfti( float a);
|
||||
tu_int __fixunsdfti( double a);
|
||||
tu_int __fixunsxfti(long double a);
|
||||
uint64_t __fixunstfdi(long double input); // ppc only
|
||||
|
||||
float __floatdisf(di_int a);
|
||||
double __floatdidf(di_int a);
|
||||
long double __floatdixf(di_int a);
|
||||
long double __floatditf(int64_t a); // ppc only
|
||||
|
||||
float __floattisf(ti_int a);
|
||||
double __floattidf(ti_int a);
|
||||
long double __floattixf(ti_int a);
|
||||
|
||||
float __floatundisf(du_int a);
|
||||
double __floatundidf(du_int a);
|
||||
long double __floatundixf(du_int a);
|
||||
long double __floatunditf(uint64_t a); // ppc only
|
||||
|
||||
float __floatuntisf(tu_int a);
|
||||
double __floatuntidf(tu_int a);
|
||||
long double __floatuntixf(tu_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
|
||||
long double __powitf2(long double a, si_int b); // ppc only, 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);
|
||||
long double _Complex __multc3(long double a, long double b,
|
||||
long double c, long double d); // ppc only
|
||||
|
||||
// (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);
|
||||
long double _Complex __divtc3(long double a, long double b,
|
||||
long double c, long double d); // ppc only
|
||||
|
||||
|
||||
// Runtime support
|
||||
|
||||
// __clear_cache() is used to tell process that new instructions have been
|
||||
// written to an address range. Necessary on processors that do not have
|
||||
// a unified instuction and data cache.
|
||||
void __clear_cache(void* start, void* end);
|
||||
|
||||
// __enable_execute_stack() is used with nested functions when a trampoline
|
||||
// function is written onto the stack and that page range needs to be made
|
||||
// executable.
|
||||
void __enable_execute_stack(void* addr);
|
||||
|
||||
// __gcc_personality_v0() is normally only called by the system unwinder.
|
||||
// C code (as opposed to C++) normally does not need a personality function
|
||||
// because there are no catch clauses or destructors to be run. But there
|
||||
// is a C language extension __attribute__((cleanup(func))) which marks local
|
||||
// variables as needing the cleanup function "func" to be run when the
|
||||
// variable goes out of scope. That includes when an exception is thrown,
|
||||
// so a personality handler is needed.
|
||||
_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
|
||||
uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
|
||||
_Unwind_Context_t context);
|
||||
|
||||
// for use with some implementations of assert() in <assert.h>
|
||||
void __eprintf(const char* format, const char* assertion_expression,
|
||||
const char* line, const char* file);
|
||||
|
||||
|
||||
|
||||
// Power PC specific functions
|
||||
|
||||
// There is no C interface to the saveFP/restFP functions. They are helper
|
||||
// functions called by the prolog and epilog of functions that need to save
|
||||
// a number of non-volatile float point registers.
|
||||
saveFP
|
||||
restFP
|
||||
|
||||
// PowerPC has a standard template for trampoline functions. This function
|
||||
// generates a custom trampoline function with the specific realFunc
|
||||
// and localsPtr values.
|
||||
void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated,
|
||||
const void* realFunc, void* localsPtr);
|
||||
|
||||
// adds two 128-bit double-double precision values ( x + y )
|
||||
long double __gcc_qadd(long double x, long double y);
|
||||
|
||||
// subtracts two 128-bit double-double precision values ( x - y )
|
||||
long double __gcc_qsub(long double x, long double y);
|
||||
|
||||
// multiples two 128-bit double-double precision values ( x * y )
|
||||
long double __gcc_qmul(long double x, long double y);
|
||||
|
||||
// divides two 128-bit double-double precision values ( x / y )
|
||||
long double __gcc_qdiv(long double a, long double b);
|
||||
|
||||
|
||||
// ARM specific functions
|
||||
|
||||
// There is no C interface to the switch* functions. These helper functions
|
||||
// are only needed by Thumb1 code for efficient switch table generation.
|
||||
switch16
|
||||
switch32
|
||||
switch8
|
||||
switchu8
|
||||
|
||||
// There is no C interface to the *_vfp_d8_d15_regs functions. There are
|
||||
// called in the prolog and epilog of Thumb1 functions. When the C++ ABI use
|
||||
// SJLJ for exceptions, each function with a catch clause or destuctors needs
|
||||
// to save and restore all registers in it prolog and epliog. But there is
|
||||
// no way to access vector and high float registers from thumb1 code, so the
|
||||
// compiler must add call outs to these helper functions in the prolog and
|
||||
// epilog.
|
||||
restore_vfp_d8_d15_regs
|
||||
save_vfp_d8_d15_regs
|
||||
|
||||
|
||||
// Note: long ago ARM processors did not have floating point hardware support.
|
||||
// Floating point was done in software and floating point parameters were
|
||||
// passed in integer registers. When hardware support was added for floating
|
||||
// point, new *vfp functions were added to do the same operations but with
|
||||
// floating point parameters in floating point registers.
|
||||
|
||||
|
||||
// Undocumented functions
|
||||
|
||||
float __addsf3vfp(float a, float b); // Appears to return a + b
|
||||
double __adddf3vfp(double a, double b); // Appears to return a + b
|
||||
float __divsf3vfp(float a, float b); // Appears to return a / b
|
||||
double __divdf3vfp(double a, double b); // Appears to return a / b
|
||||
int __eqsf2vfp(float a, float b); // Appears to return one
|
||||
// iff a == b and neither is NaN.
|
||||
int __eqdf2vfp(double a, double b); // Appears to return one
|
||||
// iff a == b and neither is NaN.
|
||||
double __extendsfdf2vfp(float a); // Appears to convert from
|
||||
// float to double.
|
||||
int __fixdfsivfp(double a); // Appears to convert from
|
||||
// double to int.
|
||||
int __fixsfsivfp(float a); // Appears to convert from
|
||||
// float to int.
|
||||
unsigned int __fixunssfsivfp(float a); // Appears to convert from
|
||||
// float to unsigned int.
|
||||
unsigned int __fixunsdfsivfp(double a); // Appears to convert from
|
||||
// double to unsigned int.
|
||||
double __floatsidfvfp(int a); // Appears to convert from
|
||||
// int to double.
|
||||
float __floatsisfvfp(int a); // Appears to convert from
|
||||
// int to float.
|
||||
double __floatunssidfvfp(unsigned int a); // Appears to convert from
|
||||
// unisgned int to double.
|
||||
float __floatunssisfvfp(unsigned int a); // Appears to convert from
|
||||
// unisgned int to float.
|
||||
int __gedf2vfp(double a, double b); // Appears to return __gedf2
|
||||
// (a >= b)
|
||||
int __gesf2vfp(float a, float b); // Appears to return __gesf2
|
||||
// (a >= b)
|
||||
int __gtdf2vfp(double a, double b); // Appears to return __gtdf2
|
||||
// (a > b)
|
||||
int __gtsf2vfp(float a, float b); // Appears to return __gtsf2
|
||||
// (a > b)
|
||||
int __ledf2vfp(double a, double b); // Appears to return __ledf2
|
||||
// (a <= b)
|
||||
int __lesf2vfp(float a, float b); // Appears to return __lesf2
|
||||
// (a <= b)
|
||||
int __ltdf2vfp(double a, double b); // Appears to return __ltdf2
|
||||
// (a < b)
|
||||
int __ltsf2vfp(float a, float b); // Appears to return __ltsf2
|
||||
// (a < b)
|
||||
double __muldf3vfp(double a, double b); // Appears to return a * b
|
||||
float __mulsf3vfp(float a, float b); // Appears to return a * b
|
||||
int __nedf2vfp(double a, double b); // Appears to return __nedf2
|
||||
// (a != b)
|
||||
double __negdf2vfp(double a); // Appears to return -a
|
||||
float __negsf2vfp(float a); // Appears to return -a
|
||||
float __negsf2vfp(float a); // Appears to return -a
|
||||
double __subdf3vfp(double a, double b); // Appears to return a - b
|
||||
float __subsf3vfp(float a, float b); // Appears to return a - b
|
||||
float __truncdfsf2vfp(double a); // Appears to convert from
|
||||
// double to float.
|
||||
int __unorddf2vfp(double a, double b); // Appears to return __unorddf2
|
||||
int __unordsf2vfp(float a, float b); // Appears to return __unordsf2
|
||||
|
||||
|
||||
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.
|
||||
@@ -1,38 +0,0 @@
|
||||
INCLUDE( CheckIncludeFile )
|
||||
INCLUDE( CheckFunctionExists )
|
||||
INCLUDE( CheckSymbolExists )
|
||||
INCLUDE( CheckCSourceCompiles )
|
||||
|
||||
SET( PACKAGE ${PACKAGE_NAME} )
|
||||
SET( VERSION ${PACKAGE_VERSION} )
|
||||
|
||||
SET( BINARYDIR ${CMAKE_BINARY_DIR} )
|
||||
SET( SOURCEDIR ${CMAKE_SOURCE_DIR} )
|
||||
|
||||
# HEADER FILES
|
||||
CHECK_INCLUDE_FILE( sys/byteorder.h HAVE_SYS_BYTEORDER_H )
|
||||
CHECK_INCLUDE_FILE( AvailabilityMacros.h HAVE_AVAILABILITY_MACROS_H )
|
||||
CHECK_INCLUDE_FILE( TargetConditionals.h HAVE_TARGET_CONDITIONALS_H )
|
||||
CHECK_INCLUDE_FILE( libkern/OSAtomic.h HAVE_LIBKERN_OSATOMIC_H )
|
||||
|
||||
# FUNCTIONS
|
||||
CHECK_FUNCTION_EXISTS( sysconf HAVE_SYSCONF )
|
||||
CHECK_SYMBOL_EXISTS( OSAtomicCompareAndSwapInt libkern/OSAtomic.h HAVE_OSATOMIC_COMPARE_AND_SWAP_INT )
|
||||
CHECK_SYMBOL_EXISTS( OSAtomicCompareAndSwapLong libkern/OSAtomic.h HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG )
|
||||
|
||||
# BUILTIN
|
||||
CHECK_C_SOURCE_COMPILES( "
|
||||
volatile int a;
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)__sync_bool_compare_and_swap(&a, 1, 2);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT )
|
||||
|
||||
CHECK_C_SOURCE_COMPILES( "
|
||||
volatile long a;
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)__sync_bool_compare_and_swap(&a, 1, 2);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG )
|
||||
@@ -1,6 +0,0 @@
|
||||
# Define compiler flags
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
#ADD_DEFINITIONS( -Wall -W -Werror -pedantic )
|
||||
ADD_DEFINITIONS( -std=c99 -Wall -Wextra -W -pedantic -Wno-unused-parameter )
|
||||
endif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
@@ -1,12 +0,0 @@
|
||||
# - macro_add_check_test(test_name test_source linklib1 ... linklibN)
|
||||
|
||||
ENABLE_TESTING()
|
||||
include(CTest)
|
||||
set(CMAKE_C_FLAGS_PROFILING "-g -pg")
|
||||
|
||||
macro (MACRO_ADD_CHECK_TEST _testName _testSource)
|
||||
add_executable(${_testName} ${_testSource})
|
||||
target_link_libraries(${_testName} ${ARGN})
|
||||
get_target_property(_targetLocation ${_testName} LOCATION)
|
||||
add_test(${_testName} ${_targetLocation})
|
||||
endmacro (MACRO_ADD_CHECK_TEST)
|
||||
@@ -1,18 +0,0 @@
|
||||
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
|
||||
macro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage )
|
||||
|
||||
string( COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource )
|
||||
if( _insource )
|
||||
message( SEND_ERROR "${_errorMessage}" )
|
||||
message( FATAL_ERROR
|
||||
"In-source builds are not allowed.
|
||||
CMake would overwrite the makefiles distributed with Compiler-RT.
|
||||
Please create a directory and run cmake from there, passing the path
|
||||
to this source directory as the last argument.
|
||||
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
|
||||
Please delete them."
|
||||
)
|
||||
endif( _insource )
|
||||
|
||||
endmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD )
|
||||
@@ -1,12 +0,0 @@
|
||||
#cmakedefine HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER}
|
||||
#cmakedefine HAVE_AVAILABILITY_MACROS_H ${HAVE_AVAILABILITY_MACROS_H}
|
||||
#cmakedefine HAVE_TARGET_CONDITIONALS_H ${HAVE_TARGET_CONDITIONALS_H}
|
||||
#cmakedefine HAVE_LIBKERN_OSATOMIC_H ${HAVE_LIBKERN_OSATOMIC_H}
|
||||
|
||||
#cmakedefine HAVE_SYSCONF ${HAVE_SYSCONF}
|
||||
|
||||
#cmakedefine HAVE_OSATOMIC_COMPARE_AND_SWAP_INT ${HAVE_OSATOMIC_COMPARE_AND_SWAP_INT}
|
||||
#cmakedefine HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG ${HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG}
|
||||
|
||||
#cmakedefine HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT ${HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT}
|
||||
#cmakedefine HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG ${HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG}
|
||||
@@ -1,81 +0,0 @@
|
||||
#
|
||||
# Create a library called "CompilerRT" which includes the source files.
|
||||
|
||||
#INCLUDE_DIRECTORIES(
|
||||
# ${CMAKE_CURRENT_BINARY_DIR}
|
||||
#)
|
||||
|
||||
# Generic functions needed for each architecture
|
||||
# libcompiler_rt.Generic.a libcompiler_rt.Optimized.a
|
||||
|
||||
# Generic
|
||||
SET( Generic_SRCS
|
||||
absvdi2.c absvsi2.c addvdi3.c addvsi3.c ashldi3.c ashrdi3.c
|
||||
clzdi2.c clzsi2.c cmpdi2.c ctzdi2.c ctzsi2.c
|
||||
divdc3.c divdi3.c divsc3.c ffsdi2.c
|
||||
fixdfdi.c fixsfdi.c fixunsdfdi.c fixunsdfsi.c fixunssfdi.c
|
||||
fixunssfsi.c floatdidf.c floatdisf.c floatundidf.c floatundisf.c
|
||||
gcc_personality_v0.c lshrdi3.c moddi3.c muldc3.c muldi3.c
|
||||
mulsc3.c mulvdi3.c mulvsi3.c negdi2.c negvdi2.c negvsi2.c
|
||||
paritydi2.c paritysi2.c popcountdi2.c popcountsi2.c powidf2.c
|
||||
powisf2.c subvdi3.c subvsi3.c ucmpdi2.c udivdi3.c
|
||||
udivmoddi4.c umoddi3.c apple_versioning.c eprintf.c
|
||||
)
|
||||
|
||||
# Optimized functions for each architecture
|
||||
|
||||
# Commenting out for the min until the basics are working first.
|
||||
# ADD_SUBDIRECTORY( ppc )
|
||||
# ADD_SUBDIRECTORY( x86_64 )
|
||||
# ADD_SUBDIRECTORY( i386 )
|
||||
# ADD_SUBDIRECTORY( arm )
|
||||
|
||||
# List of functions needed for each architecture.
|
||||
SET( i386_Functions
|
||||
divxc3.c fixunsxfdi.c fixunsxfsi.c fixxfdi.c floatdixf.c
|
||||
floatundixf.c mulxc3.c powixf2.c clear_cache.c enable_execute_stack.c
|
||||
)
|
||||
|
||||
SET( x86_64_Functions
|
||||
absvti2.c addvti3.c ashlti3.c ashrti3.c clzti2.c cmpti2.c
|
||||
ctzti2.c divti3.c divxc3.c ffsti2.c fixdfti.c fixsfti.c
|
||||
fixunsdfti.c fixunssfti.c fixunsxfdi.c fixunsxfsi.c
|
||||
fixunsxfti.c fixxfdi.c fixxfti.c floatdixf.c floattidf.c
|
||||
floattisf.c floattixf.c floatundixf.c floatuntidf.c
|
||||
floatuntisf.c floatuntixf.c lshrti3.c modti3.c multi3.c
|
||||
mulvti3.c mulxc3.c negti2.c negvti2.c parityti2.c
|
||||
popcountti2.c powixf2.c subvti3.c ucmpti2.c udivmodti4.c
|
||||
udivti3.c umodti3.c clear_cache.c enable_execute_stack.c
|
||||
)
|
||||
|
||||
SET( PPC_Functions
|
||||
divtc3.c fixtfdi.c fixunstfdi.c floatditf.c floatunditf.c
|
||||
gcc_qadd.c gcc_qdiv.c gcc_qmul.c gcc_qsub.c multc3.c
|
||||
powitf2.c restFP.c saveFP.c trampoline_setup.c
|
||||
clear_cache.c enable_execute_stack.c
|
||||
)
|
||||
|
||||
SET( ARM_Functions
|
||||
adddf3vfp.c addsf3vfp.c bswapdi2.c bswapsi2.c divdf3vfp.c
|
||||
divsf3vfp.c eqdf2vfp.c eqsf2vfp.c extendsfdf2vfp.c
|
||||
fixdfsivfp.c fixsfsivfp.c fixunsdfsivfp.c fixunssfsivfp.c
|
||||
floatsidfvfp.c floatsisfvfp.c floatunssidfvfp.c floatunssisfvfp.c
|
||||
gedf2vfp.c gesf2vfp.c gtdf2vfp.c gtsf2vfp.c
|
||||
ledf2vfp.c lesf2vfp.c ltdf2vfp.c ltsf2vfp.c
|
||||
muldf3vfp.c mulsf3vfp.c
|
||||
nedf2vfp.c negdf2vfp.c negsf2vfp.c nesf2vfp.c
|
||||
subdf3vfp.c subsf3vfp.c truncdfsf2vfp.c unorddf2vfp.c unordsf2vfp.c
|
||||
modsi3.c umodsi3.c udivsi3.c divsi3.c switch.c
|
||||
)
|
||||
|
||||
#FOREACH( LOOP_VAR ${Achitectures} )
|
||||
# See ARCHIVE_OUTPUT_DIRECTORY docs.
|
||||
#${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${LOOP_VAR}
|
||||
#ENDFOREACH
|
||||
|
||||
ADD_LIBRARY( ${PROJECT_NAME}-Generic STATIC ${Generic_SRCS} )
|
||||
#ADD_LIBRARY( ${PROJECT_NAME}-i386 STATIC ${i386_Functions} )
|
||||
|
||||
# [[debug|optimized|general]
|
||||
#TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${PROJECT_NAME}-Common optimized ${PROJECT_NAME}-i386 )
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#===- 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.
|
||||
#
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
SubDirs := i386 ppc x86_64 arm
|
||||
|
||||
Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
|
||||
ObjNames := $(Sources:%.c=%.o)
|
||||
Implementation := Generic
|
||||
|
||||
# FIXME: use automatic dependencies?
|
||||
Dependencies := $(wildcard $(Dir)/*.h)
|
||||
@@ -1,30 +0,0 @@
|
||||
/*===-- 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;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* ===-- 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;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/* ===-- 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
|
||||
@@ -1,37 +0,0 @@
|
||||
/* ===-- 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;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* ===-- 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;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* ===-- 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
|
||||
@@ -1,150 +0,0 @@
|
||||
/* ===-- 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 __arm__
|
||||
#define NOT_HERE_BEFORE_10_6(sym)
|
||||
#elif __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 /* __ppc__ */
|
||||
|
||||
|
||||
/* 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 /* __ppc__ */
|
||||
|
||||
#else /* !__APPLE__ */
|
||||
|
||||
extern int avoid_empty_file;
|
||||
|
||||
#endif /* !__APPLE__*/
|
||||
@@ -1,19 +0,0 @@
|
||||
#===- lib/arm/Makefile.mk ----------------------------------*- Makefile -*--===#
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
SubDirs :=
|
||||
OnlyArchs := armv6 armv7
|
||||
|
||||
AsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))
|
||||
Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
|
||||
ObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)
|
||||
Implementation := Optimized
|
||||
|
||||
# FIXME: use automatic dependencies?
|
||||
Dependencies := $(wildcard lib/*.h $(Dir)/*.h)
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- adddf3vfp.S - Implement adddf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// double __adddf3vfp(double a, double b) { return a + b; }
|
||||
//
|
||||
// Adds two double precision floating point numbers using the Darwin
|
||||
// calling convention where double arguments are passsed in GPR pairs
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
faddd d6, d6, d7
|
||||
fmrrd r0, r1, d6 // move result back to r0/r1 pair
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- addsf3vfp.S - Implement addsf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __addsf3vfp(float a, float b);
|
||||
//
|
||||
// Adds two single precision floating point numbers using the Darwin
|
||||
// calling convention where single arguments are passsed in GPRs
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__addsf3vfp)
|
||||
fmsr s14, r0 // move first param from r0 into float register
|
||||
fmsr s15, r1 // move second param from r1 into float register
|
||||
fadds s14, s14, s15
|
||||
fmrs r0, s14 // move result back to r0
|
||||
bx lr
|
||||
@@ -1,22 +0,0 @@
|
||||
//===------- bswapdi2 - Implement bswapdi2 ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern uint64_t __bswapdi2(uint64_t);
|
||||
//
|
||||
// Reverse all the bytes in a 64-bit integer.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__bswapdi2)
|
||||
rev r2, r1 // reverse bytes in high 32-bits into temp2
|
||||
rev r3, r0 // reverse bytes in low 32-bit into temp3
|
||||
mov r0, r2 // set low 32-bits of result to temp2
|
||||
mov r1, r3 // set high 32-bits of result to temp3
|
||||
bx lr
|
||||
@@ -1,19 +0,0 @@
|
||||
//===------- bswapsi2 - Implement bswapsi2 ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern uint32_t __bswapsi2(uint32_t);
|
||||
//
|
||||
// Reverse all the bytes in a 32-bit integer.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__bswapsi2)
|
||||
rev r0, r0 // reverse bytes in parameter and put into result register
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- divdf3vfp.S - Implement divdf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __divdf3vfp(double a, double b);
|
||||
//
|
||||
// Divides two double precision floating point numbers using the Darwin
|
||||
// calling convention where double arguments are passsed in GPR pairs
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__divdf3vfp)
|
||||
fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
fdivd d5, d6, d7
|
||||
fmrrd r0, r1, d5 // move result back to r0/r1 pair
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- divsf3vfp.S - Implement divsf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __divsf3vfp(float a, float b);
|
||||
//
|
||||
// Divides two single precision floating point numbers using the Darwin
|
||||
// calling convention where single arguments are passsed like 32-bit ints.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__divsf3vfp)
|
||||
fmsr s14, r0 // move first param from r0 into float register
|
||||
fmsr s15, r1 // move second param from r1 into float register
|
||||
fdivs s13, s14, s15
|
||||
fmrs r0, s13 // move result back to r0
|
||||
bx lr
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- eqdf2vfp.S - Implement eqdf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __eqdf2vfp(double a, double b);
|
||||
//
|
||||
// Returns one iff a == b and neither is NaN.
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
moveq r0, #1 // set result register to 1 if equal
|
||||
movne r0, #0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- eqsf2vfp.S - Implement eqsf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __eqsf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a == b and neither is NaN.
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
moveq r0, #1 // set result register to 1 if equal
|
||||
movne r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- extendsfdf2vfp.S - Implement extendsfdf2vfp -----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __extendsfdf2vfp(float a);
|
||||
//
|
||||
// Converts single precision float to double precision result.
|
||||
// Uses Darwin calling convention where a single precision parameter is
|
||||
// passed in a GPR and a double precision result is returned in R0/R1 pair.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)
|
||||
fmsr s15, r0 // load float register from R0
|
||||
fcvtds d7, s15 // convert single to double
|
||||
fmrrd r0, r1, d7 // return result in r0/r1 pair
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- fixdfsivfp.S - Implement fixdfsivfp -----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __fixdfsivfp(double a);
|
||||
//
|
||||
// Converts double precision float to a 32-bit int rounding towards zero.
|
||||
// Uses Darwin calling convention where a double precision parameter is
|
||||
// passed in GPR register pair.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)
|
||||
fmdrr d7, r0, r1 // load double register from R0/R1
|
||||
ftosizd s15, d7 // convert double to 32-bit int into s15
|
||||
fmrs r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- fixsfsivfp.S - Implement fixsfsivfp -----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __fixsfsivfp(float a);
|
||||
//
|
||||
// Converts single precision float to a 32-bit int rounding towards zero.
|
||||
// Uses Darwin calling convention where a single precision parameter is
|
||||
// passed in a GPR..
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)
|
||||
fmsr s15, r0 // load float register from R0
|
||||
ftosizs s15, s15 // convert single to 32-bit int into s15
|
||||
fmrs r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
@@ -1,24 +0,0 @@
|
||||
//===-- fixunsdfsivfp.S - Implement fixunsdfsivfp -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern unsigned int __fixunsdfsivfp(double a);
|
||||
//
|
||||
// Converts double precision float to a 32-bit unsigned int rounding towards
|
||||
// zero. All negative values become zero.
|
||||
// Uses Darwin calling convention where a double precision parameter is
|
||||
// passed in GPR register pair.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)
|
||||
fmdrr d7, r0, r1 // load double register from R0/R1
|
||||
ftouizd s15, d7 // convert double to 32-bit int into s15
|
||||
fmrs r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
@@ -1,24 +0,0 @@
|
||||
//===-- fixunssfsivfp.S - Implement fixunssfsivfp -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern unsigned int __fixunssfsivfp(float a);
|
||||
//
|
||||
// Converts single precision float to a 32-bit unsigned int rounding towards
|
||||
// zero. All negative values become zero.
|
||||
// Uses Darwin calling convention where a single precision parameter is
|
||||
// passed in a GPR..
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)
|
||||
fmsr s15, r0 // load float register from R0
|
||||
ftouizs s15, s15 // convert single to 32-bit unsigned into s15
|
||||
fmrs r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- floatsidfvfp.S - Implement floatsidfvfp ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __floatsidfvfp(int a);
|
||||
//
|
||||
// Converts a 32-bit int to a double precision float.
|
||||
// Uses Darwin calling convention where a double precision result is
|
||||
// return in GPR register pair.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)
|
||||
fmsr s15, r0 // move int to float register s15
|
||||
fsitod d7, s15 // convert 32-bit int in s15 to double in d7
|
||||
fmrrd r0, r1, d7 // move d7 to result register pair r0/r1
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- floatsisfvfp.S - Implement floatsisfvfp ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __floatsisfvfp(int a);
|
||||
//
|
||||
// Converts single precision float to a 32-bit int rounding towards zero.
|
||||
// Uses Darwin calling convention where a single precision result is
|
||||
// return in a GPR..
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)
|
||||
fmsr s15, r0 // move int to float register s15
|
||||
fsitos s15, s15 // convert 32-bit int in s15 to float in s15
|
||||
fmrs r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- floatunssidfvfp.S - Implement floatunssidfvfp ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __floatunssidfvfp(unsigned int a);
|
||||
//
|
||||
// Converts a 32-bit int to a double precision float.
|
||||
// Uses Darwin calling convention where a double precision result is
|
||||
// return in GPR register pair.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)
|
||||
fmsr s15, r0 // move int to float register s15
|
||||
fuitod d7, s15 // convert 32-bit int in s15 to double in d7
|
||||
fmrrd r0, r1, d7 // move d7 to result register pair r0/r1
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- floatunssisfvfp.S - Implement floatunssisfvfp ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __floatunssisfvfp(unsigned int a);
|
||||
//
|
||||
// Converts single precision float to a 32-bit int rounding towards zero.
|
||||
// Uses Darwin calling convention where a single precision result is
|
||||
// return in a GPR..
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)
|
||||
fmsr s15, r0 // move int to float register s15
|
||||
fuitos s15, s15 // convert 32-bit int in s15 to float in s15
|
||||
fmrs r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- gedf2vfp.S - Implement gedf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __gedf2vfp(double a, double b);
|
||||
//
|
||||
// Returns one iff a >= b and neither is NaN.
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__gedf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
movge r0, #1 // set result register to 1 if greater than or equal
|
||||
movlt r0, #0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- gesf2vfp.S - Implement gesf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __gesf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a >= b and neither is NaN.
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__gesf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
movge r0, #1 // set result register to 1 if greater than or equal
|
||||
movlt r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- gtdf2vfp.S - Implement gtdf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __gtdf2vfp(double a, double b);
|
||||
//
|
||||
// Returns one iff a > b and neither is NaN.
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__gtdf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
movgt r0, #1 // set result register to 1 if equal
|
||||
movle r0, #0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- gtsf2vfp.S - Implement gtsf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __gtsf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a > b and neither is NaN.
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__gtsf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
movgt r0, #1 // set result register to 1 if equal
|
||||
movle r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- ledf2vfp.S - Implement ledf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __ledf2vfp(double a, double b);
|
||||
//
|
||||
// Returns one iff a <= b and neither is NaN.
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__ledf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
movls r0, #1 // set result register to 1 if equal
|
||||
movhi r0, #0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- lesf2vfp.S - Implement lesf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __lesf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a <= b and neither is NaN.
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__lesf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
movls r0, #1 // set result register to 1 if equal
|
||||
movhi r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- ltdf2vfp.S - Implement ltdf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __ltdf2vfp(double a, double b);
|
||||
//
|
||||
// Returns one iff a < b and neither is NaN.
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__ltdf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
movmi r0, #1 // set result register to 1 if equal
|
||||
movpl r0, #0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- ltsf2vfp.S - Implement ltsf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __ltsf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a < b and neither is NaN.
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__ltsf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
movmi r0, #1 // set result register to 1 if equal
|
||||
movpl r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- muldf3vfp.S - Implement muldf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __muldf3vfp(double a, double b);
|
||||
//
|
||||
// Multiplies two double precision floating point numbers using the Darwin
|
||||
// calling convention where double arguments are passsed in GPR pairs
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__muldf3vfp)
|
||||
fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
fmuld d6, d6, d7
|
||||
fmrrd r0, r1, d6 // move result back to r0/r1 pair
|
||||
bx lr
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- mulsf3vfp.S - Implement mulsf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __mulsf3vfp(float a, float b);
|
||||
//
|
||||
// Multiplies two single precision floating point numbers using the Darwin
|
||||
// calling convention where single arguments are passsed like 32-bit ints.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__mulsf3vfp)
|
||||
fmsr s14, r0 // move first param from r0 into float register
|
||||
fmsr s15, r1 // move second param from r1 into float register
|
||||
fmuls s13, s14, s15
|
||||
fmrs r0, s13 // move result back to r0
|
||||
bx lr
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- nedf2vfp.S - Implement nedf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __nedf2vfp(double a, double b);
|
||||
//
|
||||
// Returns zero if a and b are unequal and neither is NaN.
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__nedf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
movne r0, #1 // set result register to 0 if unequal
|
||||
moveq r0, #0
|
||||
bx lr
|
||||
@@ -1,20 +0,0 @@
|
||||
//===-- negdf2vfp.S - Implement negdf2vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __negdf2vfp(double a, double b);
|
||||
//
|
||||
// Returns the negation a double precision floating point numbers using the
|
||||
// Darwin calling convention where double arguments are passsed in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__negdf2vfp)
|
||||
eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair
|
||||
bx lr
|
||||
@@ -1,20 +0,0 @@
|
||||
//===-- negsf2vfp.S - Implement negsf2vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __negsf2vfp(float a);
|
||||
//
|
||||
// Returns the negation of a single precision floating point numbers using the
|
||||
// Darwin calling convention where single arguments are passsed like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__negsf2vfp)
|
||||
eor r0, r0, #-2147483648 // flip sign bit on float in r0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- nesf2vfp.S - Implement nesf2vfp -----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __nesf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a != b and neither is NaN.
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__nesf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
movne r0, #1 // set result register to 1 if unequal
|
||||
moveq r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
//===-- save_restore_regs.S - Implement save/restore* ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling C++ functions that need to handle thrown exceptions the
|
||||
// compiler is required to save all registers and call __Unwind_SjLj_Register
|
||||
// in the function prolog. But when compiling for thumb1, there are
|
||||
// no instructions to access the floating point registers, so the
|
||||
// compiler needs to add a call to the helper function _save_vfp_d8_d15_regs
|
||||
// written in ARM to save the float registers. In the epilog, the compiler
|
||||
// must also add a call to __restore_vfp_d8_d15_regs to restore those registers.
|
||||
//
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
//
|
||||
// Restore registers d8-d15 from stack
|
||||
//
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__restore_vfp_d8_d15_regs)
|
||||
vldmia sp!, {d8-d15} // pop registers d8-d15 off stack
|
||||
bx lr // return to prolog
|
||||
|
||||
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
//===-- save_restore_regs.S - Implement save/restore* ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling C++ functions that need to handle thrown exceptions the
|
||||
// compiler is required to save all registers and call __Unwind_SjLj_Register
|
||||
// in the function prolog. But when compiling for thumb1, there are
|
||||
// no instructions to access the floating point registers, so the
|
||||
// compiler needs to add a call to the helper function _save_vfp_d8_d15_regs
|
||||
// written in ARM to save the float registers. In the epilog, the compiler
|
||||
// must also add a call to __restore_vfp_d8_d15_regs to restore those registers.
|
||||
//
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
//
|
||||
// Save registers d8-d15 onto stack
|
||||
//
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__save_vfp_d8_d15_regs)
|
||||
vstmdb sp!, {d8-d15} // push registers d8-d15 onto stack
|
||||
bx lr // return to prolog
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- subdf3vfp.S - Implement subdf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern double __subdf3vfp(double a, double b);
|
||||
//
|
||||
// Returns difference between two double precision floating point numbers using
|
||||
// the Darwin calling convention where double arguments are passsed in GPR pairs
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__subdf3vfp)
|
||||
fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
fsubd d6, d6, d7
|
||||
fmrrd r0, r1, d6 // move result back to r0/r1 pair
|
||||
bx lr
|
||||
@@ -1,24 +0,0 @@
|
||||
//===-- subsf3vfp.S - Implement subsf3vfp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __subsf3vfp(float a, float b);
|
||||
//
|
||||
// Returns the difference between two single precision floating point numbers
|
||||
// using the Darwin calling convention where single arguments are passsed
|
||||
// like 32-bit ints.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__subsf3vfp)
|
||||
fmsr s14, r0 // move first param from r0 into float register
|
||||
fmsr s15, r1 // move second param from r1 into float register
|
||||
fsubs s14, s14, s15
|
||||
fmrs r0, s14 // move result back to r0
|
||||
bx lr
|
||||
@@ -1,43 +0,0 @@
|
||||
//===-- switch.S - Implement switch* --------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling switch statements in thumb mode, the compiler
|
||||
// can use these __switch* helper functions The compiler emits a blx to
|
||||
// the __switch* function followed by a table of displacements for each
|
||||
// case statement. On entry, R0 is the index into the table. The __switch*
|
||||
// function uses the return address in lr to find the start of the table.
|
||||
// The first entry in the table is the count of the entries in the table.
|
||||
// It then uses R0 to index into the table and get the displacement of the
|
||||
// address to jump to. If R0 is greater than the size of the table, it jumps
|
||||
// to the last entry in the table. Each displacement in the table is actually
|
||||
// the distance from lr to the label, thus making the tables PIC.
|
||||
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
//
|
||||
// The table contains signed 2-byte sized elements which are 1/2 the distance
|
||||
// from lr to the target label.
|
||||
//
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16)
|
||||
ldrh ip, [lr, #-1] // get first 16-bit word in table
|
||||
cmp r0, ip // compare with index
|
||||
add r0, lr, r0, lsl #1 // compute address of element in table
|
||||
ldrshcc r0, [r0, #1] // load 16-bit element if r0 is in range
|
||||
add ip, lr, ip, lsl #1 // compute address of last element in table
|
||||
ldrshhs r0, [ip, #1] // load 16-bit element if r0 out of range
|
||||
add ip, lr, r0, lsl #1 // compute label = lr + element*2
|
||||
bx ip // jump to computed label
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
@@ -1,45 +0,0 @@
|
||||
//===-- switch.S - Implement switch* --------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling switch statements in thumb mode, the compiler
|
||||
// can use these __switch* helper functions The compiler emits a blx to
|
||||
// the __switch* function followed by a table of displacements for each
|
||||
// case statement. On entry, R0 is the index into the table. The __switch*
|
||||
// function uses the return address in lr to find the start of the table.
|
||||
// The first entry in the table is the count of the entries in the table.
|
||||
// It then uses R0 to index into the table and get the displacement of the
|
||||
// address to jump to. If R0 is greater than the size of the table, it jumps
|
||||
// to the last entry in the table. Each displacement in the table is actually
|
||||
// the distance from lr to the label, thus making the tables PIC.
|
||||
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
//
|
||||
// The table contains signed 4-byte sized elements which are the distance
|
||||
// from lr to the target label.
|
||||
//
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch32)
|
||||
ldr ip, [lr, #-1] // get first 32-bit word in table
|
||||
cmp r0, ip // compare with index
|
||||
add r0, lr, r0, lsl #2 // compute address of element in table
|
||||
ldrcc r0, [r0, #3] // load 32-bit element if r0 is in range
|
||||
add ip, lr, ip, lsl #2 // compute address of last element in table
|
||||
ldrcs r0, [ip, #3] // load 32-bit element if r0 out of range
|
||||
add ip, lr, r0 // compute label = lr + element
|
||||
bx ip // jump to computed label
|
||||
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
//===-- switch.S - Implement switch* --------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling switch statements in thumb mode, the compiler
|
||||
// can use these __switch* helper functions The compiler emits a blx to
|
||||
// the __switch* function followed by a table of displacements for each
|
||||
// case statement. On entry, R0 is the index into the table. The __switch*
|
||||
// function uses the return address in lr to find the start of the table.
|
||||
// The first entry in the table is the count of the entries in the table.
|
||||
// It then uses R0 to index into the table and get the displacement of the
|
||||
// address to jump to. If R0 is greater than the size of the table, it jumps
|
||||
// to the last entry in the table. Each displacement in the table is actually
|
||||
// the distance from lr to the label, thus making the tables PIC.
|
||||
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
//
|
||||
// The table contains signed byte sized elements which are 1/2 the distance
|
||||
// from lr to the target label.
|
||||
//
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch8)
|
||||
ldrb ip, [lr, #-1] // get first byte in table
|
||||
cmp r0, ip // signed compare with index
|
||||
ldrsbcc r0, [lr, r0] // get indexed byte out of table
|
||||
ldrsbhs r0, [lr, ip] // if out of range, use last entry in table
|
||||
add ip, lr, r0, lsl #1 // compute label = lr + element*2
|
||||
bx ip // jump to computed label
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
//===-- switch.S - Implement switch* --------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling switch statements in thumb mode, the compiler
|
||||
// can use these __switch* helper functions The compiler emits a blx to
|
||||
// the __switch* function followed by a table of displacements for each
|
||||
// case statement. On entry, R0 is the index into the table. The __switch*
|
||||
// function uses the return address in lr to find the start of the table.
|
||||
// The first entry in the table is the count of the entries in the table.
|
||||
// It then uses R0 to index into the table and get the displacement of the
|
||||
// address to jump to. If R0 is greater than the size of the table, it jumps
|
||||
// to the last entry in the table. Each displacement in the table is actually
|
||||
// the distance from lr to the label, thus making the tables PIC.
|
||||
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
//
|
||||
// The table contains unsigned byte sized elements which are 1/2 the distance
|
||||
// from lr to the target label.
|
||||
//
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switchu8)
|
||||
ldrb ip, [lr, #-1] // get first byte in table
|
||||
cmp r0, ip // compare with index
|
||||
ldrbcc r0, [lr, r0] // get indexed byte out of table
|
||||
ldrbhs r0, [lr, ip] // if out of range, use last entry in table
|
||||
add ip, lr, r0, lsl #1 // compute label = lr + element*2
|
||||
bx ip // jump to computed label
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
//===-- sync_synchronize - Implement memory barrier * ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// When compiling a use of the gcc built-in __sync_synchronize() in thumb1 mode
|
||||
// the compiler may emit a call to __sync_synchronize.
|
||||
// On Darwin the implementation jumps to an OS supplied function named
|
||||
// OSMemoryBarrier
|
||||
//
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
#if __APPLE__
|
||||
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(__sync_synchronize)
|
||||
stmfd sp!, {r7, lr}
|
||||
add r7, sp, #0
|
||||
bl _OSMemoryBarrier
|
||||
ldmfd sp!, {r7, pc}
|
||||
|
||||
// tell linker it can break up file at label boundaries
|
||||
.subsections_via_symbols
|
||||
|
||||
#endif
|
||||
@@ -1,23 +0,0 @@
|
||||
//===-- truncdfsf2vfp.S - Implement truncdfsf2vfp -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern float __truncdfsf2vfp(double a);
|
||||
//
|
||||
// Converts double precision float to signle precision result.
|
||||
// Uses Darwin calling convention where a double precision parameter is
|
||||
// passed in a R0/R1 pair and a signle precision result is returned in R0.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__truncdfsf2vfp)
|
||||
fmdrr d7, r0, r1 // load double from r0/r1 pair
|
||||
fcvtsd s15, d7 // convert double to single (trucate precision)
|
||||
fmrs r0, s15 // return result in r0
|
||||
bx lr
|
||||
@@ -1,26 +0,0 @@
|
||||
//===-- unorddf2vfp.S - Implement unorddf2vfp ------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __unorddf2vfp(double a, double b);
|
||||
//
|
||||
// Returns one iff a or b is NaN
|
||||
// Uses Darwin calling convention where double precision arguments are passsed
|
||||
// like in GPR pairs.
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__unorddf2vfp)
|
||||
fmdrr d6, r0, r1 // load r0/r1 pair in double register
|
||||
fmdrr d7, r2, r3 // load r2/r3 pair in double register
|
||||
fcmpd d6, d7
|
||||
fmstat
|
||||
movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
|
||||
movvc r0, #0
|
||||
bx lr
|
||||
@@ -1,27 +0,0 @@
|
||||
//===-- unordsf2vfp.S - Implement unordsf2vfp -----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
//
|
||||
// extern int __unordsf2vfp(float a, float b);
|
||||
//
|
||||
// Returns one iff a or b is NaN
|
||||
// Uses Darwin calling convention where single precision arguments are passsed
|
||||
// like 32-bit ints
|
||||
//
|
||||
DEFINE_COMPILERRT_FUNCTION(__unordsf2vfp)
|
||||
fmsr s14, r0 // move from GPR 0 to float register
|
||||
fmsr s15, r1 // move from GPR 1 to float register
|
||||
fcmps s14, s15
|
||||
fmstat
|
||||
movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
|
||||
movvc r0, #0
|
||||
bx lr
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/* ====-- 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.s.low = 0;
|
||||
result.s.high = input.s.low << (b - bits_in_word);
|
||||
}
|
||||
else /* 0 <= b < bits_in_word */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.low = input.s.low << b;
|
||||
result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b));
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/* ===-- 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.s.low = 0;
|
||||
result.s.high = input.s.low << (b - bits_in_dword);
|
||||
}
|
||||
else /* 0 <= b < bits_in_dword */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.low = input.s.low << b;
|
||||
result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_dword - b));
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
|
||||
#endif /* __x86_64 */
|
||||
@@ -1,42 +0,0 @@
|
||||
/*===-- 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.s.high = input.s.high < 0 ? -1 : 0 */
|
||||
result.s.high = input.s.high >> (bits_in_word - 1);
|
||||
result.s.low = input.s.high >> (b - bits_in_word);
|
||||
}
|
||||
else /* 0 <= b < bits_in_word */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.high = input.s.high >> b;
|
||||
result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/* ===-- 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.s.high = input.s.high < 0 ? -1 : 0 */
|
||||
result.s.high = input.s.high >> (bits_in_dword - 1);
|
||||
result.s.low = input.s.high >> (b - bits_in_dword);
|
||||
}
|
||||
else /* 0 <= b < bits_in_dword */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.high = input.s.high >> b;
|
||||
result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b);
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
|
||||
#endif /* __x86_64 */
|
||||
@@ -1,54 +0,0 @@
|
||||
/* ===-- assembly.h - compiler-rt assembler support macros -----------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file defines macros for use in compiler-rt assembler source.
|
||||
* This file is not part of the interface of this library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef COMPILERRT_ASSEMBLY_H
|
||||
#define COMPILERRT_ASSEMBLY_H
|
||||
|
||||
#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
|
||||
#define SEPARATOR @
|
||||
#else
|
||||
#define SEPARATOR ;
|
||||
#endif
|
||||
|
||||
/* We can't use __USER_LABEL_PREFIX__ here, it isn't possible to concatenate the
|
||||
*values* of two macros. This is quite brittle, though. */
|
||||
#if defined(__APPLE__)
|
||||
#define SYMBOL_NAME(name) _##name
|
||||
#else
|
||||
#define SYMBOL_NAME(name) name
|
||||
#endif
|
||||
|
||||
#ifdef VISIBILITY_HIDDEN
|
||||
#define DEFINE_COMPILERRT_FUNCTION(name) \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
.private_extern SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_NAME(name):
|
||||
#else
|
||||
#define DEFINE_COMPILERRT_FUNCTION(name) \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_NAME(name):
|
||||
#endif
|
||||
|
||||
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
.private_extern SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_NAME(name):
|
||||
|
||||
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
|
||||
.globl name SEPARATOR \
|
||||
.private_extern name SEPARATOR \
|
||||
name:
|
||||
|
||||
#endif /* COMPILERRT_ASSEMBLY_H */
|
||||
@@ -1,40 +0,0 @@
|
||||
/* ===-- 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
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/* ===-- 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.s.high == 0);
|
||||
return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) +
|
||||
(f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/* ===-- 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));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/* ===-- 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.s.high == 0);
|
||||
return __builtin_clzll((x.s.high & ~f) | (x.s.low & f)) +
|
||||
((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
|
||||
}
|
||||
|
||||
#endif /* __x86_64 */
|
||||
@@ -1,38 +0,0 @@
|
||||
/* ===-- 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.s.high < y.s.high)
|
||||
return 0;
|
||||
if (x.s.high > y.s.high)
|
||||
return 2;
|
||||
if (x.s.low < y.s.low)
|
||||
return 0;
|
||||
if (x.s.low > y.s.low)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* ===-- 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.s.high < y.s.high)
|
||||
return 0;
|
||||
if (x.s.high > y.s.high)
|
||||
return 2;
|
||||
if (x.s.low < y.s.low)
|
||||
return 0;
|
||||
if (x.s.low > y.s.low)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
/* ===-- 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.s.low == 0);
|
||||
return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) +
|
||||
(f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* ===-- 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));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/* ===-- 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.s.low == 0);
|
||||
return __builtin_ctzll((x.s.high & f) | (x.s.low & ~f)) +
|
||||
((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
/* ===-- 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;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/* ===-- 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 */
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*===-- 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;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/* ===-- 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 */
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/* ===-- 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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user