diff options
| author | Graydon Hoare <[email protected]> | 2010-09-23 15:46:31 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-09-23 15:46:31 -0700 |
| commit | 46e46d0b49de8e245d091f7062dfc28ab71e869e (patch) | |
| tree | 5ca0d7ab10eb2a89b9c2a299ff3490eac912bf5d /src/comp | |
| parent | More fleshing-out on rustc.me.trans. Emitting modules and fns corresponding t... (diff) | |
| download | rust-46e46d0b49de8e245d091f7062dfc28ab71e869e.tar.xz rust-46e46d0b49de8e245d091f7062dfc28ab71e869e.zip | |
Translate a bunch of the material (lltrans, llasm, abi) from rustboot to rustc, and move files around.
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/back/abi.rs | 46 | ||||
| -rw-r--r-- | src/comp/back/x86.rs | 159 | ||||
| -rw-r--r-- | src/comp/driver/rustc.rs | 7 | ||||
| -rw-r--r-- | src/comp/front/ast.rs (renamed from src/comp/fe/ast.rs) | 0 | ||||
| -rw-r--r-- | src/comp/front/lexer.rs (renamed from src/comp/fe/lexer.rs) | 0 | ||||
| -rw-r--r-- | src/comp/front/parser.rs (renamed from src/comp/fe/parser.rs) | 0 | ||||
| -rw-r--r-- | src/comp/front/token.rs (renamed from src/comp/fe/token.rs) | 0 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs (renamed from src/comp/me/trans.rs) | 21 | ||||
| -rw-r--r-- | src/comp/rustc.rc | 11 |
9 files changed, 232 insertions, 12 deletions
diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs new file mode 100644 index 00000000..157bf876 --- /dev/null +++ b/src/comp/back/abi.rs @@ -0,0 +1,46 @@ + +const int rc_base_field_refcnt = 0; + +const int task_field_refcnt = 0; +const int task_field_stk = 2; +const int task_field_runtime_sp = 3; +const int task_field_rust_sp = 4; +const int task_field_gc_alloc_chain = 5; +const int task_field_dom = 6; +const int n_visible_task_fields = 7; + +const int dom_field_interrupt_flag = 1; + +const int frame_glue_fns_field_mark = 0; +const int frame_glue_fns_field_drop = 1; +const int frame_glue_fns_field_reloc = 2; + +const int box_rc_field_refcnt = 0; +const int box_rc_field_body = 1; + +const int general_code_alignment = 16; + +const int vec_elt_rc = 0; +const int vec_elt_alloc = 1; +const int vec_elt_fill = 2; +const int vec_elt_data = 3; + +const int calltup_elt_out_ptr = 0; +const int calltup_elt_task_ptr = 1; +const int calltup_elt_indirect_args = 2; +const int calltup_elt_ty_params = 3; +const int calltup_elt_args = 4; +const int calltup_elt_iterator_args = 5; + +const int worst_case_glue_call_args = 7; + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// diff --git a/src/comp/back/x86.rs b/src/comp/back/x86.rs new file mode 100644 index 00000000..fcf65cc0 --- /dev/null +++ b/src/comp/back/x86.rs @@ -0,0 +1,159 @@ +import lib.llvm.llvm; +import lib.llvm.llvm.ModuleRef; +import std._str; +import std._int; +import std._vec; + +const int wordsz = 4; + +fn istr(int i) -> str { + ret _int.to_str(i, 10u); +} + +fn wstr(int i) -> str { + ret istr(i * wordsz); +} + +fn save_callee_saves() -> vec[str] { + ret vec("pushl %ebp", + "pushl %edi", + "pushl %esi", + "pushl %ebx"); +} + +fn restore_callee_saves() -> vec[str] { + ret vec("popl %ebx", + "popl %esi", + "popl %edi", + "popl %ebp"); +} + +fn load_esp_from_rust_sp() -> vec[str] { + ret vec("movl " + wstr(abi.task_field_rust_sp) + "(%edx), %esp"); +} + +fn load_esp_from_runtime_sp() -> vec[str] { + ret vec("movl " + wstr(abi.task_field_runtime_sp) + "(%edx), %esp"); +} + +fn store_esp_to_rust_sp() -> vec[str] { + ret vec("movl %esp, " + wstr(abi.task_field_rust_sp) + "(%edx)"); +} + +fn store_esp_to_runtime_sp() -> vec[str] { + ret vec("movl %esp, " + wstr(abi.task_field_runtime_sp) + "(%edx)"); +} + +fn rust_activate_glue() -> vec[str] { + ret vec("movl 4(%esp), %edx # edx = rust_task") + + save_callee_saves() + + store_esp_to_runtime_sp() + + load_esp_from_rust_sp() + + // This 'add' instruction is a bit surprising. + // See lengthy comment in boot/be/x86.ml activate_glue. + + vec("addl $20, " + wstr(abi.task_field_rust_sp) + "(%edx)") + + + restore_callee_saves() + + vec("ret"); +} + +fn rust_yield_glue() -> vec[str] { + ret vec("movl 0(%esp), %edx # edx = rust_task") + + load_esp_from_rust_sp() + + save_callee_saves() + + store_esp_to_rust_sp() + + load_esp_from_runtime_sp() + + restore_callee_saves() + + vec("ret"); +} + +fn upcall_glue(int n_args) -> vec[str] { + + /* + * 0, 4, 8, 12 are callee-saves + * 16 is retpc + * 20 is taskptr + * 24 is callee + * 28 .. (7+i) * 4 are args + */ + + fn copy_arg(uint i) -> str { + auto off = wstr(7 + (i as int)); + auto m = vec("movl " + off + "(%ebp),%edx", + "movl %edx," + off + "(%esp)"); + ret _str.connect(m, "\n\t"); + } + + auto carg = copy_arg; + + ret + save_callee_saves() + + + vec("movl %esp, %ebp # ebp = rust_sp", + "movl 20(%esp), %edx # edx = rust_task") + + + store_esp_to_rust_sp() + + load_esp_from_runtime_sp() + + + vec("subl $" + wstr(n_args + 1) + ", %esp # esp -= args", + "andl $~0xf, %esp # align esp down", + "movl %edx, (%esp) # arg[0] = rust_task ") + + + _vec.init_fn[str](carg, n_args as uint) + + + vec("movl 24(%ebp), %edx # edx = callee", + "call *%edx # call *%edx", + "movl 20(%ebp), %edx # edx = rust_task") + + + load_esp_from_rust_sp() + + restore_callee_saves() + + vec("ret"); + +} + + +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 get_module_asm() -> str { + auto align = 4; + auto prefix = ""; + + auto glues = + vec(decl_glue(align, prefix, + "rust_activate_glue", + rust_activate_glue()), + + decl_glue(align, prefix, + "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; + } + + ret _str.connect(glues, "\n\n"); +} + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index c59d5b56..e3eb10cf 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -1,8 +1,8 @@ // -*- rust -*- -import fe.parser; -import fe.token; -import me.trans; +import front.parser; +import front.token; +import middle.trans; fn main(vec[str] args) { @@ -16,7 +16,6 @@ fn main(vec[str] args) { for (str filename in args) { if (i > 0) { auto p = parser.new_parser(sess, filename); - log "opened file: " + filename; auto crate = parser.parse_crate(p); trans.trans_crate(sess, crate); } diff --git a/src/comp/fe/ast.rs b/src/comp/front/ast.rs index 327570d6..327570d6 100644 --- a/src/comp/fe/ast.rs +++ b/src/comp/front/ast.rs diff --git a/src/comp/fe/lexer.rs b/src/comp/front/lexer.rs index d058db4a..d058db4a 100644 --- a/src/comp/fe/lexer.rs +++ b/src/comp/front/lexer.rs diff --git a/src/comp/fe/parser.rs b/src/comp/front/parser.rs index ab2e15e3..ab2e15e3 100644 --- a/src/comp/fe/parser.rs +++ b/src/comp/front/parser.rs diff --git a/src/comp/fe/token.rs b/src/comp/front/token.rs index b9b2fa07..b9b2fa07 100644 --- a/src/comp/fe/token.rs +++ b/src/comp/front/token.rs diff --git a/src/comp/me/trans.rs b/src/comp/middle/trans.rs index 57213d93..1b1c5b2d 100644 --- a/src/comp/me/trans.rs +++ b/src/comp/middle/trans.rs @@ -3,8 +3,9 @@ import std._vec; import std._str.rustrt.sbuf; import std._vec.rustrt.vbuf; -import fe.ast; +import front.ast; import driver.session; +import back.x86; import lib.llvm.llvm; import lib.llvm.builder; @@ -36,10 +37,12 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef { False()); } +type terminator = fn(&trans_ctxt cx, builder b); + fn trans_log(&trans_ctxt cx, builder b, &ast.atom a) { } -fn trans_stmt(&trans_ctxt cx, builder b, &ast.stmt s) { +fn trans_stmt(&trans_ctxt cx, builder b, &ast.stmt s, terminator t) { alt (s) { case (ast.stmt_log(?a)) { trans_log(cx, b, *a); @@ -50,15 +53,20 @@ fn trans_stmt(&trans_ctxt cx, builder b, &ast.stmt s) { } } -fn trans_block(&trans_ctxt cx, ValueRef llfn, &ast.block b) { +fn default_terminate(&trans_ctxt cx, builder b) { + b.RetVoid(); +} + +fn trans_block(&trans_ctxt cx, ValueRef llfn, &ast.block b, terminator t) { let BasicBlockRef llbb = llvm.LLVMAppendBasicBlock(llfn, _str.buf("")); let BuilderRef llbuild = llvm.LLVMCreateBuilder(); llvm.LLVMPositionBuilderAtEnd(llbuild, llbb); auto bld = builder(llbuild); for (@ast.stmt s in b) { - trans_stmt(cx, bld, *s); + trans_stmt(cx, bld, *s, t); } + t(cx, bld); } fn trans_fn(&trans_ctxt cx, &ast._fn f) { @@ -66,7 +74,8 @@ fn trans_fn(&trans_ctxt cx, &ast._fn f) { let TypeRef llty = T_fn(args, T_nil()); let ValueRef llfn = llvm.LLVMAddFunction(cx.llmod, _str.buf(cx.path), llty); - trans_block(cx, llfn, f.body); + auto term = default_terminate; + trans_block(cx, llfn, f.body, term); } fn trans_item(&trans_ctxt cx, &str name, &ast.item item) { @@ -92,6 +101,8 @@ fn trans_crate(session.session sess, ast.crate crate) { llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"), llvm.LLVMGetGlobalContext()); + llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm())); + auto cx = rec(sess=sess, llmod=llmod, path=""); trans_mod(cx, crate.module); diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index c4e7c7e6..cf2c25ae 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -3,17 +3,22 @@ use std; -mod fe { +mod front { mod ast; mod lexer; mod parser; mod token; } -mod me { +mod middle { mod trans; } +mod back { + mod abi; + mod x86; +} + mod driver { mod rustc; mod session; @@ -24,7 +29,7 @@ mod util { } auth driver.rustc.main = state; -auth me.trans = unsafe; +auth middle.trans = unsafe; mod lib { |