Commit 1fd56fe4 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Implemented Current_stack common instruction

parent 5584d466
Pipeline #924 canceled with stages
......@@ -101,7 +101,9 @@ impl Instruction {
TailCall(_) | Branch1(_) | Branch2 { .. } | Watchpoint { .. } | WPBranch { .. } |
Call { .. } | CCall { .. }| SwapStackExpr{..}| SwapStackExc { .. } | SwapStackKill { .. } | Switch { .. } | ExnInstruction { .. } |
CommonInst_GetThreadLocal | CommonInst_SetThreadLocal(_) | CommonInst_Pin(_) | CommonInst_Unpin(_) |
CommonInst_GetAddr(_) | PrintHex(_) | SetRetval(_) => true,
CommonInst_GetAddr(_) | PrintHex(_) | SetRetval(_) |
CurrentStack // Just heir to prevent interferance with swapstacks
=> true,
_ => false
}
}
......
......@@ -1457,7 +1457,25 @@ impl<'a> InstructionSelection {
vm
);
}
Instruction_::CurrentStack => {
trace!("instsel on CURRENT_STACK");
// get thread local
let tl = self.emit_get_threadlocal(f_context, vm);
let tmp_res = self.get_result_value(node, 0);
// load [tl + STACK_OFFSET] -> tmp_res
// WARNING: This assumes that an Option<Box<MuStack>> is actually just a pointer to a MuStack
emit_load_base_offset(
self.backend.as_mut(),
&tmp_res,
&tl,
*thread::STACK_OFFSET as i64,
f_context,
vm
);
}
Instruction_::CommonInst_GetThreadLocal => {
trace!("instsel on GETTHREADLOCAL");
// get thread local
......@@ -2044,6 +2062,7 @@ impl<'a> InstructionSelection {
is_exception,
ref args
} => {
trace!("Instruction Selection on SWPASTACK-EXPR");
self.emit_swapstack(
is_exception, // is_exception
false, // is_kill
......@@ -2063,6 +2082,7 @@ impl<'a> InstructionSelection {
ref args,
ref resume
} => {
trace!("Instruction Selection on SWPASTACK-EXC");
self.emit_swapstack(
is_exception, // is_exception
false, // is_kill
......@@ -2082,6 +2102,7 @@ impl<'a> InstructionSelection {
is_exception,
ref args
} => {
trace!("Instruction Selection on SWPASTACK-KILL");
self.emit_swapstack(
is_exception, // is_exception
true, // is_kill
......@@ -4362,10 +4383,6 @@ impl<'a> InstructionSelection {
vm
);
} else {
// Pass new_sp and cur_stack in X9 and X10 respectivley
self.backend.emit_mov(&X9, &new_sp);
self.backend.emit_mov(&X10, &cur_stack);
// Prepare arguments
let mut arg_values = vec![];
let arg_nodes = args.iter().map(|a| ops[*a].clone()).collect::<Vec<_>>();
......@@ -4391,6 +4408,10 @@ impl<'a> InstructionSelection {
f_context,
vm
);
// Pass new_sp and cur_stack in X9 and X10 respectivley
self.backend.emit_mov(&X9, &new_sp);
self.backend.emit_mov(&X10, &cur_stack);
arg_regs.push(X9.clone());
arg_regs.push(X10.clone());
......
......@@ -163,12 +163,6 @@ impl MuStack {
);
}
debug!("creating stack {} with entry address {:?}", id, func_addr);
debug!("overflow_guard : {}", overflow_guard);
debug!("lower_bound : {}", lower_bound);
debug!("upper_bound : {}", upper_bound);
debug!("underflow_guard: {}", underflow_guard);
// Set up the stack
let mut sp = upper_bound;
sp -= stack_arg_size; // Allocate space for the arguments
......@@ -184,6 +178,13 @@ impl MuStack {
// Reserve space for callee saved registers (they will be loaded with undefined values)
sp -= WORD_SIZE*CALLEE_SAVED_COUNT;
debug!("creating stack {} with entry address {:?}", id, func_addr);
debug!("overflow_guard : {}", overflow_guard);
debug!("lower_bound : {}", lower_bound);
debug!("stack_pointer : {}", sp);
debug!("upper_bound : {}", upper_bound);
debug!("underflow_guard: {}", underflow_guard);
MuStack {
hdr: MuEntityHeader::unnamed(id),
func: None,
......@@ -347,6 +348,8 @@ lazy_static! {
offset_of!(MuThread=>native_sp_loc).get_byte_offset();
pub static ref USER_TLS_OFFSET : usize =
offset_of!(MuThread=>user_tls).get_byte_offset();
pub static ref STACK_OFFSET : usize =
offset_of!(MuThread=>stack).get_byte_offset();
pub static ref EXCEPTION_OBJ_OFFSET : usize =
offset_of!(MuThread=>exception_obj).get_byte_offset();
}
......@@ -670,7 +673,10 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_ret(new_stack: *mut MuStack)
// Save the current stack, don't deallocate it
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack));
((*new_stack).sp, &mut (*cur_stack).sp)
let new_sp = (*new_stack).sp;
let old_sp_loc =&mut (*cur_stack).sp;
trace!("ISAAC: muentry_prepare_swapstack_ret({}) -> ({}, {})", Address::from_ptr(new_stack), new_sp, Address::from_ref(old_sp_loc));
(new_sp, old_sp_loc)
}
// This prepares a thread for a swap stack operation that kills the current stack
......
......@@ -16,6 +16,7 @@ from util import execute, compile_bundle, load_bundle, get_function;
import pytest;
import ctypes;
# passes on aarch64
def test_swapstack_simple():
compile_bundle(
"""
......@@ -34,19 +35,20 @@ def test_swapstack_simple():
""", "test_swapstack_simple");
assert(execute("test_swapstack_simple", []) == 3);
# passes on aarch64
def test_swapstack_swap_back():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
SWAPSTACK s KILL_OLD PASS_VALUES<>()
SWAPSTACK s KILL_OLD PASS_VALUES<>()
}
.funcdef test_swapstack_swap_back <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
cs = COMMINST current_stack()
s = COMMINST new_stack<[(stackref)->()]>(new_func)
cs = COMMINST uvm.current_stack()
s = COMMINST uvm.new_stack<[(stackref)->()]>(new_func)
SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs)
RET <int<32>>3
......@@ -54,42 +56,26 @@ def test_swapstack_swap_back():
""", "test_swapstack_swap_back");
assert(execute("test_swapstack_swap_back", []) == 3);
# segfaults on aarch64
def test_swapstack_pass_vals():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32> 3)
SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32>> 3)
}
.funcdef test_swapstack_pass_vals <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
s = COMMINST new_stack<[()->()]>(new_func)
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>() EXC(body(r))
RET r
}
""", "test_swapstack_pass_vals");
assert(execute("test_swapstack_pass_vals", []) == 3);
def test_swapstack_pass_vals():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32> 3)
}
.funcdef test_swapstack_pass_vals <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
s = COMMINST new_stack<[()->()]>(new_func)
s = COMMINST uvm.new_stack<[(stackref)->()]>(new_func)
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>()
RET r
}
""", "test_swapstack_pass_vals");
assert(execute("test_swapstack_pass_vals", []) == 3);
# Work in progress...
def test_swapstack_throw():
compile_bundle(
"""
......@@ -102,8 +88,13 @@ def test_swapstack_throw():
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
s = COMMINST new_stack<[()->()]>(new_func)
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>() EXC(norm(r))
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>() EXC(nor_dest(r) exc_dest())
RET r
nor_dest(<int<32>>):
RET <int<32>>0
exc_dest()[exc_param]:
REFCAST <from_ty tot__ty>
RET <int<32>>0
}
""", "test_swapstack_pass_vals");
assert(execute("test_swapstack_pass_vals", []) == 3);
\ No newline at end of file
assert(execute("test_swapstack_pass_vals", []) == 3);
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