Remove native glues. All calls to C are direct now.
This commit is contained in:
parent
89e5f6c883
commit
8e945dcd81
4 changed files with 10 additions and 261 deletions
|
|
@ -69,14 +69,6 @@ const int closure_elt_ty_params = 3;
|
|||
|
||||
const int worst_case_glue_call_args = 7;
|
||||
|
||||
const int n_native_glues = 8;
|
||||
|
||||
tag native_glue_type {
|
||||
ngt_rust;
|
||||
ngt_pure_rust;
|
||||
ngt_cdecl;
|
||||
}
|
||||
|
||||
fn memcpy_glue_name() -> str {
|
||||
ret "rust_memcpy_glue";
|
||||
}
|
||||
|
|
@ -89,16 +81,6 @@ fn vec_append_glue_name() -> str {
|
|||
ret "rust_vec_append_glue";
|
||||
}
|
||||
|
||||
fn native_glue_name(int n, native_glue_type ngt) -> str {
|
||||
auto prefix;
|
||||
alt (ngt) {
|
||||
case (ngt_rust) { prefix = "rust_native_rust_"; }
|
||||
case (ngt_pure_rust) { prefix = "rust_native_pure_rust_"; }
|
||||
case (ngt_cdecl) { prefix = "rust_native_cdecl_"; }
|
||||
}
|
||||
ret prefix + util::common::istr(n);
|
||||
}
|
||||
|
||||
fn yield_glue_name() -> str {
|
||||
ret "rust_yield_glue";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,193 +5,8 @@ import std::vec;
|
|||
import std::os::target_os;
|
||||
import util::common::istr;
|
||||
|
||||
const int wordsz = 4;
|
||||
|
||||
fn wstr(int i) -> str {
|
||||
ret istr(i * wordsz);
|
||||
}
|
||||
|
||||
fn start() -> vec[str] {
|
||||
ret [".cfi_startproc"];
|
||||
}
|
||||
|
||||
fn end() -> vec[str] {
|
||||
ret [".cfi_endproc"];
|
||||
}
|
||||
|
||||
fn save_callee_saves() -> vec[str] {
|
||||
ret ["pushl %ebp",
|
||||
"pushl %edi",
|
||||
"pushl %esi",
|
||||
"pushl %ebx"];
|
||||
}
|
||||
|
||||
fn save_callee_saves_with_cfi() -> vec[str] {
|
||||
auto offset = 8;
|
||||
auto t;
|
||||
t = ["pushl %ebp"];
|
||||
t += [".cfi_def_cfa_offset " + istr(offset)];
|
||||
t += [".cfi_offset %ebp, -" + istr(offset)];
|
||||
|
||||
t += ["pushl %edi"];
|
||||
offset += 4;
|
||||
t += [".cfi_def_cfa_offset " + istr(offset)];
|
||||
|
||||
t += ["pushl %esi"];
|
||||
offset += 4;
|
||||
t += [".cfi_def_cfa_offset " + istr(offset)];
|
||||
|
||||
t += ["pushl %ebx"];
|
||||
offset += 4;
|
||||
t += [".cfi_def_cfa_offset " + istr(offset)];
|
||||
ret t;
|
||||
}
|
||||
|
||||
fn restore_callee_saves() -> vec[str] {
|
||||
ret ["popl %ebx",
|
||||
"popl %esi",
|
||||
"popl %edi",
|
||||
"popl %ebp"];
|
||||
}
|
||||
|
||||
fn load_esp_from_rust_sp_first_arg() -> vec[str] {
|
||||
ret ["movl " + wstr(abi::task_field_rust_sp) + "(%ecx), %esp"];
|
||||
}
|
||||
|
||||
fn load_esp_from_runtime_sp_first_arg() -> vec[str] {
|
||||
ret ["movl " + wstr(abi::task_field_runtime_sp) + "(%ecx), %esp"];
|
||||
}
|
||||
|
||||
fn store_esp_to_rust_sp_first_arg() -> vec[str] {
|
||||
ret ["movl %esp, " + wstr(abi::task_field_rust_sp) + "(%ecx)"];
|
||||
}
|
||||
|
||||
fn store_esp_to_runtime_sp_first_arg() -> vec[str] {
|
||||
ret ["movl %esp, " + wstr(abi::task_field_runtime_sp) + "(%ecx)"];
|
||||
}
|
||||
|
||||
fn load_esp_from_rust_sp_second_arg() -> vec[str] {
|
||||
ret ["movl " + wstr(abi::task_field_rust_sp) + "(%edx), %esp"];
|
||||
}
|
||||
|
||||
fn load_esp_from_runtime_sp_second_arg() -> vec[str] {
|
||||
ret ["movl " + wstr(abi::task_field_runtime_sp) + "(%edx), %esp"];
|
||||
}
|
||||
|
||||
fn store_esp_to_rust_sp_second_arg() -> vec[str] {
|
||||
ret ["movl %esp, " + wstr(abi::task_field_rust_sp) + "(%edx)"];
|
||||
}
|
||||
|
||||
fn store_esp_to_runtime_sp_second_arg() -> vec[str] {
|
||||
ret ["movl %esp, " + wstr(abi::task_field_runtime_sp) + "(%edx)"];
|
||||
}
|
||||
|
||||
fn native_glue(int n_args, abi::native_glue_type ngt) -> vec[str] {
|
||||
|
||||
let bool pass_task;
|
||||
alt (ngt) {
|
||||
case (abi::ngt_rust) { pass_task = true; }
|
||||
case (abi::ngt_pure_rust) { pass_task = true; }
|
||||
case (abi::ngt_cdecl) { pass_task = false; }
|
||||
}
|
||||
|
||||
/*
|
||||
* 0, 4, 8, 12 are callee-saves
|
||||
* 16 is retpc
|
||||
* 20 .. (5+i) * 4 are args
|
||||
*
|
||||
* ecx is taskptr
|
||||
* edx is callee
|
||||
*
|
||||
*/
|
||||
|
||||
fn copy_arg(bool pass_task, uint i) -> str {
|
||||
if (i == 0u && pass_task) {
|
||||
ret "movl %edx, (%esp)";
|
||||
}
|
||||
auto dst_off = wstr(0 + (i as int));
|
||||
auto src_off;
|
||||
if (pass_task) {
|
||||
src_off = wstr(4 + (i as int));
|
||||
} else {
|
||||
src_off = wstr(5 + (i as int));
|
||||
}
|
||||
auto m = ["movl " + src_off + "(%ebp),%eax",
|
||||
"movl %eax," + dst_off + "(%esp)"];
|
||||
ret str::connect(m, "\n\t");
|
||||
}
|
||||
|
||||
auto carg = bind copy_arg(pass_task, _);
|
||||
|
||||
ret
|
||||
start()
|
||||
+ save_callee_saves_with_cfi()
|
||||
|
||||
+ ["movl %esp, %ebp # ebp = rust_sp"]
|
||||
+ [".cfi_def_cfa_register %ebp"]
|
||||
|
||||
+ store_esp_to_rust_sp_second_arg()
|
||||
+ load_esp_from_runtime_sp_second_arg()
|
||||
|
||||
+ ["subl $" + wstr(n_args) + ", %esp # esp -= args",
|
||||
"andl $~0xf, %esp # align esp down"]
|
||||
|
||||
+ vec::init_fn[str](carg, (n_args) as uint)
|
||||
|
||||
+ ["movl %edx, %edi # save task from edx to edi",
|
||||
"call *%ecx # call *%ecx",
|
||||
"movl %edi, %edx # restore edi-saved task to edx"]
|
||||
|
||||
+ load_esp_from_rust_sp_second_arg()
|
||||
+ restore_callee_saves()
|
||||
+ ["ret"]
|
||||
+ end();
|
||||
|
||||
}
|
||||
|
||||
|
||||
fn decl_glue(int align, str prefix, str name, vec[str] insns) -> str {
|
||||
auto sym = prefix + name;
|
||||
ret "\t.globl " + sym + "\n" +
|
||||
"\t.balign " + istr(align) + "\n" +
|
||||
sym + ":\n" +
|
||||
"\t" + str::connect(insns, "\n\t");
|
||||
}
|
||||
|
||||
|
||||
fn decl_native_glue(int align, str prefix, abi::native_glue_type ngt, uint n)
|
||||
-> str {
|
||||
let int i = n as int;
|
||||
ret decl_glue(align, prefix,
|
||||
abi::native_glue_name(i, ngt),
|
||||
native_glue(i, ngt));
|
||||
}
|
||||
|
||||
fn get_symbol_prefix() -> str {
|
||||
if (str::eq(target_os(), "macos") ||
|
||||
str::eq(target_os(), "win32")) {
|
||||
ret "_";
|
||||
} else {
|
||||
ret "";
|
||||
}
|
||||
}
|
||||
|
||||
fn get_module_asm() -> str {
|
||||
auto align = 4;
|
||||
|
||||
auto prefix = get_symbol_prefix();
|
||||
|
||||
let vec[str] glues =
|
||||
[]
|
||||
+ vec::init_fn[str](bind decl_native_glue(align, prefix,
|
||||
abi::ngt_rust, _), (abi::n_native_glues + 1) as uint)
|
||||
+ vec::init_fn[str](bind decl_native_glue(align, prefix,
|
||||
abi::ngt_pure_rust, _), (abi::n_native_glues + 1) as uint)
|
||||
+ vec::init_fn[str](bind decl_native_glue(align, prefix,
|
||||
abi::ngt_cdecl, _), (abi::n_native_glues + 1) as uint);
|
||||
|
||||
|
||||
ret str::connect(glues, "\n\n");
|
||||
ret "";
|
||||
}
|
||||
|
||||
fn get_meta_sect_name() -> str {
|
||||
|
|
|
|||
|
|
@ -56,9 +56,6 @@ state obj namegen(mutable int i) {
|
|||
type derived_tydesc_info = rec(ValueRef lltydesc, bool escapes);
|
||||
|
||||
type glue_fns = rec(ValueRef yield_glue,
|
||||
vec[ValueRef] native_glues_rust,
|
||||
vec[ValueRef] native_glues_pure_rust,
|
||||
vec[ValueRef] native_glues_cdecl,
|
||||
ValueRef no_op_type_glue,
|
||||
ValueRef vec_append_glue);
|
||||
|
||||
|
|
@ -80,10 +77,7 @@ type tydesc_info = rec(ty::t ty,
|
|||
* please make sure you link it in at runtime". This could be a reference to
|
||||
* C code found in a C library, or rust code found in a rust crate.
|
||||
*
|
||||
* A "native" is a combination of an extern that references C code, plus a
|
||||
* glue-code stub that "looks like" a rust function, emitted here, plus a
|
||||
* generic N-ary bit of asm glue (found over in back/x86::rs) that performs a
|
||||
* control transfer into C from rust. Natives may be normal C library code.
|
||||
* A "native" is an extern that references C code. Called with cdecl.
|
||||
*
|
||||
* An upcall is a native call generated by the compiler (not corresponding to
|
||||
* any user-written call in the code) into librustrt, to perform some helper
|
||||
|
|
@ -1048,32 +1042,6 @@ fn decl_glue(ModuleRef llmod, type_names tn, &str s) -> ValueRef {
|
|||
ret decl_cdecl_fn(llmod, s, T_fn([T_taskptr(tn)], T_void()));
|
||||
}
|
||||
|
||||
fn decl_native_glue(ModuleRef llmod, &type_names tn,
|
||||
abi::native_glue_type ngt, uint _n) -> ValueRef {
|
||||
let bool pass_task;
|
||||
alt (ngt) {
|
||||
case (abi::ngt_rust) { pass_task = true; }
|
||||
case (abi::ngt_pure_rust) { pass_task = true; }
|
||||
case (abi::ngt_cdecl) { pass_task = false; }
|
||||
}
|
||||
|
||||
// It doesn't actually matter what type we come up with here, at the
|
||||
// moment, as we cast the native function pointers to int before passing
|
||||
// them to the indirect native-invocation glue. But eventually we'd like
|
||||
// to call them directly, once we have a calling convention worked out.
|
||||
let int n = _n as int;
|
||||
let str s = abi::native_glue_name(n, ngt);
|
||||
let vec[TypeRef] args = [T_int()]; // callee
|
||||
|
||||
if (!pass_task) {
|
||||
args += [T_int()]; // taskptr, will not be passed
|
||||
}
|
||||
|
||||
args += vec::init_elt[TypeRef](T_int(), n as uint);
|
||||
|
||||
ret decl_fastcall_fn(llmod, s, T_fn(args, T_int()));
|
||||
}
|
||||
|
||||
fn get_extern_fn(&hashmap[str, ValueRef] externs,
|
||||
ModuleRef llmod, &str name,
|
||||
uint cc, TypeRef ty) -> ValueRef {
|
||||
|
|
@ -1108,27 +1076,16 @@ fn trans_native_call(&builder b, @glue_fns glues, ValueRef lltaskptr,
|
|||
&hashmap[str, ValueRef] externs,
|
||||
&type_names tn, ModuleRef llmod, &str name,
|
||||
bool pass_task, &vec[ValueRef] args) -> ValueRef {
|
||||
|
||||
let int n = (vec::len[ValueRef](args) as int);
|
||||
let ValueRef llnative = get_simple_extern_fn(externs, llmod, name, n);
|
||||
llnative = llvm::LLVMConstPointerCast(llnative, T_int());
|
||||
|
||||
let ValueRef llglue;
|
||||
if (pass_task) {
|
||||
llglue = glues.native_glues_rust.(n);
|
||||
} else {
|
||||
llglue = glues.native_glues_cdecl.(n);
|
||||
}
|
||||
let vec[ValueRef] call_args = [llnative];
|
||||
|
||||
if (!pass_task) {
|
||||
call_args += [lltaskptr];
|
||||
}
|
||||
|
||||
let vec[ValueRef] call_args = [];
|
||||
for (ValueRef a in args) {
|
||||
call_args += [b.ZExtOrBitCast(a, T_int())];
|
||||
}
|
||||
|
||||
ret b.FastCall(llglue, call_args);
|
||||
ret b.Call(llnative, call_args);
|
||||
}
|
||||
|
||||
fn trans_non_gc_free(&@block_ctxt cx, ValueRef v) -> result {
|
||||
|
|
@ -8030,16 +7987,6 @@ fn trans_vec_append_glue(@local_ctxt cx, &ast::span sp) {
|
|||
|
||||
fn make_glues(ModuleRef llmod, &type_names tn) -> @glue_fns {
|
||||
ret @rec(yield_glue = decl_glue(llmod, tn, abi::yield_glue_name()),
|
||||
|
||||
native_glues_rust =
|
||||
vec::init_fn[ValueRef](bind decl_native_glue(llmod, tn,
|
||||
abi::ngt_rust, _), abi::n_native_glues + 1 as uint),
|
||||
native_glues_pure_rust =
|
||||
vec::init_fn[ValueRef](bind decl_native_glue(llmod, tn,
|
||||
abi::ngt_pure_rust, _), abi::n_native_glues + 1 as uint),
|
||||
native_glues_cdecl =
|
||||
vec::init_fn[ValueRef](bind decl_native_glue(llmod, tn,
|
||||
abi::ngt_cdecl, _), abi::n_native_glues + 1 as uint),
|
||||
no_op_type_glue = decl_no_op_type_glue(llmod, tn),
|
||||
vec_append_glue = make_vec_append_glue(llmod, tn));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue