diff options
| author | Amanieu d'Antras <amanieu@gmail.com> | 2018-07-14 23:28:39 +0100 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2018-07-14 23:28:39 +0100 |
| commit | 303306cf5ede678719ec1324bb02d3d02c014183 (patch) | |
| tree | b203264b0dbbc76bca04a0dc706c8c4916f21ad7 /src/librustc_codegen_llvm | |
| parent | 9363342be956d1bf7781a3b7455d80fc5d94b1f8 (diff) | |
| download | rust-303306cf5ede678719ec1324bb02d3d02c014183.tar.gz rust-303306cf5ede678719ec1324bb02d3d02c014183.zip | |
Add unaligned volatile intrinsics
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/builder.rs | 8 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 14 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/operand.rs | 4 |
3 files changed, 23 insertions, 3 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 7b4998e8588..c8dc579cd62 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -54,6 +54,7 @@ bitflags! { pub struct MemFlags: u8 { const VOLATILE = 1 << 0; const NONTEMPORAL = 1 << 1; + const UNALIGNED = 1 << 2; } } @@ -602,7 +603,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let ptr = self.check_store(val, ptr); unsafe { let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr); - llvm::LLVMSetAlignment(store, align.abi() as c_uint); + let align = if flags.contains(MemFlags::UNALIGNED) { + 1 + } else { + align.abi() as c_uint + }; + llvm::LLVMSetAlignment(store, align); if flags.contains(MemFlags::VOLATILE) { llvm::LLVMSetVolatile(store, llvm::True); } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 6bb5456f903..567595b6997 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -234,15 +234,20 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, memset_intrinsic(bx, true, substs.type_at(0), args[0].immediate(), args[1].immediate(), args[2].immediate()) } - "volatile_load" => { + "volatile_load" | "unaligned_volatile_load" => { let tp_ty = substs.type_at(0); let mut ptr = args[0].immediate(); if let PassMode::Cast(ty) = fn_ty.ret.mode { ptr = bx.pointercast(ptr, ty.llvm_type(cx).ptr_to()); } let load = bx.volatile_load(ptr); + let align = if name == "unaligned_volatile_load" { + 1 + } else { + cx.align_of(tp_ty).abi() as u32 + }; unsafe { - llvm::LLVMSetAlignment(load, cx.align_of(tp_ty).abi() as u32); + llvm::LLVMSetAlignment(load, align); } to_immediate(bx, load, cx.layout_of(tp_ty)) }, @@ -251,6 +256,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, args[1].val.volatile_store(bx, dst); return; }, + "unaligned_volatile_store" => { + let dst = args[0].deref(bx.cx); + args[1].val.unaligned_volatile_store(bx, dst); + return; + }, "prefetch_read_data" | "prefetch_write_data" | "prefetch_read_instruction" | "prefetch_write_instruction" => { let expect = cx.get_intrinsic(&("llvm.prefetch")); diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 3d3a4400bd8..49cc07d6854 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -286,6 +286,10 @@ impl<'a, 'tcx> OperandValue { self.store_with_flags(bx, dest, MemFlags::VOLATILE); } + pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED); + } + pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); } |
