Skip to content

Commit

Permalink
[TEST] starting tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Aug 25, 2024
1 parent 1e47c54 commit 5a230b2
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 17 deletions.
14 changes: 10 additions & 4 deletions src/IR/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ impl Function {
let mut fmt = String::new();

for (name, metadata) in &self.ty.args {
fmt += &format!("{} %{},", metadata, name);
fmt += &format!("{} %{}, ", metadata, name);
}

if self.ty.args.len() > 0 {
fmt.remove(fmt.chars().count() - 1); // The last space
fmt.remove(fmt.chars().count() - 1); // The last comma
}

fmt
Expand All @@ -130,11 +135,12 @@ impl Function {
let mut fmt = String::new();

for (name, metadata) in &self.ty.args {
fmt += &format!("{} %{},", metadata, name);
fmt += &format!("{} %{}, ", metadata, name);
}

if self.ty.args.len() != 0 {
fmt.remove(fmt.len() - 2); // The last comma
if self.ty.args.len() > 0 {
fmt.remove(fmt.chars().count() - 1); // The last space
fmt.remove(fmt.chars().count() - 1); // The last comma
}

fmt
Expand Down
2 changes: 1 addition & 1 deletion src/Obj/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ impl ObjectBuilder {
let mut offset = 0;

if self.triple.getCallConv() == Ok(CallConv::WindowsFastCall) {
//addend = -1;
addend = -1;
offset = -4;
} else if self.triple.getCallConv() == Ok(CallConv::SystemV) {
addend = 0;
Expand Down
6 changes: 4 additions & 2 deletions src/Target/x64/asm/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Instr {
else { None }
} else { None };

let (mut r, mut m, mut i, ibase, ibase8) = match self.mnemonic {
let (mut r, mut m, i, ibase, ibase8) = match self.mnemonic {
Mnemonic::Add => (0x01, 0x03, 0, 0x81, 0x80),
Mnemonic::Adc => (0x11, 0x03, 2, 0x81, 0x80),
Mnemonic::Sub => (0x29, 0x2B, 5, 0x81, 0x80),
Expand All @@ -66,7 +66,9 @@ impl Instr {
};

if let Some(Operand::Reg(reg)) = &self.op1 {
if reg.is_gr8() { r -= 1; m -= 1; i -= 1; }
if reg.is_gr8() {
r -= 1; m -= 1;
}
}

(match self.op2.as_ref().expect("verifycation failed") {
Expand Down
15 changes: 5 additions & 10 deletions src/Target/x64/compilation/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T

let mut asm = vec![];

let mut to_pop = vec![];

for reg in vec![x64Reg::Rcx, x64Reg::Rdx, x64Reg::Rsi, x64Reg::Rdi, x64Reg::Rsi] { // save mutable registers
if !registry.backend.openUsableRegisters64.contains(&reg.boxed()) {
let var = registry.backend.getVarByReg(reg.boxed()).cloned();

if let Some(var) = var {
if block.isVarUsedAfterNode(&boxed, &var) {
asm.push(Instr::with1(Mnemonic::Push, Operand::Reg(reg.boxed())));
to_pop.push(reg);
}
}
}
Expand Down Expand Up @@ -104,16 +107,8 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T
registry.backend.insertVar(call.inner3.clone(), store);
}

for reg in vec![x64Reg::Rcx, x64Reg::Rdx, x64Reg::Rsi, x64Reg::Rdi, x64Reg::Rsi] { // getback mutable registers
if !registry.backend.openUsableRegisters64.contains(&reg.boxed()) {
let var = registry.backend.getVarByReg(reg.boxed()).cloned();

if let Some(var) = var {
if block.isVarUsedAfterNode(&boxed, &var) {
asm.push(Instr::with1(Mnemonic::Pop, Operand::Reg(reg.boxed())));
}
}
}
for reg in to_pop {
asm.push(Instr::with1(Mnemonic::Pop, Operand::Reg(reg.boxed())));
}

asm
Expand Down
30 changes: 30 additions & 0 deletions tests/ir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use ygen::prelude::*;

#[test]
pub fn ir_optimization() {
let mut module = Module();

let mut builder = IRBuilder();

let other = module.add("cfunc", &FnTy(vec![TypeMetadata::i32, TypeMetadata::i32], TypeMetadata::i32));
other.import();
let other = other.clone();

let ty = FnTy(vec![TypeMetadata::i32, TypeMetadata::i32], TypeMetadata::i32);

let func = module.add(
"add", &ty
);

func.extrn();

let entry = func.addBlock("entry");
builder.positionAtEnd(entry);

let val = builder.BuildCall( &other, vec![ty.arg(0), ty.arg(1)] );
let val = builder.BuildAdd(val, ty.arg(0));

builder.BuildRet( val );

//assert_eq!(module.dump(), "define i32 @add(i32 %0, i32 %1) {\n entry:\n\t%2 = call i32 cfunc i32 %0 i32 %1 \n\tadd = %3 i32 %2, %0\n\tret i32 %3\n\n}\ndeclare i32 @cfunc(i32 %0, i32 %1)\n\n".to_string());
}
45 changes: 45 additions & 0 deletions tests/x64_instruction_encoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use ygen::{Optimizations::auto_max_optimize, Target::{instr::*, x64Reg, Reg}};

#[test]
pub fn test_mov() {
let instr = Instr::with2(
Mnemonic::Mov,
Operand::Reg(x64Reg::Rcx.boxed()),
Operand::Mem(MemOp { base: Some(x64Reg::R15.boxed()), index: None, scale: 1, displ: 5, rip: false })
);

assert_eq!(instr.encode(), Ok((vec![0x49, 0x8B, 0x4F, 0x05], None)));

let instr = Instr::with2(
Mnemonic::Mov,
Operand::Reg(x64Reg::R12b.boxed()),
Operand::Imm(12)
);

assert_eq!(instr.encode(), Ok((vec![0x41, 0xC6, 0xC4, 0x0C], None)));
}

#[test]
pub fn test_ret() {
let instr = Instr::with0(Mnemonic::Ret);

assert_eq!(instr.encode(), Ok((vec![0xC3], None)));
}

#[test]
pub fn test_optimization() {
let mut instrs = vec![
Instr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rax.boxed()), Operand::Reg(x64Reg::Rcx.boxed())),
Instr::with2(Mnemonic::Add, Operand::Reg(x64Reg::Rax.boxed()), Operand::Reg(x64Reg::Rdx.boxed())),
Instr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rcx.boxed()), Operand::Reg(x64Reg::Rax.boxed())),
];

let expected_optimized = vec![
Instr::with2(Mnemonic::Lea, Operand::Reg(x64Reg::Rax.boxed()), Operand::Mem(x64Reg::Rcx + x64Reg::Rdx)),
Instr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rcx.boxed()), Operand::Reg(x64Reg::Rax.boxed())),
];

auto_max_optimize(&mut instrs);

assert_eq!(instrs, expected_optimized);
}

0 comments on commit 5a230b2

Please sign in to comment.