Commit 0ca6181a authored by qinsoon's avatar qinsoon

NEWSTACK/NEWTHREAD implemented for x64, test_newthread_simple works

parent 79589ae4
......@@ -1012,6 +1012,23 @@ impl Value {
}
}
pub fn is_const_zero(&self) -> bool {
match self.v {
Value_::Constant(Constant::Int(val)) if val == 0 => true,
Value_::Constant(Constant::Double(val)) if val == 0f64 => true,
Value_::Constant(Constant::Float(val)) if val == 0f32 => true,
Value_::Constant(Constant::IntEx(ref vec)) => {
if vec.iter().all(|x| *x == 0) {
true
} else {
false
}
}
Value_::Constant(Constant::NullRef) => true,
_ => false
}
}
/// disguises a value as another type.
/// This is usually used for treat an integer type as an integer of a different length
/// This method is unsafe
......
......@@ -25,12 +25,16 @@ pub mod c {
/// computes arguments for the function signature,
/// returns a vector of CallConvResult for each argument type
pub fn compute_arguments(sig: &MuFuncSig) -> Vec<CallConvResult> {
compute_arguments_by_type(&sig.arg_tys)
}
pub fn compute_arguments_by_type(tys: &Vec<P<MuType>>) -> Vec<CallConvResult> {
let mut ret = vec![];
let mut gpr_arg_count = 0;
let mut fpr_arg_count = 0;
for ty in sig.arg_tys.iter() {
for ty in tys.iter() {
let arg_reg_group = RegGroup::get_from_ty(ty);
if arg_reg_group == RegGroup::GPR {
......@@ -127,9 +131,24 @@ pub mod c {
ret
}
pub fn compute_stack_args(sig: &MuFuncSig, vm: &VM) -> (ByteSize, Vec<ByteSize>) {
let callconv = compute_arguments(sig);
let mut stack_arg_tys = vec![];
for i in 0..callconv.len() {
let ref cc = callconv[i];
match cc {
&CallConvResult::STACK => stack_arg_tys.push(sig.arg_tys[i].clone()),
_ => {}
}
}
compute_stack_args_by_type(&stack_arg_tys, vm)
}
/// computes the return area on the stack for the function signature,
/// returns a tuple of (size, callcand offset for each stack arguments)
pub fn compute_stack_args(
pub fn compute_stack_args_by_type(
stack_arg_tys: &Vec<P<MuType>>,
vm: &VM
) -> (ByteSize, Vec<ByteSize>) {
......
......@@ -17,7 +17,7 @@
#if defined (__linux__)
#define CNAME(n) n
#define CNAME(n) n
.macro begin_func n
.text
......@@ -31,9 +31,17 @@ CNAME(\n):
.size CNAME(\n), .-CNAME(\n)
.endm
.macro jmp_to target
jmp CNAME(\target@PLT)
.endm
.macro call_to target
call CNAME(\target@PLT)
.endm
#elif defined (__APPLE__)
#define CNAME(n) _##n
#define CNAME(n) _##n
.macro begin_func n
.text
......@@ -45,8 +53,14 @@ CNAME(\n):
.macro end_func n
.endm
.macro jmp_to target
jmp CNAME(\target)
.endm
.macro call_to target
call CNAME(\target)
.endm
#else
#error "Only Linux and OSX are supported."
#endif
; vim: ft=asm
......@@ -75,9 +75,8 @@ begin_func muthread_start_normal
BR LR
end_func muthread_start_normal
# starts a muthread that passes values to the target
# muthread_start_throw(exception: Address, new_sp: Address, old_sp_loc: &mut Adress)
# starts a muthread with an exception thrown
# muthread_start_exceptional(exception: Address, new_sp: Address, old_sp_loc: &mut Adress)
# X0 X1 X2
begin_func muthread_start_exceptional
enter_frame
......
......@@ -14,6 +14,12 @@
#include "asm_common_x64.S.inc"
# _get_current_frame_bp() -> Address
begin_func get_current_frame_bp
movq %rbp, %rax
ret
end_func get_current_frame_bp
# muthread_start_normal(new_sp: Address, old_sp_loc: Address)
# %rdi %rsi
begin_func muthread_start_normal
......@@ -66,6 +72,32 @@ begin_func muthread_start_normal
call *%r10
end_func muthread_start_normal
# starts a muthread with an exception thrown
# muthread_start_exceptional(exception: Address, new_sp: Address, old_sp_loc: &mut Address)
# %rdi %rsi %rdx
begin_func muthread_start_exceptional
# -- on old stack --
# C calling convention - enter frame
pushq %rbp
movq %rsp, %rbp
# save callee saved registers
pushq %rbx
pushq %r12
pushq %r13
pushq %r14
pushq %r15
# save SP to old_sp_loc
movq %rsp, (%rdx)
# swap to new stack
movq %rsi, %rsp
subq 48, %rsp
jmp_to throw_exception_internal
end_func muthread_start_exceptional
# muentry_thread_exit(old_sp: Address)
# %rdi
begin_func muentry_thread_exit
......@@ -81,12 +113,6 @@ begin_func muentry_thread_exit
ret
end_func muentry_thread_exit
# _get_current_frame_bp() -> Address
begin_func get_current_frame_bp
movq %rbp, %rax
ret
end_func get_current_frame_bp
# muentry_throw_exception(obj: Address)
# %rdi
begin_func muentry_throw_exception
......@@ -102,14 +128,9 @@ begin_func muentry_throw_exception
# %rsp points to %rbx, pass this as 2nd argument
movq %rbp, %rsi
#if defined (__linux__)
jmp CNAME(throw_exception_internal@PLT)
#elif defined (__APPLE__)
jmp CNAME(throw_exception_internal)
#else
#error "Only Linux and OSX are supported. "
#endif
jmp_to throw_exception_internal
# won't return
end_func muentry_throw_exception
# _exception_restore(dest: Address, callee_saved: *const Word, rsp: Address) -> !
# %rdi %rsi %rdx
......
......@@ -185,9 +185,9 @@ impl MuStack {
/// sets up arguments for the stack's entry function, so it is ready to be executed.
/// We use a special calling convention for the entry function: we push all the argument
/// registers for the platform to the stack. If the argument register is used, we get
/// its value and push the value. Otherwise we push an empty value (0). swap_to_mu_stack
/// its value and push the value. Otherwise we push an empty value (0). muthread_start_normal
/// will consume those values on the stack by popping them one by one.
/// NOTE: any changes to here need to be reflected in swap_to_mu_stack, which consumes
/// NOTE: any changes to here need to be reflected in muthread_start_normal, which consumes
/// those values pushed to the stack
pub fn setup_args(&mut self, vals: Vec<ValueLocation>) {
use utils::Word;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment