Skip to content

Commit e43e47d

Browse files
yvtantoyo
authored andcommitted
Implement volatile store
1 parent 6a1ecf3 commit e43e47d

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

src/builder.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -1103,21 +1103,34 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
11031103

11041104
fn store_with_flags(
11051105
&mut self,
1106-
val: RValue<'gcc>,
1106+
mut val: RValue<'gcc>,
11071107
ptr: RValue<'gcc>,
11081108
align: Align,
1109-
_flags: MemFlags,
1109+
flags: MemFlags,
11101110
) -> RValue<'gcc> {
11111111
let ptr = self.check_store(val, ptr);
11121112
let destination = ptr.dereference(self.location);
11131113
// NOTE: libgccjit does not support specifying the alignment on the assignment, so we cast
11141114
// to type so it gets the proper alignment.
11151115
let destination_type = destination.to_rvalue().get_type().unqualified();
1116-
let aligned_type = destination_type.get_aligned(align.bytes()).make_pointer();
1117-
let aligned_destination = self.cx.context.new_bitcast(self.location, ptr, aligned_type);
1118-
let aligned_destination = aligned_destination.dereference(self.location);
1119-
self.llbb().add_assignment(self.location, aligned_destination, val);
1120-
// TODO(antoyo): handle align and flags.
1116+
let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() };
1117+
let mut modified_destination_type = destination_type.get_aligned(align);
1118+
if flags.contains(MemFlags::VOLATILE) {
1119+
modified_destination_type = modified_destination_type.make_volatile();
1120+
}
1121+
1122+
// FIXME: The type checking in `add_assignment` removes only one
1123+
// qualifier from each side. So the writes `int → volatile int` and
1124+
// `int → int __attribute__((aligned(1)))` are considered legal but
1125+
// `int → volatile int __attribute__((aligned(1)))` is not. This seems
1126+
// like a bug in libgccjit. The easiest way to work around this is to
1127+
// bitcast `val` to have the matching qualifiers.
1128+
val = self.cx.context.new_bitcast(None, val, modified_destination_type);
1129+
1130+
let modified_ptr = self.cx.context.new_bitcast(None, ptr, modified_destination_type.make_pointer());
1131+
let modified_destination = modified_ptr.dereference(None);
1132+
self.llbb().add_assignment(None, modified_destination, val);
1133+
// TODO: handle `MemFlags::NONTEMPORAL`.
11211134
// NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here?
11221135
self.cx.context.new_rvalue_zero(self.type_i32())
11231136
}

0 commit comments

Comments
 (0)