445 lines
14 KiB
C++
445 lines
14 KiB
C++
/*
|
|
Copyright (c) 2019-2021, Intel Corporation
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are
|
|
met:
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of Intel Corporation nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/** @file target_enums.cpp
|
|
@brief Define enums describing target platform.
|
|
*/
|
|
|
|
#include "target_enums.h"
|
|
|
|
#include "ispc.h"
|
|
#include "util.h"
|
|
|
|
#include <cstring>
|
|
|
|
namespace ispc {
|
|
|
|
Arch ParseArch(std::string arch) {
|
|
if (arch == "x86") {
|
|
return Arch::x86;
|
|
} else if (arch == "x86_64" || arch == "x86-64") {
|
|
return Arch::x86_64;
|
|
} else if (arch == "arm") {
|
|
return Arch::arm;
|
|
} else if (arch == "aarch64") {
|
|
return Arch::aarch64;
|
|
} else if (arch == "wasm32") {
|
|
return Arch::wasm32;
|
|
} else if (arch == "xe32") {
|
|
return Arch::xe32;
|
|
} else if (arch == "xe64") {
|
|
return Arch::xe64;
|
|
}
|
|
return Arch::error;
|
|
}
|
|
|
|
std::string ArchToString(Arch arch) {
|
|
switch (arch) {
|
|
case Arch::none:
|
|
return "none";
|
|
case Arch::x86:
|
|
return "x86";
|
|
case Arch::x86_64:
|
|
return "x86-64";
|
|
case Arch::arm:
|
|
return "arm";
|
|
case Arch::aarch64:
|
|
return "aarch64";
|
|
case Arch::wasm32:
|
|
return "wasm32";
|
|
case Arch::xe32:
|
|
return "xe32";
|
|
case Arch::xe64:
|
|
return "xe64";
|
|
case Arch::error:
|
|
return "error";
|
|
default:
|
|
// none and error are not supposed to be printed.
|
|
Error(SourcePos(), "Invalid arch is processed");
|
|
exit(1);
|
|
}
|
|
return "error";
|
|
}
|
|
|
|
ISPCTarget ParseISPCTarget(std::string target) {
|
|
// TODO: ensure skx-i32x8 is not enabled and linked for earli LLVM version.
|
|
|
|
// The first matching string for each target is the canonical way to name the target,
|
|
// all other strings are aliases.
|
|
if (target == "host") {
|
|
return ISPCTarget::host;
|
|
} else if (target == "sse2-i32x4" || target == "sse2") {
|
|
return ISPCTarget::sse2_i32x4;
|
|
} else if (target == "sse2-i32x8" || target == "sse2-x2") {
|
|
return ISPCTarget::sse2_i32x8;
|
|
} else if (target == "sse4-i8x16") {
|
|
return ISPCTarget::sse4_i8x16;
|
|
} else if (target == "sse4-i16x8") {
|
|
return ISPCTarget::sse4_i16x8;
|
|
} else if (target == "sse4-i32x4" || target == "sse4") {
|
|
return ISPCTarget::sse4_i32x4;
|
|
} else if (target == "sse4-i32x8" || target == "sse4-x2" || target == "sse4x2") {
|
|
return ISPCTarget::sse4_i32x8;
|
|
} else if (target == "avx1-i32x4") {
|
|
return ISPCTarget::avx1_i32x4;
|
|
} else if (target == "avx1-i32x8" || target == "avx" || target == "avx1") {
|
|
return ISPCTarget::avx1_i32x8;
|
|
} else if (target == "avx1-i64x4" || target == "avx-i64x4") {
|
|
return ISPCTarget::avx1_i64x4;
|
|
} else if (target == "avx1-i32x16" || target == "avx-x2" || target == "avx1-x2") {
|
|
return ISPCTarget::avx1_i32x16;
|
|
} else if (target == "avx2-i8x32") {
|
|
return ISPCTarget::avx2_i8x32;
|
|
} else if (target == "avx2-i16x16") {
|
|
return ISPCTarget::avx2_i16x16;
|
|
} else if (target == "avx2-i32x4") {
|
|
return ISPCTarget::avx2_i32x4;
|
|
} else if (target == "avx2-i32x8" || target == "avx2") {
|
|
return ISPCTarget::avx2_i32x8;
|
|
} else if (target == "avx2-i64x4") {
|
|
return ISPCTarget::avx2_i64x4;
|
|
} else if (target == "avx2-i32x16" || target == "avx2-x2") {
|
|
return ISPCTarget::avx2_i32x16;
|
|
} else if (target == "avx512knl-i32x16") {
|
|
return ISPCTarget::avx512knl_i32x16;
|
|
} else if (target == "avx512skx-i32x16") {
|
|
return ISPCTarget::avx512skx_i32x16;
|
|
} else if (target == "avx512skx-i32x8") {
|
|
return ISPCTarget::avx512skx_i32x8;
|
|
} else if (target == "avx512skx-i32x4") {
|
|
return ISPCTarget::avx512skx_i32x4;
|
|
} else if (target == "avx512skx-i8x64") {
|
|
return ISPCTarget::avx512skx_i8x64;
|
|
} else if (target == "avx512skx-i16x32") {
|
|
return ISPCTarget::avx512skx_i16x32;
|
|
} else if (target == "neon-i8x16") {
|
|
return ISPCTarget::neon_i8x16;
|
|
} else if (target == "neon-i16x8") {
|
|
return ISPCTarget::neon_i8x16;
|
|
} else if (target == "neon-i32x4" || target == "neon") {
|
|
return ISPCTarget::neon_i32x4;
|
|
} else if (target == "neon-i32x8") {
|
|
return ISPCTarget::neon_i32x8;
|
|
} else if (target == "wasm-i32x4") {
|
|
return ISPCTarget::wasm_i32x4;
|
|
} else if (target == "gen9-x8") {
|
|
return ISPCTarget::gen9_x8;
|
|
} else if (target == "gen9-x16" || target == "gen9") {
|
|
return ISPCTarget::gen9_x16;
|
|
} else if (target == "xelp-x8") {
|
|
return ISPCTarget::xelp_x8;
|
|
} else if (target == "xelp-x16" || target == "xelp") {
|
|
return ISPCTarget::xelp_x16;
|
|
} else if (target == "xehpg-x8") {
|
|
return ISPCTarget::xehpg_x8;
|
|
} else if (target == "xehpg-x16") {
|
|
return ISPCTarget::xehpg_x16;
|
|
}
|
|
|
|
return ISPCTarget::error;
|
|
}
|
|
|
|
// Given a comma-delimited string with one or more compilation targets of
|
|
// the form "sse4-i32x4,avx2-i32x8", return a pair. First element of the pair is a vector
|
|
// of correctly parsed targets, second element of the pair is a strings with targets, which
|
|
// were not recognized.
|
|
std::pair<std::vector<ISPCTarget>, std::string> ParseISPCTargets(const char *target) {
|
|
std::vector<ISPCTarget> targets;
|
|
std::string error_target;
|
|
const char *tstart = target;
|
|
bool done = false;
|
|
while (!done) {
|
|
const char *tend = strchr(tstart, ',');
|
|
if (tend == NULL) {
|
|
done = true;
|
|
tend = strchr(tstart, '\0');
|
|
}
|
|
std::string target_string = std::string(tstart, tend);
|
|
ISPCTarget target_parsed = ParseISPCTarget(target_string);
|
|
if (target_parsed == ISPCTarget::error) {
|
|
if (!error_target.empty()) {
|
|
error_target += ",";
|
|
}
|
|
error_target += target_string;
|
|
} else {
|
|
targets.push_back(target_parsed);
|
|
}
|
|
tstart = tend + 1;
|
|
}
|
|
return std::make_pair(targets, error_target);
|
|
}
|
|
|
|
std::string ISPCTargetToString(ISPCTarget target) {
|
|
switch (target) {
|
|
case ISPCTarget::host:
|
|
return "host";
|
|
case ISPCTarget::sse2_i32x4:
|
|
return "sse2-i32x4";
|
|
case ISPCTarget::sse2_i32x8:
|
|
return "sse2-i32x8";
|
|
case ISPCTarget::sse4_i8x16:
|
|
return "sse4-i8x16";
|
|
case ISPCTarget::sse4_i16x8:
|
|
return "sse4-i16x8";
|
|
case ISPCTarget::sse4_i32x4:
|
|
return "sse4-i32x4";
|
|
case ISPCTarget::sse4_i32x8:
|
|
return "sse4-i32x8";
|
|
case ISPCTarget::avx1_i32x4:
|
|
return "avx1-i32x4";
|
|
case ISPCTarget::avx1_i32x8:
|
|
return "avx1-i32x8";
|
|
case ISPCTarget::avx1_i32x16:
|
|
return "avx1-i32x16";
|
|
case ISPCTarget::avx1_i64x4:
|
|
return "avx1-i64x4";
|
|
case ISPCTarget::avx2_i8x32:
|
|
return "avx2-i8x32";
|
|
case ISPCTarget::avx2_i16x16:
|
|
return "avx2-i16x16";
|
|
case ISPCTarget::avx2_i32x4:
|
|
return "avx2-i32x4";
|
|
case ISPCTarget::avx2_i32x8:
|
|
return "avx2-i32x8";
|
|
case ISPCTarget::avx2_i32x16:
|
|
return "avx2-i32x16";
|
|
case ISPCTarget::avx2_i64x4:
|
|
return "avx2-i64x4";
|
|
case ISPCTarget::avx512knl_i32x16:
|
|
return "avx512knl-i32x16";
|
|
case ISPCTarget::avx512skx_i32x8:
|
|
return "avx512skx-i32x8";
|
|
case ISPCTarget::avx512skx_i32x4:
|
|
return "avx512skx-i32x4";
|
|
case ISPCTarget::avx512skx_i32x16:
|
|
return "avx512skx-i32x16";
|
|
case ISPCTarget::avx512skx_i8x64:
|
|
return "avx512skx-i8x64";
|
|
case ISPCTarget::avx512skx_i16x32:
|
|
return "avx512skx-i16x32";
|
|
case ISPCTarget::neon_i8x16:
|
|
return "neon-i8x16";
|
|
case ISPCTarget::neon_i16x8:
|
|
return "neon-i16x8";
|
|
case ISPCTarget::neon_i32x4:
|
|
return "neon-i32x4";
|
|
case ISPCTarget::neon_i32x8:
|
|
return "neon-i32x8";
|
|
case ISPCTarget::wasm_i32x4:
|
|
return "wasm-i32x4";
|
|
case ISPCTarget::gen9_x8:
|
|
return "gen9-x8";
|
|
case ISPCTarget::gen9_x16:
|
|
return "gen9-x16";
|
|
case ISPCTarget::xelp_x8:
|
|
return "xelp-x8";
|
|
case ISPCTarget::xelp_x16:
|
|
return "xelp-x16";
|
|
case ISPCTarget::xehpg_x8:
|
|
return "xehpg-x8";
|
|
case ISPCTarget::xehpg_x16:
|
|
return "xehpg-x16";
|
|
case ISPCTarget::none:
|
|
case ISPCTarget::error:
|
|
// Fall through
|
|
;
|
|
}
|
|
Error(SourcePos(), "Invalid ISPCTarget is processed");
|
|
exit(1);
|
|
}
|
|
|
|
bool ISPCTargetIsX86(ISPCTarget target) {
|
|
switch (target) {
|
|
case ISPCTarget::sse2_i32x4:
|
|
case ISPCTarget::sse2_i32x8:
|
|
case ISPCTarget::sse4_i8x16:
|
|
case ISPCTarget::sse4_i16x8:
|
|
case ISPCTarget::sse4_i32x4:
|
|
case ISPCTarget::sse4_i32x8:
|
|
case ISPCTarget::avx1_i32x4:
|
|
case ISPCTarget::avx1_i32x8:
|
|
case ISPCTarget::avx1_i32x16:
|
|
case ISPCTarget::avx1_i64x4:
|
|
case ISPCTarget::avx2_i8x32:
|
|
case ISPCTarget::avx2_i16x16:
|
|
case ISPCTarget::avx2_i32x4:
|
|
case ISPCTarget::avx2_i32x8:
|
|
case ISPCTarget::avx2_i32x16:
|
|
case ISPCTarget::avx2_i64x4:
|
|
case ISPCTarget::avx512knl_i32x16:
|
|
case ISPCTarget::avx512skx_i32x8:
|
|
case ISPCTarget::avx512skx_i32x4:
|
|
case ISPCTarget::avx512skx_i32x16:
|
|
case ISPCTarget::avx512skx_i8x64:
|
|
case ISPCTarget::avx512skx_i16x32:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ISPCTargetIsNeon(ISPCTarget target) {
|
|
switch (target) {
|
|
case ISPCTarget::neon_i8x16:
|
|
case ISPCTarget::neon_i16x8:
|
|
case ISPCTarget::neon_i32x4:
|
|
case ISPCTarget::neon_i32x8:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ISPCTargetIsWasm(ISPCTarget target) {
|
|
switch (target) {
|
|
case ISPCTarget::wasm_i32x4:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ISPCTargetIsGen(ISPCTarget target) {
|
|
switch (target) {
|
|
case ISPCTarget::gen9_x8:
|
|
case ISPCTarget::gen9_x16:
|
|
case ISPCTarget::xelp_x8:
|
|
case ISPCTarget::xelp_x16:
|
|
case ISPCTarget::xehpg_x8:
|
|
case ISPCTarget::xehpg_x16:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
TargetOS ParseOS(std::string os) {
|
|
std::string supportedOses = g->target_registry->getSupportedOSes().c_str();
|
|
if (supportedOses.find(os) == std::string::npos) {
|
|
return TargetOS::error;
|
|
}
|
|
if (os == "windows") {
|
|
return TargetOS::windows;
|
|
} else if (os == "linux") {
|
|
return TargetOS::linux;
|
|
} else if (os == "custom_linux") {
|
|
return TargetOS::custom_linux;
|
|
} else if (os == "freebsd") {
|
|
return TargetOS::freebsd;
|
|
} else if (os == "macos") {
|
|
return TargetOS::macos;
|
|
} else if (os == "android") {
|
|
return TargetOS::android;
|
|
} else if (os == "ios") {
|
|
return TargetOS::ios;
|
|
} else if (os == "ps4") {
|
|
return TargetOS::ps4;
|
|
} else if (os == "ps5") {
|
|
return TargetOS::ps5;
|
|
} else if (os == "web") {
|
|
return TargetOS::web;
|
|
}
|
|
return TargetOS::error;
|
|
}
|
|
|
|
std::string OSToString(TargetOS os) {
|
|
switch (os) {
|
|
case TargetOS::windows:
|
|
return "Windows";
|
|
case TargetOS::linux:
|
|
return "Linux";
|
|
case TargetOS::custom_linux:
|
|
return "Linux (custom)";
|
|
case TargetOS::freebsd:
|
|
return "FreeBSD";
|
|
case TargetOS::macos:
|
|
return "macOS";
|
|
case TargetOS::android:
|
|
return "Android";
|
|
case TargetOS::ios:
|
|
return "iOS";
|
|
case TargetOS::ps4:
|
|
return "PS4";
|
|
case TargetOS::ps5:
|
|
return "PS5";
|
|
case TargetOS::web:
|
|
return "web";
|
|
case TargetOS::error:
|
|
return "error";
|
|
}
|
|
UNREACHABLE();
|
|
}
|
|
|
|
std::string OSToLowerString(TargetOS os) {
|
|
switch (os) {
|
|
case TargetOS::windows:
|
|
return "windows";
|
|
case TargetOS::linux:
|
|
return "linux";
|
|
case TargetOS::custom_linux:
|
|
return "custom_linux";
|
|
case TargetOS::freebsd:
|
|
return "freebsd";
|
|
case TargetOS::macos:
|
|
return "macos";
|
|
case TargetOS::android:
|
|
return "android";
|
|
case TargetOS::ios:
|
|
return "ios";
|
|
case TargetOS::ps4:
|
|
return "ps4";
|
|
case TargetOS::ps5:
|
|
return "ps5";
|
|
case TargetOS::web:
|
|
return "web";
|
|
case TargetOS::error:
|
|
return "error";
|
|
}
|
|
UNREACHABLE();
|
|
}
|
|
|
|
TargetOS GetHostOS() {
|
|
#if defined(ISPC_HOST_IS_WINDOWS) && !defined(ISPC_WINDOWS_TARGET_OFF)
|
|
return TargetOS::windows;
|
|
#elif defined(ISPC_HOST_IS_LINUX) && !defined(ISPC_LINUX_TARGET_OFF)
|
|
return TargetOS::linux;
|
|
#elif defined(ISPC_HOST_IS_FREEBSD) && !defined(ISPC_FREEBSD_TARGET_OFF)
|
|
return TargetOS::freebsd;
|
|
#elif defined(ISPC_HOST_IS_APPLE) && !defined(ISPC_MACOS_TARGET_OFF)
|
|
return TargetOS::macos;
|
|
#else
|
|
return TargetOS::error;
|
|
#endif
|
|
}
|
|
} // namespace ispc
|