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);