@@ -152,7 +152,7 @@ impl Level for Fallback {
152152 let items = make_list (
153153 ( 0 ..vec_ty. len )
154154 . map ( |idx| {
155- let args = [ quote ! { a[ #idx ] } ] ;
155+ let args = [ lane ( quote ! { a } , vec_ty , idx ) ] ;
156156 let expr = fallback:: expr ( method, vec_ty, & args) ;
157157 quote ! { #expr }
158158 } )
@@ -170,7 +170,8 @@ impl Level for Fallback {
170170 ( 0 ..vec_ty. len )
171171 . map ( |idx| {
172172 let scalar_ty = target_ty. scalar . rust ( target_ty. scalar_bits ) ;
173- quote ! { a[ #idx] as #scalar_ty }
173+ let a = lane ( quote ! { a } , vec_ty, idx) ;
174+ quote ! { #a as #scalar_ty }
174175 } )
175176 . collect :: < Vec < _ > > ( ) ,
176177 ) ;
@@ -185,19 +186,20 @@ impl Level for Fallback {
185186 let items = make_list (
186187 ( 0 ..vec_ty. len )
187188 . map ( |idx| {
189+ let b_lane = lane ( quote ! { b } , vec_ty, idx) ;
188190 let b = if fallback:: translate_op (
189191 method,
190192 vec_ty. scalar == ScalarType :: Float ,
191193 )
192194 . map ( rhs_reference)
193195 . unwrap_or ( true )
194196 {
195- quote ! { & b [ #idx ] }
197+ quote ! { & #b_lane }
196198 } else {
197- quote ! { b [ #idx ] }
199+ b_lane
198200 } ;
199201
200- let args = [ quote ! { a[ #idx ] } , quote ! { #b } ] ;
202+ let args = [ lane ( quote ! { a } , vec_ty , idx ) , quote ! { #b } ] ;
201203 let expr = fallback:: expr ( method, vec_ty, & args) ;
202204 quote ! { #expr }
203205 } )
@@ -214,7 +216,7 @@ impl Level for Fallback {
214216 let items = make_list (
215217 ( 0 ..vec_ty. len )
216218 . map ( |idx| {
217- let args = [ quote ! { a[ #idx ] } , quote ! { shift } ] ;
219+ let args = [ lane ( quote ! { a } , vec_ty , idx ) , quote ! { shift } ] ;
218220 let expr = fallback:: expr ( method, vec_ty, & args) ;
219221 quote ! { #expr }
220222 } )
@@ -260,7 +262,9 @@ impl Level for Fallback {
260262 let items = make_list (
261263 ( 0 ..vec_ty. len )
262264 . map ( |idx : usize | {
263- let args = [ quote ! { & a[ #idx] } , quote ! { & b[ #idx] } ] ;
265+ let a = lane ( quote ! { a } , vec_ty, idx) ;
266+ let b = lane ( quote ! { b } , vec_ty, idx) ;
267+ let args = [ quote ! { & #a } , quote ! { & #b } ] ;
264268 let expr = fallback:: expr ( method, vec_ty, & args) ;
265269 let mask_ty = mask_type. scalar . rust ( vec_ty. scalar_bits ) ;
266270 quote ! { -( #expr as #mask_ty) }
@@ -275,10 +279,14 @@ impl Level for Fallback {
275279 }
276280 }
277281 OpSig :: Select => {
282+ let mask_type = vec_ty. mask_ty ( ) ;
278283 let items = make_list (
279284 ( 0 ..vec_ty. len )
280285 . map ( |idx| {
281- quote ! { if a[ #idx] != 0 { b[ #idx] } else { c[ #idx] } }
286+ let a = lane ( quote ! { a } , & mask_type, idx) ;
287+ let b = lane ( quote ! { b } , vec_ty, idx) ;
288+ let c = lane ( quote ! { c } , vec_ty, idx) ;
289+ quote ! { if #a != 0 { #b } else { #c } }
282290 } )
283291 . collect :: < Vec < _ > > ( ) ,
284292 ) ;
@@ -332,7 +340,9 @@ impl Level for Fallback {
332340 let zip = make_list (
333341 indices
334342 . map ( |idx| {
335- quote ! { a[ #idx] , b[ #idx] }
343+ let a = lane ( quote ! { a } , vec_ty, idx) ;
344+ let b = lane ( quote ! { b } , vec_ty, idx) ;
345+ quote ! { #a, #b }
336346 } )
337347 . collect :: < Vec < _ > > ( ) ,
338348 ) ;
@@ -353,12 +363,8 @@ impl Level for Fallback {
353363 let unzip = make_list (
354364 indices
355365 . clone ( )
356- . map ( |idx| {
357- quote ! { a[ #idx] }
358- } )
359- . chain ( indices. map ( |idx| {
360- quote ! { b[ #idx] }
361- } ) )
366+ . map ( |idx| lane ( quote ! { a } , vec_ty, idx) )
367+ . chain ( indices. map ( |idx| lane ( quote ! { b } , vec_ty, idx) ) )
362368 . collect :: < Vec < _ > > ( ) ,
363369 ) ;
364370
@@ -398,7 +404,8 @@ impl Level for Fallback {
398404 let items = make_list (
399405 ( 0 ..vec_ty. len )
400406 . map ( |idx| {
401- quote ! { a[ #idx] as #scalar }
407+ let a = lane ( quote ! { a } , vec_ty, idx) ;
408+ quote ! { #a as #scalar }
402409 } )
403410 . collect :: < Vec < _ > > ( ) ,
404411 ) ;
@@ -427,7 +434,6 @@ impl Level for Fallback {
427434 quantifier,
428435 condition,
429436 } => {
430- let indices = ( 0 ..vec_ty. len ) . map ( |idx| quote ! { #idx } ) ;
431437 let check = if condition {
432438 quote ! { != }
433439 } else {
@@ -436,10 +442,12 @@ impl Level for Fallback {
436442
437443 let expr = match quantifier {
438444 crate :: ops:: Quantifier :: Any => {
439- quote ! { #( a[ #indices] #check 0 ) ||* }
445+ let lanes = ( 0 ..vec_ty. len ) . map ( |idx| lane ( quote ! { a } , vec_ty, idx) ) ;
446+ quote ! { #( #lanes #check 0 ) ||* }
440447 }
441448 crate :: ops:: Quantifier :: All => {
442- quote ! { #( a[ #indices] #check 0 ) &&* }
449+ let lanes = ( 0 ..vec_ty. len ) . map ( |idx| lane ( quote ! { a } , vec_ty, idx) ) ;
450+ quote ! { #( #lanes #check 0 ) &&* }
443451 }
444452 } ;
445453
@@ -546,6 +554,14 @@ fn interleave_indices(
546554 make_list ( indices. into_iter ( ) . map ( func) . collect :: < Vec < _ > > ( ) )
547555}
548556
557+ fn lane ( value : TokenStream , vec_ty : & VecType , idx : usize ) -> TokenStream {
558+ if vec_ty. scalar == ScalarType :: Mask {
559+ quote ! { #value. val. 0 [ #idx] }
560+ } else {
561+ quote ! { #value[ #idx] }
562+ }
563+ }
564+
549565/// Whether the second argument of the function needs to be passed by reference.
550566fn rhs_reference ( method : & str ) -> bool {
551567 !matches ! (
0 commit comments