WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit 30966222 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Made register allocator aware of argument registers

parent d27813e2
......@@ -13,6 +13,7 @@
// limitations under the License.
use ast::ir::*;
use ast::ptr::P;
use runtime::ValueLocation;
use compiler::machine_code::MachineCode;
......@@ -100,15 +101,15 @@ pub trait CodeGenerator {
fn emit_stnp(&mut self, dest: Mem, src1: Reg/*GPR or FPR*/, src2: Reg/*GPR or FPR*/); // [base, #simm7]
// Calls
fn emit_bl(&mut self, callsite: String, func: MuName, pe: Option<MuName>, is_native: bool) -> ValueLocation;
fn emit_blr(&mut self, callsite: String, func: Reg, pe: Option<MuName>) -> ValueLocation;
fn emit_bl(&mut self, callsite: String, func: MuName, pe: Option<MuName>, args: Vec<P<Value>>, is_native: bool) -> ValueLocation;
fn emit_blr(&mut self, callsite: String, func: Reg, pe: Option<MuName>, args: Vec<P<Value>>) -> ValueLocation;
// Branches
fn emit_b(&mut self, dest_name: MuName);
fn emit_b_func(&mut self, func: MuName);
fn emit_b_func(&mut self, func: MuName, args: Vec<P<Value>>); // For tail calls
fn emit_b_cond(&mut self, cond: &str, dest_name: MuName);
fn emit_br(&mut self, dest_address: Reg);
fn emit_br_func(&mut self, func_address: Reg);
fn emit_br_func(&mut self, func_address: Reg, args: Vec<P<Value>>); // For tail calls
fn emit_ret(&mut self, src: Reg);
fn emit_cbnz(&mut self, src: Reg, dest_name: MuName);
......
......@@ -3123,9 +3123,12 @@ impl <'a> InstructionSelection {
// returns the stack arg offset - we will need this to collapse stack after the call
fn emit_precall_convention(&mut self, is_tail: bool, args: &Vec<P<Value>>, arg_tys: &Vec<P<MuType>>, return_size: usize, f_context: &mut FunctionContext, vm: &VM) -> usize
// as well as a list of argument registers
fn emit_precall_convention(&mut self, is_tail: bool, args: &Vec<P<Value>>, arg_tys: &Vec<P<MuType>>, return_size: usize, f_context: &mut FunctionContext, vm: &VM)
-> (usize, Vec<P<Value>>)
{
// If we're tail calling, use the current frame's argument location instead
let mut reg_args = Vec::<P<Value>>::new();
let (arg_base, arg_offset) = if is_tail { (&*FP, 16) } else { (&*SP, 0) };
let (_, locations, stack_size) = self.compute_argument_locations(&arg_tys, arg_base, arg_offset, &vm);
......@@ -3175,17 +3178,22 @@ impl <'a> InstructionSelection {
let arg_val = emit_reg_value(self.backend.as_mut(), &arg_val, f_context, vm);
let (val_l, val_h) = split_int128(&arg_val, f_context, vm);
let arg_loc_h = get_register_from_id(arg_loc.id() + 2);
reg_args.push(arg_loc.clone());
reg_args.push(arg_loc_h.clone());
emit_move_value_to_value(self.backend.as_mut(), &arg_loc, &val_l, f_context, vm);
emit_move_value_to_value(self.backend.as_mut(), &arg_loc_h, &val_h, f_context, vm);
} else {
if arg_loc.is_reg() {
reg_args.push(arg_loc.clone());
}
emit_move_value_to_value(self.backend.as_mut(), &arg_loc, &arg_val, f_context, vm)
}
}
}
}
stack_size
(stack_size, reg_args)
}
fn emit_postcall_convention(&mut self, ret_tys: &Vec<P<MuType>>, rets: &Option<Vec<P<Value>>>, ret_type: &P<MuType>, arg_size: usize, ret_size: usize, f_context: &mut FunctionContext, vm: &VM) -> Vec<P<Value>> {
......@@ -3422,7 +3430,7 @@ impl <'a> InstructionSelection {
{
let return_type = self.combine_return_types(&sig.ret_tys);
let return_size = self.compute_return_allocation(&return_type, &vm);
let stack_arg_size = self.emit_precall_convention(false, &args, &sig.arg_tys, return_size, f_context, vm);
let (stack_arg_size, arg_regs) = self.emit_precall_convention(false, &args, &sig.arg_tys, return_size, f_context, vm);
// make call
if vm.is_doing_jit() {
......@@ -3430,7 +3438,7 @@ impl <'a> InstructionSelection {
} else {
let callsite = self.new_callsite_label(cur_node);
self.backend.emit_bl(callsite.clone(), func_name, None, true); // assume ccall wont throw exception
self.backend.emit_bl(callsite.clone(), func_name, None, arg_regs, true); // assume ccall wont throw exception
// TODO: What if theres an exception block?
self.current_callsites.push_back((callsite, 0, stack_arg_size));
......@@ -3567,7 +3575,7 @@ impl <'a> InstructionSelection {
}
let return_type = self.combine_return_types(&func_sig.ret_tys);
let return_size = self.compute_return_allocation(&return_type, &vm);
let stack_arg_size = self.emit_precall_convention(is_tail, &arg_values, &func_sig.arg_tys, return_size, f_context, vm,);
let (stack_arg_size, arg_regs) = self.emit_precall_convention(is_tail, &arg_values, &func_sig.arg_tys, return_size, f_context, vm,);
// check if this call has exception clause - need to tell backend about this
let potentially_excepting = {
......@@ -3592,10 +3600,10 @@ impl <'a> InstructionSelection {
let target_id = self.node_funcref_const_to_id(func);
let funcs = vm.funcs().read().unwrap();
let target = funcs.get(&target_id).unwrap().read().unwrap();
self.backend.emit_b_func(target.name());
self.backend.emit_b_func(target.name(), arg_regs);
} else {
let target = self.emit_ireg(func, f_content, f_context, vm);
self.backend.emit_br_func(&target);
self.backend.emit_br_func(&target, arg_regs);
}
} else {
// Emit a branch with link (i.e. a call)
......@@ -3609,12 +3617,12 @@ impl <'a> InstructionSelection {
unimplemented!()
} else {
let callsite = self.new_callsite_label(Some(cur_node));
self.backend.emit_bl(callsite, target.name(), potentially_excepting, false)
self.backend.emit_bl(callsite, target.name(), potentially_excepting, arg_regs, false)
}
} else {
let target = self.emit_ireg(func, f_content, f_context, vm);
let callsite = self.new_callsite_label(Some(cur_node));
self.backend.emit_blr(callsite, &target, potentially_excepting)
self.backend.emit_blr(callsite, &target, potentially_excepting, arg_regs)
}
};
......
......@@ -1748,7 +1748,7 @@ fn emit_madd_u64(backend: &mut CodeGenerator, dest: &P<Value>, src1: &P<Value>,
let shift = log2(val as u64) as u8;
// dest = src1 << log2(val) + src2
if shift <= 4 {
backend.emit_add_ext(&dest, &dest, &src2, false, shift);
backend.emit_add_ext(&dest, &src2, &src1, false, shift);
} else {
backend.emit_lsl_imm(&dest, &src1, shift);
backend.emit_add(&dest, &dest, &src2);
......@@ -2005,10 +2005,8 @@ fn emit_fpreg_value(backend: &mut CodeGenerator, pv: &P<Value>, f_context: &mut
}
fn split_int128(int128: &P<Value>, f_context: &mut FunctionContext, vm: &VM) -> (P<Value>, P<Value>) {
trace!("ISAAC split_int128({})...", int128);
if f_context.get_value(int128.id()).unwrap().has_split() {
let vec = f_context.get_value(int128.id()).unwrap().get_split().as_ref().unwrap();
trace!("ISAAC <- get value ({}, {})", &vec[0], &vec[1]);
(vec[0].clone(), vec[1].clone())
} else {
let arg_l = make_temporary(f_context, UINT64_TYPE.clone(), vm);
......@@ -2022,7 +2020,6 @@ fn split_int128(int128: &P<Value>, f_context: &mut FunctionContext, vm: &VM) ->
}
pub fn emit_ireg_ex_value(backend: &mut CodeGenerator, pv: &P<Value>, f_context: &mut FunctionContext, vm: &VM) -> (P<Value>, P<Value>) {
trace!("ISAAC emit_ireg_ex_value({})", pv);
match pv.v {
Value_::SSAVar(_) => {
split_int128(pv, f_context, vm)
......
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