@@ -26,108 +26,131 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
26
26
) -> InterpResult < ' tcx , EmulateItemResult > {
27
27
let this = self . eval_context_mut ( ) ;
28
28
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
+ } ;
30
33
31
- fn read_ord ( ord : & str ) -> AtomicReadOrd {
34
+ fn read_ord ( ord : AtomicOrdering ) -> AtomicReadOrd {
32
35
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 {
42
36
AtomicOrdering :: SeqCst => AtomicReadOrd :: SeqCst ,
43
37
AtomicOrdering :: Acquire => AtomicReadOrd :: Acquire ,
44
38
AtomicOrdering :: Relaxed => AtomicReadOrd :: Relaxed ,
45
- _ => panic ! ( "invalid read ordering `{o :?}`" ) ,
39
+ _ => panic ! ( "invalid read ordering `{ord :?}`" ) ,
46
40
}
47
41
}
48
42
49
- fn write_ord ( ord : & str ) -> AtomicWriteOrd {
43
+ fn write_ord ( ord : AtomicOrdering ) -> AtomicWriteOrd {
50
44
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:? }`" ) ,
55
49
}
56
50
}
57
51
58
- fn rw_ord ( ord : & str ) -> AtomicRwOrd {
52
+ fn rw_ord ( ord : AtomicOrdering ) -> AtomicRwOrd {
59
53
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 ,
66
59
}
67
60
}
68
61
69
- fn fence_ord ( ord : & str ) -> AtomicFenceOrd {
62
+ fn fence_ord ( ord : AtomicOrdering ) -> AtomicFenceOrd {
70
63
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:? }`" ) ,
76
69
}
77
70
}
78
71
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) ) ?
86
81
}
87
82
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 ) ;
113
133
// Later we will use the type to indicate signed vs unsigned,
114
134
// so make sure it matches the intrinsic name.
115
135
assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
116
136
this. atomic_rmw_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ) ?;
117
137
}
118
- [ "umin" , ord] => {
138
+ "umin" => {
139
+ let ord = get_ord_at ( 1 ) ;
119
140
// Later we will use the type to indicate signed vs unsigned,
120
141
// so make sure it matches the intrinsic name.
121
142
assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
122
143
this. atomic_rmw_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ) ?;
123
144
}
124
- [ "max" , ord] => {
145
+ "max" => {
146
+ let ord = get_ord_at ( 1 ) ;
125
147
// Later we will use the type to indicate signed vs unsigned,
126
148
// so make sure it matches the intrinsic name.
127
149
assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
128
150
this. atomic_rmw_op ( args, dest, AtomicOp :: Max , rw_ord ( ord) ) ?;
129
151
}
130
- [ "umax" , ord] => {
152
+ "umax" => {
153
+ let ord = get_ord_at ( 1 ) ;
131
154
// Later we will use the type to indicate signed vs unsigned,
132
155
// so make sure it matches the intrinsic name.
133
156
assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
0 commit comments