Support generating ext_hhvm files with ARM ABI

ARM's convention for returning bigger-than-a-register types is
different; there's a register reserved for the purpose of passing the
return-value pointer. On x64, it just gets added as a hidden first
parameter.
Esse commit está contido em:
Owen Yamauchi
2013-04-29 16:06:16 -07:00
commit de Sara Golemon
commit e6a3807f23
4 arquivos alterados com 46 adições e 19 exclusões
+11 -4
Ver Arquivo
@@ -2,8 +2,14 @@ set(files)
set(CXX_SOURCES)
set(C_SOURCES)
set(CXX_HEADERS)
set(EXT_HHVM_ARCH "x64")
macro(EXT_HHVM_FILE SOURCES HEADERS REL)
exec_program("uname -m" OUTPUT_VARIABLE UNAME_M)
if (UNAME_M STREQUAL "aarch64")
set(EXT_HHVM_ARCH "arm")
endif()
macro(EXT_HHVM_FILE SOURCES HEADERS REL EHHVM_ARCH)
set(f_SRC "${HPHP_HOME}/hphp/${REL}")
set(f_OBJ "${HPHP_HOME}/hphp/CMakeFiles/hphp_runtime_static.dir/${REL}.o")
list(APPEND ${SOURCES} "${f_SRC}.ext_hhvm.cpp")
@@ -11,7 +17,8 @@ macro(EXT_HHVM_FILE SOURCES HEADERS REL)
add_custom_command(OUTPUT "${f_SRC}.ext_hhvm.cpp" "${f_SRC}.ext_hhvm.h"
DEPENDS ${f_SRC} gen-ext-hhvm
COMMAND "${HPHP_HOME}/hphp/tools/gen-ext-hhvm/gen-ext-hhvm.sh"
ARGS ${f_OBJ} "${f_SRC}.ext_hhvm.cpp" "${f_SRC}.ext_hhvm.h"
ARGS ${EHHVM_ARCH} ${f_OBJ}
"${f_SRC}.ext_hhvm.cpp" "${f_SRC}.ext_hhvm.h"
WORKING_DIRECTORY "${HPHP_HOME}/hphp/tools/gen-ext-hhvm"
COMMENT "Generating ext_hhvm wrapper for ${REL}")
endmacro()
@@ -23,10 +30,10 @@ foreach (f ${files})
string(LENGTH ${f} f_LEN)
math(EXPR f_REL_LEN "${f_LEN} - ${HPHP_DIR_LEN}")
string(SUBSTRING ${f} ${HPHP_DIR_LEN} ${f_REL_LEN} f_REL)
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS ${f_REL})
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS ${f_REL} ${EXT_HHVM_ARCH})
endif()
endforeach()
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS "runtime/base/builtin_functions.cpp")
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS "runtime/base/builtin_functions.cpp" ${EXT_HHVM_ARCH})
foreach (dir ${RECURSIVE_SOURCE_SUBDIRS})
auto_sources(files "*.cpp" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -99,7 +99,7 @@ enterTCHelper:
ret
.cfi_endproc
///////////////////////////////////////////////////////////////////////////////
#elif defined(__AARCH64_EL__)
#elif defined(__AARCH64EL__)
.globl enterTCHelper
enterTCHelper:
brk 0
+28 -9
Ver Arquivo
@@ -34,6 +34,12 @@ using folly::fbstring;
std::unordered_map<fbstring, const PhpFunc*> g_mangleMap;
std::unordered_map<fbstring, const PhpClass*> g_classMap;
// Functions with return types that don't fit in registers are handled
// differently on ARM. Instead of using a pointer-to-return-value-space hidden
// first parameter like on x64, the pointer is passed in a register reserved for
// this purpose, not part of the normal argument sequence.
bool g_armMode = false;
constexpr char* g_allIncludes = R"(
#include "runtime/ext_hhvm/ext_hhvm.h"
#include "runtime/base/builtin_functions.h"
@@ -83,7 +89,7 @@ void emitRemappedFuncDecl(const PhpFunc& func,
bool isFirstParam = true;
if (isTypeCppIndirectPass(func.returnCppType)) {
if (!g_armMode && isTypeCppIndirectPass(func.returnCppType)) {
if (func.returnCppType == "HPHP::Variant") {
out << "TypedValue* _rv";
} else {
@@ -266,7 +272,7 @@ void emitCallExpression(const PhpFunc& func, const fbstring& prefix,
out << prefix << func.getUniqueName() << '(';
bool isFirstParam = true;
if (isTypeCppIndirectPass(func.returnCppType)) {
if (!g_armMode && isTypeCppIndirectPass(func.returnCppType)) {
isFirstParam = false;
if (func.returnCppType == "HPHP::Variant") {
out << "rv";
@@ -418,7 +424,7 @@ void emitExtCall(const PhpFunc& func, std::ostream& out, const char* ind) {
}
out << ind << type << " defVal" << k;
if (type != "Variant" ||
(param.defVal != "null" && param.defVal != "null_varant")) {
(param.defVal != "null" && param.defVal != "null_variant")) {
out << " = ";
out << (param.defVal == "null" ? "uninit_null()" : param.defVal);
}
@@ -426,6 +432,17 @@ void emitExtCall(const PhpFunc& func, std::ostream& out, const char* ind) {
}
}
// Put the return-value-space pointer into x8
if (g_armMode) {
out << ind << "asm volatile (\"mov x8, %0\\n\" : : \"r\"(";
if (func.returnCppType == "HPHP::Variant") {
out << "rv";
} else {
out << "&(rv->m_data)";
}
out << ") : \"x8\");\n";
}
out << ind << call_prefix;
emitCallExpression(func, func.className.empty() ? "fh_" : "th_", out);
out << call_suffix;
@@ -667,17 +684,22 @@ void processSymbol(const fbstring& symbol, std::ostream& header,
}
int main(int argc, const char* argv[]) {
if (argc < 4) {
if (argc < 5) {
std::cout << "Usage: " << argv[0]
<< " <output .h file> <output .cpp file> <*.idl.json>...\n"
<< " <x64|arm> <output .h> <output .cpp> <*.idl.json>...\n"
<< "Pipe mangled C++ symbols to stdin.\n";
return 0;
}
g_armMode = (strcmp(argv[1], "arm") == 0);
std::ofstream header(argv[2]);
std::ofstream cpp(argv[3]);
fbvector<PhpFunc> funcs;
fbvector<PhpClass> classes;
for (auto i = 3; i < argc; ++i) {
for (auto i = 4; i < argc; ++i) {
try {
parseIDL(argv[i], funcs, classes);
} catch (const std::exception& exc) {
@@ -696,9 +718,6 @@ int main(int argc, const char* argv[]) {
}
}
std::ofstream header(argv[1]);
std::ofstream cpp(argv[2]);
header << "namespace HPHP {\n\n";
cpp << g_allIncludes << "\n";
cpp << "namespace HPHP {\n\n";
+6 -5
Ver Arquivo
@@ -1,10 +1,11 @@
#!/bin/sh
# $1 Object file to read symbols from
# $2 ext_hhvm.cpp source to generate
# $3 ext_hhvm.h header to generate
readelf -s -W $1 | grep 'FUNC.*GLOBAL' | \
# $1 Machine architecture (currently: "x64" or "arm")
# $2 Object file to read symbols from
# $3 ext_hhvm.cpp source to generate
# $4 ext_hhvm.h header to generate
readelf -s -W $2 | grep 'FUNC.*GLOBAL' | \
sed -e 's/^.*DEFAULT[0-9 ]*//' | \
$HPHP_HOME/hphp/tools/gen-ext-hhvm/gen-ext-hhvm \
$3 $2 $HPHP_HOME/hphp/idl/*.idl.json
$1 $4 $3 $HPHP_HOME/hphp/idl/*.idl.json