Skip to content

Commit

Permalink
[TESTS] adding tests for all math instrs (which are supported by the …
Browse files Browse the repository at this point in the history
…x64 backend)
  • Loading branch information
Cr0a3 committed Sep 11, 2024
1 parent b72d002 commit 121f980
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 157 deletions.
202 changes: 45 additions & 157 deletions src/Target/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,74 +44,9 @@ pub(crate) fn x64_lower(conv: CallConv, instrs: Vec<MachineInstr>) -> Vec<Box<dy
mc_instrs
}

fn x64_lower_add(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(1).expect("expected a second operand");
let out = instr.out.expect("expected a output operand");

let op1 = match op1 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};


let op2 = match op2 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};

let out = match out {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

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

sink.push( X64MCInstr::with2(Mnemonic::Mov, tmp(), op1).into() );
sink.push( X64MCInstr::with2(Mnemonic::Add, tmp(), op2).into() );
sink.push( X64MCInstr::with2(Mnemonic::Mov, out, tmp()).into() );

}

fn x64_lower_div(_sink: &mut Vec<X64MCInstr>, _instr: &MachineInstr) {
todo!()
}
fn x64_lower_and(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(1).expect("expected a second operand");
let out = instr.out.expect("expected a output operand");

let op1 = match op1 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};


let op2 = match op2 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};

let out = match out {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

sink.push( X64MCInstr::with2(Mnemonic::Mov, out.clone(), op1).into() );
sink.push( X64MCInstr::with2(Mnemonic::And, out, op2).into() );
}
fn x64_lower_move(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {

let op1 = instr.operands.get(0).expect("expected a first operand");
Expand Down Expand Up @@ -180,97 +115,6 @@ fn x64_lower_mul(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
sink.push( X64MCInstr::with2(Mnemonic::Mov, out, Operand::Reg(x64Reg::Rax.sub_ty(instr.meta))).into() );
sink.push( X64MCInstr::with1(Mnemonic::Pop, Operand::Reg(x64Reg::Rdx)).into() );
}

fn x64_lower_or(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(1).expect("expected a second operand");
let out = instr.out.expect("expected a output operand");

let op1 = match op1 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};


let op2 = match op2 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};

let out = match out {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

sink.push( X64MCInstr::with2(Mnemonic::Mov, out.clone(), op1).into() );
sink.push( X64MCInstr::with2(Mnemonic::Or, out, op2).into() );
}
fn x64_lower_sub(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(1).expect("expected a second operand");
let out = instr.out.expect("expected a output operand");

let op1 = match op1 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};


let op2 = match op2 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};

let out = match out {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

sink.push( X64MCInstr::with2(Mnemonic::Mov, out.clone(), op1).into() );
sink.push( X64MCInstr::with2(Mnemonic::Sub, out, op2).into() );
}
fn x64_lower_xor(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(1).expect("expected a second operand");
let out = instr.out.expect("expected a output operand");

let op1 = match op1 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};


let op2 = match op2 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};

let out = match out {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

sink.push( X64MCInstr::with2(Mnemonic::Mov, out.clone(), op1).into() );
sink.push( X64MCInstr::with2(Mnemonic::Xor, out, op2).into() );
}
fn x64_lower_zext(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {

let op1 = instr.operands.get(0).expect("expected a first operand");
Expand Down Expand Up @@ -374,4 +218,48 @@ fn x64_lower_br(sink: &mut Vec<X64MCInstr>, _: &MachineInstr, symbol: &String) {
sink.push(
X64MCInstr::with1(Mnemonic::Link, target)
);
}
}

macro_rules! LowerSimpleMath {
($func:ident, $mnemonic:expr) => {
fn $func(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
let op1 = instr.operands.get(0).expect("expected a first operand");
let op2 = instr.operands.get(1).expect("expected a second operand");
let out = instr.out.expect("expected a output operand");

let op1 = match op1 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};


let op2 = match op2 {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(*i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(*x64),
},
};

let out = match out {
crate::CodeGen::MachineOperand::Imm(i) => Operand::Imm(i),
crate::CodeGen::MachineOperand::Reg(reg) => match reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

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

sink.push( X64MCInstr::with2(Mnemonic::Mov, tmp(), op1).into() );
sink.push( X64MCInstr::with2($mnemonic, tmp(), op2).into() );
sink.push( X64MCInstr::with2(Mnemonic::Mov, out, tmp()).into() );
}
};
}

LowerSimpleMath!(x64_lower_add, Mnemonic::Add);
LowerSimpleMath!(x64_lower_and, Mnemonic::And);
LowerSimpleMath!(x64_lower_or, Mnemonic::Or);
LowerSimpleMath!(x64_lower_sub, Mnemonic::Sub);
LowerSimpleMath!(x64_lower_xor, Mnemonic::Xor);
12 changes: 12 additions & 0 deletions tests/IR/and0.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define u32 @main() {
entry:
%1 = and u32 14, 71
ret u32 %1
}

# EXIT_CODE=6
16 changes: 16 additions & 0 deletions tests/IR/and1.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define i32 @main() {
entry:
%0 = i32 60
%1 = i32 47

%2 = and i32 %0, %1

ret i32 %2
}

# EXIT_CODE=44
14 changes: 14 additions & 0 deletions tests/IR/and2.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define i32 @main() {
entry:
%0 = i32 34
%1 = and i32 %0, 99

ret i32 %1
}

# EXIT_CODE=34
12 changes: 12 additions & 0 deletions tests/IR/mul0.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define u32 @main() {
entry:
%1 = mul u32 13, 10
ret u32 %1
}

# EXIT_CODE=130
16 changes: 16 additions & 0 deletions tests/IR/mul1.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define i32 @main() {
entry:
%0 = i32 11
%1 = i32 14

%2 = mul i32 %0, %1

ret i32 %2
}

# EXIT_CODE=154
14 changes: 14 additions & 0 deletions tests/IR/mul2.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define i32 @main() {
entry:
%0 = i32 4
%1 = mul i32 %0, 3

ret i32 %1
}

# EXIT_CODE=12
12 changes: 12 additions & 0 deletions tests/IR/or0.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define u32 @main() {
entry:
%1 = or u32 56, 92
ret u32 %1
}

# EXIT_CODE=124
16 changes: 16 additions & 0 deletions tests/IR/or1.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define i32 @main() {
entry:
%0 = i32 51
%1 = i32 57

%2 = or i32 %0, %1

ret i32 %2
}

# EXIT_CODE=59
14 changes: 14 additions & 0 deletions tests/IR/or2.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define i32 @main() {
entry:
%0 = i32 29
%1 = or i32 %0, 26

ret i32 %1
}

# EXIT_CODE=31
12 changes: 12 additions & 0 deletions tests/IR/sub0.yl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RUN:
cargo run -p ylc -- -in=%s -o=out.o
gcc out.o -o a.exe
./a.exe
# IN:
define u32 @main() {
entry:
%1 = sub u32 47, 33
ret u32 %1
}

# EXIT_CODE=14
Loading

0 comments on commit 121f980

Please sign in to comment.