aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-23 15:46:31 -0700
committerGraydon Hoare <[email protected]>2010-09-23 15:46:31 -0700
commit46e46d0b49de8e245d091f7062dfc28ab71e869e (patch)
tree5ca0d7ab10eb2a89b9c2a299ff3490eac912bf5d /src/comp
parentMore fleshing-out on rustc.me.trans. Emitting modules and fns corresponding t... (diff)
downloadrust-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.rs46
-rw-r--r--src/comp/back/x86.rs159
-rw-r--r--src/comp/driver/rustc.rs7
-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.rc11
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 {