diff options
author | Logan Chien <loganchien@google.com> | 2012-03-30 17:46:04 +0800 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2012-04-02 10:15:02 -0700 |
commit | d23c5ad21e0b93a50a23d4b92a9e9e0867258083 (patch) | |
tree | 1db88ab423f936b356baf66d5ac8e7a622e1cf2a | |
parent | 5539ad0fe3ac455ac3f8b051f3b4502729f0ba53 (diff) | |
download | art-d23c5ad21e0b93a50a23d4b92a9e9e0867258083.zip art-d23c5ad21e0b93a50a23d4b92a9e9e0867258083.tar.gz art-d23c5ad21e0b93a50a23d4b92a9e9e0867258083.tar.bz2 |
Add compiler runtime function list for symbol lookup.
Change-Id: I1eba443f6a66f08bc8692bfef7a9b16815751516
-rw-r--r-- | src/compiler_llvm/compiler_runtime_func_list.h | 180 | ||||
-rw-r--r-- | src/compiler_llvm/runtime_support_llvm.cc | 51 |
2 files changed, 231 insertions, 0 deletions
diff --git a/src/compiler_llvm/compiler_runtime_func_list.h b/src/compiler_llvm/compiler_runtime_func_list.h new file mode 100644 index 0000000..5cf5bb5 --- /dev/null +++ b/src/compiler_llvm/compiler_runtime_func_list.h @@ -0,0 +1,180 @@ +/* + * Copyright (C) 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. + */ + +// NOTE: COMPILER_RUNTIME_FUNC_LIST should be sorted! + +#if defined(__i386__) || defined(__mips__) + +#define COMPILER_RUNTIME_FUNC_LIST(V) \ + V(__ashldi3) \ + V(__ashrdi3) \ + V(__divdi3) \ + V(__fixdfdi) \ + V(__fixsfdi) \ + V(__fixtfdi) \ + V(__fixtfsi) \ + V(__fixunsdfdi) \ + V(__fixunsdfsi) \ + V(__fixunssfdi) \ + V(__fixunssfsi) \ + V(__fixunstfdi) \ + V(__fixunstfsi) \ + V(__fixunsxfdi) \ + V(__fixunsxfsi) \ + V(__fixxfdi) \ + V(__floatdidf) \ + V(__floatdisf) \ + V(__floatditf) \ + V(__floatdixf) \ + V(__floatsitf) \ + V(__floatundidf) \ + V(__floatundisf) \ + V(__floatunditf) \ + V(__floatundixf) \ + V(__floatunsitf) \ + V(__lshrdi3) \ + V(__moddi3) \ + V(__muldi3) \ + V(__negdi2) \ + V(__powidf2) \ + V(__powisf2) \ + V(__powitf2) \ + V(__powixf2) \ + V(__trunctfdf2) \ + V(__trunctfsf2) \ + V(__udivdi3) \ + V(__umoddi3) \ + V(ceil) \ + V(ceilf) \ + V(ceill) \ + V(copysign) \ + V(copysignf) \ + V(copysignl) \ + V(cos) \ + V(cosf) \ + V(cosl) \ + V(exp) \ + V(exp2) \ + V(exp2f) \ + V(exp2l) \ + V(expf) \ + V(expl) \ + V(floor) \ + V(floorf) \ + V(floorl) \ + V(fma) \ + V(fmaf) \ + V(fmal) \ + V(fmod) \ + V(fmodf) \ + V(fmodl) \ + V(log) \ + V(log10) \ + V(log10f) \ + V(log10l) \ + V(log2) \ + V(log2f) \ + V(log2l) \ + V(logf) \ + V(logl) \ + V(memcpy) \ + V(memmove) \ + V(memset) \ + V(nearbyint) \ + V(nearbyintf) \ + V(nearbyintl) \ + V(pow) \ + V(powf) \ + V(powl) \ + V(rint) \ + V(rintf) \ + V(rintl) \ + V(sin) \ + V(sinf) \ + V(sinl) \ + V(sqrt) \ + V(sqrtf) \ + V(sqrtl) \ + V(trunc) \ + V(truncf) \ + V(truncl) + +#elif defined(__arm__) + +#define COMPILER_RUNTIME_FUNC_LIST(V) \ + V(__aeabi_d2f) \ + V(__aeabi_d2iz) \ + V(__aeabi_d2lz) \ + V(__aeabi_d2uiz) \ + V(__aeabi_d2ulz) \ + V(__aeabi_dadd) \ + V(__aeabi_dcmpeq) \ + V(__aeabi_dcmpeq) \ + V(__aeabi_dcmpge) \ + V(__aeabi_dcmpgt) \ + V(__aeabi_dcmple) \ + V(__aeabi_dcmplt) \ + V(__aeabi_dcmpun) \ + V(__aeabi_dcmpun) \ + V(__aeabi_ddiv) \ + V(__aeabi_dmul) \ + V(__aeabi_dsub) \ + V(__aeabi_f2d) \ + V(__aeabi_f2iz) \ + V(__aeabi_f2lz) \ + V(__aeabi_f2uiz) \ + V(__aeabi_f2ulz) \ + V(__aeabi_fadd) \ + V(__aeabi_fcmpeq) \ + V(__aeabi_fcmpeq) \ + V(__aeabi_fcmpge) \ + V(__aeabi_fcmpgt) \ + V(__aeabi_fcmple) \ + V(__aeabi_fcmplt) \ + V(__aeabi_fcmpun) \ + V(__aeabi_fcmpun) \ + V(__aeabi_fdiv) \ + V(__aeabi_fmul) \ + V(__aeabi_fsub) \ + V(__aeabi_i2d) \ + V(__aeabi_i2f) \ + V(__aeabi_idiv) \ + V(__aeabi_idiv) \ + V(__aeabi_idiv) \ + V(__aeabi_l2d) \ + V(__aeabi_l2f) \ + V(__aeabi_lasr) \ + V(__aeabi_ldivmod) \ + V(__aeabi_llsl) \ + V(__aeabi_llsr) \ + V(__aeabi_lmul) \ + V(__aeabi_memcpy) \ + V(__aeabi_memmove) \ + V(__aeabi_memset) \ + V(__aeabi_ui2d) \ + V(__aeabi_ui2f) \ + V(__aeabi_uidiv) \ + V(__aeabi_uidiv) \ + V(__aeabi_uidiv) \ + V(__aeabi_ul2d) \ + V(__aeabi_ul2f) \ + V(__aeabi_uldivmod) + +#else + +#error "Unknown target platform" + +#endif diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc index 3d2b84a..0bf2699 100644 --- a/src/compiler_llvm/runtime_support_llvm.cc +++ b/src/compiler_llvm/runtime_support_llvm.cc @@ -24,6 +24,7 @@ #include "thread.h" #include "thread_list.h" +#include <algorithm> #include <stdint.h> namespace art { @@ -432,6 +433,50 @@ void art_check_cast_from_code(Object* dest_type, Object* src_type) { // Runtime Support Function Lookup Callback //---------------------------------------------------------------------------- +class CStringComparator { + public: + bool operator()(const char* lhs, const char* rhs) const { + return (strcmp(lhs, rhs) <= 0); + } +}; + +#define EXTERNAL_LINKAGE(NAME) \ +extern "C" void NAME(...); + +#include "compiler_runtime_func_list.h" +COMPILER_RUNTIME_FUNC_LIST(EXTERNAL_LINKAGE) +#undef COMPILER_RUNTIME_FUNC_LIST +#undef EXTERNAL_LINKAGE + +static void* art_find_compiler_runtime_func(char const* name) { + static const char* const names[] = { +#define DEFINE_ENTRY(NAME) #NAME , +#include "compiler_runtime_func_list.h" + COMPILER_RUNTIME_FUNC_LIST(DEFINE_ENTRY) +#undef COMPILER_RUNTIME_FUNC_LIST +#undef DEFINE_ENTRY + }; + + static void* const funcs[] = { +#define DEFINE_ENTRY(NAME) reinterpret_cast<void*>(NAME) , +#include "compiler_runtime_func_list.h" + COMPILER_RUNTIME_FUNC_LIST(DEFINE_ENTRY) +#undef COMPILER_RUNTIME_FUNC_LIST +#undef DEFINE_ENTRY + }; + + static const size_t num_entries = sizeof(names) / sizeof(const char* const); + + const char* const* matched_name_ptr = + std::lower_bound(names, names + num_entries, name, CStringComparator()); + + if (matched_name_ptr == names + num_entries) { + return NULL; + } else { + return funcs[matched_name_ptr - names]; + } +} + void* art_find_runtime_support_func(void* context, char const* name) { struct func_entry_t { char const* name; @@ -451,6 +496,12 @@ void* art_find_runtime_support_func(void* context, char const* name) { static size_t const tab_size = sizeof(tab) / sizeof(struct func_entry_t); + // Search the compiler runtime (such as __divdi3) + void* result = art_find_compiler_runtime_func(name); + if (result != NULL) { + return result; + } + // Note: Since our table is small, we are using trivial O(n) searching // function. For bigger table, it will be better to use binary // search or hash function. |