diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index 5a7e986b532c4..7f01aaa3ac113 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -3,8 +3,15 @@ "intrinsic_prefix": "_vec_", "llvm_prefix": "llvm.ppc.altivec.", "number_info": { - "unsigned": {}, - "signed": {} + "unsigned": { + "kind" : "u", + "data_type_short": { "8": "b", "16": "h", "32": "w", "64": "d" } + }, + "signed": { + "kind" : "s", + "data_type_short": { "8": "b", "16": "h", "32": "w", "64": "d" } + }, + "float": {} }, "width_info": { "128": { "width": "" } @@ -16,6 +23,55 @@ "llvm": "vperm", "ret": "s32", "args": ["0", "0", "s8"] + }, + { + "intrinsic": "mradds", + "width": [128], + "llvm": "vmhraddshs", + "ret": "s16", + "args": ["0", "0", "0"] + }, + { + "intrinsic": "cmpb", + "width": [128], + "llvm": "vcmpbfp", + "ret": "s32", + "args": ["f32", "f32"] + }, + { + "intrinsic": "cmpeq{0.data_type_short}", + "width": [128], + "llvm": "vcmpequ{0.data_type_short}", + "ret": "s(8-32)", + "args": ["0", "0"] + }, + { + "intrinsic": "cmpgt{1.kind}{1.data_type_short}", + "width": [128], + "llvm": "vcmpgt{1.kind}{1.data_type_short}", + "ret": "s(8-32)", + "args": ["0u", "1"] + }, + { + "intrinsic": "cmpgt{1.kind}{1.data_type_short}", + "width": [128], + "llvm": "vcmpgt{1.kind}{1.data_type_short}", + "ret": "s(8-32)", + "args": ["0", "1"] + }, + { + "intrinsic": "max{0.kind}{0.data_type_short}", + "width": [128], + "llvm": "vmax{0.kind}{0.data_type_short}", + "ret": "i(8-32)", + "args": ["0", "0"] + }, + { + "intrinsic": "min{0.kind}{0.data_type_short}", + "width": [128], + "llvm": "vmin{0.kind}{0.data_type_short}", + "ret": "i(8-32)", + "args": ["0", "0"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index 31b642b4055b9..60074cce2b9a3 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -27,6 +27,121 @@ pub fn find(name: &str) -> Option { output: &::I32x4, definition: Named("llvm.ppc.altivec.vperm") }, + "_vec_mradds" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 3] = [&::I16x8, &::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vmhraddshs") + }, + "_vec_cmpb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpbfp") + }, + "_vec_cmpeqb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vcmpequb") + }, + "_vec_cmpeqh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vcmpequh") + }, + "_vec_cmpeqw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpequw") + }, + "_vec_cmpgtub" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vcmpgtub") + }, + "_vec_cmpgtuh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vcmpgtuh") + }, + "_vec_cmpgtuw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpgtuw") + }, + "_vec_cmpgtsb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vcmpgtsb") + }, + "_vec_cmpgtsh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vcmpgtsh") + }, + "_vec_cmpgtsw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpgtsw") + }, + "_vec_maxsb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vmaxsb") + }, + "_vec_maxub" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS }, + output: &::U8x16, + definition: Named("llvm.ppc.altivec.vmaxub") + }, + "_vec_maxsh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vmaxsh") + }, + "_vec_maxuh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS }, + output: &::U16x8, + definition: Named("llvm.ppc.altivec.vmaxuh") + }, + "_vec_maxsw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vmaxsw") + }, + "_vec_maxuw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS }, + output: &::U32x4, + definition: Named("llvm.ppc.altivec.vmaxuw") + }, + "_vec_minsb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vminsb") + }, + "_vec_minub" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS }, + output: &::U8x16, + definition: Named("llvm.ppc.altivec.vminub") + }, + "_vec_minsh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vminsh") + }, + "_vec_minuh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS }, + output: &::U16x8, + definition: Named("llvm.ppc.altivec.vminuh") + }, + "_vec_minsw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vminsw") + }, + "_vec_minuw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS }, + output: &::U32x4, + definition: Named("llvm.ppc.altivec.vminuw") + }, _ => return None, }) } diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 99ab1c47bed31..448feb5259ddd 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -80,7 +80,10 @@ const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bm const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; -const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0", "vsx\0"]; +const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0", + "power8-altivec\0", "power9-altivec\0", + "power8-vector\0", "power9-vector\0", + "vsx\0"]; pub fn target_features(sess: &Session) -> Vec { let target_machine = create_target_machine(sess); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 7fb1eafb30da7..57e90be27748f 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -181,20 +181,14 @@ extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const FeatureBitset &Bits = MCInfo->getFeatureBits(); - const llvm::SubtargetFeatureKV *FeatureEntry; - -#define SUBTARGET(x) \ - if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \ - FeatureEntry = x##FeatureKV; \ - } else - - GEN_SUBTARGETS { return false; } -#undef SUBTARGET - - while (strcmp(Feature, FeatureEntry->Key) != 0) - FeatureEntry++; +#if LLVM_VERSION_GE(4, 0) + const ArrayRef FeatTable = MCInfo->getFeatureTable(); - return (Bits & FeatureEntry->Value) == FeatureEntry->Value; + for (auto &FeatureEntry : FeatTable) + if (!strcmp(FeatureEntry.Key, Feature)) + return (Bits & FeatureEntry.Value) == FeatureEntry.Value; +#endif + return false; } enum class LLVMRustCodeModel { diff --git a/src/test/run-make/print-cfg/Makefile b/src/test/run-make/print-cfg/Makefile index a820a463f4a02..82fa3f6a3c5e0 100644 --- a/src/test/run-make/print-cfg/Makefile +++ b/src/test/run-make/print-cfg/Makefile @@ -5,7 +5,7 @@ all: default $(RUSTC) --target x86_64-pc-windows-gnu --print cfg | grep x86_64 $(RUSTC) --target i686-pc-windows-msvc --print cfg | grep msvc $(RUSTC) --target i686-apple-darwin --print cfg | grep macos - $(RUSTC) --target i686-unknown-linux-gnu --print cfg | grep sse2 + $(RUSTC) --target i686-unknown-linux-gnu --print cfg | grep gnu ifdef IS_WINDOWS default: diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs index 8d88c17af79b3..c27f83011cb1b 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/run-pass/sse2.rs @@ -7,6 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +// min-llvm-version 4.0 #![feature(cfg_target_feature)]