Skip to content

Commit

Permalink
[FIX] fixing i32/i64 to f32/f64 cast
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Oct 19, 2024
1 parent eb0028a commit fb5aecc
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/CodeGen/compilation/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl CompilationHelper {
let out = *self.vars.get(&node.inner3.name).unwrap();

let op = {
if node.inner1.ty.float() {
if node.inner1.ty.float() || node.inner2.float() {
MachineMnemonic::FCast(node.inner1.ty)
} else if node.inner1.ty.bitSize() > node.inner2.bitSize() {
MachineMnemonic::Zext
Expand Down
32 changes: 32 additions & 0 deletions src/Target/x64/asm/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,32 @@ impl X64MCInstr {
} else { todo!("{}", self) }
} else { todo!("{}", self) }
},
Mnemonic::Cvtsi2ss => {
if let Some(Operand::Reg(op1)) = &self.op1 {
if let Some(Operand::Reg(op2)) = &self.op2 {
if op1.is_xmm() {
Instruction::with2::<Register, Register>(Code::Cvtsi2ss_xmm_rm32, (*op1).into(), (*op2).into())?
} else { todo!("{}", self) }
} else if let Some(Operand::Mem(op2)) = &self.op2 {
if op1.is_xmm() {
Instruction::with2::<Register, MemoryOperand>(Code::Cvtsi2ss_xmm_rm32, (*op1).into(), op2.into())?
} else { todo!("{}", self) }
} else { todo!("{}", self) }
} else { todo!("{}", self) }
},
Mnemonic::Cvtsi2sd => {
if let Some(Operand::Reg(op1)) = &self.op1 {
if let Some(Operand::Reg(op2)) = &self.op2 {
if op1.is_xmm() {
Instruction::with2::<Register, Register>(Code::Cvtsi2sd_xmm_rm64, (*op1).into(), (*op2).into())?
} else { todo!("{}", self) }
} else if let Some(Operand::Mem(op2)) = &self.op2 {
if op1.is_xmm() {
Instruction::with2::<Register, MemoryOperand>(Code::Cvtsi2sd_xmm_rm64, (*op1).into(), op2.into())?
} else { todo!("{}", self) }
} else { todo!("{}", self) }
} else { todo!("{}", self) }
},

};

Expand Down Expand Up @@ -1359,6 +1385,8 @@ pub enum Mnemonic {
Cvtsd2si,
Cvtss2sd,
Cvtsd2ss,
Cvtsi2ss,
Cvtsi2sd,
}

impl FromStr for Mnemonic {
Expand Down Expand Up @@ -1420,6 +1448,8 @@ impl FromStr for Mnemonic {
"cvtsd2si" => Ok(Mnemonic::Cvtsd2si),
"cvtss2sd" => Ok(Mnemonic::Cvtss2sd),
"cvtsd2ss" => Ok(Mnemonic::Cvtsd2ss),
"cvtsi2ss" => Ok(Mnemonic::Cvtsi2ss),
"cvtsi2sd" => Ok(Mnemonic::Cvtsi2sd),
_ => Err(()),
}
}
Expand Down Expand Up @@ -1486,6 +1516,8 @@ impl Display for Mnemonic {
Mnemonic::Cvtsd2si => "cvtsd2si",
Mnemonic::Cvtss2sd => "cvtss2sd",
Mnemonic::Cvtsd2ss => "cvtsd2ss",
Mnemonic::Cvtsi2ss => "cvtsi2ss",
Mnemonic::Cvtsi2sd => "cvtsi2sd",
})
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/Target/x64/lower/fcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(crate) fn X64_lower_fcast(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr,

TypeMetadata::f32 => sink.push(X64MCInstr::with2(Mnemonic::Movss, Operand::Reg(output_reg), input)),
TypeMetadata::f64 => sink.push(X64MCInstr::with2(Mnemonic::Cvtss2sd, Operand::Reg(output_reg), input)),
_ => panic!("fcast can only cast from f32/f64 to i32/i64/f32/f64")
_ => panic!("fcast can only cast from f32 to i32/i64/f32/f64")
}
} else if input_type == TypeMetadata::f64 {
match instr.meta {
Expand All @@ -29,9 +29,17 @@ pub(crate) fn X64_lower_fcast(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr,

TypeMetadata::f32 => sink.push(X64MCInstr::with2(Mnemonic::Cvtsd2ss, Operand::Reg(output_reg), input)),
TypeMetadata::f64 => sink.push(X64MCInstr::with2(Mnemonic::Cvtsd2ss, Operand::Reg(output_reg), input)),
_ => panic!("fcast can only cast from f32/f64 to i32/i64/f32/f64")
_ => panic!("fcast can only cast from f64 to i32/i64/f32/f64")
}
} else { panic!("fcast expect that the input type is a float") }
} else if input_type == TypeMetadata::i32 || input_type == TypeMetadata::i64 {
match instr.meta {
TypeMetadata::f32 => sink.push(X64MCInstr::with2(Mnemonic::Cvtsi2ss, Operand::Reg(output_reg), input)),
TypeMetadata::f64 => sink.push(X64MCInstr::with2(Mnemonic::Cvtsi2sd, Operand::Reg(output_reg), input)),
_ => panic!("fcast can only cast from i32 to f32/f64")
}
} else {
panic!("fcast expects the input type to be either f32/f64/i32/i64")
}

if let Operand::Mem(out) = &out {
sink.push(if instr.meta == TypeMetadata::f32 {
Expand Down

0 comments on commit fb5aecc

Please sign in to comment.