Skip to content

Commit

Permalink
[FIX] fixed signed zext
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Oct 30, 2024
1 parent ddaad90 commit 55d936a
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 48 deletions.
4 changes: 2 additions & 2 deletions src/CodeGen/compilation/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ impl CompilationHelper {
let op = {
if node.inner1.ty.float() || node.inner2.float() {
MachineMnemonic::FCast
} else if node.inner1.ty.bitSize() > node.inner2.bitSize() {
} else if node.inner1.ty.bitSize() < node.inner2.bitSize() {
MachineMnemonic::Zext
} else if node.inner1.ty.bitSize() < node.inner2.bitSize(){
} else if node.inner1.ty.bitSize() > node.inner2.bitSize(){
MachineMnemonic::Downcast
} else {
return;
Expand Down
21 changes: 12 additions & 9 deletions src/CodeGen/compilation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,23 @@ impl CompilationHelper {
}

pub(crate) fn alloc_stack(&mut self, ty: TypeMetadata) -> VarLocation {
if let Some(alloc_stack) = self.alloc.alloc_stack {
let out = if let Some(alloc_stack) = self.alloc.alloc_stack {
alloc_stack(&mut self.alloc, ty)
} else { panic!("no registered stack allocation function for {:?}", self.arch) }
} else { panic!("no registered stack allocation function for {:?}", self.arch) };

self.epilog = self.alloc.epilog;

out
}

pub(crate) fn alloc_rv(&mut self, ty: TypeMetadata) -> VarLocation {
if let Some(alloc) = self.alloc.alloc_rv {
let out = if let Some(alloc) = self.alloc.alloc_rv {
alloc(&mut self.alloc, ty)
} else { panic!("no registered allocation function for {:?}", self.arch) }
} else { panic!("no registered allocation function for {:?}", self.arch) };

self.epilog = self.alloc.epilog;

out
}

pub(crate) fn free(&mut self, loc: VarLocation) {
Expand All @@ -155,11 +163,6 @@ impl CompilationHelper {

with_name
}

#[inline]
pub(crate) fn epilog(&self) -> bool {
self.epilog
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down
16 changes: 6 additions & 10 deletions src/CodeGen/compilation/prolog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@ use super::CompilationHelper;
impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_prolog(&mut self, sink: &mut Vec<MachineInstr>) {
if self.epilog() {
let mut instr = MachineInstr::new( MachineMnemonic::Prolog );
instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) );
let mut instr = MachineInstr::new( MachineMnemonic::Prolog );
instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) );

sink.push( instr );
}
sink.push( instr );
}

#[allow(missing_docs)]
pub fn compile_epilog(&mut self, sink: &mut Vec<MachineInstr>) {
if self.epilog() {
let mut instr = MachineInstr::new( MachineMnemonic::Epilog );
instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) );
let mut instr = MachineInstr::new( MachineMnemonic::Epilog );
instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) );

sink.push( instr );
}
sink.push( instr );
}
}
4 changes: 2 additions & 2 deletions src/CodeGen/reg_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl RegVec {
}
}

pub(crate) fn inner(&mut self, arch: Arch) -> &mut Vec<Reg> {
/*pub(crate) fn inner(&mut self, arch: Arch) -> &mut Vec<Reg> {
let keys = self.regs.clone();
let keys = keys.keys();
Expand All @@ -50,5 +50,5 @@ impl RegVec {
} else {
panic!("unkown entry: {:?} (known entrys: {:?})", arch, keys)
}
}
}*/
}
4 changes: 2 additions & 2 deletions src/Target/target_descr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ impl TargetBackendDescr {
let mut ir_helper = IrCodeGenHelper::new(helper.to_owned());

for node in block.nodes.to_owned() {
if ir_helper.helper.epilog() {
if ir_helper.helper.alloc.epilog {
self.epilog = true;
}

// VERY UGLY CODE WHICH SINCRONICES THE MAX STACK_OFF
// VERY UGLY CODE WHICH SYNCS THE MAX STACK_OFF
// OF EITHER ir_helper or helper (the one who has the biggest gets selected)
if helper.alloc.stack_off < ir_helper.helper.alloc.stack_off {
helper.alloc.stack_off = ir_helper.helper.alloc.stack_off;
Expand Down
39 changes: 39 additions & 0 deletions src/Target/x64/asm/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,39 @@ impl X64MCInstr {
} else { todo!("{}", self)}
} else { todo!("{}", self) }
},
Mnemonic::Movsx => {
if let Some(Operand::Reg(op1)) = &self.op1 {
if let Some(Operand::Reg(op2)) = &self.op2 {
if op1.is_gr64() {
if op2.is_gr16() {
Instruction::with2::<Register, Register>(Code::Movsx_r64_rm16, (*op1).into(), (*op2).into())?
} else if op2.is_gr8() {
Instruction::with2::<Register, Register>(Code::Movsx_r64_rm8, (*op1).into(), (*op2).into())?
} else { todo!("{}", self) }
} else if op1.is_gr32() {
if op2.is_gr16() {
Instruction::with2::<Register, Register>(Code::Movsx_r32_rm16, (*op1).into(), (*op2).into())?
} else if op2.is_gr8() {
Instruction::with2::<Register, Register>(Code::Movsx_r32_rm8, (*op1).into(), (*op2).into())?
} else { todo!("{}", self) }
} else if op1.is_gr16() {
if op2.is_gr16() {
Instruction::with2::<Register, Register>(Code::Movsx_r32_rm16, (*op1).into(), (*op2).into())?
} else if op2.is_gr8() {
Instruction::with2::<Register, Register>(Code::Movsx_r32_rm8, (*op1).into(), (*op2).into())?
} else { todo!("{}", self) }
} else { todo!("{}", self)}
} else if let Some(Operand::Mem(op2)) = &self.op2 {
if op1.is_gr64() {
Instruction::with2::<Register, MemoryOperand>(Code::Movsx_r64_rm16, (*op1).into(), op2.into())?
} else if op1.is_gr32() {
Instruction::with2::<Register, MemoryOperand>(Code::Movsx_r32_rm16, (*op1).into(), op2.into())?
} else if op1.is_gr16() {
Instruction::with2::<Register, MemoryOperand>(Code::Movsx_r16_rm16, (*op1).into(), op2.into())?
} else {todo!("{}", self) }
} else { todo!("{}", self)}
} else { todo!("{}", self) }
},
Mnemonic::Push => {
if let Some(Operand::Reg(op1)) = &self.op1 {
if op1.is_gr64() {
Expand Down Expand Up @@ -1347,6 +1380,7 @@ pub enum Mnemonic {
Lea,
Mov,
Movzx,
Movsx,
Push,
Pop,
Ret,
Expand Down Expand Up @@ -1494,6 +1528,7 @@ impl FromStr for Mnemonic {
"cwd" => Ok(Mnemonic::Cwd),
"cdq" => Ok(Mnemonic::Cdq),
"cqo" => Ok(Mnemonic::Cqo),
"movsx" => Ok(Mnemonic::Movsx),
_ => Err(()),
}
}
Expand Down Expand Up @@ -1570,6 +1605,7 @@ impl Display for Mnemonic {
Mnemonic::Cwd => "cwd",
Mnemonic::Cdq => "cdq",
Mnemonic::Cqo => "cqo",
Mnemonic::Movsx => "movxz",
})
}
}
Expand Down Expand Up @@ -1923,6 +1959,7 @@ IsCheckerOps0!(is_cmp, Mnemonic::Cmp);
IsCheckerOps0!(is_lea, Mnemonic::Lea);
IsCheckerOps0!(is_mov, Mnemonic::Mov);
IsCheckerOps0!(is_movzx, Mnemonic::Movzx);
IsCheckerOps0!(is_movsx, Mnemonic::Movsx);
IsCheckerOps0!(is_push, Mnemonic::Push);
IsCheckerOps0!(is_pop, Mnemonic::Pop);
IsCheckerOps0!(is_ret, Mnemonic::Ret);
Expand Down Expand Up @@ -1995,6 +2032,7 @@ IsCheckerOps1!(is_cmp1, Mnemonic::Cmp);
IsCheckerOps1!(is_lea1, Mnemonic::Lea);
IsCheckerOps1!(is_mov1, Mnemonic::Mov);
IsCheckerOps1!(is_movzx1, Mnemonic::Movzx);
IsCheckerOps1!(is_movsx1, Mnemonic::Movsx);
IsCheckerOps1!(is_push1, Mnemonic::Push);
IsCheckerOps1!(is_pop1, Mnemonic::Pop);
IsCheckerOps1!(is_imul1, Mnemonic::Imul);
Expand Down Expand Up @@ -2054,6 +2092,7 @@ IsCheckerOps2!(is_cmp2, Mnemonic::Cmp);
IsCheckerOps2!(is_lea2, Mnemonic::Lea);
IsCheckerOps2!(is_mov2, Mnemonic::Mov);
IsCheckerOps2!(is_movzx2, Mnemonic::Movzx);
IsCheckerOps2!(is_movsx2, Mnemonic::Movsx);
IsCheckerOps2!(is_cmove2, Mnemonic::Cmove);
IsCheckerOps2!(is_cmovne2, Mnemonic::Cmovne);
IsCheckerOps2!(is_sal2, Mnemonic::Sal);
Expand Down
2 changes: 1 addition & 1 deletion src/Target/x64/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub(crate) fn construct_compilation_helper(call_conv: CallConv) -> CompilationHe
helper
}

fn x64_after_alloc(compiler: &CompilationHelper) {
fn x64_after_alloc(_compiler: &CompilationHelper) {
/*if compiler.alloc.stack_off - 8 < compiler.call.shadow(compiler.arch) {
unsafe {
super::lower::USE_SP_FOR_STACK = true;
Expand Down
22 changes: 7 additions & 15 deletions src/Target/x64/lower/zext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,35 @@ use crate::Target::x64::X64Reg;
use crate::Target::x64::asm::instr::*;

pub(crate) fn x64_lower_zext(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {

let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(0).expect("expected a secound operand");
let out = instr.out.expect("expected a output operand");

let mut movxz = false;

let op1 = (*op1).into();

let op2 = (*op2).into();

let out = out.into();

if let Operand::Reg(op1) = op1 {
if let Operand::Reg(op2) = op2 {
if (op1.is_gr16() | op1.is_gr8()) && (op2.is_gr32() | op2.is_gr64()) { // movxz allowes a gr8/16 zext into gr32/64
if let Operand::Reg(out) = out {
if (op1.is_gr16() | op1.is_gr8()) && (out.is_gr32() | out.is_gr64()) { // movxz allowes a gr8/16 zext into gr32/64
movxz = true;
}
}
}

if movxz {
let mnemonic = if instr.meta.signed() { Mnemonic::Movsx } else { Mnemonic::Movzx };

let tmp = Operand::Reg(X64Reg::Rax.sub_ty(instr.meta).sub_ty(instr.meta));

sink.push(X64MCInstr::with2(Mnemonic::Mov, tmp.clone(), op1));
sink.push(X64MCInstr::with2(Mnemonic::Movzx, tmp.clone(), op2));
sink.push(X64MCInstr::with2(mnemonic, tmp.clone(), op1));
sink.push(X64MCInstr::with2(Mnemonic::Mov, out, tmp));
} else {
let tmp = Operand::Reg(X64Reg::Rax.sub_ty(instr.meta).sub_ty(instr.meta));

if op1 == out {
sink.push(X64MCInstr::with2(Mnemonic::Mov, op1, op2));
} else {
sink.push(X64MCInstr::with2(Mnemonic::Mov, tmp.clone(), op1));
sink.push(X64MCInstr::with2(Mnemonic::Mov, tmp.clone(), op2));
sink.push(X64MCInstr::with2(Mnemonic::Mov, out, tmp));
}
sink.push(X64MCInstr::with2(Mnemonic::Mov, tmp.clone(), op1));
sink.push(X64MCInstr::with2(Mnemonic::Mov, out, tmp.clone()));
}

}
12 changes: 6 additions & 6 deletions src/Target/x64/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,25 +154,25 @@ fn X64MergeAdd(instr0: &X64MCInstr, instr1: &X64MCInstr, instr2: &X64MCInstr) ->
return None;
}

let mut out = instr2.op1.clone();
let mut ls = instr0.op2.clone();
let mut rs = instr1.op2.clone();
let out = instr2.op1.clone();
let ls = instr0.op2.clone();
let rs = instr1.op2.clone();

if let Some(Operand::Reg(reg)) = out {
if !(reg.is_gr32() || reg.is_gr64()) {
out = Some(Operand::Reg(reg.sub16()))
return None;
}
}

if let Some(Operand::Reg(reg)) = ls {
if !(reg.is_gr32() || reg.is_gr64()) {
ls = Some(Operand::Reg(reg.sub64()))
return None;
}
}

if let Some(Operand::Reg(reg)) = rs {
if !(reg.is_gr32() || reg.is_gr64()) {
rs = Some(Operand::Reg(reg.sub64()))
return None;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Target/x64/reg_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub(crate) fn x64_alloc_stack(alloc: &mut Allocator, ty: TypeMetadata) -> VarLoc
alloc.epilog = true;

let ret = VarLocation::Mem(alloc.stack_off, ty);
alloc.stack_off += ty.byteSize() as i64;
alloc.stack_off += 8; // alignment

ret
}
Expand Down

0 comments on commit 55d936a

Please sign in to comment.