Skip to content

Commit

Permalink
Revert removal of intrinsics
Browse files Browse the repository at this point in the history
Oops. We can't do this yet until the next snapshot.
  • Loading branch information
marijnh committed Mar 23, 2012
1 parent c704d5a commit 52d618a
Show file tree
Hide file tree
Showing 25 changed files with 1,038 additions and 32 deletions.
1 change: 1 addition & 0 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ HSREQ$(1)_H_$(3) = \
TSREQ$(1)_T_$(2)_H_$(3) = \
$$(HSREQ$(1)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME) \
$$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.bc \
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a

# Prerequisites for complete stageN targets
Expand Down
2 changes: 2 additions & 0 deletions mk/clean.mk
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ clean$(1)_T_$(2)_H_$(3):
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB)
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM)
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.bc
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.ll
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
endef

Expand Down
1 change: 1 addition & 0 deletions mk/install.mk
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ install-target-$(1)-host-$(2): $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(STDLIB_GLOB))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTC_GLOB))
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),intrinsics.bc)
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a)

endef
Expand Down
11 changes: 11 additions & 0 deletions mk/target.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ USE_SNAPSHOT_CORELIB=0

define TARGET_STAGE_N

$$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.ll: \
$$(S)src/rt/intrinsics/intrinsics.$(HOST_$(2)).ll.in
@$$(call E, sed: $$@)
$$(Q)sed s/@CFG_TARGET_TRIPLE@/$(2)/ $$< > $$@

$$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.bc: \
$$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.ll \
$$(LLVM_CONFIG_$(2))
@$$(call E, llvms-as: $$@)
$$(Q)$$(LLVM_AS_$(2)) -o $$@ $$<

$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
rt/$(2)/arch/$$(HOST_$(2))/libmorestack.a
@$$(call E, cp: $$@)
Expand Down
27 changes: 27 additions & 0 deletions src/etc/gen-intrinsics
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/sh

# This script generates new definitions for the intrinsics using
# clang. This is not currently in the Makefile to avoid any dependency
# on clang.

for ARCH in i386 x86_64
do
if [ $ARCH = "i386" ]
then
BITS=32
else
BITS=64
fi

clang++ -emit-llvm -S -m$BITS -O3 -Isrc/rt/isaac -Isrc/rt/uthash \
-Isrc/rt/arch/$ARCH -Isrc/rt -fno-stack-protector \
-o src/rt/intrinsics/intrinsics.$ARCH.ll.in \
src/rt/intrinsics/intrinsics.cpp
sed -i .orig \
-e 's/^target datalayout =/; target datalayout =/' \
src/rt/intrinsics/intrinsics.$ARCH.ll.in
sed -i .orig \
-e 's/^target triple = "[^"]*"/target triple = "@CFG_TARGET_TRIPLE@"/' \
src/rt/intrinsics/intrinsics.$ARCH.ll.in
rm src/rt/intrinsics/intrinsics.$ARCH.ll.in.orig
done
174 changes: 174 additions & 0 deletions src/rt/intrinsics/intrinsics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Rust intrinsics. These are built into each compilation unit and are
// run on the Rust stack. They should not call C methods because that
// will very likely result in running off the end of the stack.
// Build with the script in src/etc/gen-intrinsics

#include "../rust_internal.h"
#include "../rust_util.h"
#include <cstdlib>
#include <cstring>

extern "C" CDECL void
rust_task_yield(rust_task *task, bool *killed);

extern "C" void
rust_intrinsic_vec_len(size_t *retptr,
void *env,
type_desc *ty,
rust_vec **vp)
{
*retptr = (*vp)->fill / ty->size;
}

extern "C" void
rust_intrinsic_ptr_offset(void **retptr,
void *env,
type_desc *ty,
void *ptr,
uintptr_t count)
{
*retptr = &((uint8_t *)ptr)[ty->size * count];
}

