Declare the global and upcall glues as ValueRefs in rustc's trans.
This commit is contained in:
parent
bba4cae1b8
commit
2db1f864e2
5 changed files with 94 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue