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 88f7cd13 authored by qinsoon's avatar qinsoon
Browse files

try fix x86_64 (not sure if it works)

parent 4ca214f6
......@@ -1910,6 +1910,10 @@ impl <'a> InstructionSelection {
}
}
128 => {
// emit_ireg_ex will split 128 bits register to two 64-bits temporaries
// but here we want to pass 128-bit registers as argument, and let
// calling convention deal with splitting.
// FIXME: emit_ireg() may not be proper here (though it might work)
let reg_op1 = self.emit_ireg(&op1, f_content, f_context, vm);
let reg_op2 = self.emit_ireg(&op2, f_content, f_context, vm);
......@@ -2888,7 +2892,8 @@ impl <'a> InstructionSelection {
// returns the stack arg offset - we will need this to collapse stack after the call
fn emit_precall_convention(
&mut self,
args: &Vec<P<Value>>,
args: &Vec<P<Value>>,
f_context: &mut FunctionContext,
vm: &VM) -> usize {
// put args into registers if we can
// in the meantime record args that do not fit in registers
......@@ -2934,6 +2939,37 @@ impl <'a> InstructionSelection {
// use stack to pass argument
stack_args.push(arg.clone());
}
} else if arg_reg_group == RegGroup::GPREX && arg.is_reg() {
// need two regsiters for this, otherwise, we need to pass on stack
if gpr_arg_count + 1 < x86_64::ARGUMENT_GPRs.len() {
let arg_gpr1 = x86_64::ARGUMENT_GPRs[gpr_arg_count].clone();
let arg_gpr2 = x86_64::ARGUMENT_GPRs[gpr_arg_count + 1].clone();
let (arg_l, arg_h) = self.split_int128(&arg, f_context, vm);
self.backend.emit_mov_r_r(&arg_gpr1, &arg_l);
self.backend.emit_mov_r_r(&arg_gpr2, &arg_h);
gpr_arg_count += 2;
} else {
stack_args.push(arg.clone());
}
} else if arg_reg_group == RegGroup::GPREX && arg.is_const() {
// need two registers for this, otherwise we need to pass on stack
if gpr_arg_count + 1 < x86_64::ARGUMENT_GPRs.len() {
let arg_gpr1 = x86_64::ARGUMENT_GPRs[gpr_arg_count].clone();
let arg_gpr2 = x86_64::ARGUMENT_GPRs[gpr_arg_count + 1].clone();
let const_vals = arg.extract_int_ex_const();
assert!(const_vals.len() == 2);
self.backend.emit_mov_r64_imm64(&arg_gpr1, const_vals[0] as i64);
self.backend.emit_mov_r64_imm64(&arg_gpr2, const_vals[1] as i64);
gpr_arg_count += 2;
} else {
stack_args.push(arg.clone());
}
} else if arg_reg_group == RegGroup::FPR && arg.is_reg() {
if fpr_arg_count < x86_64::ARGUMENT_FPRs.len() {
let arg_fpr = x86_64::ARGUMENT_FPRs[fpr_arg_count].clone();
......@@ -3093,7 +3129,7 @@ impl <'a> InstructionSelection {
f_context: &mut FunctionContext,
vm: &VM) -> Vec<P<Value>>
{
let stack_arg_size = self.emit_precall_convention(&args, vm);
let stack_arg_size = self.emit_precall_convention(&args, f_context, vm);
// make call
if vm.is_running() {
......@@ -3233,7 +3269,7 @@ impl <'a> InstructionSelection {
unimplemented!();
}
}
let stack_arg_size = self.emit_precall_convention(&arg_values, vm);
let stack_arg_size = self.emit_precall_convention(&arg_values, f_context, vm);
// check if this call has exception clause - need to tell backend about this
let potentially_excepting = {
......
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