@@ -50,6 +50,13 @@ fn noname() -> *const c_char {
50
50
& CNULL
51
51
}
52
52
53
+ bitflags ! {
54
+ pub struct MemFlags : u8 {
55
+ const VOLATILE = 1 << 0 ;
56
+ const NONTEMPORAL = 1 << 1 ;
57
+ }
58
+ }
59
+
53
60
impl < ' a , ' tcx > Builder < ' a , ' tcx > {
54
61
pub fn new_block < ' b > ( cx : & ' a CodegenCx < ' a , ' tcx > , llfn : ValueRef , name : & ' b str ) -> Self {
55
62
let bx = Builder :: with_cx ( cx) ;
@@ -579,29 +586,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
579
586
}
580
587
581
588
pub fn store ( & self , val : ValueRef , ptr : ValueRef , align : Align ) -> ValueRef {
582
- debug ! ( "Store {:?} -> {:?}" , Value ( val) , Value ( ptr) ) ;
589
+ self . store_with_flags ( val, ptr, align, MemFlags :: empty ( ) )
590
+ }
591
+
592
+ pub fn store_with_flags (
593
+ & self ,
594
+ val : ValueRef ,
595
+ ptr : ValueRef ,
596
+ align : Align ,
597
+ flags : MemFlags ,
598
+ ) -> ValueRef {
599
+ debug ! ( "Store {:?} -> {:?} ({:?})" , Value ( val) , Value ( ptr) , flags) ;
583
600
assert ! ( !self . llbuilder. is_null( ) ) ;
584
601
self . count_insn ( "store" ) ;
585
602
let ptr = self . check_store ( val, ptr) ;
586
603
unsafe {
587
604
let store = llvm:: LLVMBuildStore ( self . llbuilder , val, ptr) ;
588
605
llvm:: LLVMSetAlignment ( store, align. abi ( ) as c_uint ) ;
606
+ if flags. contains ( MemFlags :: VOLATILE ) {
607
+ llvm:: LLVMSetVolatile ( store, llvm:: True ) ;
608
+ }
609
+ if flags. contains ( MemFlags :: NONTEMPORAL ) {
610
+ // According to LLVM [1] building a nontemporal store must
611
+ // *always* point to a metadata value of the integer 1.
612
+ //
613
+ // [1]: http://llvm.org/docs/LangRef.html#store-instruction
614
+ let one = C_i32 ( self . cx , 1 ) ;
615
+ let node = llvm:: LLVMMDNodeInContext ( self . cx . llcx , & one, 1 ) ;
616
+ llvm:: LLVMSetMetadata ( store, llvm:: MD_nontemporal as c_uint , node) ;
617
+ }
589
618
store
590
619
}
591
620
}
592
621
593
- pub fn volatile_store ( & self , val : ValueRef , ptr : ValueRef ) -> ValueRef {
594
- debug ! ( "Store {:?} -> {:?}" , Value ( val) , Value ( ptr) ) ;
595
- assert ! ( !self . llbuilder. is_null( ) ) ;
596
- self . count_insn ( "store.volatile" ) ;
597
- let ptr = self . check_store ( val, ptr) ;
598
- unsafe {
599
- let insn = llvm:: LLVMBuildStore ( self . llbuilder , val, ptr) ;
600
- llvm:: LLVMSetVolatile ( insn, llvm:: True ) ;
601
- insn
602
- }
603
- }
604
-
605
622
pub fn atomic_store ( & self , val : ValueRef , ptr : ValueRef ,
606
623
order : AtomicOrdering , align : Align ) {
607
624
debug ! ( "Store {:?} -> {:?}" , Value ( val) , Value ( ptr) ) ;
@@ -615,29 +632,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
615
632
}
616
633
}
617
634
618
- pub fn nontemporal_store ( & self , val : ValueRef , ptr : ValueRef ) -> ValueRef {
619
- debug ! ( "Store {:?} -> {:?}" , Value ( val) , Value ( ptr) ) ;
620
- assert ! ( !self . llbuilder. is_null( ) ) ;
621
- self . count_insn ( "store.nontemporal" ) ;
622
- let ptr = self . check_store ( val, ptr) ;
623
- unsafe {
624
- let insn = llvm:: LLVMBuildStore ( self . llbuilder , val, ptr) ;
625
-
626
- // According to LLVM [1] building a nontemporal store must *always*
627
- // point to a metadata value of the integer 1. Who knew?
628
- //
629
- // [1]: http://llvm.org/docs/LangRef.html#store-instruction
630
- let one = C_i32 ( self . cx , 1 ) ;
631
- let node = llvm:: LLVMMDNodeInContext ( self . cx . llcx ,
632
- & one,
633
- 1 ) ;
634
- llvm:: LLVMSetMetadata ( insn,
635
- llvm:: MD_nontemporal as c_uint ,
636
- node) ;
637
- insn
638
- }
639
- }
640
-
641
635
pub fn gep ( & self , ptr : ValueRef , indices : & [ ValueRef ] ) -> ValueRef {
642
636
self . count_insn ( "gep" ) ;
643
637
unsafe {
0 commit comments