Skip to content

Commit

Permalink
[X64] implementing all necessary instructions for conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Sep 11, 2024
1 parent 697ff08 commit 5ea4ecf
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
37 changes: 33 additions & 4 deletions src/Target/x64/asm/instr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::{fmt::Display, ops::{Add, Sub}, str::FromStr};

use crate::{CodeGen::MCInstr, Obj::Link, Support::{ColorClass, ColorProfile}, Target::{x64::isa::{buildOpcode, MandatoryPrefix, RexPrefix}, x64Reg}};
use crate::CodeGen::MCInstr;
use crate::Obj::Link;
use crate::Support::{ColorClass, ColorProfile};
use crate::Target::x64::isa::{buildOpcode, MandatoryPrefix, RexPrefix};
use crate::Target::x64::x64Reg;

use super::isa::ModRm;

Expand Down Expand Up @@ -48,7 +51,7 @@ impl X64MCInstr {
self.verify()?;

Ok(match self.mnemonic {
Mnemonic::Add | Mnemonic::Adc | Mnemonic::And | Mnemonic::Or | Mnemonic::Sub | Mnemonic::Xor | Mnemonic::Mov => {
Mnemonic::Add | Mnemonic::Adc | Mnemonic::And | Mnemonic::Or | Mnemonic::Sub | Mnemonic::Xor | Mnemonic::Mov | Mnemonic::Cmp => {
let mandatory = if let Some(Operand::Reg(reg)) = &self.op1 {
if reg.is_gr16() { Some(MandatoryPrefix::t16BitOps)}
else { None }
Expand All @@ -62,6 +65,8 @@ impl X64MCInstr {
Mnemonic::Or => (0x09, 0x0B, 1, 0x81, 0x80),
Mnemonic::Xor => (0x31, 0x33, 6, 0x81, 0x80),
Mnemonic::Mov => (0x89, 0x8B, 0, 0xC7, 0xC6),

Mnemonic::Cmp => (0x83, 0x3B, 7, 0x81, 0x80),
_ => unreachable!(),
};

Expand Down Expand Up @@ -310,6 +315,19 @@ impl X64MCInstr {

(buildOpcode(None, None, op), None)
}
Mnemonic::Jne => {
let mut op = vec![0x0F, 0x85];

if let Some(Operand::Imm(num)) = self.op1 {
let bytes = num.to_be_bytes();
op.push( bytes[7] );
op.push( bytes[6] );
op.push( bytes[5] );
op.push( bytes[4] );
} else { unreachable!() }

(buildOpcode(None, None, op), None)
}
Mnemonic::Link => {
if let Some(Operand::LinkDestination(dst, addend)) = &self.op1 {
(vec![], Some(Link { from: "".into(), to: dst.to_string(), at: 0, addend: *addend, special: false }))
Expand Down Expand Up @@ -387,7 +405,7 @@ impl X64MCInstr {
}
}
},
Mnemonic::Add | Mnemonic::Adc | Mnemonic::Sub | Mnemonic::And | Mnemonic::Or | Mnemonic::Xor => {
Mnemonic::Add | Mnemonic::Adc | Mnemonic::Sub | Mnemonic::And | Mnemonic::Or | Mnemonic::Xor | Mnemonic::Cmp => {
if self.op2 == None || self.op1 == None {
Err(InstrEncodingError::InvalidVariant(self.clone(), "add/sub/and/or/xor needs to have two operand".into()))?
}
Expand Down Expand Up @@ -452,6 +470,11 @@ impl X64MCInstr {
))?
}
}
Mnemonic::Jne => {
if let Some(Operand::Imm(_)) = self.op1 {} else {
Err(InstrEncodingError::InvalidVariant(self.to_owned(), "jne expects one imm as its ops".to_owned()))?
}
}
};

Ok(())
Expand Down Expand Up @@ -616,6 +639,7 @@ pub enum Mnemonic {
Or,
Xor,
Sub,
Cmp,

Lea,
Mov,
Expand All @@ -629,6 +653,7 @@ pub enum Mnemonic {

Call,
Jmp,
Jne,

Endbr64,

Expand Down Expand Up @@ -664,6 +689,8 @@ impl FromStr for Mnemonic {
"endbr64" => Ok(Mnemonic::Endbr64),
"imul" => Ok(Mnemonic::Imul),
"mul" => Ok(Mnemonic::Mul),
"jne" => Ok(Mnemonic::Jne),
"cmp" => Ok(Mnemonic::Cmp),
_ => Err(()),
}
}
Expand Down Expand Up @@ -693,6 +720,8 @@ impl Display for Mnemonic {
Mnemonic::StartOptimization => "",
Mnemonic::EndOptimization => "",
Mnemonic::Debug => "#",
Mnemonic::Jne => "jne",
Mnemonic::Cmp => "cmp",
})
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/Target/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,11 @@ fn x64_lower_cond_br(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr, iftrue: &
},
};

X64MCInstr::with2(Mnemonic::Cmp, src, value);
X64MCInstr::with1(Mnemonic::Jne, Operand::Imm(0));
X64MCInstr::with1(Mnemonic::Link, Operand::BlockLinkDestination(iffalse.to_owned(), -4));
X64MCInstr::with1(Mnemonic::Jmp, Operand::Imm(0));
X64MCInstr::with1(Mnemonic::Link, Operand::BlockLinkDestination(iftrue.to_owned(), -4));
sink.push(X64MCInstr::with2(Mnemonic::Cmp, src, value));
sink.push(X64MCInstr::with1(Mnemonic::Jne, Operand::Imm(0)));
sink.push(X64MCInstr::with1(Mnemonic::Link, Operand::BlockLinkDestination(iffalse.to_owned(), -4)));
sink.push(X64MCInstr::with1(Mnemonic::Jmp, Operand::Imm(0)));
sink.push(X64MCInstr::with1(Mnemonic::Link, Operand::BlockLinkDestination(iftrue.to_owned(), -4)));
}

macro_rules! LowerSimpleMath {
Expand Down

0 comments on commit 5ea4ecf

Please sign in to comment.