@@ -26,108 +26,131 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2626 ) -> InterpResult < ' tcx , EmulateItemResult > {
2727 let this = self . eval_context_mut ( ) ;
2828
29- let intrinsic_structure: Vec < _ > = intrinsic_name. split ( '_' ) . collect ( ) ;
29+ let get_ord_at = |i : usize | {
30+ let ordering = generic_args. const_at ( i) . to_value ( ) ;
31+ ordering. valtree . unwrap_branch ( ) [ 0 ] . unwrap_leaf ( ) . to_atomic_ordering ( )
32+ } ;
3033
31- fn read_ord ( ord : & str ) -> AtomicReadOrd {
34+ fn read_ord ( ord : AtomicOrdering ) -> AtomicReadOrd {
3235 match ord {
33- "seqcst" => AtomicReadOrd :: SeqCst ,
34- "acquire" => AtomicReadOrd :: Acquire ,
35- "relaxed" => AtomicReadOrd :: Relaxed ,
36- _ => panic ! ( "invalid read ordering `{ord}`" ) ,
37- }
38- }
39-
40- fn read_ord_const_generic ( o : AtomicOrdering ) -> AtomicReadOrd {
41- match o {
4236 AtomicOrdering :: SeqCst => AtomicReadOrd :: SeqCst ,
4337 AtomicOrdering :: Acquire => AtomicReadOrd :: Acquire ,
4438 AtomicOrdering :: Relaxed => AtomicReadOrd :: Relaxed ,
45- _ => panic ! ( "invalid read ordering `{o :?}`" ) ,
39+ _ => panic ! ( "invalid read ordering `{ord :?}`" ) ,
4640 }
4741 }
4842
49- fn write_ord ( ord : & str ) -> AtomicWriteOrd {
43+ fn write_ord ( ord : AtomicOrdering ) -> AtomicWriteOrd {
5044 match ord {
51- "seqcst" => AtomicWriteOrd :: SeqCst ,
52- "release" => AtomicWriteOrd :: Release ,
53- "relaxed" => AtomicWriteOrd :: Relaxed ,
54- _ => panic ! ( "invalid write ordering `{ord}`" ) ,
45+ AtomicOrdering :: SeqCst => AtomicWriteOrd :: SeqCst ,
46+ AtomicOrdering :: Release => AtomicWriteOrd :: Release ,
47+ AtomicOrdering :: Relaxed => AtomicWriteOrd :: Relaxed ,
48+ _ => panic ! ( "invalid write ordering `{ord:? }`" ) ,
5549 }
5650 }
5751
58- fn rw_ord ( ord : & str ) -> AtomicRwOrd {
52+ fn rw_ord ( ord : AtomicOrdering ) -> AtomicRwOrd {
5953 match ord {
60- "seqcst" => AtomicRwOrd :: SeqCst ,
61- "acqrel" => AtomicRwOrd :: AcqRel ,
62- "acquire" => AtomicRwOrd :: Acquire ,
63- "release" => AtomicRwOrd :: Release ,
64- "relaxed" => AtomicRwOrd :: Relaxed ,
65- _ => panic ! ( "invalid read-write ordering `{ord}`" ) ,
54+ AtomicOrdering :: SeqCst => AtomicRwOrd :: SeqCst ,
55+ AtomicOrdering :: AcqRel => AtomicRwOrd :: AcqRel ,
56+ AtomicOrdering :: Acquire => AtomicRwOrd :: Acquire ,
57+ AtomicOrdering :: Release => AtomicRwOrd :: Release ,
58+ AtomicOrdering :: Relaxed => AtomicRwOrd :: Relaxed ,
6659 }
6760 }
6861
69- fn fence_ord ( ord : & str ) -> AtomicFenceOrd {
62+ fn fence_ord ( ord : AtomicOrdering ) -> AtomicFenceOrd {
7063 match ord {
71- "seqcst" => AtomicFenceOrd :: SeqCst ,
72- "acqrel" => AtomicFenceOrd :: AcqRel ,
73- "acquire" => AtomicFenceOrd :: Acquire ,
74- "release" => AtomicFenceOrd :: Release ,
75- _ => panic ! ( "invalid fence ordering `{ord}`" ) ,
64+ AtomicOrdering :: SeqCst => AtomicFenceOrd :: SeqCst ,
65+ AtomicOrdering :: AcqRel => AtomicFenceOrd :: AcqRel ,
66+ AtomicOrdering :: Acquire => AtomicFenceOrd :: Acquire ,
67+ AtomicOrdering :: Release => AtomicFenceOrd :: Release ,
68+ _ => panic ! ( "invalid fence ordering `{ord:? }`" ) ,
7669 }
7770 }
7871
79- match & * intrinsic_structure {
80- // New-style intrinsics that use const generics
81- [ "load" ] => {
82- let ordering = generic_args. const_at ( 1 ) . to_value ( ) ;
83- let ordering =
84- ordering. valtree . unwrap_branch ( ) [ 0 ] . unwrap_leaf ( ) . to_atomic_ordering ( ) ;
85- this. atomic_load ( args, dest, read_ord_const_generic ( ordering) ) ?;
72+ match intrinsic_name {
73+ "load" => {
74+ let ord = get_ord_at ( 1 ) ;
75+ this. atomic_load ( args, dest, read_ord ( ord) ) ?;
76+ }
77+
78+ "store" => {
79+ let ord = get_ord_at ( 1 ) ;
80+ this. atomic_store ( args, write_ord ( ord) ) ?
8681 }
8782
88- // Old-style intrinsics that have the ordering in the intrinsic name
89- [ "store" , ord] => this. atomic_store ( args, write_ord ( ord) ) ?,
90-
91- [ "fence" , ord] => this. atomic_fence_intrinsic ( args, fence_ord ( ord) ) ?,
92- [ "singlethreadfence" , ord] => this. compiler_fence_intrinsic ( args, fence_ord ( ord) ) ?,
93-
94- [ "xchg" , ord] => this. atomic_exchange ( args, dest, rw_ord ( ord) ) ?,
95- [ "cxchg" , ord1, ord2] =>
96- this. atomic_compare_exchange ( args, dest, rw_ord ( ord1) , read_ord ( ord2) ) ?,
97- [ "cxchgweak" , ord1, ord2] =>
98- this. atomic_compare_exchange_weak ( args, dest, rw_ord ( ord1) , read_ord ( ord2) ) ?,
99-
100- [ "or" , ord] =>
101- this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , rw_ord ( ord) ) ?,
102- [ "xor" , ord] =>
103- this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , rw_ord ( ord) ) ?,
104- [ "and" , ord] =>
105- this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , rw_ord ( ord) ) ?,
106- [ "nand" , ord] =>
107- this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , rw_ord ( ord) ) ?,
108- [ "xadd" , ord] =>
109- this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , rw_ord ( ord) ) ?,
110- [ "xsub" , ord] =>
111- this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , rw_ord ( ord) ) ?,
112- [ "min" , ord] => {
83+ "fence" => {
84+ let ord = get_ord_at ( 0 ) ;
85+ this. atomic_fence_intrinsic ( args, fence_ord ( ord) ) ?
86+ }
87+ "singlethreadfence" => {
88+ let ord = get_ord_at ( 0 ) ;
89+ this. compiler_fence_intrinsic ( args, fence_ord ( ord) ) ?;
90+ }
91+
92+ "xchg" => {
93+ let ord = get_ord_at ( 1 ) ;
94+ this. atomic_exchange ( args, dest, rw_ord ( ord) ) ?;
95+ }
96+ "cxchg" => {
97+ let ord1 = get_ord_at ( 1 ) ;
98+ let ord2 = get_ord_at ( 2 ) ;
99+ this. atomic_compare_exchange ( args, dest, rw_ord ( ord1) , read_ord ( ord2) ) ?;
100+ }
101+ "cxchgweak" => {
102+ let ord1 = get_ord_at ( 1 ) ;
103+ let ord2 = get_ord_at ( 2 ) ;
104+ this. atomic_compare_exchange_weak ( args, dest, rw_ord ( ord1) , read_ord ( ord2) ) ?;
105+ }
106+
107+ "or" => {
108+ let ord = get_ord_at ( 1 ) ;
109+ this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , rw_ord ( ord) ) ?;
110+ }
111+ "xor" => {
112+ let ord = get_ord_at ( 1 ) ;
113+ this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , rw_ord ( ord) ) ?;
114+ }
115+ "and" => {
116+ let ord = get_ord_at ( 1 ) ;
117+ this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , rw_ord ( ord) ) ?;
118+ }
119+ "nand" => {
120+ let ord = get_ord_at ( 1 ) ;
121+ this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , rw_ord ( ord) ) ?;
122+ }
123+ "xadd" => {
124+ let ord = get_ord_at ( 1 ) ;
125+ this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , rw_ord ( ord) ) ?;
126+ }
127+ "xsub" => {
128+ let ord = get_ord_at ( 1 ) ;
129+ this. atomic_rmw_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , rw_ord ( ord) ) ?;
130+ }
131+ "min" => {
132+ let ord = get_ord_at ( 1 ) ;
113133 // Later we will use the type to indicate signed vs unsigned,
114134 // so make sure it matches the intrinsic name.
115135 assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
116136 this. atomic_rmw_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ) ?;
117137 }
118- [ "umin" , ord] => {
138+ "umin" => {
139+ let ord = get_ord_at ( 1 ) ;
119140 // Later we will use the type to indicate signed vs unsigned,
120141 // so make sure it matches the intrinsic name.
121142 assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
122143 this. atomic_rmw_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ) ?;
123144 }
124- [ "max" , ord] => {
145+ "max" => {
146+ let ord = get_ord_at ( 1 ) ;
125147 // Later we will use the type to indicate signed vs unsigned,
126148 // so make sure it matches the intrinsic name.
127149 assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
128150 this. atomic_rmw_op ( args, dest, AtomicOp :: Max , rw_ord ( ord) ) ?;
129151 }
130- [ "umax" , ord] => {
152+ "umax" => {
153+ let ord = get_ord_at ( 1 ) ;
131154 // Later we will use the type to indicate signed vs unsigned,
132155 // so make sure it matches the intrinsic name.
133156 assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
0 commit comments