diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-07-09 20:14:20 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2011-07-09 20:14:47 -0700 |
| commit | e823ca496518c1dea4c6f2b3e90e32d38df8540c (patch) | |
| tree | c92c3ef24e8247c83abb80a939515f330155bc47 /src/rt | |
| parent | 75047ea87e2a26c0e9518af0dbc22dc6631e3ebd (diff) | |
| download | rust-e823ca496518c1dea4c6f2b3e90e32d38df8540c.tar.gz rust-e823ca496518c1dea4c6f2b3e90e32d38df8540c.zip | |
stdlib: Implement casts. The horror.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/intrinsics/intrinsics.cpp | 18 | ||||
| -rw-r--r-- | src/rt/intrinsics/intrinsics.ll.in | 28 |
2 files changed, 46 insertions, 0 deletions
diff --git a/src/rt/intrinsics/intrinsics.cpp b/src/rt/intrinsics/intrinsics.cpp index be756a28159..a390abae370 100644 --- a/src/rt/intrinsics/intrinsics.cpp +++ b/src/rt/intrinsics/intrinsics.cpp @@ -2,6 +2,11 @@ // -I../arch/i386 -fno-stack-protector -o intrinsics.ll intrinsics.cpp` #include "../rust_internal.h" +#include <cstdlib> +#include <cstring> + +extern "C" CDECL void +upcall_fail(rust_task *task, char const *expr, char const *file, size_t line); extern "C" size_t rust_intrinsic_vec_len(rust_task *task, type_desc *ty, rust_vec *v) @@ -29,3 +34,16 @@ rust_intrinsic_ptr_offset(rust_task *task, type_desc *ty, void *ptr, return &((uint8_t *)ptr)[ty->size * count]; } +extern "C" void +rust_intrinsic_cast(rust_task *task, type_desc *t1, type_desc *t2, void *dest, + void *src) +{ + if (t1->size != t2->size) { + upcall_fail(task, "attempt to cast values of differing sizes", + __FILE__, __LINE__); + return; + } + + memmove(dest, src, t1->size); +} + diff --git a/src/rt/intrinsics/intrinsics.ll.in b/src/rt/intrinsics/intrinsics.ll.in index c871b6e5a31..a20ef07c218 100644 --- a/src/rt/intrinsics/intrinsics.ll.in +++ b/src/rt/intrinsics/intrinsics.ll.in @@ -61,6 +61,9 @@ target triple = "@CFG_LLVM_TRIPLE@" %struct.type_desc = type { %struct.type_desc**, i32, i32, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*)*, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*)*, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*)*, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*)*, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*)*, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*)*, i32, void (i8*, %struct.rust_task*, i8*, %struct.type_desc**, i8*, i8*, i8)*, %struct.UT_hash_handle, i32, [0 x %struct.type_desc*] } %union.rust_ivec_payload = type { %struct.rust_ivec_heap* } +@.str = private unnamed_addr constant [42 x i8] c"attempt to cast values of differing sizes\00", align 1 +@.str1 = private unnamed_addr constant [15 x i8] c"intrinsics.cpp\00", align 1 + define linkonce_odr i32 @rust_intrinsic_vec_len(%struct.rust_task* nocapture %task, %struct.type_desc* nocapture %ty, %struct.rust_vec* nocapture %v) nounwind readonly { entry: %fill = getelementptr inbounds %struct.rust_vec* %v, i32 0, i32 2 @@ -106,6 +109,31 @@ entry: ret i8* %arrayidx } +define linkonce_odr void @rust_intrinsic_cast(%struct.rust_task* %task, %struct.type_desc* nocapture %t1, %struct.type_desc* nocapture %t2, i8* nocapture %dest, i8* nocapture %src) { +entry: + %size = getelementptr inbounds %struct.type_desc* %t1, i32 0, i32 1 + %tmp1 = load i32* %size, align 4, !tbaa !0 + %size3 = getelementptr inbounds %struct.type_desc* %t2, i32 0, i32 1 + %tmp4 = load i32* %size3, align 4, !tbaa !0 + %cmp = icmp eq i32 %tmp1, %tmp4 + br i1 %cmp, label %if.end, label %if.then + +if.then: ; preds = %entry + tail call void @upcall_fail(%struct.rust_task* %task, i8* getelementptr inbounds ([42 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8]* @.str1, i32 0, i32 0), i32 43) + br label %return + +if.end: ; preds = %entry + tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %tmp1, i32 1, i1 false) + br label %return + +return: ; preds = %if.end, %if.then + ret void +} + +declare void @upcall_fail(%struct.rust_task*, i8*, i8*, i32) + +declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind + !0 = metadata !{metadata !"long", metadata !1} !1 = metadata !{metadata !"omnipotent char", metadata !2} !2 = metadata !{metadata !"Simple C/C++ TBAA", null} |
