Skip to content

Commit

Permalink
[X64] fixes #47
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Nov 4, 2024
1 parent ceccb62 commit 86eb9e7
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 84 deletions.
2 changes: 2 additions & 0 deletions src/CodeGen/compilation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub struct Allocator {
pub(crate) ffpregs: Vec<Reg>,

pub(crate) call: MachineCallingConvention,

pub(crate) callee_save_registers: Vec<Reg>,
}
/// helps with compilation
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down
8 changes: 8 additions & 0 deletions src/CodeGen/compilation/prolog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ impl CompilationHelper {
let mut instr = MachineInstr::new( MachineMnemonic::Prolog );
instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) );

for save in &self.alloc.callee_save_registers {
instr.add_operand( MachineOperand::Reg(*save) );
}

sink.push( instr );
}

Expand All @@ -16,6 +20,10 @@ impl CompilationHelper {
let mut instr = MachineInstr::new( MachineMnemonic::Epilog );
instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) );

for save in &self.alloc.callee_save_registers {
instr.add_operand( MachineOperand::Reg(*save) );
}

sink.push( instr );
}
}
1 change: 1 addition & 0 deletions src/Target/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub fn initializeWasmTarget(_: CallConv) -> TargetBackendDescr {
fregs: Vec::new(),
ffpregs: Vec::new(),
call: MachineCallingConvention { call_conv: CallConv::WasmBasicCAbi },
callee_save_registers: Vec::new(),
};

let mut compiler = CompilationHelper::new(
Expand Down
6 changes: 4 additions & 2 deletions src/Target/x64/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,24 @@ pub(crate) fn construct_compilation_helper(call_conv: CallConv) -> CompilationHe
Reg::x64(X64Reg::Xmm13)],

fregs: vec![
// Please do not move rbx forward, cuz then it will be select earlier and rbx is a callee saved register
Reg::x64(X64Reg::Rcx),
Reg::x64(X64Reg::Rdx),
Reg::x64(X64Reg::Rsi),
Reg::x64(X64Reg::Rdi),
Reg::x64(X64Reg::R8),
Reg::x64(X64Reg::R9),
Reg::x64(X64Reg::R10),
Reg::x64(X64Reg::R11),
Reg::x64(X64Reg::R12),
Reg::x64(X64Reg::Rbx),
Reg::x64(X64Reg::R12),
Reg::x64(X64Reg::R13),
Reg::x64(X64Reg::R14),
Reg::x64(X64Reg::R15),
],

call: calling_convention,

callee_save_registers: Vec::new(), // will be set in the allocation
};

alloc.fregs.reverse();
Expand Down
20 changes: 10 additions & 10 deletions src/Target/x64/lower/cmov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pub(crate) fn x64_lower_cmov_zero(sink: &mut Vec<X64MCInstr>, instr: &MachineIns
let out = out.into();

let cmp = if let Operand::Mem(_) = cond {
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::Rbx))]
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::R11))]
} else {
vec![X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Imm(0))]
};
Expand Down Expand Up @@ -61,8 +61,8 @@ pub(crate) fn x64_lower_cmov_not_zero(sink: &mut Vec<X64MCInstr>, instr: &Machin
let out = out.into();

let cmp = if let Operand::Mem(_) = cond {
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::Rbx))]
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::R11))]
} else {
vec![X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Imm(0))]
};
Expand Down Expand Up @@ -100,7 +100,7 @@ pub(crate) fn x64_lower_fcmov0(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr)
let out: Operand = out.into();

let tmp = if instr.meta == TypeMetadata::f32 { X64Reg::Eax } else { X64Reg::Rax };
let tmp2 = if instr.meta == TypeMetadata::f32 { X64Reg::Ebx } else { X64Reg::Rbx };
let tmp2 = if instr.meta == TypeMetadata::f32 { X64Reg::Ebx } else { X64Reg::R11 };

let mnemonic =if instr.meta == TypeMetadata::f32 {
Mnemonic::Movd
Expand All @@ -109,8 +109,8 @@ pub(crate) fn x64_lower_fcmov0(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr)
};