extern "C" void
rust_intrinsic_cast(void *retptr,
void *env,
type_desc *t1,
type_desc *t2,
void *src)
{
// assert t1->size == t2->size
// FIXME: This should be easily expressible in rust
memmove(retptr, src, t1->size);
}

extern "C" void
rust_intrinsic_addr_of(void **retptr,
void *env,
type_desc *ty,
void *valptr) {
*retptr = valptr;
}

struct rust_fn {
uintptr_t *fn;
rust_box *env;
};

typedef void (*retptr_fn)(void **retptr,
void *env,
void **dptr);
// FIXME (1185): This exists just to get access to the return pointer
extern "C" void
rust_intrinsic_call_with_retptr(void **retptr,
void *env,
type_desc *ty,
rust_fn *recvfn) {
retptr_fn fn = ((retptr_fn)(recvfn->fn));
((retptr_fn)(*fn))(NULL, recvfn->env, retptr);
}

extern "C" void
rust_intrinsic_get_type_desc(void **retptr,
void *env,
type_desc* ty) {
*(type_desc**)retptr = ty;
}

extern "C" void
rust_intrinsic_task_yield(void **retptr,
void *env,
rust_task *task,
bool *killed) {
rust_task_yield(task, killed);
}

extern "C" void
rust_intrinsic_memmove(void *retptr,
void *env,
type_desc *ty,
void *dst,
void *src,
uintptr_t count)
{
memmove(dst, src, ty->size * count);
}

extern "C" void
rust_intrinsic_memcpy(void *retptr,
void *env,
type_desc *ty,
void *dst,
void *src,
uintptr_t count)
{
memcpy(dst, src, ty->size * count);
}

extern "C" void
rust_intrinsic_leak(void *retptr,
void *env,
type_desc *ty,
void *thing)
{
}

extern "C" CDECL void *
upcall_shared_realloc(void *ptr, size_t size);

inline void reserve_vec_fast(rust_vec **vpp, size_t size) {
if (size > (*vpp)->alloc) {
size_t new_size = next_power_of_two(size);
size_t alloc_size = new_size + sizeof(rust_vec);
// Because this is called from an intrinsic we need to use
// the exported API
*vpp = (rust_vec*)upcall_shared_realloc(*vpp, alloc_size);
(*vpp)->alloc = new_size;
}
}

// Copy elements from one vector to another,
// dealing with reference counts
static inline void
copy_elements(type_desc *elem_t,
void *pdst, void *psrc, size_t n) {
char *dst = (char *)pdst, *src = (char *)psrc;
memmove(dst, src, n);

// increment the refcount of each element of the vector
if (elem_t->take_glue) {
glue_fn *take_glue = elem_t->take_glue;
size_t elem_size = elem_t->size;
const type_desc **tydescs = elem_t->first_param;
for (char *p = dst; p < dst+n; p += elem_size) {
take_glue(NULL, NULL, tydescs, p);
}
}
}

// Because this is used so often, and it calls take glue that must run
// on the rust stack, it is statically compiled into every crate.
extern "C" CDECL void
upcall_intrinsic_vec_push(rust_vec** vp,
type_desc* elt_ty, void* elt) {

size_t new_sz = (*vp)->fill + elt_ty->size;
reserve_vec_fast(vp, new_sz);
rust_vec* v = *vp;
copy_elements(elt_ty, &v->data[0] + v->fill,
elt, elt_ty->size);
v->fill += elt_ty->size;
}

// FIXME: Transational. Remove
extern "C" CDECL void
upcall_vec_push(rust_vec** vp,
type_desc* elt_ty, void* elt) {
upcall_intrinsic_vec_push(vp, elt_ty, elt);
}

extern "C" CDECL void
rust_intrinsic_frame_address(void **p, unsigned n) {
*p = __builtin_frame_address(n);
}

Loading

0 comments on commit 52d618a

Please sign in to comment.