From 8cd432e90ad57386efcbcb2735b28276cda175c0 Mon Sep 17 00:00:00 2001 From: Austin Horning Date: Sun, 19 Jun 2016 21:06:57 -0700 Subject: [PATCH] Add AMD target definition --- configure | 2 +- mk/main.mk | 2 +- src/bootstrap/native.rs | 2 +- src/libcore/intrinsics.rs | 60 +++++++++++++++++++ .../target/amdgcn_unknown_unknown.rs | 38 ++++++++++++ src/librustc_back/target/mod.rs | 7 ++- .../target/r600_unknown_unknown.rs | 37 ++++++++++++ src/librustc_llvm/build.rs | 9 ++- src/librustc_llvm/lib.rs | 5 ++ src/librustc_trans/context.rs | 39 ++++++++++++ src/librustc_trans/intrinsic.rs | 38 ++++++++++++ src/librustc_typeck/check/intrinsic.rs | 16 +++++ 12 files changed, 249 insertions(+), 6 deletions(-) create mode 100644 src/librustc_back/target/amdgcn_unknown_unknown.rs create mode 100644 src/librustc_back/target/r600_unknown_unknown.rs diff --git a/configure b/configure index 1dd1d2c2689ed..7074916cd5564 100755 --- a/configure +++ b/configure @@ -1718,7 +1718,7 @@ do CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=ON" fi - CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TARGETS_TO_BUILD='X86;ARM;AArch64;Mips;PowerPC;NVPTX'" + CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TARGETS_TO_BUILD='X86;ARM;AArch64;Mips;PowerPC;NVPTX;AMDGPU'" CMAKE_ARGS="$CMAKE_ARGS -G '$CFG_CMAKE_GENERATOR'" CMAKE_ARGS="$CMAKE_ARGS $CFG_LLVM_SRC_DIR" diff --git a/mk/main.mk b/mk/main.mk index 626392fe38f61..3bf90b9e20100 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -296,7 +296,7 @@ endif # LLVM macros ###################################################################### -LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc pnacl nvptx +LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc pnacl nvptx amdgpu LLVM_REQUIRED_COMPONENTS=ipo bitreader bitwriter linker asmparser mcjit \ interpreter instrumentation diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 7a008109b91fd..cdbb94b5ced63 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -65,7 +65,7 @@ pub fn llvm(build: &Build, target: &str) { .out_dir(&dst) .profile(if build.config.llvm_optimize {"Release"} else {"Debug"}) .define("LLVM_ENABLE_ASSERTIONS", assertions) - .define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC;NVPTX") + .define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC;NVPTX;AMDGPU") .define("LLVM_INCLUDE_EXAMPLES", "OFF") .define("LLVM_INCLUDE_TESTS", "OFF") .define("LLVM_INCLUDE_DOCS", "OFF") diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 5e6d0a4c39230..05b0b6180fce3 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -616,3 +616,63 @@ extern "rust-intrinsic" { pub fn grid_dim_z() -> i32; pub fn syncthreads(); } + +#[cfg(not(stage0))] +#[cfg(arch = "amdgcn")] +extern "rust-intrinsic" { + pub fn amdgcn_read_workdim() -> i32; + + pub fn amdgcn_ngroups_x() -> i32; + pub fn amdgcn_ngroups_y() -> i32; + pub fn amdgcn_ngroups_z() -> i32; + + pub fn amdgcn_global_size_x() -> i32; + pub fn amdgcn_global_size_y() -> i32; + pub fn amdgcn_global_size_z() -> i32; + + pub fn amdgcn_local_size_x() -> i32; + pub fn amdgcn_local_size_y() -> i32; + pub fn amdgcn_local_size_z() -> i32; + + pub fn amdgcn_workgroup_id_x() -> i32; + pub fn amdgcn_workgroup_id_y() -> i32; + pub fn amdgcn_workgroup_id_z() -> i32; + + pub fn amdgcn_workitem_id_x() -> i32; + pub fn amdgcn_workitem_id_y() -> i32; + pub fn amdgcn_workitem_id_z() -> i32; + + pub fn amdgcn_global_offset_x() -> i32; + pub fn amdgcn_global_offset_y() -> i32; + pub fn amdgcn_global_offset_z() -> i32; +} + +#[cfg(not(stage0))] +#[cfg(arch = "r600")] +extern "rust-intrinsic" { + pub fn r600_read_workdim() -> i32; + + pub fn r600_read_ngroups_x() -> i32; + pub fn r600_read_ngroups_y() -> i32; + pub fn r600_read_ngroups_z() -> i32; + + pub fn r600_read_global_size_x() -> i32; + pub fn r600_read_global_size_y() -> i32; + pub fn r600_read_global_size_z() -> i32; + + pub fn r600_read_local_size_x() -> i32; + pub fn r600_read_local_size_y() -> i32; + pub fn r600_read_local_size_z() -> i32; + + pub fn r600_read_tgid_x() -> i32; + pub fn r600_read_tgid_y() -> i32; + pub fn r600_read_tgid_z() -> i32; + + pub fn r600_read_tidig_x() -> i32; + pub fn r600_read_tidig_y() -> i32; + pub fn r600_read_tidig_z() -> i32; + + pub fn r600_read_global_offset_x() -> i32; + pub fn r600_read_global_offset_y() -> i32; + pub fn r600_read_global_offset_z() -> i32; +} diff --git a/src/librustc_back/target/amdgcn_unknown_unknown.rs b/src/librustc_back/target/amdgcn_unknown_unknown.rs new file mode 100644 index 0000000000000..366ac0b316b8e --- /dev/null +++ b/src/librustc_back/target/amdgcn_unknown_unknown.rs @@ -0,0 +1,38 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::{Target, TargetOptions}; + +pub fn target() -> Target { + let opts = TargetOptions { + linker: "".to_string(), + ar: "".to_string(), + cpu: "fiji".to_string(), + + dynamic_linking: false, + executables: false, + no_compiler_rt: true, + allow_asm: false, + .. Default::default() + }; + Target { + llvm_target: "amdgcn-unknown-unknown".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_os: "none".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + data_layout: "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:\ + 64:64-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:\ + 256-v512:512-v1024:1024-v2048:2048-n32:64".to_string(), + arch: "amdgcn".to_string(), + options: opts, + } +} \ No newline at end of file diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 7c9fd9d7e4d26..fa1fb228a0a11 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -142,8 +142,11 @@ supported_targets! { ("le32-unknown-nacl", le32_unknown_nacl), ("asmjs-unknown-emscripten", asmjs_unknown_emscripten), + ("nvptx-unknown-unknown", nvptx_unknown_unknown), - ("nvptx64-unknown-unknown", nvptx64_unknown_unknown) + ("nvptx64-unknown-unknown", nvptx64_unknown_unknown), + ("r600-unknown-unknown", r600_unknown_unknown), + ("amdgcn-unknown-unknown", amdgcn_unknown_unknown) } /// Everything `rustc` knows about how to compile for a specific target. @@ -164,7 +167,7 @@ pub struct Target { /// Vendor name to use for conditional compilation. pub target_vendor: String, /// Architecture to use for ABI considerations. Valid options: "x86", - /// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64". + /// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", "nvptx", "r600", and "amdgcn". pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, diff --git a/src/librustc_back/target/r600_unknown_unknown.rs b/src/librustc_back/target/r600_unknown_unknown.rs new file mode 100644 index 0000000000000..ce8c67b6a8ce5 --- /dev/null +++ b/src/librustc_back/target/r600_unknown_unknown.rs @@ -0,0 +1,37 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::{Target, TargetOptions}; + +pub fn target() -> Target { + let opts = TargetOptions { + linker: "".to_string(), + ar: "".to_string(), + cpu: "r600".to_string(), + + dynamic_linking: false, + executables: false, + no_compiler_rt: true, + allow_asm: false, + .. Default::default() + }; + Target { + llvm_target: "r600-unknown-unknown".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_os: "none".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + data_layout: "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:\ + 128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64".to_string(), + arch: "r600".to_string(), + options: opts, + } +} \ No newline at end of file diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 043e66d92db64..e7421f42c029c 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -66,7 +66,14 @@ fn main() { let host = env::var("HOST").unwrap(); let is_crossed = target != host; - let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "nvptx"]; + let optional_components = ["x86", + "arm", + "aarch64", + "mips", + "powerpc", + "pnacl", + "nvptx", + "amdgpu"]; // FIXME: surely we don't need all these components, right? Stuff like mcjit // or interpreter the compiler itself never uses. diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 36be86f3794ec..7bb55633f373c 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -2401,6 +2401,11 @@ pub fn initialize_available_targets() { LLVMInitializeAArch64TargetMC, LLVMInitializeAArch64AsmPrinter, LLVMInitializeAArch64AsmParser); + init_target!(llvm_component = "amdgpu", + LLVMInitializeAMDGPUTargetInfo, + LLVMInitializeAMDGPUTarget, + LLVMInitializeAMDGPUTargetMC, + LLVMInitializeAMDGPUAsmPrinter); init_target!(llvm_component = "mips", LLVMInitializeMipsTargetInfo, LLVMInitializeMipsTarget, diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 42330fca06df5..4a9b74c3aeb20 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -1097,6 +1097,45 @@ fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option { ifn!("llvm.nvvm.read.ptx.sreg.nctaid.x", fn() -> t_i32); ifn!("llvm.nvvm.read.ptx.sreg.nctaid.y", fn() -> t_i32); ifn!("llvm.nvvm.read.ptx.sreg.nctaid.z", fn() -> t_i32); + + ifn!("llvm.amdgcn.read.workdim", fn() -> t_i32); + ifn!("llvm.amdgcn.ngroups.x", fn() -> t_i32); + ifn!("llvm.amdgcn.ngroups.y", fn() -> t_i32); + ifn!("llvm.amdgcn.ngroups.z", fn() -> t_i32); + ifn!("llvm.amdgcn.global.size.x", fn() -> t_i32); + ifn!("llvm.amdgcn.global.size.y", fn() -> t_i32); + ifn!("llvm.amdgcn.global.size.z", fn() -> t_i32); + ifn!("llvm.amdgcn.local.size.x", fn() -> t_i32); + ifn!("llvm.amdgcn.local.size.y", fn() -> t_i32); + ifn!("llvm.amdgcn.local.size.z", fn() -> t_i32); + ifn!("llvm.amdgcn.workgroup.id.x", fn() -> t_i32); + ifn!("llvm.amdgcn.workgroup.id.y", fn() -> t_i32); + ifn!("llvm.amdgcn.workgroup.id.z", fn() -> t_i32); + ifn!("llvm.amdgcn.workitem.id.x", fn() -> t_i32); + ifn!("llvm.amdgcn.workitem.id.y", fn() -> t_i32); + ifn!("llvm.amdgcn.workitem.id.z", fn() -> t_i32); + ifn!("llvm.amdgcn.global.offset.x", fn() -> t_i32); + ifn!("llvm.amdgcn.global.offset.y", fn() -> t_i32); + ifn!("llvm.amdgcn.global.offset.z", fn() -> t_i32); + ifn!("llvm.r600.read.workdim", fn() -> t_i32); + ifn!("llvm.r600.read.ngroups.x", fn() -> t_i32); + ifn!("llvm.r600.read.ngroups.y", fn() -> t_i32); + ifn!("llvm.r600.read.ngroups.z", fn() -> t_i32); + ifn!("llvm.r600.read.global.size.x", fn() -> t_i32); + ifn!("llvm.r600.read.global.size.y", fn() -> t_i32); + ifn!("llvm.r600.read.global.size.z", fn() -> t_i32); + ifn!("llvm.r600.read.local.size.x", fn() -> t_i32); + ifn!("llvm.r600.read.local.size.y", fn() -> t_i32); + ifn!("llvm.r600.read.local.size.z", fn() -> t_i32); + ifn!("llvm.r600.read.tgid.x", fn() -> t_i32); + ifn!("llvm.r600.read.tgid.y", fn() -> t_i32); + ifn!("llvm.r600.read.tgid.z", fn() -> t_i32); + ifn!("llvm.r600.read.tidig.x", fn() -> t_i32); + ifn!("llvm.r600.read.tidig.y", fn() -> t_i32); + ifn!("llvm.r600.read.tidig.z", fn() -> t_i32); + ifn!("llvm.r600.read.offset.x", fn() -> t_i32); + ifn!("llvm.r600.read.offset.y", fn() -> t_i32); + ifn!("llvm.r600.read.offset.z", fn() -> t_i32); ifn!("llvm.assume", fn(i1) -> void); if ccx.sess().opts.debuginfo != NoDebugInfo { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 16bd47b8a80a8..58fc192c45a42 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -102,6 +102,44 @@ fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option { "grid_dim_y" => "llvm.nvvm.read.ptx.sreg.nctaid.y", "grid_dim_z" => "llvm.nvvm.read.ptx.sreg.nctaid.z", "syncthreads" => "llvm.cuda.syncthreads", + "amdgcn_read_workdim" => "llvm.amdgcn.read.workdim", + "amdgcn_ngroups_x" => "llvm.amdgcn.ngroups.x", + "amdgcn_ngroups_y" => "llvm.amdgcn.ngroups.y", + "amdgcn_ngroups_z" => "llvm.amdgcn.ngroups.z", + "amdgcn_global_size_x" => "llvm.amdgcn.global.size.x", + "amdgcn_global_size_y" => "llvm.amdgcn.global.size.y", + "amdgcn_global_size_z" => "llvm.amdgcn.global.size.z", + "amdgcn_local_size_x" => "llvm.amdgcn.local.size.x", + "amdgcn_local_size_y" => "llvm.amdgcn.local.size.y", + "amdgcn_local_size_z" => "llvm.amdgcn.local.size.z", + "amdgcn_workgroup_id_x" => "llvm.amdgcn.workgroup.id.x", + "amdgcn_workgroup_id_y" => "llvm.amdgcn.workgroup.id.y", + "amdgcn_workgroup_id_z" => "llvm.amdgcn.workgroup.id.z", + "amdgcn_workitem_id_x" => "llvm.amdgcn.workitem.id.x", + "amdgcn_workitem_id_y" => "llvm.amdgcn.workitem.id.y", + "amdgcn_workitem_id_z" => "llvm.amdgcn.workitem.id.z", + "amdgcn_global_offset_x" => "llvm.amdgcn.global.offset.x", + "amdgcn_global_offset_y" => "llvm.amdgcn.global.offset.y", + "amdgcn_global_offset_z" => "llvm.amdgcn.global.offset.z", + "r600_read_workdim" => "llvm.r600.read.workdim", + "r600_read_ngroups_x" => "llvm.r600.read.ngroups.x", + "r600_read_ngroups_y" => "llvm.r600.read.ngroups.y", + "r600_read_ngroups_z" => "llvm.r600.read.ngroups.z", + "r600_read_global_size_x" => "llvm.r600.read.global.size.x", + "r600_read_global_size_y" => "llvm.r600.read.global.size.y", + "r600_read_global_size_z" => "llvm.r600.read.global.size.z", + "r600_read_local_size_x" => "llvm.r600.read.local.size.x", + "r600_read_local_size_y" => "llvm.r600.read.local.size.y", + "r600_read_local_size_z" => "llvm.r600.read.local.size.z", + "r600_read_tgid_x" => "llvm.r600.read.tgid.x", + "r600_read_tgid_y" => "llvm.r600.read.tgid.y", + "r600_read_tgid_z" => "llvm.r600.read.tgid.z", + "r600_read_tidig_x" => "llvm.r600.read.tidig.x", + "r600_read_tidig_y" => "llvm.r600.read.tidig.y", + "r600_read_tidig_z" => "llvm.r600.read.tidig.z", + "r600_read_global_offset_x" => "llvm.r600.read.offset.x", + "r600_read_global_offset_y" => "llvm.r600.read.offset.y", + "r600_read_global_offset_z" => "llvm.r600.read.offset.z", _ => return None }; Some(ccx.get_intrinsic(&llvm_name)) diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 42c1c8670c2f4..60cfb77801e81 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -305,6 +305,22 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { "syncthreads" => (0, vec![], tcx.mk_nil()), + "r600_read_workdim" | "r600_read_ngroups_x" | "r600_read_ngroups_y" | + "r600_read_ngroups_z" | "r600_read_global_size_x" | "r600_read_global_size_y" | + "r600_read_global_size_z" | "r600_read_local_size_x" | "r600_read_local_size_y" | + "r600_read_local_size_z" | "r600_read_tgid_x" | "r600_read_tgid_y" | + "r600_read_tgid_z" | "r600_read_tidig_x" | "r600_read_tidig_y" | + "r600_read_tidig_z" | "r600_read_global_offset_x" | "r600_read_global_offset_y" | + "r600_read_global_offset_z" => (0, vec![], tcx.types.i32), + + "amdgcn_read_workdim" | "amdgcn_ngroups_x" | "amdgcn_ngroups_y" | + "amdgcn_ngroups_z" | "amdgcn_global_size_x" | "amdgcn_global_size_y" | + "amdgcn_global_size_z" | "amdgcn_local_size_x" | "amdgcn_local_size_y" | + "amdgcn_local_size_z" | "amdgcn_workgroup_id_x" | "amdgcn_workgroup_id_y" | + "amdgcn_workgroup_id_z" | "amdgcn_workitem_id_x" | "amdgcn_workitem_id_y" | + "amdgcn_workitem_id_z" | "amdgcn_global_offset_x" | "amdgcn_global_offset_y" | + "amdgcn_global_offset_z" => (0, vec![], tcx.types.i32), + ref other => { span_err!(tcx.sess, it.span, E0093, "unrecognized intrinsic function: `{}`", *other);