mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 14:56:27 +00:00
64 bit switches
This commit is contained in:
parent
e1f1d88d33
commit
b6d2c0972b
@ -162,14 +162,58 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
else_llbb: Self::BasicBlock,
|
||||
cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>,
|
||||
) {
|
||||
// pass in signed into the closure to be able to unify closure types
|
||||
let (signed, construct_case) = match self.lookup_type(v.ty) {
|
||||
SpirvType::Integer(width, signed) => {
|
||||
let construct_case = match width {
|
||||
// TODO: How are negative values represented? sign-extended? if so, they'll be >MAX
|
||||
8 => |signed, v| {
|
||||
if v > u8::MAX as u128 {
|
||||
panic!("Switches to values above u8::MAX not supported: {:?}", v)
|
||||
} else if signed {
|
||||
// this cast chain can probably be collapsed, but, whatever, be safe
|
||||
Operand::LiteralInt32(v as u8 as i8 as i32 as u32)
|
||||
} else {
|
||||
Operand::LiteralInt32(v as u8 as u32)
|
||||
}
|
||||
},
|
||||
16 => |signed, v| {
|
||||
if v > u16::MAX as u128 {
|
||||
panic!("Switches to values above u16::MAX not supported: {:?}", v)
|
||||
} else if signed {
|
||||
Operand::LiteralInt32(v as u16 as i16 as i32 as u32)
|
||||
} else {
|
||||
Operand::LiteralInt32(v as u16 as u32)
|
||||
}
|
||||
},
|
||||
32 => |_signed, v| {
|
||||
if v > u32::MAX as u128 {
|
||||
panic!("Switches to values above u32::MAX not supported: {:?}", v)
|
||||
} else {
|
||||
Operand::LiteralInt32(v as u32)
|
||||
}
|
||||
},
|
||||
64 => |_signed, v| {
|
||||
if v > u64::MAX as u128 {
|
||||
panic!("Switches to values above u64::MAX not supported: {:?}", v)
|
||||
} else {
|
||||
Operand::LiteralInt64(v as u64)
|
||||
}
|
||||
},
|
||||
other => panic!(
|
||||
"switch selector cannot have width {} (only 32 and 64 bits allowed)",
|
||||
other
|
||||
),
|
||||
};
|
||||
(signed, construct_case)
|
||||
}
|
||||
other => panic!(
|
||||
"switch selector cannot have non-integer type {}",
|
||||
other.debug(self)
|
||||
),
|
||||
};
|
||||
let cases = cases
|
||||
.map(|(i, b)| {
|
||||
if i > u32::MAX as u128 {
|
||||
panic!("Switches to values above u32::MAX not supported: {:?}", i)
|
||||
} else {
|
||||
(i as u32, b)
|
||||
}
|
||||
})
|
||||
.map(|(i, b)| (construct_case(signed, i), b))
|
||||
.collect::<Vec<_>>();
|
||||
self.emit().switch(v.def, else_llbb, cases).unwrap()
|
||||
}
|
||||
|
@ -216,20 +216,22 @@ impl BuilderSpirv {
|
||||
pub fn set_global_initializer(&self, global: Word, initialiezr: Word) {
|
||||
let mut builder = self.builder.borrow_mut();
|
||||
for inst in &mut builder.module_mut().types_global_values {
|
||||
if inst.class.opcode == Op::Variable {
|
||||
if let Some(&Operand::IdRef(id_ref)) = inst.operands.get(1) {
|
||||
if id_ref == global {
|
||||
assert_eq!(
|
||||
inst.operands.len(),
|
||||
1,
|
||||
"global already has initializer defined: {}",
|
||||
global
|
||||
);
|
||||
inst.operands.push(Operand::IdRef(initialiezr));
|
||||
}
|
||||
}
|
||||
if inst.result_id == Some(global) {
|
||||
assert_eq!(inst.class.opcode, Op::Variable);
|
||||
assert_eq!(
|
||||
inst.operands.len(),
|
||||
1,
|
||||
"global already has initializer defined: {}",
|
||||
global
|
||||
);
|
||||
inst.operands.push(Operand::IdRef(initialiezr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
panic!(
|
||||
"set_global_initializer global not found: {} with init {}",
|
||||
global, initialiezr
|
||||
);
|
||||
}
|
||||
|
||||
pub fn select_block_by_id(&self, id: Word) -> BuilderCursor {
|
||||
|
@ -67,6 +67,8 @@ pub struct CodegenCx<'spv, 'tcx> {
|
||||
pub type_defs: RefCell<HashMap<Word, SpirvType>>,
|
||||
/// Inverse of type_defs (used to cache generating types)
|
||||
pub type_cache: RefCell<HashMap<SpirvType, Word>>,
|
||||
/// Cache generated vtables
|
||||
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), SpirvValue>>,
|
||||
}
|
||||
|
||||
impl<'spv, 'tcx> CodegenCx<'spv, 'tcx> {
|
||||
@ -85,6 +87,7 @@ impl<'spv, 'tcx> CodegenCx<'spv, 'tcx> {
|
||||
function_parameter_values: RefCell::new(HashMap::new()),
|
||||
type_defs: RefCell::new(HashMap::new()),
|
||||
type_cache: RefCell::new(HashMap::new()),
|
||||
vtables: RefCell::new(Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,7 +534,7 @@ impl<'spv, 'tcx> MiscMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
fn vtables(
|
||||
&self,
|
||||
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), Self::Value>> {
|
||||
todo!()
|
||||
&self.vtables
|
||||
}
|
||||
|
||||
fn check_overflow(&self) -> bool {
|
||||
@ -702,7 +705,7 @@ impl<'spv, 'tcx> DeclareMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
|
||||
impl<'spv, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
fn create_vtable_metadata(&self, _ty: Ty<'tcx>, _vtable: Self::Value) {
|
||||
todo!()
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
fn create_function_debug_context(
|
||||
@ -989,8 +992,9 @@ impl<'spv, 'tcx> ConstMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
PlaceRef::new_sized(result, layout)
|
||||
}
|
||||
|
||||
fn const_ptrcast(&self, _val: Self::Value, _ty: Self::Type) -> Self::Value {
|
||||
todo!()
|
||||
fn const_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
|
||||
// TODO: hack to get things working, this *will* fail spirv-val
|
||||
val.def.with_type(ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,8 @@ impl CodegenBackend for SsaBackend {
|
||||
};
|
||||
providers.is_reachable_non_generic = |_tcx, _defid| true;
|
||||
providers.exported_symbols = |_tcx, _crate| &[];
|
||||
// Temp hack to make wasm target work
|
||||
providers.wasm_import_module_map = |_tcx, _crate| Default::default();
|
||||
}
|
||||
|
||||
fn provide_extern(&self, providers: &mut Providers) {
|
||||
|
Loading…
Reference in New Issue
Block a user