From fb5aecc1811849879ad7f372818a2e6adca2b31d Mon Sep 17 00:00:00 2001 From: TheCPP Date: Sat, 19 Oct 2024 08:04:20 +0200 Subject: [PATCH] [FIX] fixing i32/i64 to f32/f64 cast --- src/CodeGen/compilation/cast.rs | 2 +- src/Target/x64/asm/instr.rs | 32 ++++++++++++++++++++++++++++++++ src/Target/x64/lower/fcast.rs | 14 +++++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/CodeGen/compilation/cast.rs b/src/CodeGen/compilation/cast.rs index 6074a0bd..56235107 100644 --- a/src/CodeGen/compilation/cast.rs +++ b/src/CodeGen/compilation/cast.rs @@ -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 diff --git a/src/Target/x64/asm/instr.rs b/src/Target/x64/asm/instr.rs index 150d3b04..fea5891d 100644 --- a/src/Target/x64/asm/instr.rs +++ b/src/Target/x64/asm/instr.rs @@ -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::(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::(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::(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::(Code::Cvtsi2sd_xmm_rm64, (*op1).into(), op2.into())? + } else { todo!("{}", self) } + } else { todo!("{}", self) } + } else { todo!("{}", self) } + }, }; @@ -1359,6 +1385,8 @@ pub enum Mnemonic { Cvtsd2si, Cvtss2sd, Cvtsd2ss, + Cvtsi2ss, + Cvtsi2sd, } impl FromStr for Mnemonic { @@ -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(()), } } @@ -1486,6 +1516,8 @@ impl Display for Mnemonic { Mnemonic::Cvtsd2si => "cvtsd2si", Mnemonic::Cvtss2sd => "cvtss2sd", Mnemonic::Cvtsd2ss => "cvtsd2ss", + Mnemonic::Cvtsi2ss => "cvtsi2ss", + Mnemonic::Cvtsi2sd => "cvtsi2sd", }) } } diff --git a/src/Target/x64/lower/fcast.rs b/src/Target/x64/lower/fcast.rs index e3073328..2508b4b6 100644 --- a/src/Target/x64/lower/fcast.rs +++ b/src/Target/x64/lower/fcast.rs @@ -20,7 +20,7 @@ pub(crate) fn X64_lower_fcast(sink: &mut Vec, 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 { @@ -29,9 +29,17 @@ pub(crate) fn X64_lower_fcast(sink: &mut Vec, 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 {