mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
add windows cc implementation of new register picker
This commit is contained in:
parent
e12a7f4f81
commit
3c6c5a3e53
1 changed files with 88 additions and 98 deletions
|
@ -598,24 +598,22 @@ 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_PARAM_REGS[self.general_i],
|
|
||||||
);
|
|
||||||
self.general_i += 1;
|
self.general_i += 1;
|
||||||
} else {
|
}
|
||||||
|
None => {
|
||||||
// Copy to stack using return reg as buffer.
|
// Copy to stack using return reg as buffer.
|
||||||
storage_manager.load_to_specified_general_reg(buf, &sym, Self::GENERAL_RETURN_REGS[0]);
|
let tmp = Self::GENERAL_RETURN_REGS[0];
|
||||||
X86_64Assembler::mov_stack32_reg64(
|
|
||||||
buf,
|
storage_manager.load_to_specified_general_reg(buf, &sym, tmp);
|
||||||
self.tmp_stack_offset,
|
X86_64Assembler::mov_stack32_reg64(buf, self.tmp_stack_offset, tmp);
|
||||||
Self::GENERAL_RETURN_REGS[0],
|
|
||||||
);
|
|
||||||
self.tmp_stack_offset += 8;
|
self.tmp_stack_offset += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn store_arg_float<'a>(
|
fn store_arg_float<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -623,24 +621,22 @@ 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_PARAM_REGS[self.float_i],
|
|
||||||
);
|
|
||||||
self.float_i += 1;
|
self.float_i += 1;
|
||||||
} else {
|
}
|
||||||
|
None => {
|
||||||
// Copy to stack using return reg as buffer.
|
// Copy to stack using return reg as buffer.
|
||||||
storage_manager.load_to_specified_float_reg(buf, &sym, Self::FLOAT_RETURN_REGS[0]);
|
let tmp = Self::FLOAT_RETURN_REGS[0];
|
||||||
X86_64Assembler::mov_stack32_freg64(
|
|
||||||
buf,
|
storage_manager.load_to_specified_float_reg(buf, &sym, tmp);
|
||||||
self.tmp_stack_offset,
|
X86_64Assembler::mov_stack32_freg64(buf, self.tmp_stack_offset, tmp);
|
||||||
Self::FLOAT_RETURN_REGS[0],
|
|
||||||
);
|
|
||||||
self.tmp_stack_offset += 8;
|
self.tmp_stack_offset += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct X64_64SystemVLoadArgs {
|
struct X64_64SystemVLoadArgs {
|
||||||
|
@ -884,38 +880,46 @@ 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!() => {
|
||||||
storage_manager.general_reg_arg(sym, Self::GENERAL_PARAM_REGS[i]);
|
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
|
||||||
i += 1;
|
Some(reg) => {
|
||||||
|
storage_manager.general_reg_arg(sym, *reg);
|
||||||
|
general_registers_used += 1;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
storage_manager.primitive_stack_arg(sym, arg_offset);
|
||||||
|
arg_offset += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
single_register_floats!() => {
|
single_register_floats!() => {
|
||||||
storage_manager.float_reg_arg(sym, Self::FLOAT_PARAM_REGS[i]);
|
match Self::FLOAT_PARAM_REGS.get(float_registers_used) {
|
||||||
i += 1;
|
Some(reg) => {
|
||||||
|
storage_manager.float_reg_arg(sym, *reg);
|
||||||
|
float_registers_used += 1;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
storage_manager.primitive_stack_arg(sym, arg_offset);
|
||||||
|
arg_offset += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
x if layout_interner.stack_size(x) == 0 => {}
|
x if layout_interner.stack_size(x) == 0 => {}
|
||||||
x => {
|
x => {
|
||||||
todo!("Loading args with layout {:?}", x);
|
todo!("Loading args with layout {:?}", x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
match *layout {
|
|
||||||
single_register_layouts!() => {
|
|
||||||
storage_manager.primitive_stack_arg(sym, arg_offset);
|
|
||||||
arg_offset += 8;
|
|
||||||
}
|
|
||||||
x => {
|
|
||||||
todo!("Loading args with layout {:?}", x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,56 +950,42 @@ 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,
|
|
||||||
Self::GENERAL_PARAM_REGS[general_registers_used],
|
|
||||||
);
|
|
||||||
|
|
||||||
general_registers_used += 1;
|
general_registers_used += 1;
|
||||||
} else {
|
}
|
||||||
|
None => {
|
||||||
// Copy to stack using return reg as buffer.
|
// Copy to stack using return reg as buffer.
|
||||||
storage_manager.load_to_specified_general_reg(
|
let tmp = Self::GENERAL_RETURN_REGS[0];
|
||||||
buf,
|
|
||||||
sym,
|
storage_manager.load_to_specified_general_reg(buf, sym, tmp);
|
||||||
Self::GENERAL_RETURN_REGS[0],
|
X86_64Assembler::mov_stack32_reg64(buf, tmp_stack_offset, tmp);
|
||||||
);
|
|
||||||
X86_64Assembler::mov_stack32_reg64(
|
|
||||||
buf,
|
|
||||||
tmp_stack_offset,
|
|
||||||
Self::GENERAL_RETURN_REGS[0],
|
|
||||||
);
|
|
||||||
tmp_stack_offset += 8;
|
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,
|
|
||||||
Self::FLOAT_PARAM_REGS[float_registers_used],
|
|
||||||
);
|
|
||||||
|
|
||||||
float_registers_used += 1;
|
float_registers_used += 1;
|
||||||
} else {
|
}
|
||||||
|
None => {
|
||||||
// Copy to stack using return reg as buffer.
|
// Copy to stack using return reg as buffer.
|
||||||
storage_manager.load_to_specified_float_reg(
|
let tmp = Self::FLOAT_RETURN_REGS[0];
|
||||||
buf,
|
|
||||||
sym,
|
storage_manager.load_to_specified_float_reg(buf, sym, tmp);
|
||||||
Self::FLOAT_RETURN_REGS[0],
|
X86_64Assembler::mov_stack32_freg64(buf, tmp_stack_offset, tmp);
|
||||||
);
|
|
||||||
X86_64Assembler::mov_stack32_freg64(
|
|
||||||
buf,
|
|
||||||
tmp_stack_offset,
|
|
||||||
Self::FLOAT_RETURN_REGS[0],
|
|
||||||
);
|
|
||||||
tmp_stack_offset += 8;
|
tmp_stack_offset += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
x if layout_interner.stack_size(x) == 0 => {}
|
x if layout_interner.stack_size(x) == 0 => {}
|
||||||
x => {
|
x => {
|
||||||
todo!("calling with arg type, {:?}", x);
|
todo!("calling with arg type, {:?}", x);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue