Translate a bunch of the material (lltrans, llasm, abi) from rustboot to rustc, and move files around.

This commit is contained in:
Graydon Hoare 2010-09-23 15:46:31 -07:00
parent 2c514f33f2
commit 46e46d0b49
9 changed files with 232 additions and 12 deletions

46
src/comp/back/abi.rs Normal file
View file

@ -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:
//

159
src/comp/back/x86.rs Normal file
View file

@ -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:
//

View file

@ -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);
}

View file

@ -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);

View file

@ -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 {