sink.extend_from_slice(&if let Operand::Mem(_) = cond {
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::Rbx))]
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::R11))]
} else {
vec![X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Imm(0))]
});
Expand Down Expand Up @@ -143,7 +143,7 @@ pub(crate) fn x64_lower_fcmovne0(sink: &mut Vec<X64MCInstr>, instr: &MachineInst
let out: Operand = out.into();

let tmp = if instr.meta == TypeMetadata::f32 { X64Reg::Eax } else { X64Reg::Rax };
let tmp2 = if instr.meta == TypeMetadata::f32 { X64Reg::Ebx } else { X64Reg::Rbx };
let tmp2 = if instr.meta == TypeMetadata::f32 { X64Reg::Ebx } else { X64Reg::R11 };

let mnemonic =if instr.meta == TypeMetadata::f32 {
Mnemonic::Movd
Expand All @@ -152,8 +152,8 @@ pub(crate) fn x64_lower_fcmovne0(sink: &mut Vec<X64MCInstr>, instr: &MachineInst
};

sink.extend_from_slice(&if let Operand::Mem(_) = cond {
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::Rbx))]
vec![X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11), Operand::Imm(0)),
X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Reg(X64Reg::R11))]
} else {
vec![X64MCInstr::with2(Mnemonic::Cmp, cond, Operand::Imm(0))]
});
Expand Down
8 changes: 4 additions & 4 deletions src/Target/x64/lower/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ fn x64_lower_cmp(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr, mode: &CmpMod

if let Operand::Mem(_) = ls {
if ls == out {
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), ls.clone()));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), ls.clone()));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Imm(0)));
sink.push(X64MCInstr::with2(Mnemonic::Mov, ls, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta))));
sink.push(X64MCInstr::with2(Mnemonic::Cmp, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), rs));
sink.push(X64MCInstr::with2(Mnemonic::Cmp, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), rs));
} else if rs == out {
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), rs.clone()));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), rs.clone()));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Imm(0)));
sink.push(X64MCInstr::with2(Mnemonic::Mov, rs, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta))));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), ls));
sink.push(X64MCInstr::with2(Mnemonic::Cmp, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta))));
sink.push(X64MCInstr::with2(Mnemonic::Cmp, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Reg(X64Reg::R11.sub_ty(instr.meta))));
} else {
if let Operand::Reg(_) = out {
sink.push(X64MCInstr::with2(Mnemonic::Mov, out.clone(), Operand::Imm(0)));
Expand Down
20 changes: 10 additions & 10 deletions src/Target/x64/lower/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ pub(crate) fn x64_lower_mul(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
if op1.is_imm() && op2.is_imm() { // theoraticly we could precalculate it here but if the user wanted us to do this he would use `-O` flag
sink.extend_from_slice(&[
X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), op1),
X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), op2),
X64MCInstr::with2(Mnemonic::Imul, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta))),
X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), op2),
X64MCInstr::with2(Mnemonic::Imul, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Reg(X64Reg::R11.sub_ty(instr.meta))),
X64MCInstr::with2(Mnemonic::Mov, out, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta))),
]);

Expand Down Expand Up @@ -162,11 +162,11 @@ pub(crate) fn x64_lower_div(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {

// assembly code is here
let div_instr = if op2.is_imm() {
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), op2));
X64MCInstr::with1(div_mnemonic, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)))
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), op2));
X64MCInstr::with1(div_mnemonic, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)))
} else if matches!(op2, Operand::Reg(X64Reg::Rdx) | Operand::Reg(X64Reg::Edx)) {
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), op2));
X64MCInstr::with1(div_mnemonic, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)))
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), op2));
X64MCInstr::with1(div_mnemonic, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)))
} else {
X64MCInstr::with1(div_mnemonic, op2)
};
Expand Down Expand Up @@ -232,11 +232,11 @@ pub(crate) fn x64_lower_rem(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {

// mul/imul only accept r/m
if let Operand::Imm(_) = op2 {
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), op2.clone()));
sink.push(X64MCInstr::with1(mnemonic, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta))));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), op2.clone()));
sink.push(X64MCInstr::with1(mnemonic, Operand::Reg(X64Reg::R11.sub_ty(instr.meta))));
} else if let Operand::Mem(_) = op2 {
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta)), op2.clone()));
sink.push(X64MCInstr::with1(mnemonic, Operand::Reg(X64Reg::Rbx.sub_ty(instr.meta))));
sink.push(X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(instr.meta)), op2.clone()));
sink.push(X64MCInstr::with1(mnemonic, Operand::Reg(X64Reg::R11.sub_ty(instr.meta))));
} else {
sink.push(X64MCInstr::with1(mnemonic, op2.clone()));
}
Expand Down
43 changes: 36 additions & 7 deletions src/Target/x64/lower/prolog.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,47 @@
use crate::CodeGen::MachineInstr;
use crate::CodeGen::{MachineInstr, MachineOperand};
use crate::Target::x64::X64Reg;
use crate::Target::x64::asm::instr::*;

pub(crate) fn x64_lower_prolog(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
//sink.push( X64MCInstr::with0(Mnemonic::Endbr64) );
sink.push( X64MCInstr::with1(Mnemonic::Push, Operand::Reg(X64Reg::Rbp) ) );
sink.push( X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbp), Operand::Reg(X64Reg::Rsp) ) );
if let Some(op0) = instr.operands.get(0) {
let op0 = (*op0).into();

sink.push( X64MCInstr::with2(Mnemonic::Sub, Operand::Reg(X64Reg::Rbp), op0) );
for op in instr.operands.iter() { // we remove the stack_off
let MachineOperand::Reg(crate::CodeGen::Reg::x64(callee_save)) = op else { continue; };

if callee_save.is_xmm() {
sink.extend_from_slice(&[
X64MCInstr::with2(Mnemonic::Movq, Operand::Mem(MemOp { base: Some(X64Reg::Rsp), index: None, scale: 1, displ: 0, rip: false }), Operand::Reg(*callee_save)),
X64MCInstr::with2(Mnemonic::Sub, Operand::Reg(X64Reg::Rsp), Operand::Imm(8)),
]);
} else {
sink.push(X64MCInstr::with1(Mnemonic::Push, Operand::Reg(*callee_save)));
}
}

let Some(MachineOperand::Imm(stack_off)) = instr.operands.get(0) else { panic!("expected valid stack_off for prolog")};
let stack_off = *stack_off as i64;

if stack_off > 0 {
sink.push( X64MCInstr::with1(Mnemonic::Push, Operand::Reg(X64Reg::Rbp) ) );
sink.push( X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbp), Operand::Reg(X64Reg::Rsp) ) );
sink.push( X64MCInstr::with2(Mnemonic::Sub, Operand::Reg(X64Reg::Rbp), Operand::Imm(stack_off)) );
}

}

pub(crate) fn x64_lower_epilog(sink: &mut Vec<X64MCInstr>, _: &MachineInstr) {
pub(crate) fn x64_lower_epilog(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
for op in instr.operands.iter().rev() { // we remove the stack_off
let MachineOperand::Reg(crate::CodeGen::Reg::x64(callee_save)) = op else { continue; };

if callee_save.is_xmm() {
sink.extend_from_slice(&[
X64MCInstr::with2(Mnemonic::Movq, Operand::Reg(*callee_save), Operand::Mem(MemOp { base: Some(X64Reg::Rsp), index: None, scale: 1, displ: 0, rip: false })),
X64MCInstr::with2(Mnemonic::Add, Operand::Reg(X64Reg::Rsp), Operand::Imm(8)),
]);
} else {
sink.push(X64MCInstr::with1(Mnemonic::Pop, Operand::Reg(*callee_save)));
}
}

sink.push( X64MCInstr::with1(Mnemonic::Pop, Operand::Reg(X64Reg::Rbp) ) );
}
4 changes: 2 additions & 2 deletions src/Target/x64/lower/switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ pub(crate) fn x64_lower_fswitch(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr
let cmp_mne = if instr.meta == TypeMetadata::f32 { Mnemonic::Ucomiss } else { Mnemonic::Ucomisd };

sink.extend_from_slice(&[
X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rbx.sub_ty(size)), Operand::Imm(imm)),
X64MCInstr::with2(move_mne, Operand::Reg(X64Reg::Xmm14), Operand::Reg(X64Reg::Rbx.sub_ty(size))),
X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::R11.sub_ty(size)), Operand::Imm(imm)),
X64MCInstr::with2(move_mne, Operand::Reg(X64Reg::Xmm14), Operand::Reg(X64Reg::R11.sub_ty(size))),
X64MCInstr::with2(cmp_mne, Operand::Reg(X64Reg::Xmm15), Operand::Reg(X64Reg::Xmm14)),
X64MCInstr::with1(Mnemonic::Je, Operand::BlockLinkDestination(block.name.to_owned(), -4)),
]);
Expand Down
73 changes: 24 additions & 49 deletions src/Target/x64/reg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::Display;

use crate::IR::TypeMetadata;
use crate::{Target::CallConv, IR::TypeMetadata};

