Add support for 32b MIPS architecture
* LLVM reactor backend: requires LLVM 7.0
* Subzero reactor backend: unittests hit unimplemented
TargetMIPS32::lowerShuffleVector()
Bug: b/117854176
Change-Id: Ie58e3e438db6f1b442b05efecf9b645aff82321a
Reviewed-on: https://swiftshader-review.googlesource.com/c/21748
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Milko Leporis <milko.leporis@mips.com>
diff --git a/BUILD.gn b/BUILD.gn
index b36d9f9..672e51e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -96,16 +96,30 @@
"-march=pentium4",
"-mtune=generic",
]
+ } else if (target_cpu == "mipsel" && current_cpu == target_cpu) {
+ cflags += [
+ "-march=mipsel",
+ "-mcpu=mips32r2",
+ "-fPIC",
+ "-mhard-float",
+ "-mfp32",
+ ]
}
if (is_linux) {
- ldflags = [
- "-Wl,--hash-style=both",
- "-Wl,--gc-sections",
- ]
+ ldflags = [ "-Wl,--gc-sections" ]
+
+ if (target_cpu == "mipsel") {
+ ldflags += [
+ "-Wl,--hash-style=sysv",
+ "-mips32r2",
+ ]
+ } else {
+ ldflags += [ "-Wl,--hash-style=both" ]
+ }
# A bug in the gold linker prevents using ICF on 32-bit (crbug.com/729532)
- if (use_gold && target_cpu == "x86") {
+ if (use_gold && (target_cpu == "x86" || target_cpu == "mipsel")) {
ldflags += [ "-Wl,--icf=none" ]
}
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 90a62fa..8023fd4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,12 @@
else()
set(ARCH "arm")
endif()
+elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "mips*")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(ARCH "mips64el")
+ else()
+ set(ARCH "mipsel")
+ endif()
else()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ARCH "x86_64")
@@ -133,9 +139,14 @@
# Don't allow symbols to be overridden by another module.
set_property(TARGET ${TARGET} APPEND_STRING PROPERTY COMPILE_FLAGS " -fvisibility=protected")
- # Both hash-style are needed, because we want both gold and
- # GNU ld to be able to read our libraries.
- set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=both")
+ if(ARCH STREQUAL "mipsel")
+ # MIPS supports sysv hash-style only.
+ set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=sysv")
+ else()
+ # Both hash-style are needed, because we want both gold and
+ # GNU ld to be able to read our libraries.
+ set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=both")
+ endif()
# Gc sections is used in combination with each functions being
# in its own section, to reduce the binary size.
@@ -214,6 +225,12 @@
set_cpp_flag("-march=x86-64")
set_cpp_flag("-mtune=generic")
endif()
+ if(ARCH STREQUAL "mipsel")
+ set_cpp_flag("-march=mips32r2")
+ set_cpp_flag("-fPIC")
+ set_cpp_flag("-mhard-float")
+ set_cpp_flag("-mfp32")
+ endif()
if(LINUX)
set_cpp_flag("-DUSE_X11=1")
@@ -1408,6 +1425,59 @@
${LLVM_DIR}/lib/Target/ARM/Thumb1InstrInfo.cpp
${LLVM_DIR}/lib/Target/ARM/ARMLegalizerInfo.cpp
${LLVM_DIR}/lib/Target/ARM/ARMOptimizeBarriersPass.cpp
+ ${LLVM_DIR}/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+ ${LLVM_DIR}/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16FrameLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16HardFloat.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16HardFloatInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16InstrInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16ISelLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/Mips16RegisterInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsAnalyzeImmediate.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsAsmPrinter.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsCallLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsCCState.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsConstantIslandPass.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsDelaySlotFiller.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsExpandPseudo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsFastISel.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsInstrInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsInstructionSelector.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsISelDAGToDAG.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsISelLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsFrameLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsLegalizerInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsBranchExpansion.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsMCInstLower.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsMachineFunction.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsOptimizePICCall.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsOs16.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsRegisterBankInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsRegisterInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsSEFrameLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsSEInstrInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsSEISelLowering.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsSERegisterInfo.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsSubtarget.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsTargetMachine.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MipsTargetObjectFile.cpp
+ ${LLVM_DIR}/lib/Target/Mips/MicroMipsSizeReduction.cpp
+ ${LLVM_DIR}/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
${LLVM_DIR}/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
${LLVM_DIR}/lib/Target/X86/AsmParser/X86AsmParser.cpp
${LLVM_DIR}/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
@@ -1625,11 +1695,13 @@
${LLVM_DIR}/include
${LLVM_DIR}/lib/Target/AArch64
${LLVM_DIR}/lib/Target/ARM
+ ${LLVM_DIR}/lib/Target/Mips
${LLVM_DIR}/lib/Target/X86
${LLVM_CONFIG_DIR}/common/include
${LLVM_CONFIG_DIR}/common/lib/IR
${LLVM_CONFIG_DIR}/common/lib/Target/AArch64
${LLVM_CONFIG_DIR}/common/lib/Target/ARM
+ ${LLVM_CONFIG_DIR}/common/lib/Target/Mips
${LLVM_CONFIG_DIR}/common/lib/Target/X86
${LLVM_CONFIG_DIR}/common/lib/Transforms/InstCombine
)
@@ -1705,6 +1777,13 @@
${SUBZERO_DIR}/src/IceTargetLoweringARM32.cpp
)
set(SUBZERO_TARGET ARM32)
+ elseif(ARCH STREQUAL "mipsel")
+ list(APPEND SUBZERO_LIST
+ ${SUBZERO_DIR}/src/IceAssemblerMIPS32.cpp
+ ${SUBZERO_DIR}/src/IceInstMIPS32.cpp
+ ${SUBZERO_DIR}/src/IceTargetLoweringMIPS32.cpp
+ )
+ set(SUBZERO_TARGET MIPS32)
else()
message(FATAL_ERROR "Architecture '${ARCH}' not supported by Subzero")
endif()
diff --git a/src/Reactor/BUILD.gn b/src/Reactor/BUILD.gn
index 9cf8e13..1ad06e4 100644
--- a/src/Reactor/BUILD.gn
+++ b/src/Reactor/BUILD.gn
@@ -41,11 +41,16 @@
"SZTARGET=X8664",
"SUBZERO_TARGET=X8664",
]
- } else {
+ } else if (target_cpu == "x86") {
defines += [
"SZTARGET=X8632",
"SUBZERO_TARGET=X8632",
]
+ } else if (target_cpu == "mipsel") {
+ defines += [
+ "SZTARGET=MIPS32",
+ "SUBZERO_TARGET=MIPS32",
+ ]
}
include_dirs = [
@@ -153,16 +158,16 @@
"/wd4201", # nameless struct/union
"/wd4245", # conversion from int to unsigned int (llvm)
]
- } else if (target_cpu == "x86" || target_cpu == "x64") {
- cflags = [
- "-Wno-unused-local-typedef",
- "-msse2",
- ]
-
+ } else {
+ cflags = [ "-Wno-unused-local-typedef" ]
defines = [
"__STDC_CONSTANT_MACROS",
"__STDC_LIMIT_MACROS",
]
+
+ if (target_cpu == "x86" || target_cpu == "x64") {
+ cflags += [ "-msse2" ]
+ }
}
}
@@ -247,11 +252,17 @@
"$subzero_dir/src/IceInstX8664.cpp",
"$subzero_dir/src/IceTargetLoweringX8664.cpp",
]
- } else {
+ } else if (target_cpu == "x86") {
sources += [
"$subzero_dir/src/IceInstX8632.cpp",
"$subzero_dir/src/IceTargetLoweringX8632.cpp",
]
+ } else if (target_cpu == "mipsel") {
+ sources += [
+ "$subzero_dir/src/IceAssemblerMIPS32.cpp",
+ "$subzero_dir/src/IceInstMIPS32.cpp",
+ "$subzero_dir/src/IceTargetLoweringMIPS32.cpp",
+ ]
}
configs = [
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index ca0c0ae..c08572c 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -822,6 +822,8 @@
static const char arch[] = "arm64";
#elif defined(__arm__)
static const char arch[] = "arm";
+ #elif defined(__mips__)
+ static const char arch[] = "mipsel";
#else
#error "unknown architecture"
#endif
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 2126afb..76f5a72 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -106,6 +106,8 @@
return true;
#elif defined(__i386__) || defined(__x86_64__)
return false;
+ #elif defined(__mips__)
+ return false;
#else
#error "Unknown architecture"
#endif
@@ -373,6 +375,8 @@
assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM);
#elif defined(__aarch64__)
assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_AARCH64);
+ #elif defined(__mips__)
+ assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_MIPS);
#else
#error "Unsupported platform"
#endif
@@ -526,6 +530,9 @@
#if defined(__arm__)
Flags.setTargetArch(Ice::Target_ARM32);
Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm);
+ #elif defined(__mips__)
+ Flags.setTargetArch(Ice::Target_MIPS32);
+ Flags.setTargetInstructionSet(Ice::BaseInstructionSet);
#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);
diff --git a/third_party/llvm-7.0/scripts/update.py b/third_party/llvm-7.0/scripts/update.py
index badabe2..fe30730 100755
--- a/third_party/llvm-7.0/scripts/update.py
+++ b/third_party/llvm-7.0/scripts/update.py
@@ -33,6 +33,7 @@
('AArch64', ('__aarch64__',)),
('ARM', ('__arm__',)),
('X86', ('__i386__', '__x86_64__')),
+ ('Mips', ('__mips__',)),
]
LLVM_TRIPLES = {
@@ -47,6 +48,7 @@
('__i386__', 'i686-pc-linux-gnu'),
('__arm__', 'armv7-linux-gnueabihf'),
('__aarch64__', 'aarch64-linux-gnu'),
+ ('__mips__', 'mipsel-linux-gnu'),
],
}
@@ -102,6 +104,7 @@
os.path.join('lib', 'Target', 'AArch64'),
os.path.join('lib', 'Target', 'ARM'),
os.path.join('lib', 'Target', 'X86'),
+ os.path.join('lib', 'Target', 'Mips'),
os.path.join('lib', 'Transforms', 'InstCombine'),
]
for subdir in subdirs: