Merge "Add approx_atan function" into jb-mr1-dev
diff --git a/include/bcc/AndroidBitcode/ABCCompiler.h b/include/bcc/AndroidBitcode/ABCCompiler.h
new file mode 100644
index 0000000..91b8009
--- /dev/null
+++ b/include/bcc/AndroidBitcode/ABCCompiler.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_ABC_COMPILER_H
+#define BCC_ABC_COMPILER_H
+
+#include "bcc/Compiler.h"
+
+namespace bcc {
+
+class ABCCompilerDriver;
+
+class ABCCompiler : public Compiler {
+private:
+ const ABCCompilerDriver &mDriver;
+
+public:
+ ABCCompiler(const ABCCompilerDriver &pDriver) : mDriver(pDriver) { }
+
+ virtual ~ABCCompiler() { }
+
+private:
+ virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM);
+};
+
+} // end namespace bcc
+
+#endif // BCC_ABC_COMPILER_H
diff --git a/include/bcc/AndroidBitcode/ABCCompilerDriver.h b/include/bcc/AndroidBitcode/ABCCompilerDriver.h
index 0fa38fe..5f5ad7f 100644
--- a/include/bcc/AndroidBitcode/ABCCompilerDriver.h
+++ b/include/bcc/AndroidBitcode/ABCCompilerDriver.h
@@ -17,6 +17,7 @@
#ifndef BCC_ABC_COMPILER_DRIVER_H
#define BCC_ABC_COMPILER_DRIVER_H
+#include "bcc/AndroidBitcode/ABCCompiler.h"
#include "bcc/BCCContext.h"
#include "bcc/Compiler.h"
#include "bcc/Linker.h"
@@ -25,13 +26,14 @@
namespace bcc {
+class ABCExpandVAArgPass;
class CompilerConfig;
class LinkerConfig;
class ABCCompilerDriver {
private:
BCCContext mContext;
- Compiler mCompiler;
+ ABCCompiler mCompiler;
Linker mLinker;
CompilerConfig *mCompilerConfig;
@@ -50,11 +52,33 @@
bool link(const Script &pScript, const std::string &input_relocatable,
int pOutputFd);
-public:
- ABCCompilerDriver(const std::string &pTriple,
- const std::string &pAndroidSysroot);
+protected:
+ virtual const char **getNonPortableList() const {
+ return NULL;
+ }
- ~ABCCompilerDriver();
+public:
+ virtual ABCExpandVAArgPass *createExpandVAArgPass() const = 0;
+
+protected:
+ ABCCompilerDriver(const std::string &pTriple);
+
+public:
+ static ABCCompilerDriver *Create(const std::string &pTriple);
+
+ virtual ~ABCCompilerDriver();
+
+ inline const std::string &getAndroidSysroot() const {
+ return mAndroidSysroot;
+ }
+
+ inline void setAndroidSysroot(const std::string &pAndroidSysroot) {
+ mAndroidSysroot = pAndroidSysroot;
+ }
+
+ inline const std::string &getTriple() const {
+ return mTriple;
+ }
// Compile the bitcode and link the shared object
bool build(int pInputFd, int pOutputFd);
diff --git a/include/bcc/AndroidBitcode/ABCExpandVAArgPass.h b/include/bcc/AndroidBitcode/ABCExpandVAArgPass.h
new file mode 100644
index 0000000..162eeb2
--- /dev/null
+++ b/include/bcc/AndroidBitcode/ABCExpandVAArgPass.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_ABC_EXPAND_VAARG_PASS_H
+#define BCC_ABC_EXPAND_VAARG_PASS_H
+
+#include <llvm/Pass.h>
+
+namespace llvm {
+ class Function;
+ class Instruction;
+ class LLVMContext;
+ class Value;
+} // end llvm namespace
+
+namespace bcc {
+
+/*
+ * This pass expands va_arg LLVM instruction generated from llvm-ndk-cc.
+ *
+ * LLVM backend does not yet fully support va_arg on many targets. Also,
+ * it does not currently support va_arg with aggregate types on any target.
+ * Therefore, each target should implement its own verion of
+ * ABCExpandVAArg::expandVAArg to expand va_arg.
+ */
+
+class ABCExpandVAArgPass : public llvm::FunctionPass {
+private:
+ static char ID;
+
+protected:
+ llvm::LLVMContext *mContext;
+
+private:
+ virtual llvm::Value *expandVAArg(llvm::Instruction *pInst) = 0;
+
+public:
+ ABCExpandVAArgPass() : llvm::FunctionPass(ID), mContext(NULL) { }
+
+ virtual bool runOnFunction(llvm::Function &pFunc);
+};
+
+} // end bcc namespace
+
+#endif // BCC_ABC_EXPAND_VAARG_PASS_H
diff --git a/include/bcc/Config/Config.h b/include/bcc/Config/Config.h
index 9dd2a93..0331ae0 100644
--- a/include/bcc/Config/Config.h
+++ b/include/bcc/Config/Config.h
@@ -57,6 +57,7 @@
#endif
#define DEFAULT_ARM_TRIPLE_STRING "armv7-none-linux-gnueabi"
+#define DEFAULT_THUMB_TRIPLE_STRING "thumbv7-none-linux-gnueabi"
#define DEFAULT_MIPS_TRIPLE_STRING "mipsel-none-linux-gnueabi"
#define DEFAULT_X86_TRIPLE_STRING "i686-unknown-linux"
#define DEFAULT_X86_64_TRIPLE_STRING "x86_64-unknown-linux"
diff --git a/lib/AndroidBitcode/ABCCompiler.cpp b/lib/AndroidBitcode/ABCCompiler.cpp
new file mode 100644
index 0000000..8393d48
--- /dev/null
+++ b/lib/AndroidBitcode/ABCCompiler.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcc/AndroidBitcode/ABCCompiler.h"
+
+#include <llvm/Module.h>
+#include <llvm/PassManager.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Target/TargetMachine.h>
+
+#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
+#include "bcc/AndroidBitcode/ABCExpandVAArgPass.h"
+#include "bcc/Script.h"
+#include "bcc/Source.h"
+
+
+namespace bcc {
+
+bool ABCCompiler::beforeAddCodeGenPasses(Script &pScript,
+ llvm::PassManager &pPM) {
+ llvm::PassManager pm;
+ llvm::Module &module = pScript.getSource().getModule();
+ const llvm::TargetMachine &tm = getTargetMachine();
+ llvm::TargetData *target_data =
+ new (std::nothrow) llvm::TargetData(*(tm.getTargetData()));
+
+ if (target_data == NULL) {
+ return false;
+ }
+
+ pm.add(target_data);
+ pm.add(mDriver.createExpandVAArgPass());
+ pm.run(module);
+
+ return true;
+}
+
+} // namespace bcc
diff --git a/lib/AndroidBitcode/ABCCompilerDriver.cpp b/lib/AndroidBitcode/ABCCompilerDriver.cpp
index 84b6583..4eb33e6 100644
--- a/lib/AndroidBitcode/ABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/ABCCompilerDriver.cpp
@@ -17,8 +17,10 @@
#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
#include <llvm/Module.h>
+#include <llvm/Pass.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/raw_ostream.h>
+#include <mcld/Config/Config.h>
#include "bcc/Config/Config.h"
#include "bcc/Script.h"
@@ -30,15 +32,22 @@
#include "bcc/Support/TargetLinkerConfigs.h"
#include "bcc/Support/TargetCompilerConfigs.h"
-#include "mcld/Config/Config.h"
+#if defined(PROVIDE_ARM_CODEGEN)
+# include "ARM/ARMABCCompilerDriver.h"
+#endif
+#if defined(PROVIDE_MIPS_CODEGEN)
+# include "Mips/MipsABCCompilerDriver.h"
+#endif
+#if defined(PROVIDE_X86_CODEGEN)
+# include "X86/X86ABCCompilerDriver.h"
+#endif
namespace bcc {
-ABCCompilerDriver::ABCCompilerDriver(const std::string &pTriple,
- const std::string &pAndroidSysroot)
- : mContext(), mCompiler(), mLinker(),
+ABCCompilerDriver::ABCCompilerDriver(const std::string &pTriple)
+ : mContext(), mCompiler(*this), mLinker(),
mCompilerConfig(NULL), mLinkerConfig(NULL),
- mTriple(pTriple), mAndroidSysroot(pAndroidSysroot) {
+ mTriple(pTriple), mAndroidSysroot("/") {
}
ABCCompilerDriver::~ABCCompilerDriver() {
@@ -95,16 +104,13 @@
// Add non-portable function list. For each function X, linker will rename
// it to X_portable. And X_portable" is implemented in libportable to solve
// portable issues.
- mLinkerConfig->addPortable("stat");
- mLinkerConfig->addPortable("fstat");
- mLinkerConfig->addPortable("lstat");
- mLinkerConfig->addPortable("fstatat");
- mLinkerConfig->addPortable("socket");
- mLinkerConfig->addPortable("setsockopt");
- mLinkerConfig->addPortable("getsockopt");
- mLinkerConfig->addPortable("epoll_event");
- mLinkerConfig->addPortable("epoll_ctl");
- mLinkerConfig->addPortable("epoll_wait");
+ const char **non_portable_func = getNonPortableList();
+ if (non_portable_func != NULL) {
+ while (*non_portable_func != NULL) {
+ mLinkerConfig->addPortable(*non_portable_func);
+ non_portable_func++;
+ }
+ }
// -shared
mLinkerConfig->setShared(true);
@@ -211,6 +217,44 @@
//------------------------------------------------------------------------------
+ABCCompilerDriver *ABCCompilerDriver::Create(const std::string &pTriple) {
+ std::string error;
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(pTriple, error);
+
+ if (target == NULL) {
+ ALOGE("Unsupported target '%s' (detail: %s)!", pTriple.c_str(),
+ error.c_str());
+ return NULL;
+ }
+
+ switch (llvm::Triple::getArchTypeForLLVMName(target->getName())) {
+#if defined(PROVIDE_ARM_CODEGEN)
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb: {
+ return new ARMABCCompilerDriver(pTriple);
+ }
+#endif
+#if defined(PROVIDE_MIPS_CODEGEN)
+ case llvm::Triple::mipsel: {
+ return new MipsABCCompilerDriver(pTriple);
+ }
+#endif
+#if defined(PROVIDE_X86_CODEGEN)
+ case llvm::Triple::x86: {
+ return new X86ABCCompilerDriver(pTriple);
+ }
+#endif
+ default: {
+ ALOGE("Unknown architecture '%s' supplied in %s!", target->getName(),
+ pTriple.c_str());
+ break;
+ }
+ }
+
+ return NULL;
+}
+
bool ABCCompilerDriver::build(int pInputFd, int pOutputFd) {
//===--------------------------------------------------------------------===//
// Prepare the input.
diff --git a/lib/AndroidBitcode/ABCExpandVAArgPass.cpp b/lib/AndroidBitcode/ABCExpandVAArgPass.cpp
new file mode 100644
index 0000000..7b89ced
--- /dev/null
+++ b/lib/AndroidBitcode/ABCExpandVAArgPass.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_ABC_EXPAND_VAARG_H
+#define BCC_ABC_EXPAND_VAARG_H
+
+#include "bcc/AndroidBitcode/ABCExpandVAArgPass.h"
+
+#include <llvm/Instructions.h>
+#include <llvm/Support/InstIterator.h>
+
+namespace bcc {
+
+char ABCExpandVAArgPass::ID = 0;
+
+bool ABCExpandVAArgPass::runOnFunction(llvm::Function &pFunc) {
+ bool changed = false;
+
+ mContext = &pFunc.getContext();
+
+ // process va_arg inst
+ for (llvm::inst_iterator inst = llvm::inst_begin(pFunc),
+ inst_end = llvm::inst_end(pFunc); inst != inst_end; inst++) {
+ if (inst->getOpcode() == llvm::Instruction::VAArg) {
+ llvm::Value *v = expandVAArg(&*inst);
+ inst->replaceAllUsesWith(v);
+ inst->eraseFromParent();
+ changed = true;
+ continue;
+ }
+ }
+ return changed;
+}
+
+} // end bcc namespace
+
+#endif // BCC_ABC_EXPAND_VAARG_H
diff --git a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
new file mode 100644
index 0000000..29f4f0a
--- /dev/null
+++ b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_ARM_ABC_COMPILER_DRIVER_H
+#define BCC_ARM_ABC_COMPILER_DRIVER_H
+
+#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
+
+namespace bcc {
+
+class ARMABCCompilerDriver : public ABCCompilerDriver {
+public:
+ ARMABCCompilerDriver(const std::string &pTriple)
+ : ABCCompilerDriver(pTriple) { }
+
+ virtual ~ARMABCCompilerDriver() { }
+
+private:
+ virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
+};
+
+} // end namespace bcc
+
+#endif // BCC_ARM_ABC_COMPILER_DRIVER_H
diff --git a/lib/AndroidBitcode/ARM/ARMABCExpandVAArg.cpp b/lib/AndroidBitcode/ARM/ARMABCExpandVAArg.cpp
new file mode 100644
index 0000000..7f154af
--- /dev/null
+++ b/lib/AndroidBitcode/ARM/ARMABCExpandVAArg.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Function.h>
+#include <llvm/Instructions.h>
+#include <llvm/IRBuilder.h>
+#include <llvm/Module.h>
+#include <llvm/Pass.h>
+#include <llvm/Type.h>
+#include <llvm/Target/TargetData.h>
+
+#include "bcc/AndroidBitcode/ABCExpandVAArgPass.h"
+
+#include "ARM/ARMABCCompilerDriver.h"
+
+namespace {
+
+class ARMABCExpandVAArg : public bcc::ABCExpandVAArgPass {
+public:
+ virtual const char *getPassName() const {
+ return "ARM LLVM va_arg Instruction Expansion Pass";
+ }
+
+private:
+ // Derivative work from external/clang/lib/CodeGen/TargetInfo.cpp.
+ llvm::Value *expandVAArg(llvm::Instruction *pInst) {
+ llvm::Type *pty = pInst->getType();
+ llvm::Type *ty = pty->getContainedType(0);
+ llvm::Value *va_list_addr = pInst->getOperand(0);
+ llvm::IRBuilder<> builder(pInst);
+ const llvm::TargetData *td = getAnalysisIfAvailable<llvm::TargetData>();
+
+ llvm::Type *bp = llvm::Type::getInt8PtrTy(*mContext);
+ llvm::Type *bpp = bp->getPointerTo(0);
+
+ llvm::Value *va_list_addr_bpp =
+ builder.CreateBitCast(va_list_addr, bpp, "ap");
+ llvm::Value *addr = builder.CreateLoad(va_list_addr_bpp, "ap.cur");
+ // Handle address alignment for type alignment > 32 bits.
+ uint64_t ty_align = td->getABITypeAlignment(ty);
+
+ if (ty_align > 4) {
+ assert((ty_align & (ty_align - 1)) == 0 &&
+ "Alignment is not power of 2!");
+ llvm::Value *addr_as_int =
+ builder.CreatePtrToInt(addr, llvm::Type::getInt32Ty(*mContext));
+ addr_as_int = builder.CreateAdd(addr_as_int,
+ builder.getInt32(ty_align-1));
+ addr_as_int = builder.CreateAnd(addr_as_int,
+ builder.getInt32(~(ty_align-1)));
+ addr = builder.CreateIntToPtr(addr_as_int, bp);
+ }
+ llvm::Value *addr_typed = builder.CreateBitCast(addr, pty);
+
+ uint64_t offset = llvm::RoundUpToAlignment(td->getTypeSizeInBits(ty)/8, 4);
+ llvm::Value *next_addr = builder.CreateGEP(addr,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mContext), offset),
+ "ap.next");
+ builder.CreateStore(next_addr, va_list_addr_bpp);
+ return addr_typed;
+ }
+
+};
+
+} // end anonymous namespace
+
+namespace bcc {
+
+ABCExpandVAArgPass *ARMABCCompilerDriver::createExpandVAArgPass() const {
+ return new ARMABCExpandVAArg();
+}
+
+} // end namespace bcc
diff --git a/lib/AndroidBitcode/Android.mk b/lib/AndroidBitcode/Android.mk
index 1abc7b2..806202c 100644
--- a/lib/AndroidBitcode/Android.mk
+++ b/lib/AndroidBitcode/Android.mk
@@ -22,8 +22,22 @@
#=====================================================================
libbcc_androidbitcode_SRC_FILES := \
+ ABCCompiler.cpp \
+ ABCExpandVAArgPass.cpp \
ABCCompilerDriver.cpp
+libbcc_arm_androidbitcode_SRC_FILES := \
+ ARM/ARMABCExpandVAArg.cpp
+
+libbcc_mips_androidbitcode_SRC_FILES := \
+ Mips/MipsABCCompilerDriver.cpp \
+ Mips/MipsABCExpandVAArg.cpp
+
+libbcc_x86_androidbitcode_SRC_FILES := \
+ X86/X86ABCCompilerDriver.cpp \
+ X86/X86ABCExpandVAArg.cpp
+
+
#=====================================================================
# Device Static Library: libbccAndroidBitcode
#=====================================================================
@@ -33,9 +47,22 @@
LOCAL_MODULE := libbccAndroidBitcode
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-
LOCAL_SRC_FILES := $(libbcc_androidbitcode_SRC_FILES)
+ifeq ($(TARGET_ARCH),arm)
+ LOCAL_SRC_FILES += $(libbcc_arm_androidbitcode_SRC_FILES)
+else
+ ifeq ($(TARGET_ARCH),mips)
+ LOCAL_SRC_FILES += $(libbcc_mips_androidbitcode_SRC_FILES)
+ else
+ ifeq ($(TARGET_ARCH),x86) # We don't support x86-64 right now
+ LOCAL_SRC_FILES += $(libbcc_x86_androidbitcode_SRC_FILES)
+ else
+ $(error Unsupported TARGET_ARCH $(TARGET_ARCH))
+ endif
+ endif
+endif
+
include $(LIBBCC_DEVICE_BUILD_MK)
include $(LIBBCC_GEN_CONFIG_MK)
include $(MCLD_DEVICE_BUILD_MK)
@@ -50,8 +77,11 @@
LOCAL_MODULE := libbccAndroidBitcode
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-
-LOCAL_SRC_FILES := $(libbcc_androidbitcode_SRC_FILES)
+LOCAL_SRC_FILES := \
+ $(libbcc_androidbitcode_SRC_FILES) \
+ $(libbcc_arm_androidbitcode_SRC_FILES) \
+ $(libbcc_mips_androidbitcode_SRC_FILES) \
+ $(libbcc_x86_androidbitcode_SRC_FILES) \
include $(LIBBCC_HOST_BUILD_MK)
include $(LIBBCC_GEN_CONFIG_MK)
diff --git a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
new file mode 100644
index 0000000..54b9d61
--- /dev/null
+++ b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Mips/MipsABCCompilerDriver.h"
+
+namespace {
+
+static const char *MipsNonPortableList[] = {
+ "stat",
+ "fstat",
+ "lstat",
+ "fstatat",
+ "socket",
+ "setsockopt",
+ "getsockopt",
+ "open",
+ "mmap",
+ "ioctl",
+
+ NULL // NUL-terminator
+};
+
+} // end anonymous namespace
+
+namespace bcc {
+
+const char **MipsABCCompilerDriver::getNonPortableList() const {
+ return MipsNonPortableList;
+}
+
+} // end namespace bcc
diff --git a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
new file mode 100644
index 0000000..7cfc34f
--- /dev/null
+++ b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_MIPS_ABC_COMPILER_DRIVER_H
+#define BCC_MIPS_ABC_COMPILER_DRIVER_H
+
+#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
+
+namespace bcc {
+
+class MipsABCCompilerDriver : public ABCCompilerDriver {
+public:
+ MipsABCCompilerDriver(const std::string &pTriple)
+ : ABCCompilerDriver(pTriple) { }
+
+ virtual ~MipsABCCompilerDriver() { }
+
+private:
+ virtual const char **getNonPortableList() const;
+
+ virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
+};
+
+} // end namespace bcc
+
+#endif // BCC_MIPS_ABC_COMPILER_DRIVER_H
diff --git a/lib/AndroidBitcode/Mips/MipsABCExpandVAArg.cpp b/lib/AndroidBitcode/Mips/MipsABCExpandVAArg.cpp
new file mode 100644
index 0000000..495cef4
--- /dev/null
+++ b/lib/AndroidBitcode/Mips/MipsABCExpandVAArg.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Function.h>
+#include <llvm/Instructions.h>
+#include <llvm/IRBuilder.h>
+#include <llvm/Module.h>
+#include <llvm/Pass.h>
+#include <llvm/Type.h>
+#include <llvm/Target/TargetData.h>
+
+#include "bcc/AndroidBitcode/ABCExpandVAArgPass.h"
+
+#include "Mips/MipsABCCompilerDriver.h"
+
+namespace {
+
+class MipsABCExpandVAArg : public bcc::ABCExpandVAArgPass {
+public:
+ virtual const char *getPassName() const {
+ return "Mips LLVM va_arg Instruction Expansion Pass";
+ }
+
+private:
+ // Derivative work from external/clang/lib/CodeGen/TargetInfo.cpp.
+ virtual llvm::Value *expandVAArg(llvm::Instruction *pInst) {
+ llvm::Type *pty = pInst->getType();
+ llvm::Type *ty = pty->getContainedType(0);
+ llvm::Value *va_list_addr = pInst->getOperand(0);
+ llvm::IRBuilder<> builder(pInst);
+ const llvm::TargetData *td = getAnalysisIfAvailable<llvm::TargetData>();
+
+ llvm::Type *bp = llvm::Type::getInt8PtrTy(*mContext);
+ llvm::Type *bpp = bp->getPointerTo(0);
+ llvm::Value *va_list_addr_bpp = builder.CreateBitCast(va_list_addr,
+ bpp, "ap");
+ llvm::Value *addr = builder.CreateLoad(va_list_addr_bpp, "ap.cur");
+ int64_t type_align = td->getABITypeAlignment(ty);
+ llvm::Value *addr_typed;
+ llvm::IntegerType *int_ty = llvm::Type::getInt32Ty(*mContext);
+
+ if (type_align > 4) {
+ llvm::Value *addr_as_int = builder.CreatePtrToInt(addr, int_ty);
+ llvm::Value *inc = llvm::ConstantInt::get(int_ty, type_align - 1);
+ llvm::Value *mask = llvm::ConstantInt::get(int_ty, -type_align);
+ llvm::Value *add_v = builder.CreateAdd(addr_as_int, inc);
+ llvm::Value *and_v = builder.CreateAnd(add_v, mask);
+ addr_typed = builder.CreateIntToPtr(and_v, pty);
+ }
+ else {
+ addr_typed = builder.CreateBitCast(addr, pty);
+ }
+
+ llvm::Value *aligned_addr = builder.CreateBitCast(addr_typed, bp);
+ type_align = std::max((unsigned)type_align, (unsigned) 4);
+ uint64_t offset =
+ llvm::RoundUpToAlignment(td->getTypeSizeInBits(ty) / 8, type_align);
+ llvm::Value *next_addr =
+ builder.CreateGEP(aligned_addr, llvm::ConstantInt::get(int_ty, offset),
+ "ap.next");
+ builder.CreateStore(next_addr, va_list_addr_bpp);
+
+ return addr_typed;
+ }
+
+};
+
+} // end anonymous namespace
+
+namespace bcc {
+
+ABCExpandVAArgPass *MipsABCCompilerDriver::createExpandVAArgPass() const {
+ return new MipsABCExpandVAArg();
+}
+
+} // end namespace bcc
diff --git a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
new file mode 100644
index 0000000..171da7c
--- /dev/null
+++ b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "X86/X86ABCCompilerDriver.h"
+
+namespace {
+
+static const char *X86NonPortableList[] = {
+ "stat",
+ "fstat",
+ "lstat",
+ "fstatat",
+ "open",
+ "ioctl",
+ "fcntl",
+ "epoll_ctl",
+ "epoll_wait",
+
+ NULL // NUL-terminator
+};
+
+} // end anonymous namespace
+
+namespace bcc {
+
+const char **X86ABCCompilerDriver::getNonPortableList() const {
+ return X86NonPortableList;
+}
+
+} // end namespace bcc
diff --git a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
new file mode 100644
index 0000000..af52866
--- /dev/null
+++ b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_X86_ABC_COMPILER_DRIVER_H
+#define BCC_X86_ABC_COMPILER_DRIVER_H
+
+#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
+
+namespace bcc {
+
+class X86ABCCompilerDriver : public ABCCompilerDriver {
+public:
+ X86ABCCompilerDriver(const std::string &pTriple)
+ : ABCCompilerDriver(pTriple) { }
+
+ virtual ~X86ABCCompilerDriver() { }
+
+private:
+ virtual const char **getNonPortableList() const;
+
+ virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
+};
+
+} // end namespace bcc
+
+#endif // BCC_X86_ABC_COMPILER_DRIVER_H
diff --git a/lib/AndroidBitcode/X86/X86ABCExpandVAArg.cpp b/lib/AndroidBitcode/X86/X86ABCExpandVAArg.cpp
new file mode 100644
index 0000000..6d9acbc
--- /dev/null
+++ b/lib/AndroidBitcode/X86/X86ABCExpandVAArg.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Function.h>
+#include <llvm/Instructions.h>
+#include <llvm/IRBuilder.h>
+#include <llvm/Module.h>
+#include <llvm/Pass.h>
+#include <llvm/Type.h>
+#include <llvm/Target/TargetData.h>
+
+#include "bcc/AndroidBitcode/ABCExpandVAArgPass.h"
+
+#include "X86/X86ABCCompilerDriver.h"
+
+namespace {
+
+class X86ABCExpandVAArg : public bcc::ABCExpandVAArgPass {
+public:
+ virtual const char *getPassName() const {
+ return "X86 LLVM va_arg Instruction Expansion Pass";
+ }
+
+private:
+ // Derivative work from external/clang/lib/CodeGen/TargetInfo.cpp.
+ virtual llvm::Value *expandVAArg(llvm::Instruction *pInst) {
+ llvm::Type *pty = pInst->getType();
+ llvm::Type *ty = pty->getContainedType(0);
+ llvm::Value *va_list_addr = pInst->getOperand(0);
+ llvm::IRBuilder<> builder(pInst);
+ const llvm::TargetData *td = getAnalysisIfAvailable<llvm::TargetData>();
+
+ llvm::Type *bp = llvm::Type::getInt8PtrTy(*mContext);
+ llvm::Type *bpp = bp->getPointerTo(0);
+ llvm::Value *va_list_addr_bpp = builder.CreateBitCast(va_list_addr,
+ bpp, "ap");
+ llvm::Value *addr = builder.CreateLoad(va_list_addr_bpp, "ap.cur");
+
+ llvm::Value *addr_typed = builder.CreateBitCast(addr, pty);
+
+ // X86-32 stack type alignment is always 4.
+ uint64_t offset = llvm::RoundUpToAlignment(td->getTypeSizeInBits(ty)/8, 4);
+ llvm::Value *next_addr = builder.CreateGEP(addr,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mContext), offset),
+ "ap.next");
+ builder.CreateStore(next_addr, va_list_addr_bpp);
+
+ return addr_typed;
+ }
+
+}; // end X86ABCExpandVAArg
+
+} // end anonymous namespace
+
+namespace bcc {
+
+ABCExpandVAArgPass *X86ABCCompilerDriver::createExpandVAArgPass() const {
+ return new X86ABCExpandVAArg();
+}
+
+} // end namespace bcc
diff --git a/libbcc-device-build.mk b/libbcc-device-build.mk
index bc250b8..8673be8 100644
--- a/libbcc-device-build.mk
+++ b/libbcc-device-build.mk
@@ -45,6 +45,9 @@
ifeq ($(ARCH_ARM_HAVE_NEON),true)
LOCAL_CFLAGS += -DARCH_ARM_HAVE_NEON
endif
+ ifeq ($(ARCH_ARM_HAVE_THUMB_SUPPORT),true)
+ LOCAL_CFLAGS += -DARCH_ARM_HAVE_THUMB_SUPPORT
+ endif
else
ifeq ($(TARGET_ARCH),mips)
LOCAL_CFLAGS += -DFORCE_MIPS_CODEGEN
diff --git a/tools/abcc/Main.cpp b/tools/abcc/Main.cpp
index 7fe99eb..44ceadd 100644
--- a/tools/abcc/Main.cpp
+++ b/tools/abcc/Main.cpp
@@ -120,8 +120,19 @@
static bool Build(int input_fd, int output_fd,
const char *triple, const char *sysroot) {
- ABCCompilerDriver driver(triple, sysroot);
- return driver.build(input_fd, output_fd);;
+ ABCCompilerDriver *driver = ABCCompilerDriver::Create(triple);
+
+ if (driver == NULL) {
+ return false;
+ }
+
+ driver->setAndroidSysroot(sysroot);
+
+ bool build_result = driver->build(input_fd, output_fd);;
+
+ delete driver;
+
+ return build_result;
}
static int ProcessFromFd(const char *input, const char *output,