Commit 6e368103 authored by qinsoon's avatar qinsoon

Merge branch 'swapstack' of gitlab.anu.edu.au:mu/mu-impl-fast into swapstack

parents dac9704d 087fd433
......@@ -2473,7 +2473,7 @@ impl CodeGenerator for ASMCodeGen {
let mut ret = ret;
ret.push(LR.clone());
let asm = format!("B {}", func);
let asm = format!("/*CALL*/ B {}", func);
self.internal_call(callsite, asm, pe, args, ret, None, may_return)
}
......@@ -2520,7 +2520,7 @@ impl CodeGenerator for ASMCodeGen {
ret.push(LR.clone());
let (reg1, id1, loc1) = self.prepare_reg(func, 3 + 1);
let asm = format!("BR {}", reg1);
let asm = format!("/*CALL*/ BR {}", reg1);
self.internal_call(callsite, asm, pe, args, ret, Some((id1, loc1)), may_return)
}
......
......@@ -4435,69 +4435,60 @@ impl<'a> InstructionSelection {
if is_exception {
assert!(arg_values.len() == 1);
//Reserve temporary space for the exception throwing routine
emit_sub_u64(self.backend.as_mut(), &SP, &SP, (WORD_SIZE*CALLEE_SAVED_COUNT) as u64);
// Throw the exception
self.emit_runtime_entry(
&entrypoints::THROW_EXCEPTION_INTERNAL,
vec![arg_values[0].clone(), new_sp.clone()],
Some(vec![]),
Some(node),
f_context,
vm
);
// Pass the base of this area as an extra argument
arg_values.push(new_sp.clone());
} else {
self.backend.emit_pop_pair(&FP, &LR, &SP);
}
// Emit precall convention
let arg_tys = arg_nodes.iter().map(|a| a.ty()).collect::<Vec<_>>();
let (stack_arg_size, arg_regs) = self.emit_precall_convention(
&new_sp,
// The frame contains space for all callee saved registers (including the FP and LR)
((CALLEE_SAVED_COUNT + 2) * POINTER_SIZE) as isize,
false,
&arg_values,
&arg_tys,
0,
f_context,
vm
);
// Emit precall convention
let arg_tys = arg_values.iter().map(|a| a.ty.clone()).collect::<Vec<_>>();
let (stack_arg_size, arg_regs) = self.emit_precall_convention(
&new_sp,
// The frame contains space for all callee saved registers (including the FP and LR)
((CALLEE_SAVED_COUNT + 2) * POINTER_SIZE) as isize,
false,
&arg_values,
&arg_tys,
0,
f_context,
vm
);
let potentially_excepting = {
if resumption.is_some() {
let target_id = resumption.unwrap().exn_dest.target;
Some(f_content.get_block(target_id).name())
} else {
None
}
};
let potentially_excepting = {
if resumption.is_some() {
let target_id = resumption.unwrap().exn_dest.target;
Some(f_content.get_block(target_id).name())
} else {
None
}
};
// Call the function that swaps the stack
let callsite = {
if vm.is_doing_jit() {
unimplemented!()
// Call the function that swaps the stack
let callsite = {
if vm.is_doing_jit() {
unimplemented!()
} else {
if is_exception {
// Throw an exception, don't call the swapee's resumption point
self.backend.emit_b_call(callsite_label, "throw_exception_internal".to_string(), potentially_excepting, arg_regs, ALL_USABLE_MACHINE_REGS.to_vec(), true, false)
} else {
let caller_saved = if is_kill {
vec![]
} else {
ALL_USABLE_MACHINE_REGS.to_vec()
};
self.backend.emit_br_call(callsite_label, &LR, potentially_excepting, arg_regs, caller_saved, false)
self.backend.emit_br_call(callsite_label, &LR, potentially_excepting, arg_regs, ALL_USABLE_MACHINE_REGS.to_vec(), false)
}
};
}
};
if resumption.is_some() {
let ref exn_dest = resumption.as_ref().unwrap().exn_dest;
let target_block = exn_dest.target;
if resumption.is_some() {
let ref exn_dest = resumption.as_ref().unwrap().exn_dest;
let target_block = exn_dest.target;
self.current_callsites.push_back((callsite.unwrap().to_relocatable(), target_block, stack_arg_size));
} else if !is_kill {
self.current_callsites.push_back((callsite.unwrap().to_relocatable(), 0, stack_arg_size));
}
self.current_callsites.push_back((callsite.unwrap().to_relocatable(), target_block, stack_arg_size));
} else if !is_kill {
self.current_callsites.push_back((callsite.unwrap().to_relocatable(), 0, stack_arg_size));
}
if !is_kill {
self.emit_unload_arguments(inst.value.as_ref().unwrap(), res_locs, f_context, vm);
emit_add_u64(self.backend.as_mut(), &SP, &SP, res_stack_size as u64);
......
......@@ -582,9 +582,30 @@ fn copy_inline_blocks(
block_content.body.push(TreeNode::new_boxed_inst(switch));
}
&Instruction_::SwapStackExc {
stack,
is_exception,
ref args,
ref resume
} => {
let swapstack = Instruction {
hdr: hdr,
value: value.clone(),
ops: ops.clone(),
v: Instruction_::SwapStackExc {
stack: stack,
is_exception: is_exception,
args: args.clone(),
resume: fix_resume(resume.clone())
}
};
trace!("rewrite to: {}", swapstack);
block_content.body.push(TreeNode::new_boxed_inst(swapstack));
}
&Instruction_::Watchpoint { .. } |
&Instruction_::WPBranch { .. } |
&Instruction_::SwapStackExc { .. } | // Should be safe, just inline it like a call...
&Instruction_::ExnInstruction { .. } => unimplemented!(),
_ => {
......
......@@ -40,11 +40,11 @@ FP .req X29
LR .req X30
.macro push_pair src1 src2 stack=SP
STP \src2 , \src1, [ \stack ,#-16]!
STP \src2 , \src1, [ \stack ,#-16]!
.endm
.macro pop_pair dest1 dest2 stack=SP
LDP \dest1 , \dest2 , [ \stack ],#16
LDP \dest1 , \dest2 , [ \stack ],#16
.endm
.macro enter_frame
......@@ -53,92 +53,31 @@ MOV FP, SP
.endm
.macro exit_frame
pop_pair FP, LR
pop_pair FP, LR
.endm
.macro push_callee_saved stack=SP
push_pair X19, X20, \stack
push_pair X21, X22, \stack
push_pair X23, X24, \stack
push_pair X25, X26, \stack
push_pair X27, X28, \stack
push_pair D8, D9, \stack
push_pair D10, D11, \stack
push_pair D12, D13, \stack
push_pair D14, D15, \stack
push_pair X19, X20, \stack
push_pair X21, X22, \stack
push_pair X23, X24, \stack
push_pair X25, X26, \stack
push_pair X27, X28, \stack
push_pair D8, D9, \stack
push_pair D10, D11, \stack
push_pair D12, D13, \stack
push_pair D14, D15, \stack
.endm
.macro pop_callee_saved stack=SP
pop_pair D15, D14, \stack
pop_pair D13, D12, \stack
pop_pair D11, D10, \stack
pop_pair D9, D8, \stack
pop_pair X28, X27, \stack
pop_pair X26, X25, \stack
pop_pair X24, X23, \stack
pop_pair X22, X21, \stack
pop_pair X20, X19, \stack
.endm
.macro pop_arguments stack=SP
pop_pair x7, x6, \stack
pop_pair x5, x4, \stack
pop_pair x3, x2, \stack
pop_pair x1, x0, \stack
pop_pair d7, d6, \stack
pop_pair d5, d4, \stack
pop_pair d3, d2, \stack
pop_pair d1, d0, \stack
.endm
.macro load_arguments stack=SP
LDP D0, D1, [\stack, #-2*8]
LDP D2, D3, [\stack, #-4*8]
LDP D4, D5, [\stack, #-6*8]
LDP D6, D7, [\stack, #-8*8]
LDP X0, X1, [\stack, #-10*8]
LDP X2, X3, [\stack, #-12*8]
LDP X4, X5, [\stack, #-14*8]
LDP X6, X7, [\stack, #-16*8]
.endm
.macro mov_args_to_callee_saved
MOV X19, X0
MOV X20, X1
MOV X21, X2
MOV X22, X3
MOV X23, X4
MOV X24, X5
MOV X25, X6
MOV X26, X7
FMOV D8, D0
FMOV D9, D1
FMOV D10, D2
FMOV D11, D3
FMOV D12, D4
FMOV D13, D5
FMOV D14, D6
FMOV D15, D7
.endm
.macro mov_callee_saved_to_args
MOV X0, X19
MOV X1, X20
MOV X2, X21
MOV X3, X22
MOV X4, X23
MOV X5, X24
MOV X6, X25
MOV X7, X26
FMOV D0, D8
FMOV D1, D9
FMOV D2, D10
FMOV D3, D11
FMOV D4, D12
FMOV D5, D13
FMOV D6, D14
FMOV D7, D15
pop_pair D15, D14, \stack
pop_pair D13, D12, \stack
pop_pair D11, D10, \stack
pop_pair D9, D8, \stack
pop_pair X28, X27, \stack
pop_pair X26, X25, \stack
pop_pair X24, X23, \stack
pop_pair X22, X21, \stack
pop_pair X20, X19, \stack
.endm
\ No newline at end of file
......@@ -179,16 +179,6 @@ lazy_static! {
jit: RwLock::new(None),
};
pub static ref THROW_EXCEPTION_INTERNAL : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![],
arg_tys: vec![ADDRESS_TYPE.clone(), ADDRESS_TYPE.clone()]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_throw_exception_internal")),
jit: RwLock::new(None),
};
// impl/decl: math.rs
pub static ref FREM32 : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
......
......@@ -38,7 +38,8 @@ use runtime::*;
/// (and are accessed by get/set_return_address and get/set_previous_frame and may be passed
/// real frame pointers or the frame cursor)
#[no_mangle]
pub extern "C" fn throw_exception_internal(exception_obj: Address, frame_cursor: Address) -> ! {
pub extern "C" fn throw_exception_internal(exception_obj: Address, frame_cursor: Address) ->
! {
trace!("throwing exception: {}", exception_obj);
if cfg!(debug_assertions) {
......
......@@ -59,8 +59,16 @@ begin_func muthread_start_normal
// Swap to the new stack
MOV SP, X0
// Load the argument registers from the new stack
load_arguments SP
// Pop the argument registers from the new stack
LDP D0, D1, [SP, #14*8]
LDP D2, D3, [SP, #12*8]
LDP D4, D5, [SP, #10*8]
LDP D6, D7, [SP, #8*8]
LDP X0, X1, [SP, #6*8]
LDP X2, X3, [SP, #4*8]
LDP X4, X5, [SP, #2*8]
LDP X6, X7, [SP, #0*8]
ADD SP, SP, #16*8
// Jump to the new stack
exit_frame
......
......@@ -207,9 +207,8 @@ impl MuStack {
}
// store floating point argument registers
let mut stack_ptr = self.sp;
for i in 0..ARGUMENT_FPRS.len() {
stack_ptr -= WORD_SIZE;
self.sp -= WORD_SIZE;
let val = {
if i < fpr_used.len() {
fpr_used[i]
......@@ -218,15 +217,15 @@ impl MuStack {
}
};
debug!("store {} to {}", val, stack_ptr);
debug!("store {} to {}", val, self.sp);
unsafe {
stack_ptr.store(val);
self.sp.store(val);
}
}
// store general purpose argument registers
for i in 0..ARGUMENT_GPRS.len() {
stack_ptr -= WORD_SIZE;
self.sp -= WORD_SIZE;
let val = {
if i < gpr_used.len() {
gpr_used[i]
......@@ -235,9 +234,9 @@ impl MuStack {
}
};
debug!("store {} to {}", val, stack_ptr);
debug!("store {} to {}", val, self.sp);
unsafe {
stack_ptr.store(val);
self.sp.store(val);
}
}
......
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