this.copy_op(dest, &place.into())?;
}
- "write_bytes" => {
+ "write_bytes" | "volatile_set_memory" => {
let &[ref ptr, ref val_byte, ref count] = check_arg_count(args)?;
let ty = instance.substs.type_at(0);
let ty_layout = this.layout_of(ty)?;
let ptr = this.read_pointer(ptr)?;
let count = this.read_scalar(count)?.to_machine_usize(this)?;
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
- err_ub_format!("overflow computing total size of `write_bytes`")
+ err_ub_format!("overflow computing total size of `{}`", intrinsic_name)
})?;
this.memory
.write_bytes(ptr, iter::repeat(val_byte).take(byte_count.bytes() as usize))?;
+#![feature(core_intrinsics)] // for `volatile_set_memory`
+
#[repr(C)]
#[derive(Copy, Clone)]
struct Foo {
assert_eq!(w[idx].b, 0xcdcdcdcdcdcdcdcd);
assert_eq!(w[idx].c, 0xcdcdcdcdcdcdcdcd);
}
+
+ // -----
+ // `std::intrinsics::volatile_set_memory` should behave identically
+
+ let mut v: [u64; LENGTH] = [0; LENGTH];
+
+ for idx in 0..LENGTH {
+ assert_eq!(v[idx], 0);
+ }
+
+ unsafe {
+ let p = v.as_mut_ptr();
+ ::std::intrinsics::volatile_set_memory(p, 0xab, LENGTH);
+ }
+
+ for idx in 0..LENGTH {
+ assert_eq!(v[idx], 0xabababababababab);
+ }
+
+ // -----
+
+ let mut w: [Foo; LENGTH] = [Foo { a: 0, b: 0, c: 0 }; LENGTH];
+ for idx in 0..LENGTH {
+ assert_eq!(w[idx].a, 0);
+ assert_eq!(w[idx].b, 0);
+ assert_eq!(w[idx].c, 0);
+ }
+
+ unsafe {
+ let p = w.as_mut_ptr();
+ ::std::intrinsics::volatile_set_memory(p, 0xcd, LENGTH);
+ }
+
+ for idx in 0..LENGTH {
+ assert_eq!(w[idx].a, 0xcdcdcdcdcdcdcdcd);
+ assert_eq!(w[idx].b, 0xcdcdcdcdcdcdcdcd);
+ assert_eq!(w[idx].c, 0xcdcdcdcdcdcdcdcd);
+ }
}