2011-05-12 10:24:54 -05:00
|
|
|
import lib::llvm::llvm;
|
|
|
|
import lib::llvm::llvm::ModuleRef;
|
|
|
|
import std::_str;
|
|
|
|
import std::_vec;
|
|
|
|
import std::os::target_os;
|
|
|
|
import util::common::istr;
|
2010-09-23 17:46:31 -05:00
|
|
|
|
|
|
|
const int wordsz = 4;
|
|
|
|
|
|
|
|
fn wstr(int i) -> str {
|
|
|
|
ret istr(i * wordsz);
|
|
|
|
}
|
|
|
|
|
2011-04-28 15:14:04 -05:00
|
|
|
fn start() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret [".cfi_startproc"];
|
2011-04-28 15:14:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn end() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret [".cfi_endproc"];
|
2011-04-28 15:14:04 -05:00
|
|
|
}
|
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
fn save_callee_saves() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["pushl %ebp",
|
2010-09-23 17:46:31 -05:00
|
|
|
"pushl %edi",
|
|
|
|
"pushl %esi",
|
2011-05-16 20:21:22 -05:00
|
|
|
"pushl %ebx"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-04-28 15:14:04 -05:00
|
|
|
fn save_callee_saves_with_cfi() -> vec[str] {
|
|
|
|
auto offset = 8;
|
|
|
|
auto t;
|
2011-05-16 20:21:22 -05:00
|
|
|
t = ["pushl %ebp"];
|
|
|
|
t += [".cfi_def_cfa_offset " + istr(offset)];
|
|
|
|
t += [".cfi_offset %ebp, -" + istr(offset)];
|
2011-04-28 15:14:04 -05:00
|
|
|
|
2011-05-16 20:21:22 -05:00
|
|
|
t += ["pushl %edi"];
|
2011-04-28 15:14:04 -05:00
|
|
|
offset += 4;
|
2011-05-16 20:21:22 -05:00
|
|
|
t += [".cfi_def_cfa_offset " + istr(offset)];
|
2011-04-28 15:14:04 -05:00
|
|
|
|
2011-05-16 20:21:22 -05:00
|
|
|
t += ["pushl %esi"];
|
2011-04-28 15:14:04 -05:00
|
|
|
offset += 4;
|
2011-05-16 20:21:22 -05:00
|
|
|
t += [".cfi_def_cfa_offset " + istr(offset)];
|
2011-04-28 15:14:04 -05:00
|
|
|
|
2011-05-16 20:21:22 -05:00
|
|
|
t += ["pushl %ebx"];
|
2011-04-28 15:14:04 -05:00
|
|
|
offset += 4;
|
2011-05-16 20:21:22 -05:00
|
|
|
t += [".cfi_def_cfa_offset " + istr(offset)];
|
2011-04-28 15:14:04 -05:00
|
|
|
ret t;
|
|
|
|
}
|
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
fn restore_callee_saves() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["popl %ebx",
|
2010-09-23 17:46:31 -05:00
|
|
|
"popl %esi",
|
|
|
|
"popl %edi",
|
2011-05-16 20:21:22 -05:00
|
|
|
"popl %ebp"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
fn load_esp_from_rust_sp_first_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl " + wstr(abi::task_field_rust_sp) + "(%ecx), %esp"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
fn load_esp_from_runtime_sp_first_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl " + wstr(abi::task_field_runtime_sp) + "(%ecx), %esp"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
fn store_esp_to_rust_sp_first_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl %esp, " + wstr(abi::task_field_rust_sp) + "(%ecx)"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
fn store_esp_to_runtime_sp_first_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl %esp, " + wstr(abi::task_field_runtime_sp) + "(%ecx)"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
fn load_esp_from_rust_sp_second_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl " + wstr(abi::task_field_rust_sp) + "(%edx), %esp"];
|
2011-03-09 14:05:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn load_esp_from_runtime_sp_second_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl " + wstr(abi::task_field_runtime_sp) + "(%edx), %esp"];
|
2011-03-09 14:05:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn store_esp_to_rust_sp_second_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl %esp, " + wstr(abi::task_field_rust_sp) + "(%edx)"];
|
2011-03-09 14:05:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn store_esp_to_runtime_sp_second_arg() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl %esp, " + wstr(abi::task_field_runtime_sp) + "(%edx)"];
|
2011-03-09 14:05:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-08 20:09:50 -06:00
|
|
|
/*
|
|
|
|
* This is a bit of glue-code. It should be emitted once per
|
|
|
|
* compilation unit.
|
|
|
|
*
|
|
|
|
* - save regs on C stack
|
|
|
|
* - align sp on a 16-byte boundary
|
|
|
|
* - save sp to task.runtime_sp (runtime_sp is thus always aligned)
|
|
|
|
* - load saved task sp (switch stack)
|
|
|
|
* - restore saved task regs
|
|
|
|
* - return to saved task pc
|
|
|
|
*
|
|
|
|
* Our incoming stack looks like this:
|
|
|
|
*
|
|
|
|
* *esp+4 = [arg1 ] = task ptr
|
|
|
|
* *esp = [retpc ]
|
|
|
|
*/
|
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
fn rust_activate_glue() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl 4(%esp), %ecx # ecx = rust_task"]
|
2010-09-23 17:46:31 -05:00
|
|
|
+ save_callee_saves()
|
2011-03-09 14:05:22 -06:00
|
|
|
+ store_esp_to_runtime_sp_first_arg()
|
|
|
|
+ load_esp_from_rust_sp_first_arg()
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-02-08 20:09:50 -06:00
|
|
|
/*
|
|
|
|
* There are two paths we can arrive at this code from:
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 1. We are activating a task for the first time. When we switch
|
|
|
|
* into the task stack and 'ret' to its first instruction, we'll
|
|
|
|
* start doing whatever the first instruction says. Probably
|
|
|
|
* saving registers and starting to establish a frame. Harmless
|
|
|
|
* stuff, doesn't look at task->rust_sp again except when it
|
2011-03-25 17:48:00 -05:00
|
|
|
* clobbers it during a later native call.
|
2011-02-08 20:09:50 -06:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* 2. We are resuming a task that was descheduled by the yield glue
|
|
|
|
* below. When we switch into the task stack and 'ret', we'll be
|
|
|
|
* ret'ing to a very particular instruction:
|
|
|
|
*
|
|
|
|
* "esp <- task->rust_sp"
|
|
|
|
*
|
|
|
|
* this is the first instruction we 'ret' to after this glue,
|
2011-03-25 17:48:00 -05:00
|
|
|
* because it is the first instruction following *any* native
|
|
|
|
* call, and the task we are activating was descheduled
|
|
|
|
* mid-native-call.
|
2011-02-08 20:09:50 -06:00
|
|
|
*
|
|
|
|
* Unfortunately for us, we have already restored esp from
|
|
|
|
* task->rust_sp and are about to eat the 5 words off the top of
|
|
|
|
* it.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* | ... | <-- where esp will be once we restore + ret, below,
|
|
|
|
* | retpc | and where we'd *like* task->rust_sp to wind up.
|
|
|
|
* | ebp |
|
|
|
|
* | edi |
|
|
|
|
* | esi |
|
|
|
|
* | ebx | <-- current task->rust_sp == current esp
|
|
|
|
*
|
2011-02-22 18:37:01 -06:00
|
|
|
*
|
2011-02-08 20:09:50 -06:00
|
|
|
* This is a problem. If we return to "esp <- task->rust_sp" it
|
|
|
|
* will push esp back down by 5 words. This manifests as a rust
|
|
|
|
* stack that grows by 5 words on each yield/reactivate. Not
|
|
|
|
* good.
|
2011-02-22 18:37:01 -06:00
|
|
|
*
|
2011-02-08 20:09:50 -06:00
|
|
|
* So what we do here is just adjust task->rust_sp up 5 words as
|
|
|
|
* well, to mirror the movement in esp we're about to
|
|
|
|
* perform. That way the "esp <- task->rust_sp" we 'ret' to below
|
|
|
|
* will be a no-op. Esp won't move, and the task's stack won't
|
|
|
|
* grow.
|
|
|
|
*/
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["addl $20, " + wstr(abi::task_field_rust_sp) + "(%ecx)"]
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-02-08 20:09:50 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In most cases, the function we're returning to (activating)
|
2011-03-25 17:48:00 -05:00
|
|
|
* will have saved any caller-saves before it yielded via native call,
|
2011-02-08 20:09:50 -06:00
|
|
|
* so no work to do here. With one exception: when we're initially
|
|
|
|
* activating, the task needs to be in the fastcall 2nd parameter
|
|
|
|
* expected by the rust main function. That's edx.
|
|
|
|
*/
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["mov %ecx, %edx"]
|
2011-02-08 20:09:50 -06:00
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
+ restore_callee_saves()
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["ret"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-02-08 20:09:50 -06:00
|
|
|
/* More glue code, this time the 'bottom half' of yielding.
|
|
|
|
*
|
2011-03-25 17:48:00 -05:00
|
|
|
* We arrived here because an native call decided to deschedule the
|
|
|
|
* running task. So the native call's return address got patched to the
|
2011-02-08 20:09:50 -06:00
|
|
|
* first instruction of this glue code.
|
|
|
|
*
|
2011-03-25 17:48:00 -05:00
|
|
|
* When the native call does 'ret' it will come here, and its esp will be
|
2011-02-08 20:09:50 -06:00
|
|
|
* pointing to the last argument pushed on the C stack before making
|
2011-03-25 17:48:00 -05:00
|
|
|
* the native call: the 0th argument to the native call, which is always
|
|
|
|
* the task ptr performing the native call. That's where we take over.
|
2011-02-08 20:09:50 -06:00
|
|
|
*
|
|
|
|
* Our goal is to complete the descheduling
|
|
|
|
*
|
|
|
|
* - Switch over to the task stack temporarily.
|
|
|
|
*
|
|
|
|
* - Save the task's callee-saves onto the task stack.
|
|
|
|
* (the task is now 'descheduled', safe to set aside)
|
|
|
|
*
|
|
|
|
* - Switch *back* to the C stack.
|
|
|
|
*
|
|
|
|
* - Restore the C-stack callee-saves.
|
|
|
|
*
|
|
|
|
* - Return to the caller on the C stack that activated the task.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
fn rust_yield_glue() -> vec[str] {
|
2011-05-16 20:21:22 -05:00
|
|
|
ret ["movl 0(%esp), %ecx # ecx = rust_task"]
|
2011-03-09 14:05:22 -06:00
|
|
|
+ load_esp_from_rust_sp_first_arg()
|
2010-09-23 17:46:31 -05:00
|
|
|
+ save_callee_saves()
|
2011-03-09 14:05:22 -06:00
|
|
|
+ store_esp_to_rust_sp_first_arg()
|
|
|
|
+ load_esp_from_runtime_sp_first_arg()
|
2010-09-23 17:46:31 -05:00
|
|
|
+ restore_callee_saves()
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["ret"];
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-05-12 10:24:54 -05:00
|
|
|
fn native_glue(int n_args, abi::native_glue_type ngt) -> vec[str] {
|
2011-04-29 18:40:30 -05:00
|
|
|
|
|
|
|
let bool pass_task;
|
|
|
|
alt (ngt) {
|
2011-05-12 10:24:54 -05:00
|
|
|
case (abi::ngt_rust) { pass_task = true; }
|
|
|
|
case (abi::ngt_pure_rust) { pass_task = true; }
|
|
|
|
case (abi::ngt_cdecl) { pass_task = false; }
|
2011-04-29 18:40:30 -05:00
|
|
|
}
|
2010-09-23 17:46:31 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 0, 4, 8, 12 are callee-saves
|
|
|
|
* 16 is retpc
|
2010-11-14 15:41:10 -06:00
|
|
|
* 20 .. (5+i) * 4 are args
|
|
|
|
*
|
|
|
|
* ecx is taskptr
|
|
|
|
* edx is callee
|
|
|
|
*
|
2010-09-23 17:46:31 -05:00
|
|
|
*/
|
|
|
|
|
2011-03-21 16:47:38 -05:00
|
|
|
fn copy_arg(bool pass_task, uint i) -> str {
|
|
|
|
if (i == 0u && pass_task) {
|
2011-03-09 13:16:11 -06:00
|
|
|
ret "movl %edx, (%esp)";
|
|
|
|
}
|
|
|
|
auto dst_off = wstr(0 + (i as int));
|
2011-03-21 16:47:38 -05:00
|
|
|
auto src_off;
|
|
|
|
if (pass_task) {
|
|
|
|
src_off = wstr(4 + (i as int));
|
|
|
|
} else {
|
|
|
|
src_off = wstr(5 + (i as int));
|
|
|
|
}
|
2011-05-16 20:21:22 -05:00
|
|
|
auto m = ["movl " + src_off + "(%ebp),%eax",
|
|
|
|
"movl %eax," + dst_off + "(%esp)"];
|
2011-05-12 10:24:54 -05:00
|
|
|
ret _str::connect(m, "\n\t");
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-21 16:47:38 -05:00
|
|
|
auto carg = bind copy_arg(pass_task, _);
|
2010-09-23 17:46:31 -05:00
|
|
|
|
|
|
|
ret
|
2011-04-28 15:14:04 -05:00
|
|
|
start()
|
|
|
|
+ save_callee_saves_with_cfi()
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["movl %esp, %ebp # ebp = rust_sp"]
|
|
|
|
+ [".cfi_def_cfa_register %ebp"]
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
+ store_esp_to_rust_sp_second_arg()
|
|
|
|
+ load_esp_from_runtime_sp_second_arg()
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["subl $" + wstr(n_args) + ", %esp # esp -= args",
|
|
|
|
"andl $~0xf, %esp # align esp down"]
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-05-12 10:24:54 -05:00
|
|
|
+ _vec::init_fn[str](carg, (n_args) as uint)
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["movl %edx, %edi # save task from edx to edi",
|
2011-03-09 14:05:22 -06:00
|
|
|
"call *%ecx # call *%ecx",
|
2011-05-16 20:21:22 -05:00
|
|
|
"movl %edi, %edx # restore edi-saved task to edx"]
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-03-09 14:05:22 -06:00
|
|
|
+ load_esp_from_rust_sp_second_arg()
|
2010-09-23 17:46:31 -05:00
|
|
|
+ restore_callee_saves()
|
2011-05-16 20:21:22 -05:00
|
|
|
+ ["ret"]
|
2011-04-28 15:14:04 -05:00
|
|
|
+ end();
|
2010-09-23 17:46:31 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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" +
|
2011-05-12 10:24:54 -05:00
|
|
|
"\t" + _str::connect(insns, "\n\t");
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-12 10:24:54 -05:00
|
|
|
fn decl_native_glue(int align, str prefix, abi::native_glue_type ngt, uint n)
|
2011-04-29 18:40:30 -05:00
|
|
|
-> str {
|
2010-09-23 19:16:34 -05:00
|
|
|
let int i = n as int;
|
|
|
|
ret decl_glue(align, prefix,
|
2011-05-12 10:24:54 -05:00
|
|
|
abi::native_glue_name(i, ngt),
|
2011-04-29 18:40:30 -05:00
|
|
|
native_glue(i, ngt));
|
2010-09-23 19:16:34 -05:00
|
|
|
}
|
|
|
|
|
2010-11-05 20:29:18 -05:00
|
|
|
fn get_symbol_prefix() -> str {
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "macos") ||
|
|
|
|
_str::eq(target_os(), "win32")) {
|
2010-11-05 20:29:18 -05:00
|
|
|
ret "_";
|
|
|
|
} else {
|
|
|
|
ret "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
fn get_module_asm() -> str {
|
|
|
|
auto align = 4;
|
2010-10-22 18:15:06 -05:00
|
|
|
|
2010-11-05 20:29:18 -05:00
|
|
|
auto prefix = get_symbol_prefix();
|
2010-09-23 17:46:31 -05:00
|
|
|
|
|
|
|
auto glues =
|
2011-05-16 20:21:22 -05:00
|
|
|
[decl_glue(align, prefix,
|
2011-05-12 10:24:54 -05:00
|
|
|
abi::activate_glue_name(),
|
2010-09-23 17:46:31 -05:00
|
|
|
rust_activate_glue()),
|
|
|
|
|
|
|
|
decl_glue(align, prefix,
|
2011-05-12 10:24:54 -05:00
|
|
|
abi::yield_glue_name(),
|
2011-05-16 20:21:22 -05:00
|
|
|
rust_yield_glue())]
|
2010-09-23 19:16:34 -05:00
|
|
|
|
2011-05-12 10:24:54 -05:00
|
|
|
+ _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);
|
2010-09-23 17:46:31 -05:00
|
|
|
|
2011-03-21 16:47:38 -05:00
|
|
|
|
2011-05-12 10:24:54 -05:00
|
|
|
ret _str::connect(glues, "\n\n");
|
2010-09-23 17:46:31 -05:00
|
|
|
}
|
|
|
|
|
2011-03-11 17:35:20 -06:00
|
|
|
fn get_meta_sect_name() -> str {
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "macos")) {
|
2011-03-11 17:35:20 -06:00
|
|
|
ret "__DATA,__note.rustc";
|
|
|
|
}
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "win32")) {
|
2011-03-11 17:35:20 -06:00
|
|
|
ret ".note.rustc";
|
|
|
|
}
|
|
|
|
ret ".note.rustc";
|
|
|
|
}
|
|
|
|
|
2010-12-03 15:51:46 -06:00
|
|
|
fn get_data_layout() -> str {
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "macos")) {
|
2011-05-05 14:45:34 -05:00
|
|
|
ret "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" +
|
|
|
|
"-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +
|
|
|
|
"-n8:16:32";
|
2010-12-03 15:51:46 -06:00
|
|
|
}
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "win32")) {
|
2010-12-03 15:51:46 -06:00
|
|
|
ret "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";
|
|
|
|
}
|
|
|
|
ret "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_target_triple() -> str {
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "macos")) {
|
2010-12-03 15:51:46 -06:00
|
|
|
ret "i686-apple-darwin";
|
|
|
|
}
|
2011-05-12 10:24:54 -05:00
|
|
|
if (_str::eq(target_os(), "win32")) {
|
2010-12-03 15:51:46 -06:00
|
|
|
ret "i686-pc-mingw32";
|
|
|
|
}
|
2011-05-05 19:20:27 -05:00
|
|
|
ret "i686-unknown-linux-gnu";
|
2010-12-03 15:51:46 -06:00
|
|
|
}
|
|
|
|
|
2010-09-23 19:16:34 -05:00
|
|
|
|
2010-09-23 17:46:31 -05:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
2011-03-25 17:07:27 -05:00
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
2010-09-23 17:46:31 -05:00
|
|
|
// End:
|
|
|
|
//
|