Support ARM compilation with Subzero. Bug b/37478805 Change-Id: Ib3af3edfcc24308b2a0f37cb0f534226aa83e446 Reviewed-on: https://swiftshader-review.googlesource.com/9448 Reviewed-by: Nicolas Capens <capn@google.com> Tested-by: Nicolas Capens <capn@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt index 693e1a1..81565c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -49,10 +49,18 @@ message(FATAL_ERROR "Platform is not supported") endif() -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH "x86_64") +if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH "aarch64") + else() + set(ARCH "arm") + endif() else() - set(ARCH "x86") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH "x86_64") + else() + set(ARCH "x86") + endif() endif() ########################################################### @@ -591,25 +599,35 @@ ${SUBZERO_DIR}/src/IceRNG.cpp ${SUBZERO_DIR}/src/IceSwitchLowering.cpp ${SUBZERO_DIR}/src/IceTargetLowering.cpp - ${SUBZERO_DIR}/src/IceTargetLoweringX86.cpp ${SUBZERO_DIR}/src/IceThreading.cpp ${SUBZERO_DIR}/src/IceTimerTree.cpp ${SUBZERO_DIR}/src/IceTypes.cpp ${SUBZERO_DIR}/src/IceVariableSplitting.cpp ) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) + if(ARCH STREQUAL "x86_64") list(APPEND SUBZERO_LIST + ${SUBZERO_DIR}/src/IceTargetLoweringX86.cpp ${SUBZERO_DIR}/src/IceInstX8664.cpp ${SUBZERO_DIR}/src/IceTargetLoweringX8664.cpp ) set(SUBZERO_TARGET X8664) - else() + elseif(ARCH STREQUAL "x86") list(APPEND SUBZERO_LIST + ${SUBZERO_DIR}/src/IceTargetLoweringX86.cpp ${SUBZERO_DIR}/src/IceInstX8632.cpp ${SUBZERO_DIR}/src/IceTargetLoweringX8632.cpp ) set(SUBZERO_TARGET X8632) + elseif(ARCH STREQUAL "arm") + list(APPEND SUBZERO_LIST + ${SUBZERO_DIR}/src/IceAssemblerARM32.cpp + ${SUBZERO_DIR}/src/IceInstARM32.cpp + ${SUBZERO_DIR}/src/IceTargetLoweringARM32.cpp + ) + set(SUBZERO_TARGET ARM32) + else() + message(FATAL_ERROR "Architecture '${ARCH}' not supported by Subzero") endif() file(GLOB_RECURSE SUBZERO_DEPENDENCIES_LIST
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp index ee3fedb..5222ddb 100644 --- a/src/Reactor/SubzeroReactor.cpp +++ b/src/Reactor/SubzeroReactor.cpp
@@ -230,21 +230,46 @@ } } - switch(relocation.getType()) - { - case R_386_NONE: - // No relocation - break; - case R_386_32: - *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite); - break; - // case R_386_PC32: - // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite); - // break; - default: - assert(false && "Unsupported relocation type"); - return nullptr; - } + #if defined(__i386__) + switch(relocation.getType()) + { + case R_386_NONE: + // No relocation + break; + case R_386_32: + *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite); + break; + // case R_386_PC32: + // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite); + // break; + default: + assert(false && "Unsupported relocation type"); + return nullptr; + } + #elif defined(__arm__) + switch(relocation.getType()) + { + case R_ARM_NONE: + // No relocation + break; + case R_ARM_MOVW_ABS_NC: + { + uint32_t thumb = 0; // Calls to Thumb code not supported. + uint32_t lo = (uint32_t)symbolValue | thumb; + *patchSite = (*patchSite & 0xFFF0F000) | ((lo & 0xF000) << 4) | (lo & 0x0FFF); + } + break; + case R_ARM_MOVT_ABS: + { + uint32_t hi = (uint32_t)(symbolValue) >> 16; + *patchSite = (*patchSite & 0xFFF0F000) | ((hi & 0xF000) << 4) | (hi & 0x0FFF); + } + break; + default: + assert(false && "Unsupported relocation type"); + return nullptr; + } + #endif return symbolValue; } @@ -286,24 +311,26 @@ } } - switch(relocation.getType()) - { - case R_X86_64_NONE: - // No relocation - break; - case R_X86_64_64: - *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend; - break; - case R_X86_64_PC32: - *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend; - break; - case R_X86_64_32S: - *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend; - break; - default: - assert(false && "Unsupported relocation type"); - return nullptr; - } + #if defined(__x86_64__) + switch(relocation.getType()) + { + case R_X86_64_NONE: + // No relocation + break; + case R_X86_64_64: + *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend; + break; + case R_X86_64_PC32: + *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend; + break; + case R_X86_64_32S: + *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend; + break; + default: + assert(false && "Unsupported relocation type"); + return nullptr; + } + #endif return symbolValue; } @@ -319,7 +346,15 @@ // Expect ELF bitness to match platform assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32); - assert(sizeof(void*) == 8 ? elfHeader->e_machine == EM_X86_64 : elfHeader->e_machine == EM_386); + #if defined(__i386__) + assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_386); + #elif defined(__x86_64__) + assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_X86_64); + #elif defined(__arm__) + assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM); + #else + #error "Unsupported platform" + #endif SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff); void *entry = nullptr; @@ -479,12 +514,18 @@ Ice::ClFlags &Flags = Ice::ClFlags::Flags; Ice::ClFlags::getParsedClFlags(Flags); - Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632); + #if defined(__arm__) + Flags.setTargetArch(Ice::Target_ARM32); + Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm); + #else // x86 + Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632); + Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2); + #endif Flags.setOutFileType(Ice::FT_Elf); Flags.setOptLevel(Ice::Opt_2); Flags.setApplicationBinaryInterface(Ice::ABI_Platform); - Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2); - Flags.setVerbose(false ? Ice::IceV_All : Ice::IceV_None); + Flags.setVerbose(false ? Ice::IceV_Most : Ice::IceV_None); + Flags.setDisableHybridAssembly(true); static llvm::raw_os_ostream cout(std::cout); static llvm::raw_os_ostream cerr(std::cerr);