about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm
diff options
context:
space:
mode:
authorAmanieu d'Antras <amanieu@gmail.com>2018-07-14 23:28:39 +0100
committerAmanieu d'Antras <amanieu@gmail.com>2018-07-14 23:28:39 +0100
commit303306cf5ede678719ec1324bb02d3d02c014183 (patch)
treeb203264b0dbbc76bca04a0dc706c8c4916f21ad7 /src/librustc_codegen_llvm
parent9363342be956d1bf7781a3b7455d80fc5d94b1f8 (diff)
downloadrust-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.rs8
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs14
-rw-r--r--src/librustc_codegen_llvm/mir/operand.rs4
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);
     }