1
Fork 0

Declare the global and upcall glues as ValueRefs in rustc's trans.

This commit is contained in:
Graydon Hoare 2010-09-23 17:16:34 -07:00
parent bba4cae1b8
commit 2db1f864e2
5 changed files with 94 additions and 21 deletions

View file

@ -34,6 +34,8 @@ const int calltup_elt_iterator_args = 5;
const int worst_case_glue_call_args = 7;
const int n_upcall_glues = 7;
//
// Local Variables:
// mode: rust

View file

@ -1,15 +1,11 @@
import lib.llvm.llvm;
import lib.llvm.llvm.ModuleRef;
import std._str;
import std._int;
import std._vec;
import util.common.istr;
const int wordsz = 4;
fn istr(int i) -> str {
ret _int.to_str(i, 10u);
}
fn wstr(int i) -> str {
ret istr(i * wordsz);
}
@ -122,6 +118,13 @@ fn decl_glue(int align, str prefix, str name, vec[str] insns) -> str {
}
fn decl_upcall_glue(int align, str prefix, uint n) -> str {
let int i = n as int;
ret decl_glue(align, prefix,
"rust_upcall_" + istr(i),
upcall_glue(i));
}
fn get_module_asm() -> str {
auto align = 4;
auto prefix = "";
@ -133,20 +136,15 @@ fn get_module_asm() -> str {
decl_glue(align, prefix,
"rust_yield_glue",
rust_yield_glue()));
rust_yield_glue()))
let int i = 0;
let int n_upcall_glues = 7;
while (i < n_upcall_glues) {
glues += decl_glue(align, prefix,
"rust_upcall_" + istr(i),
upcall_glue(i));
i += 1;
}
+ _vec.init_fn[str](bind decl_upcall_glue(align, prefix, _),
abi.n_upcall_glues as uint);
ret _str.connect(glues, "\n\n");
}
//
// Local Variables:
// mode: rust

View file

@ -25,8 +25,19 @@ type LongLong = i64;
type Long = i32;
type Bool = int;
fn True() -> Bool { ret 1; }
fn False() -> Bool { ret 0; }
const Bool True = 1;
const Bool False = 0;
// Consts for the LLVM CallConv type, pre-cast to uint.
// FIXME: figure out a way to merge these with the native
// typedef and/or a tag type in the native module below.
const uint LLVMCCallConv = 0u;
const uint LLVMFastCallConv = 8u;
const uint LLVMColdCallConv = 9u;
const uint LLVMX86StdcallCallConv = 64u;
const uint LLVMX86FastcallCallConv = 65u;
native mod llvm = llvm_lib {

View file

@ -6,6 +6,9 @@ import std._vec.rustrt.vbuf;
import front.ast;
import driver.session;
import back.x86;
import back.abi;
import util.common.istr;
import lib.llvm.llvm;
import lib.llvm.builder;
@ -18,8 +21,13 @@ import lib.llvm.llvm.BasicBlockRef;
import lib.llvm.False;
import lib.llvm.True;
type glue_fns = rec(ValueRef activate_glue,
ValueRef yield_glue,
vec[ValueRef] upcall_glues);
type trans_ctxt = rec(session.session sess,
ModuleRef llmod,
@glue_fns glues,
str path);
fn T_nil() -> TypeRef {
@ -34,9 +42,53 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
ret llvm.LLVMFunctionType(output,
_vec.buf[TypeRef](inputs),
_vec.len[TypeRef](inputs),
False());
False);
}
fn T_ptr(TypeRef t) -> TypeRef {
ret llvm.LLVMPointerType(t, 0u);
}
fn T_struct(vec[TypeRef] elts) -> TypeRef {
ret llvm.LLVMStructType(_vec.buf[TypeRef](elts),
_vec.len[TypeRef](elts),
False);
}
fn T_opaque() -> TypeRef {
ret llvm.LLVMOpaqueType();
}
fn T_task() -> TypeRef {
ret T_struct(vec(T_int(), // Refcount
T_opaque())); // Rest is opaque for now
}
fn decl_cdecl_fn(ModuleRef llmod, str name,
vec[TypeRef] inputs, TypeRef output) -> ValueRef {
let TypeRef llty = T_fn(inputs, output);
let ValueRef llfn =
llvm.LLVMAddFunction(llmod, _str.buf(name), llty);
llvm.LLVMSetFunctionCallConv(llfn, lib.llvm.LLVMCCallConv);
ret llfn;
}
fn decl_glue(ModuleRef llmod, str s) -> ValueRef {
ret decl_cdecl_fn(llmod, s, vec(T_ptr(T_task())), T_nil());
}
fn decl_upcall(ModuleRef llmod, uint _n) -> ValueRef {
let int n = _n as int;
let str s = "rust_upcall_" + istr(n);
let vec[TypeRef] args =
vec(T_ptr(T_task()), // taskptr
T_int()) // callee
+ _vec.init_elt[TypeRef](T_int(), n as uint);
ret decl_cdecl_fn(llmod, s, args, T_int());
}
type terminator = fn(&trans_ctxt cx, builder b);
fn trans_log(&trans_ctxt cx, builder b, &ast.atom a) {
@ -71,10 +123,9 @@ fn trans_block(&trans_ctxt cx, ValueRef llfn, &ast.block b, terminator t) {
fn trans_fn(&trans_ctxt cx, &ast._fn f) {
let vec[TypeRef] args = vec();
let TypeRef llty = T_fn(args, T_nil());
let ValueRef llfn =
llvm.LLVMAddFunction(cx.llmod, _str.buf(cx.path), llty);
let ValueRef llfn = decl_cdecl_fn(cx.llmod, cx.path, args, T_nil());
auto term = default_terminate;
trans_block(cx, llfn, f.body, term);
}
@ -103,7 +154,13 @@ fn trans_crate(session.session sess, ast.crate crate) {
llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm()));
auto cx = rec(sess=sess, llmod=llmod, path="");
auto glues = @rec(activate_glue = decl_glue(llmod, "rust_activate_glue"),
yield_glue = decl_glue(llmod, "rust_yield_glue"),
upcall_glues =
_vec.init_fn[ValueRef](bind decl_upcall(llmod, _),
abi.n_upcall_glues as uint));
auto cx = rec(sess=sess, llmod=llmod, glues=glues, path="");
trans_mod(cx, crate.module);
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc"));

View file

@ -1,4 +1,5 @@
import std._uint;
import std._int;
type pos = rec(uint line, uint col);
type span = rec(str filename, pos lo, pos hi);
@ -41,6 +42,10 @@ fn new_str_hash[V]() -> std.map.hashmap[str,V] {
ret std.map.mk_hashmap[str,V](hasher, eqer);
}
fn istr(int i) -> str {
ret _int.to_str(i, 10u);
}
//
// Local Variables:
// mode: rust