@@ -50,6 +50,13 @@ fn noname() -> *const c_char {
5050 & CNULL
5151}
5252
53+ bitflags ! {
54+ pub struct MemFlags : u8 {
55+ const VOLATILE = 1 << 0 ;
56+ const NONTEMPORAL = 1 << 1 ;
57+ }
58+ }
59+
5360impl < ' a , ' tcx > Builder < ' a , ' tcx > {
5461 pub fn new_block < ' b > ( cx : & ' a CodegenCx < ' a , ' tcx > , llfn : ValueRef , name : & ' b str ) -> Self {
5562 let bx = Builder :: with_cx ( cx) ;
@@ -579,29 +586,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
579586 }
580587
581588 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) ;
583600 assert ! ( !self . llbuilder. is_null( ) ) ;
584601 self . count_insn ( "store" ) ;
585602 let ptr = self . check_store ( val, ptr) ;
586603 unsafe {
587604 let store = llvm:: LLVMBuildStore ( self . llbuilder , val, ptr) ;
588605 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+ }
589618 store
590619 }
591620 }
592621
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-
605622 pub fn atomic_store ( & self , val : ValueRef , ptr : ValueRef ,
606623 order : AtomicOrdering , align : Align ) {
607624 debug ! ( "Store {:?} -> {:?}" , Value ( val) , Value ( ptr) ) ;
@@ -615,29 +632,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
615632 }
616633 }
617634
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-
641635 pub fn gep ( & self , ptr : ValueRef , indices : & [ ValueRef ] ) -> ValueRef {
642636 self . count_insn ( "gep" ) ;
643637 unsafe {
0 commit comments