Skip to content

Commit e823ca4

Browse files
committed
stdlib: Implement casts. The horror.
1 parent 75047ea commit e823ca4

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/rt/intrinsics/intrinsics.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
// -I../arch/i386 -fno-stack-protector -o intrinsics.ll intrinsics.cpp`
33

44
#include "../rust_internal.h"
5+
#include <cstdlib>
6+
#include <cstring>
7+
8+
extern "C" CDECL void
9+
upcall_fail(rust_task *task, char const *expr, char const *file, size_t line);
510

611
extern "C" size_t
712
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,
2934
return &((uint8_t *)ptr)[ty->size * count];
3035
}
3136

37+
extern "C" void
38+
rust_intrinsic_cast(rust_task *task, type_desc *t1, type_desc *t2, void *dest,
39+
void *src)
40+
{
41+
if (t1->size != t2->size) {
42+
upcall_fail(task, "attempt to cast values of differing sizes",
43+
__FILE__, __LINE__);
44+
return;
45+
}
46+
47+
memmove(dest, src, t1->size);
48+
}
49+

src/rt/intrinsics/intrinsics.ll.in

+28
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ target triple = "@CFG_LLVM_TRIPLE@"
6161
%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*] }
6262
%union.rust_ivec_payload = type { %struct.rust_ivec_heap* }
6363

64+
@.str = private unnamed_addr constant [42 x i8] c"attempt to cast values of differing sizes\00", align 1
65+
@.str1 = private unnamed_addr constant [15 x i8] c"intrinsics.cpp\00", align 1
66+
6467
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 {
6568
entry:
6669
%fill = getelementptr inbounds %struct.rust_vec* %v, i32 0, i32 2
@@ -106,6 +109,31 @@ entry:
106109
ret i8* %arrayidx
107110
}
108111

112+
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) {
113+
entry:
114+
%size = getelementptr inbounds %struct.type_desc* %t1, i32 0, i32 1
115+
%tmp1 = load i32* %size, align 4, !tbaa !0
116+
%size3 = getelementptr inbounds %struct.type_desc* %t2, i32 0, i32 1
117+
%tmp4 = load i32* %size3, align 4, !tbaa !0
118+
%cmp = icmp eq i32 %tmp1, %tmp4
119+
br i1 %cmp, label %if.end, label %if.then
120+
121+
if.then: ; preds = %entry
122+
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)
123+
br label %return
124+
125+
if.end: ; preds = %entry
126+
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %tmp1, i32 1, i1 false)
127+
br label %return
128+
129+
return: ; preds = %if.end, %if.then
130+
ret void
131+
}
132+
133+
declare void @upcall_fail(%struct.rust_task*, i8*, i8*, i32)
134+
135+
declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
136+
109137
!0 = metadata !{metadata !"long", metadata !1}
110138
!1 = metadata !{metadata !"omnipotent char", metadata !2}
111139
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}

0 commit comments

Comments
 (0)