@@ -678,49 +678,54 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
678
678
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
679
679
( _, name) if name. starts_with ( "atomic_" ) => {
680
680
let split: Vec < & str > = name. split ( '_' ) . collect ( ) ;
681
- assert ! ( split. len( ) >= 2 , "Atomic intrinsic not correct format" ) ;
682
681
683
- let order = if split. len ( ) == 2 {
684
- llvm:: SequentiallyConsistent
685
- } else {
686
- match split[ 2 ] {
687
- "unordered" => llvm:: Unordered ,
688
- "relaxed" => llvm:: Monotonic ,
689
- "acq" => llvm:: Acquire ,
690
- "rel" => llvm:: Release ,
691
- "acqrel" => llvm:: AcquireRelease ,
682
+ let ( order, failorder) = match split. len ( ) {
683
+ 2 => ( llvm:: SequentiallyConsistent , llvm:: SequentiallyConsistent ) ,
684
+ 3 => match split[ 2 ] {
685
+ "unordered" => ( llvm:: Unordered , llvm:: Unordered ) ,
686
+ "relaxed" => ( llvm:: Monotonic , llvm:: Monotonic ) ,
687
+ "acq" => ( llvm:: Acquire , llvm:: Acquire ) ,
688
+ "rel" => ( llvm:: Release , llvm:: Monotonic ) ,
689
+ "acqrel" => ( llvm:: AcquireRelease , llvm:: Acquire ) ,
690
+ "failrelaxed" if split[ 1 ] == "cxchg" || split[ 1 ] == "cxchgweak" =>
691
+ ( llvm:: SequentiallyConsistent , llvm:: Monotonic ) ,
692
+ "failacq" if split[ 1 ] == "cxchg" || split[ 1 ] == "cxchgweak" =>
693
+ ( llvm:: SequentiallyConsistent , llvm:: Acquire ) ,
692
694
_ => ccx. sess ( ) . fatal ( "unknown ordering in atomic intrinsic" )
693
- }
695
+ } ,
696
+ 4 => match ( split[ 2 ] , split[ 3 ] ) {
697
+ ( "acq" , "failrelaxed" ) if split[ 1 ] == "cxchg" || split[ 1 ] == "cxchgweak" =>
698
+ ( llvm:: Acquire , llvm:: Monotonic ) ,
699
+ ( "acqrel" , "failrelaxed" ) if split[ 1 ] == "cxchg" || split[ 1 ] == "cxchgweak" =>
700
+ ( llvm:: AcquireRelease , llvm:: Monotonic ) ,
701
+ _ => ccx. sess ( ) . fatal ( "unknown ordering in atomic intrinsic" )
702
+ } ,
703
+ _ => ccx. sess ( ) . fatal ( "Atomic intrinsic not in correct format" ) ,
694
704
} ;
695
705
696
706
match split[ 1 ] {
697
707
"cxchg" => {
698
- // See include/llvm/IR/Instructions.h for their implementation
699
- // of this, I assume that it's good enough for us to use for
700
- // now.
701
- let strongest_failure_ordering = match order {
702
- llvm:: NotAtomic | llvm:: Unordered =>
703
- ccx. sess ( ) . fatal ( "cmpxchg must be atomic" ) ,
704
-
705
- llvm:: Monotonic | llvm:: Release =>
706
- llvm:: Monotonic ,
707
-
708
- llvm:: Acquire | llvm:: AcquireRelease =>
709
- llvm:: Acquire ,
710
-
711
- llvm:: SequentiallyConsistent =>
712
- llvm:: SequentiallyConsistent
713
- } ;
714
-
715
708
let tp_ty = * substs. types . get ( FnSpace , 0 ) ;
716
709
let ptr = to_arg_ty_ptr ( bcx, llargs[ 0 ] , tp_ty) ;
717
710
let cmp = from_arg_ty ( bcx, llargs[ 1 ] , tp_ty) ;
718
711
let src = from_arg_ty ( bcx, llargs[ 2 ] , tp_ty) ;
719
- let res = AtomicCmpXchg ( bcx, ptr, cmp, src, order,
720
- strongest_failure_ordering) ;
712
+ let res = AtomicCmpXchg ( bcx, ptr, cmp, src, order, failorder, llvm:: False ) ;
721
713
ExtractValue ( bcx, res, 0 )
722
714
}
723
715
716
+ "cxchgweak" => {
717
+ let tp_ty = * substs. types . get ( FnSpace , 0 ) ;
718
+ let ptr = to_arg_ty_ptr ( bcx, llargs[ 0 ] , tp_ty) ;
719
+ let cmp = from_arg_ty ( bcx, llargs[ 1 ] , tp_ty) ;
720
+ let src = from_arg_ty ( bcx, llargs[ 2 ] , tp_ty) ;
721
+ let val = AtomicCmpXchg ( bcx, ptr, cmp, src, order, failorder, llvm:: True ) ;
722
+ let result = ExtractValue ( bcx, val, 0 ) ;
723
+ let success = ZExt ( bcx, ExtractValue ( bcx, val, 1 ) , Type :: bool ( bcx. ccx ( ) ) ) ;
724
+ Store ( bcx, result, StructGEP ( bcx, llresult, 0 ) ) ;
725
+ Store ( bcx, success, StructGEP ( bcx, llresult, 1 ) ) ;
726
+ C_nil ( ccx)
727
+ }
728
+
724
729
"load" => {
725
730
let tp_ty = * substs. types . get ( FnSpace , 0 ) ;
726
731
let ptr = to_arg_ty_ptr ( bcx, llargs[ 0 ] , tp_ty) ;
0 commit comments