add windows cc implementation of new register picker

This commit is contained in:
Folkert 2023-05-03 17:57:54 +02:00
parent e12a7f4f81
commit 3c6c5a3e53
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -598,22 +598,20 @@ impl X64_64SystemVStoreArgs {
storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>, storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>,
sym: Symbol, sym: Symbol,
) { ) {
if self.general_i < Self::GENERAL_PARAM_REGS.len() { match Self::GENERAL_PARAM_REGS.get(self.general_i) {
storage_manager.load_to_specified_general_reg( Some(reg) => {
buf, storage_manager.load_to_specified_general_reg(buf, &sym, *reg);
&sym, self.general_i += 1;
Self::GENERAL_PARAM_REGS[self.general_i], }
); None => {
self.general_i += 1; // Copy to stack using return reg as buffer.
} else { let tmp = Self::GENERAL_RETURN_REGS[0];
// Copy to stack using return reg as buffer.
storage_manager.load_to_specified_general_reg(buf, &sym, Self::GENERAL_RETURN_REGS[0]); storage_manager.load_to_specified_general_reg(buf, &sym, tmp);
X86_64Assembler::mov_stack32_reg64( X86_64Assembler::mov_stack32_reg64(buf, self.tmp_stack_offset, tmp);
buf,
self.tmp_stack_offset, self.tmp_stack_offset += 8;
Self::GENERAL_RETURN_REGS[0], }
);
self.tmp_stack_offset += 8;
} }
} }
@ -623,22 +621,20 @@ impl X64_64SystemVStoreArgs {
storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>, storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>,
sym: Symbol, sym: Symbol,
) { ) {
if self.float_i < Self::FLOAT_PARAM_REGS.len() { match Self::FLOAT_PARAM_REGS.get(self.float_i) {
storage_manager.load_to_specified_float_reg( Some(reg) => {
buf, storage_manager.load_to_specified_float_reg(buf, &sym, *reg);
&sym, self.float_i += 1;
Self::FLOAT_PARAM_REGS[self.float_i], }
); None => {
self.float_i += 1; // Copy to stack using return reg as buffer.
} else { let tmp = Self::FLOAT_RETURN_REGS[0];
// Copy to stack using return reg as buffer.
storage_manager.load_to_specified_float_reg(buf, &sym, Self::FLOAT_RETURN_REGS[0]); storage_manager.load_to_specified_float_reg(buf, &sym, tmp);
X86_64Assembler::mov_stack32_freg64( X86_64Assembler::mov_stack32_freg64(buf, self.tmp_stack_offset, tmp);
buf,
self.tmp_stack_offset, self.tmp_stack_offset += 8;
Self::FLOAT_RETURN_REGS[0], }
);
self.tmp_stack_offset += 8;
} }
} }
} }
@ -884,37 +880,45 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
ret_layout: &InLayout<'a>, ret_layout: &InLayout<'a>,
) { ) {
let mut arg_offset = Self::SHADOW_SPACE_SIZE as i32 + 16; // 16 is the size of the pushed return address and base pointer. let mut arg_offset = Self::SHADOW_SPACE_SIZE as i32 + 16; // 16 is the size of the pushed return address and base pointer.
let mut i = 0;
let mut general_registers_used = 0;
let mut float_registers_used = 0;
if X86_64WindowsFastcall::returns_via_arg_pointer(layout_interner, ret_layout) { if X86_64WindowsFastcall::returns_via_arg_pointer(layout_interner, ret_layout) {
storage_manager.ret_pointer_arg(Self::GENERAL_PARAM_REGS[i]); storage_manager.ret_pointer_arg(Self::GENERAL_PARAM_REGS[0]);
i += 1; general_registers_used += 1;
} }
for (layout, sym) in args.iter() { for (layout, sym) in args.iter() {
if i < Self::GENERAL_PARAM_REGS.len() { match *layout {
match *layout { single_register_integers!() => {
single_register_integers!() => { match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
storage_manager.general_reg_arg(sym, Self::GENERAL_PARAM_REGS[i]); Some(reg) => {
i += 1; storage_manager.general_reg_arg(sym, *reg);
} general_registers_used += 1;
single_register_floats!() => { }
storage_manager.float_reg_arg(sym, Self::FLOAT_PARAM_REGS[i]); None => {
i += 1; storage_manager.primitive_stack_arg(sym, arg_offset);
} arg_offset += 8;
x if layout_interner.stack_size(x) == 0 => {} }
x => {
todo!("Loading args with layout {:?}", x);
} }
} }
} else { single_register_floats!() => {
match *layout { match Self::FLOAT_PARAM_REGS.get(float_registers_used) {
single_register_layouts!() => { Some(reg) => {
storage_manager.primitive_stack_arg(sym, arg_offset); storage_manager.float_reg_arg(sym, *reg);
arg_offset += 8; float_registers_used += 1;
}
None => {
storage_manager.primitive_stack_arg(sym, arg_offset);
arg_offset += 8;
}
} }
x => { }
todo!("Loading args with layout {:?}", x); x if layout_interner.stack_size(x) == 0 => {}
} x => {
}; todo!("Loading args with layout {:?}", x);
}
} }
} }
} }
@ -946,54 +950,40 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
let mut general_registers_used = 0; let mut general_registers_used = 0;
let mut float_registers_used = 0; let mut float_registers_used = 0;
for (_, (sym, layout)) in args.iter().zip(arg_layouts.iter()).enumerate() { for (sym, layout) in args.iter().zip(arg_layouts.iter()) {
match *layout { match *layout {
single_register_integers!() => { single_register_integers!() => {
if general_registers_used < Self::GENERAL_PARAM_REGS.len() { match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
storage_manager.load_to_specified_general_reg( Some(reg) => {
buf, storage_manager.load_to_specified_general_reg(buf, sym, *reg);
sym, general_registers_used += 1;
Self::GENERAL_PARAM_REGS[general_registers_used], }
); None => {
// Copy to stack using return reg as buffer.
let tmp = Self::GENERAL_RETURN_REGS[0];
general_registers_used += 1; storage_manager.load_to_specified_general_reg(buf, sym, tmp);
} else { X86_64Assembler::mov_stack32_reg64(buf, tmp_stack_offset, tmp);
// Copy to stack using return reg as buffer.
storage_manager.load_to_specified_general_reg( tmp_stack_offset += 8;
buf, }
sym,
Self::GENERAL_RETURN_REGS[0],
);
X86_64Assembler::mov_stack32_reg64(
buf,
tmp_stack_offset,
Self::GENERAL_RETURN_REGS[0],
);
tmp_stack_offset += 8;
} }
} }
single_register_floats!() => { single_register_floats!() => {
if float_registers_used < Self::FLOAT_PARAM_REGS.len() { match Self::FLOAT_PARAM_REGS.get(float_registers_used) {
storage_manager.load_to_specified_float_reg( Some(reg) => {
buf, storage_manager.load_to_specified_float_reg(buf, sym, *reg);
sym, float_registers_used += 1;
Self::FLOAT_PARAM_REGS[float_registers_used], }
); None => {
// Copy to stack using return reg as buffer.
let tmp = Self::FLOAT_RETURN_REGS[0];
float_registers_used += 1; storage_manager.load_to_specified_float_reg(buf, sym, tmp);
} else { X86_64Assembler::mov_stack32_freg64(buf, tmp_stack_offset, tmp);
// Copy to stack using return reg as buffer.
storage_manager.load_to_specified_float_reg( tmp_stack_offset += 8;
buf, }
sym,
Self::FLOAT_RETURN_REGS[0],
);
X86_64Assembler::mov_stack32_freg64(
buf,
tmp_stack_offset,
Self::FLOAT_RETURN_REGS[0],
);
tmp_stack_offset += 8;
} }
} }
x if layout_interner.stack_size(x) == 0 => {} x if layout_interner.stack_size(x) == 0 => {}