mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 14:56:27 +00:00
Implement some math intrinsics
This commit is contained in:
parent
710e33258e
commit
e4a569b44e
@ -451,11 +451,17 @@ pub fn trans_fnabi<'spv, 'tcx>(
|
||||
let return_type = match fn_abi.ret.mode {
|
||||
PassMode::Ignore => SpirvType::Void.def(cx),
|
||||
PassMode::Direct(_arg_attributes) => trans_type_immediate(cx, fn_abi.ret.layout),
|
||||
PassMode::Pair(_arg_attributes_1, _arg_attributes_2) => trans_type(cx, fn_abi.ret.layout),
|
||||
// TODO: Is this right?
|
||||
PassMode::Cast(_cast_target) => trans_type(cx, fn_abi.ret.layout),
|
||||
PassMode::Pair(_arg_attributes_1, _arg_attributes_2) => {
|
||||
panic!("PassMode::Pair not supported for return type")
|
||||
}
|
||||
PassMode::Cast(_cast_target) => {
|
||||
panic!("TODO: PassMode::Cast not supported for return type")
|
||||
}
|
||||
// TODO: Deal with wide ptr?
|
||||
PassMode::Indirect(_arg_attributes, _wide_ptr_attrs) => {
|
||||
PassMode::Indirect(_arg_attributes, wide_ptr_attrs) => {
|
||||
if wide_ptr_attrs.is_some() {
|
||||
panic!("TODO: PassMode::Indirect wide ptr not supported for return type");
|
||||
}
|
||||
let pointee = trans_type(cx, fn_abi.ret.layout);
|
||||
let pointer = SpirvType::Pointer {
|
||||
storage_class: StorageClass::Generic,
|
||||
|
@ -17,7 +17,7 @@ use rustc_middle::mir::coverage::{
|
||||
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionIndex, Op,
|
||||
};
|
||||
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, TyAndLayout};
|
||||
use rustc_middle::ty::{FnDef, Instance, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{FnDef, Instance, ParamEnv, Ty, TyCtxt, TyKind};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::sym;
|
||||
@ -26,6 +26,28 @@ use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout};
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
use std::{iter::empty, ops::Deref};
|
||||
|
||||
macro_rules! math_intrinsic {
|
||||
($self:ident, $arg_tys:ident, $args:ident, $int:ident, $uint:ident, $float:ident) => {{
|
||||
assert_eq!($arg_tys[0], $arg_tys[1]);
|
||||
match &$arg_tys[0].kind {
|
||||
TyKind::Int(_) => $self.$int($args[0].immediate(), $args[1].immediate()),
|
||||
TyKind::Uint(_) => $self.$uint($args[0].immediate(), $args[1].immediate()),
|
||||
TyKind::Float(_) => $self.$float($args[0].immediate(), $args[1].immediate()),
|
||||
other => panic!("Unimplemented intrinsic type: {:#?}", other),
|
||||
}
|
||||
}};
|
||||
}
|
||||
macro_rules! math_intrinsic_int {
|
||||
($self:ident, $arg_tys:ident, $args:ident, $int:ident, $uint:ident) => {{
|
||||
assert_eq!($arg_tys[0], $arg_tys[1]);
|
||||
match &$arg_tys[0].kind {
|
||||
TyKind::Int(_) => $self.$int($args[0].immediate(), $args[1].immediate()),
|
||||
TyKind::Uint(_) => $self.$uint($args[0].immediate(), $args[1].immediate()),
|
||||
other => panic!("Unimplemented intrinsic type: {:#?}", other),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
pub struct Builder<'a, 'spv, 'tcx> {
|
||||
cx: &'a CodegenCx<'spv, 'tcx>,
|
||||
cursor: BuilderCursor,
|
||||
@ -262,7 +284,7 @@ impl<'a, 'spv, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
let sig = self
|
||||
.tcx
|
||||
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &sig);
|
||||
// let arg_tys = sig.inputs();
|
||||
let arg_tys = sig.inputs();
|
||||
let ret_ty = sig.output();
|
||||
let name = self.tcx.item_name(def_id);
|
||||
// let name_str = &*name.as_str();
|
||||
@ -318,6 +340,25 @@ impl<'a, 'spv, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
sym::assume => {
|
||||
// Drop @llvm.assume(i1 %cond). TODO: Is there a spir-v equivalent?
|
||||
return;
|
||||
}
|
||||
|
||||
sym::wrapping_add => math_intrinsic! {self, arg_tys, args, add, add, fadd},
|
||||
sym::wrapping_sub => math_intrinsic! {self, arg_tys, args, sub, sub, fsub},
|
||||
sym::wrapping_mul => math_intrinsic! {self, arg_tys, args, mul, mul, fmul},
|
||||
sym::saturating_add => math_intrinsic! {self, arg_tys, args, add, add, fadd},
|
||||
sym::saturating_sub => math_intrinsic! {self, arg_tys, args, sub, sub, fsub},
|
||||
sym::unchecked_add => math_intrinsic! {self, arg_tys, args, add, add, fadd},
|
||||
sym::unchecked_sub => math_intrinsic! {self, arg_tys, args, sub, sub, fsub},
|
||||
sym::unchecked_mul => math_intrinsic! {self, arg_tys, args, mul, mul, fmul},
|
||||
sym::unchecked_div => math_intrinsic! {self, arg_tys, args, sdiv, udiv, fdiv},
|
||||
sym::unchecked_rem => math_intrinsic! {self, arg_tys, args, srem, urem, frem},
|
||||
sym::unchecked_shl => math_intrinsic_int! {self, arg_tys, args, shl, shl},
|
||||
sym::unchecked_shr => math_intrinsic_int! {self, arg_tys, args, ashr, lshr},
|
||||
sym::exact_div => math_intrinsic! {self, arg_tys, args, sdiv, udiv, fdiv},
|
||||
|
||||
_ => panic!("TODO: Unknown intrinsic '{}'", name),
|
||||
};
|
||||
|
||||
|
@ -445,7 +445,7 @@ impl<'spv, 'tcx> MiscMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
}
|
||||
|
||||
fn check_overflow(&self) -> bool {
|
||||
todo!()
|
||||
self.tcx.sess.overflow_checks()
|
||||
}
|
||||
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function {
|
||||
|
Loading…
Reference in New Issue
Block a user