about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2020-03-28 15:21:58 +0100
committerbjorn3 <bjorn3@users.noreply.github.com>2020-07-25 12:28:24 +0200
commit08fc673190ef43b111a6fea2fadf7de25bf7f282 (patch)
tree884379f06ea492bbc2b43f7df30be4e3422a73ba /src
parentabc99c62595831127e8ac4dfd6ccacd7ccbf9942 (diff)
downloadrust-08fc673190ef43b111a6fea2fadf7de25bf7f282.tar.gz
rust-08fc673190ef43b111a6fea2fadf7de25bf7f282.zip
Handle SIMD vectors in CPlace::place_field
Diffstat (limited to 'src')
-rw-r--r--src/abi/comments.rs1
-rw-r--r--src/debuginfo/mod.rs5
-rw-r--r--src/value_and_place.rs66
3 files changed, 56 insertions, 16 deletions
diff --git a/src/abi/comments.rs b/src/abi/comments.rs
index 7c4d7b12f6e..357c28c832a 100644
--- a/src/abi/comments.rs
+++ b/src/abi/comments.rs
@@ -82,6 +82,7 @@ pub(super) fn add_local_place_comments<'tcx>(
             assert_eq!(local, place_local);
             ("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())))
         }
+        CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
         CPlaceInner::Addr(ptr, meta) => {
             let meta = if let Some(meta) = meta {
                 Cow::Owned(format!(",meta={}", meta))
diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs
index 37dc9f4e3c5..2c92fd0e47c 100644
--- a/src/debuginfo/mod.rs
+++ b/src/debuginfo/mod.rs
@@ -411,6 +411,11 @@ fn place_location<'tcx>(
 
             AttributeValue::Exprloc(Expression::new())
         }
+        CPlaceInner::VarLane(_, _, _) => {
+            // FIXME implement this
+
+            AttributeValue::Exprloc(Expression::new())
+        }
         CPlaceInner::Addr(_, _) => {
             // FIXME implement this (used by arguments and returns)
 
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index 477a417639e..d0e8a4b0c9f 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -272,6 +272,7 @@ pub(crate) struct CPlace<'tcx> {
 pub(crate) enum CPlaceInner {
     Var(Local, Variable),
     VarPair(Local, Variable, Variable),
+    VarLane(Local, Variable, u8),
     Addr(Pointer, Option<Value>),
 }
 
@@ -374,6 +375,12 @@ impl<'tcx> CPlace<'tcx> {
                 fx.bcx.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index()));
                 CValue::by_val_pair(val1, val2, layout)
             }
+            CPlaceInner::VarLane(_local, var, lane) => {
+                let val = fx.bcx.use_var(var);
+                fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
+                let val = fx.bcx.ins().extractlane(val, lane);
+                CValue::by_val(val, layout)
+            }
             CPlaceInner::Addr(ptr, extra) => {
                 if let Some(extra) = extra {
                     CValue::by_ref_unsized(ptr, extra, layout)
@@ -395,7 +402,8 @@ impl<'tcx> CPlace<'tcx> {
         match self.inner {
             CPlaceInner::Addr(ptr, extra) => (ptr, extra),
             CPlaceInner::Var(_, _)
-            | CPlaceInner::VarPair(_, _, _) => bug!("Expected CPlace::Addr, found {:?}", self),
+            | CPlaceInner::VarPair(_, _, _)
+            | CPlaceInner::VarLane(_, _, _) => bug!("Expected CPlace::Addr, found {:?}", self),
         }
     }
 
@@ -527,6 +535,22 @@ impl<'tcx> CPlace<'tcx> {
                 transmute_value(fx, var2, data2, dst_ty2);
                 return;
             }
+            CPlaceInner::VarLane(_local, var, lane) => {
+                let data = from.load_scalar(fx);
+
+                // First get the old vector
+                let vector = fx.bcx.use_var(var);
+                fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
+
+                // Next insert the written lane into the vector
+                let vector = fx.bcx.ins().insertlane(vector, data, lane);
+
+                // Finally write the new vector
+                fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
+                fx.bcx.def_var(var, vector);
+
+                return;
+            }
             CPlaceInner::Addr(ptr, None) => {
                 if dst_layout.size == Size::ZERO || dst_layout.abi == Abi::Uninhabited {
                     return;
@@ -589,23 +613,33 @@ impl<'tcx> CPlace<'tcx> {
         fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
         field: mir::Field,
     ) -> CPlace<'tcx> {
-        // FIXME handle simd values
-
         let layout = self.layout();
-        if let CPlaceInner::VarPair(local, var1, var2) = self.inner {
-            let layout = layout.field(&*fx, field.index());
-
-            match field.as_u32() {
-                0 => return CPlace {
-                    inner: CPlaceInner::Var(local, var1),
-                    layout,
-                },
-                1 => return CPlace {
-                    inner: CPlaceInner::Var(local, var2),
-                    layout,
-                },
-                _ => unreachable!("field should be 0 or 1"),
+
+        match self.inner {
+            CPlaceInner::Var(local, var) => {
+                if let Abi::Vector { .. } = layout.abi {
+                    return CPlace {
+                        inner: CPlaceInner::VarLane(local, var, field.as_u32().try_into().unwrap()),
+                        layout: layout.field(fx, field.as_u32().try_into().unwrap()),
+                    };
+                }
+            }
+            CPlaceInner::VarPair(local, var1, var2) => {
+                let layout = layout.field(&*fx, field.index());
+
+                match field.as_u32() {
+                    0 => return CPlace {
+                        inner: CPlaceInner::Var(local, var1),
+                        layout,
+                    },
+                    1 => return CPlace {
+                        inner: CPlaceInner::Var(local, var2),
+                        layout,
+                    },
+                    _ => unreachable!("field should be 0 or 1"),
+                }
             }
+            _ => {}
         }
 
         let (base, extra) = self.to_ptr_maybe_unsized();