]> git.lizzy.rs Git - rust.git/commitdiff
Generate LLVM SIMD vector types
authorSeo Sanghyeon <sanxiyn@gmail.com>
Tue, 7 May 2013 17:09:19 +0000 (02:09 +0900)
committerSeo Sanghyeon <sanxiyn@gmail.com>
Tue, 7 May 2013 17:09:19 +0000 (02:09 +0900)
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs

index fc27c11c06f24698ba8b30a982829cc11c1366a1..b8e0b58f86634c00726ecc66d8c21e8c2fdaab13 100644 (file)
@@ -155,9 +155,15 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
         }
 
         ty::ty_struct(did, _) => {
-            let repr = adt::represent_type(cx, t);
-            let packed = ty::lookup_packed(cx.tcx, did);
-            T_struct(adt::sizing_fields_of(cx, repr), packed)
+            if ty::type_is_simd(cx.tcx, t) {
+                let et = ty::simd_type(cx.tcx, t);
+                let n = ty::simd_size(cx.tcx, t);
+                T_vector(type_of(cx, et), n)
+            } else {
+                let repr = adt::represent_type(cx, t);
+                let packed = ty::lookup_packed(cx.tcx, did);
+                T_struct(adt::sizing_fields_of(cx, repr), packed)
+            }
         }
 
         ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => {
@@ -263,14 +269,19 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
       }
       ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx),
       ty::ty_struct(did, ref substs) => {
-        // Only create the named struct, but don't fill it in. We fill it
-        // in *after* placing it into the type cache. This prevents
-        // infinite recursion with recursive struct types.
-
-        common::T_named_struct(llvm_type_name(cx,
-                                              a_struct,
-                                              did,
-                                              /*bad*/ copy substs.tps))
+        if ty::type_is_simd(cx.tcx, t) {
+          let et = ty::simd_type(cx.tcx, t);
+          let n = ty::simd_size(cx.tcx, t);
+          T_vector(type_of(cx, et), n)
+        } else {
+          // Only create the named struct, but don't fill it in. We fill it
+          // in *after* placing it into the type cache. This prevents
+          // infinite recursion with recursive struct types.
+          T_named_struct(llvm_type_name(cx,
+                                        a_struct,
+                                        did,
+                                        /*bad*/ copy substs.tps))
+        }
       }
       ty::ty_self(*) => cx.tcx.sess.unimpl(~"type_of: ty_self"),
       ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"),
@@ -289,10 +300,12 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
       }
 
       ty::ty_struct(did, _) => {
-        let repr = adt::represent_type(cx, t);
-        let packed = ty::lookup_packed(cx.tcx, did);
-        common::set_struct_body(llty, adt::fields_of(cx, repr),
-                                packed);
+        if !ty::type_is_simd(cx.tcx, t) {
+          let repr = adt::represent_type(cx, t);
+          let packed = ty::lookup_packed(cx.tcx, did);
+          common::set_struct_body(llty, adt::fields_of(cx, repr),
+                                  packed);
+        }
       }
       _ => ()
     }
index 2b46497b77d0bbb13951c1fb3b172ef760e66e17..4d1d271698c42f779b49d8aeab5636772c2ce5f8 100644 (file)
@@ -1567,6 +1567,13 @@ pub fn type_is_sequence(ty: t) -> bool {
     }
 }
 
+pub fn type_is_simd(cx: ctxt, ty: t) -> bool {
+    match get(ty).sty {
+        ty_struct(did, _) => lookup_simd(cx, did),
+        _ => false
+    }
+}
+
 pub fn type_is_str(ty: t) -> bool {
     match get(ty).sty {
       ty_estr(_) => true,
@@ -1583,6 +1590,26 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t {
     }
 }
 
+pub fn simd_type(cx: ctxt, ty: t) -> t {
+    match get(ty).sty {
+        ty_struct(did, ref substs) => {
+            let fields = lookup_struct_fields(cx, did);
+            lookup_field_type(cx, did, fields[0].id, substs)
+        }
+        _ => fail!(~"simd_type called on invalid type")
+    }
+}
+
+pub fn simd_size(cx: ctxt, ty: t) -> uint {
+    match get(ty).sty {
+        ty_struct(did, _) => {
+            let fields = lookup_struct_fields(cx, did);
+            fields.len()
+        }
+        _ => fail!(~"simd_size called on invalid type")
+    }
+}
+
 pub fn get_element_type(ty: t, i: uint) -> t {
     match get(ty).sty {
       ty_tup(ref ts) => return ts[i],