/// A x64 register
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -37,7 +37,7 @@ impl X64Reg {
use X64Reg::*;
match string.to_ascii_lowercase().as_str() {
"rax" => Some(Rax), "eax" => Some(Eax), "ax" => Some(Ax), "al" => Some(Al),
"rbx" => Some(Rbx), "ebx" => Some(Ebx), "bx" => Some(Bx), "bl" => Some(Bl),
"rbx" => Some(R11), "ebx" => Some(Ebx), "bx" => Some(Bx), "bl" => Some(Bl),
"rcx" => Some(Rcx), "ecx" => Some(Ecx), "cx" => Some(Cx), "cl" => Some(Cl),
"rdx" => Some(Rdx), "edx" => Some(Edx), "dx" => Some(Dx), "dl" => Some(Dl),
"rsi" => Some(Rsi), "esi" => Some(Esi), "si" => Some(Si), "sil" => Some(Sil),
Expand Down Expand Up @@ -90,7 +90,7 @@ impl X64Reg {
use X64Reg::*;
match self {
Rax | Eax | Ax | Al => Rax,
Rbx | Ebx | Bx | Bl => Rbx,
Rbx | Ebx | Bx | Bl => R11,
Rcx | Ecx | Cx | Cl => Rcx,
Rdx | Edx | Dx | Dl => Rdx,
Rsi | Esi | Si | Sil => Rsi,
Expand Down Expand Up @@ -290,57 +290,32 @@ impl X64Reg {
_ => false,
}
}

#[doc(hidden)]
pub fn enc(&self) -> u8 {
match self {
// GR
X64Reg::Rax | X64Reg::Eax | X64Reg::Ax | X64Reg::Al => 0,
X64Reg::Rcx | X64Reg::Ecx | X64Reg::Cx | X64Reg::Cl => 1,
X64Reg::Rdx | X64Reg::Edx | X64Reg::Dx | X64Reg::Dl => 2,
X64Reg::Rbx | X64Reg::Ebx | X64Reg::Bx | X64Reg::Bl => 3,
X64Reg::Rsi | X64Reg::Esi | X64Reg::Si | X64Reg::Sil => 6,
X64Reg::Rbp | X64Reg::Ebp | X64Reg::Bp | X64Reg::Bpl => 5,
X64Reg::Rsp | X64Reg::Esp | X64Reg::Sp | X64Reg::Spl => 4,
X64Reg::Rdi | X64Reg::Edi | X64Reg::Di | X64Reg::Dil => 7,

// here use a rex prefix
X64Reg::R8 | X64Reg::R8d | X64Reg::R8w | X64Reg::R8b => 0,
X64Reg::R9 | X64Reg::R9d | X64Reg::R9w | X64Reg::R9b => 1,
X64Reg::R10 | X64Reg::R10d | X64Reg::R10w | X64Reg::R10b => 2,
X64Reg::R11 | X64Reg::R11d | X64Reg::R11w | X64Reg::R11b => 3,
X64Reg::R12 | X64Reg::R12d | X64Reg::R12w | X64Reg::R12b => 4,
X64Reg::R13 | X64Reg::R13d | X64Reg::R13w | X64Reg::R13b => 5,
X64Reg::R14 | X64Reg::R14d | X64Reg::R14w | X64Reg::R14b => 6,
X64Reg::R15 | X64Reg::R15d | X64Reg::R15w | X64Reg::R15b => 7,

// Xmm
X64Reg::Xmm0 => 0,
X64Reg::Xmm1 => 1,
X64Reg::Xmm2 => 2,
X64Reg::Xmm3 => 3,
X64Reg::Xmm4 => 4,
X64Reg::Xmm5 => 5,
X64Reg::Xmm6 => 6,
X64Reg::Xmm7 => 7,

// here use a rex prefix
X64Reg::Xmm8 => 0,
X64Reg::Xmm9 => 1,
X64Reg::Xmm10 => 2,
X64Reg::Xmm11 => 3,
X64Reg::Xmm12 => 4,
X64Reg::Xmm13 => 5,
X64Reg::Xmm14 => 6,
X64Reg::Xmm15 => 7,

}
}

#[doc(hidden)]
pub fn as_any(&self) -> &dyn std::any::Any {
self
}

/// Returns if the register is callee saved on the given calling convention
pub fn callee_saved(&self, call: CallConv) -> bool {
use X64Reg::*;

if self.is_xmm() {
return if call == CallConv::WindowsFastCall {
match self {
Xmm6 | Xmm7 | Xmm8 |
Xmm9 | Xmm10 | Xmm11 | Xmm12 |
Xmm13 | Xmm14 | Xmm15 => true,
_ => false,
}
} else { false }
}

match self.sub64() {
Rbx | Rbp | R12 | R13 | R14 | R15 | Rsp => true,
_ => false,
}
}
}

impl Display for X64Reg {
Expand Down
7 changes: 7 additions & 0 deletions src/Target/x64/reg_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ pub(crate) fn x64_alloc_rv(alloc: &mut Allocator, ty: TypeMetadata) -> VarLocati
let vec = if ty.float() { &mut alloc.ffpregs } else { &mut alloc.fregs }; // select free registers vec

if let Some(reg) = vec.pop() {
let Reg::x64(x64) = reg else { panic!("x64 reg alloc expects x64 regs") };

if x64.callee_saved(alloc.call.call_conv) {
alloc.callee_save_registers.push(Reg::x64(x64));
alloc.epilog = true;
}

VarLocation::Reg(match reg { // this code here just changes the register to be the fitting type
Reg::x64(x64) => Reg::x64(x64.sub_ty(ty)),
_ => panic!("the x64 register allocator just got an non x64 register")
Expand Down

0 comments on commit 86eb9e7

Please sign in to comment.