@@ -53,21 +53,98 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
53
53
unimplemented ! ( )
54
54
}
55
55
56
+ mir:: Rvalue :: Aggregate ( _, ref operands) => {
57
+ for ( i, operand) in operands. iter ( ) . enumerate ( ) {
58
+ let lldest_i = build:: GEPi ( bcx, lldest, & [ 0 , i] ) ;
59
+ self . trans_operand_into ( bcx, lldest_i, operand) ;
60
+ }
61
+ bcx
62
+ }
63
+
64
+ mir:: Rvalue :: Slice { ref input, from_start, from_end } => {
65
+ let ccx = bcx. ccx ( ) ;
66
+ let input = self . trans_lvalue ( bcx, input) ;
67
+ let ( llbase, lllen) = tvec:: get_base_and_len ( bcx,
68
+ input. llval ,
69
+ input. ty . to_ty ( bcx. tcx ( ) ) ) ;
70
+ let llbase1 = build:: GEPi ( bcx, llbase, & [ from_start] ) ;
71
+ let adj = common:: C_uint ( ccx, from_start + from_end) ;
72
+ let lllen1 = build:: Sub ( bcx, lllen, adj, DebugLoc :: None ) ;
73
+ build:: Store ( bcx, llbase1, build:: GEPi ( bcx, lldest, & [ 0 , abi:: FAT_PTR_ADDR ] ) ) ;
74
+ build:: Store ( bcx, lllen1, build:: GEPi ( bcx, lldest, & [ 0 , abi:: FAT_PTR_EXTRA ] ) ) ;
75
+ bcx
76
+ }
77
+
78
+ mir:: Rvalue :: InlineAsm ( inline_asm) => {
79
+ asm:: trans_inline_asm ( bcx, inline_asm)
80
+ }
81
+
82
+ _ => {
83
+ assert ! ( self . rvalue_creates_operand( rvalue) ) ;
84
+ let ( bcx, temp) = self . trans_rvalue_operand ( bcx, rvalue) ;
85
+ build:: Store ( bcx, temp. llval , lldest) ;
86
+ bcx
87
+ }
88
+ }
89
+ }
90
+
91
+ pub fn rvalue_creates_operand ( & self , rvalue : & mir:: Rvalue < ' tcx > ) -> bool {
92
+ match * rvalue {
93
+ mir:: Rvalue :: Use ( ..) | // (*)
94
+ mir:: Rvalue :: Ref ( ..) |
95
+ mir:: Rvalue :: Len ( ..) |
96
+ mir:: Rvalue :: Cast ( ..) | // (*)
97
+ mir:: Rvalue :: BinaryOp ( ..) |
98
+ mir:: Rvalue :: UnaryOp ( ..) |
99
+ mir:: Rvalue :: Box ( ..) =>
100
+ true ,
101
+ mir:: Rvalue :: Repeat ( ..) |
102
+ mir:: Rvalue :: Aggregate ( ..) |
103
+ mir:: Rvalue :: Slice { .. } |
104
+ mir:: Rvalue :: InlineAsm ( ..) =>
105
+ false ,
106
+ }
107
+
108
+ // (*) this is only true if the type is suitable
109
+ }
110
+
111
+ pub fn trans_rvalue_operand ( & mut self ,
112
+ bcx : Block < ' bcx , ' tcx > ,
113
+ rvalue : & mir:: Rvalue < ' tcx > )
114
+ -> ( Block < ' bcx , ' tcx > , OperandRef < ' tcx > )
115
+ {
116
+ assert ! ( self . rvalue_creates_operand( rvalue) , "cannot trans {:?} to operand" , rvalue) ;
117
+
118
+ match * rvalue {
119
+ mir:: Rvalue :: Use ( ref operand) => {
120
+ let operand = self . trans_operand ( bcx, operand) ;
121
+ ( bcx, operand)
122
+ }
123
+
124
+ mir:: Rvalue :: Cast ( ..) => {
125
+ unimplemented ! ( )
126
+ }
127
+
56
128
mir:: Rvalue :: Ref ( _, _, ref lvalue) => {
57
129
let tr_lvalue = self . trans_lvalue ( bcx, lvalue) ;
130
+
58
131
// Note: lvalues are indirect, so storing the `llval` into the
59
132
// destination effectively creates a reference.
60
- build:: Store ( bcx, tr_lvalue. llval , lldest) ;
61
- bcx
133
+ ( bcx, OperandRef {
134
+ llval : tr_lvalue. llval ,
135
+ ty : tr_lvalue. ty . to_ty ( bcx. tcx ( ) ) ,
136
+ } )
62
137
}
63
138
64
139
mir:: Rvalue :: Len ( ref lvalue) => {
65
140
let tr_lvalue = self . trans_lvalue ( bcx, lvalue) ;
66
141
let ( _, lllen) = tvec:: get_base_and_len ( bcx,
67
142
tr_lvalue. llval ,
68
143
tr_lvalue. ty . to_ty ( bcx. tcx ( ) ) ) ;
69
- build:: Store ( bcx, lllen, lldest) ;
70
- bcx
144
+ ( bcx, OperandRef {
145
+ llval : lllen,
146
+ ty : bcx. tcx ( ) . types . usize ,
147
+ } )
71
148
}
72
149
73
150
mir:: Rvalue :: BinaryOp ( op, ref lhs, ref rhs) => {
@@ -170,8 +247,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
170
247
mir:: BinOp :: Gt => base:: compare_scalar_types ( bcx, lhs. llval , rhs. llval , lhs. ty ,
171
248
hir:: BiGt , binop_debug_loc) ,
172
249
} ;
173
- build:: Store ( bcx, llval, lldest) ;
174
- bcx
250
+ ( bcx, OperandRef {
251
+ llval : llval,
252
+ ty : lhs. ty ,
253
+ } )
175
254
}
176
255
177
256
mir:: Rvalue :: UnaryOp ( op, ref operand) => {
@@ -186,12 +265,14 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
186
265
build:: Neg ( bcx, operand. llval , debug_loc)
187
266
}
188
267
} ;
189
- build:: Store ( bcx, llval, lldest) ;
190
- bcx
268
+ ( bcx, OperandRef {
269
+ llval : llval,
270
+ ty : operand. ty ,
271
+ } )
191
272
}
192
273
193
274
mir:: Rvalue :: Box ( content_ty) => {
194
- let content_ty: Ty < ' tcx > = content_ty;
275
+ let content_ty: Ty < ' tcx > = bcx . monomorphize ( & content_ty) ;
195
276
let llty = type_of:: type_of ( bcx. ccx ( ) , content_ty) ;
196
277
let llsize = machine:: llsize_of ( bcx. ccx ( ) , llty) ;
197
278
let align = type_of:: align_of ( bcx. ccx ( ) , content_ty) ;
@@ -204,34 +285,17 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
204
285
llsize,
205
286
llalign,
206
287
DebugLoc :: None ) ;
207
- build:: Store ( bcx, llval, lldest) ;
208
- bcx
209
- }
210
-
211
- mir:: Rvalue :: Aggregate ( _, ref operands) => {
212
- for ( i, operand) in operands. iter ( ) . enumerate ( ) {
213
- let lldest_i = build:: GEPi ( bcx, lldest, & [ 0 , i] ) ;
214
- self . trans_operand_into ( bcx, lldest_i, operand) ;
215
- }
216
- bcx
288
+ ( bcx, OperandRef {
289
+ llval : llval,
290
+ ty : box_ty,
291
+ } )
217
292
}
218
293
219
- mir:: Rvalue :: Slice { ref input, from_start, from_end } => {
220
- let ccx = bcx. ccx ( ) ;
221
- let input = self . trans_lvalue ( bcx, input) ;
222
- let ( llbase, lllen) = tvec:: get_base_and_len ( bcx,
223
- input. llval ,
224
- input. ty . to_ty ( bcx. tcx ( ) ) ) ;
225
- let llbase1 = build:: GEPi ( bcx, llbase, & [ from_start] ) ;
226
- let adj = common:: C_uint ( ccx, from_start + from_end) ;
227
- let lllen1 = build:: Sub ( bcx, lllen, adj, DebugLoc :: None ) ;
228
- build:: Store ( bcx, llbase1, build:: GEPi ( bcx, lldest, & [ 0 , abi:: FAT_PTR_ADDR ] ) ) ;
229
- build:: Store ( bcx, lllen1, build:: GEPi ( bcx, lldest, & [ 0 , abi:: FAT_PTR_EXTRA ] ) ) ;
230
- bcx
231
- }
232
-
233
- mir:: Rvalue :: InlineAsm ( inline_asm) => {
234
- asm:: trans_inline_asm ( bcx, inline_asm)
294
+ mir:: Rvalue :: Repeat ( ..) |
295
+ mir:: Rvalue :: Aggregate ( ..) |
296
+ mir:: Rvalue :: Slice { .. } |
297
+ mir:: Rvalue :: InlineAsm ( ..) => {
298
+ bcx. tcx ( ) . sess . bug ( & format ! ( "cannot generate operand from rvalue {:?}" , rvalue) ) ;
235
299
}
236
300
}
237
301
}
0 commit comments