MCPcopy Create free account
hub / github.com/Rust-GPU/rust-gpu / rotate

Method rotate

crates/rustc_codegen_spirv/src/builder/mod.rs:218–247  ·  view source on GitHub ↗

TODO: Definitely add tests to make sure this impl is right.

(&mut self, value: SpirvValue, shift: SpirvValue, is_left: bool)

Source from the content-addressed store, hash-verified

216
217 // TODO: Definitely add tests to make sure this impl is right.
218 fn rotate(&mut self, value: SpirvValue, shift: SpirvValue, is_left: bool) -> SpirvValue {
219 let width = match self.lookup_type(shift.ty) {
220 SpirvType::Integer(width, _) => width,
221 other => self.fatal(&format!(
222 "cannot rotate non-integer type: {}",
223 other.debug(shift.ty, self)
224 )),
225 };
226 let int_size = self.constant_int(shift.ty, width as u64);
227 let mask = self.constant_int(shift.ty, (width - 1) as u64);
228 let zero = self.constant_int(shift.ty, 0);
229 let bool = SpirvType::Bool.def(self.span(), self);
230 // https://stackoverflow.com/a/10134877
231 let mask_shift = self.and(shift, mask);
232 let sub = self.sub(int_size, mask_shift);
233 let (lhs, rhs) = if is_left {
234 (self.shl(value, mask_shift), self.lshr(value, sub))
235 } else {
236 (self.lshr(value, mask_shift), self.shl(value, sub))
237 };
238 let or = self.or(lhs, rhs);
239 // "The result is undefined if Shift is greater than or equal to the bit width of the components of Base."
240 // So we need to check for zero shift, and don't use the shift result if it is.
241 let mask_is_zero = self
242 .emit()
243 .i_not_equal(bool, None, mask_shift.def(self), zero.def(self))
244 .unwrap()
245 .with_type(bool);
246 self.select(mask_is_zero, value, or)
247 }
248}
249
250// Important: This lets us use CodegenCx methods on Builder

Callers 1

Calls 10

lookup_typeMethod · 0.80
fatalMethod · 0.80
constant_intMethod · 0.80
spanMethod · 0.80
with_typeMethod · 0.80
selectMethod · 0.80
defMethod · 0.45
andMethod · 0.45
orMethod · 0.45
emitMethod · 0.45

Tested by

no test coverage detected