Skip to content

Commit

Permalink
Added more tests for instruction emulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ledmington committed Dec 15, 2024
1 parent 61f4660 commit 975f77f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 11 deletions.
16 changes: 10 additions & 6 deletions emu/src/main/java/com/ledmington/emu/X86Cpu.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,23 @@ public void executeOne(final Instruction inst) {
if (inst.firstOperand() instanceof Register8 r1_8 && inst.secondOperand() instanceof Register8 r2_8) {
rf.set(r1_8, BitUtils.xor(rf.get(r1_8), rf.get(r2_8)));
} else if (inst.firstOperand() instanceof Register32 r1_32
&& inst.secondOperand() instanceof Register8 r2_32) {
&& inst.secondOperand() instanceof Register32 r2_32) {
rf.set(r1_32, rf.get(r1_32) ^ rf.get(r2_32));
} else if (inst.firstOperand() instanceof Register64 r1_64
&& inst.secondOperand() instanceof Register64 r2_64) {
rf.set(r1_64, rf.get(r1_64) ^ rf.get(r2_64));
} else {
throw new IllegalArgumentException(String.format("Don't know what to do with %s", inst));
}
}
case AND -> {
if (inst.firstOperand() instanceof Register64 r64) {
final long imm64 = ((Immediate) inst.secondOperand()).asLong();
rf.set(r64, rf.get(r64) & imm64);
if (inst.firstOperand() instanceof Register64 r1 && inst.secondOperand() instanceof Register64 r2) {
rf.set(r1, rf.get(r1) & rf.get(r2));
} else if (inst.firstOperand() instanceof Register64 r1
&& inst.secondOperand() instanceof Immediate imm) {
rf.set(r1, rf.get(r1) & imm.asLong());
} else {
throw new IllegalArgumentException(
String.format("Unknown type of first operand '%s'", inst.firstOperand()));
throw new IllegalArgumentException(String.format("Don't know what to do with %s", inst));
}
}
case TEST -> {
Expand Down
60 changes: 55 additions & 5 deletions emu/src/test/java/com/ledmington/emu/TestExecution.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Arrays;
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
import java.util.stream.Stream;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import com.ledmington.cpu.x86.Instruction;
import com.ledmington.cpu.x86.Opcode;
Expand Down Expand Up @@ -71,10 +75,14 @@ void setup() {
}
}

@Test
void add() {
final Register64 r1 = Register64.values()[rng.nextInt(0, Register64.values().length)];
final Register64 r2 = Register64.values()[rng.nextInt(0, Register64.values().length)];
private static Stream<Arguments> pairs() {
return Arrays.stream(Register64.values())
.flatMap(r -> Arrays.stream(Register64.values()).map(x -> Arguments.of(r, x)));
}

@ParameterizedTest
@MethodSource("pairs")
void add(final Register64 r1, final Register64 r2) {
final long oldValue1 = cpu.getRegisters().get(r1);
final long oldValue2 = cpu.getRegisters().get(r2);
final X86RegisterFile expected = new X86RegisterFile(cpu.getRegisters());
Expand All @@ -85,4 +93,46 @@ void add() {
cpu.getRegisters(),
() -> String.format("Expected register file to be '%s' but was '%s'.", expected, cpu.getRegisters()));
}

@ParameterizedTest
@MethodSource("pairs")
void sub(final Register64 r1, final Register64 r2) {
final long oldValue1 = cpu.getRegisters().get(r1);
final long oldValue2 = cpu.getRegisters().get(r2);
final X86RegisterFile expected = new X86RegisterFile(cpu.getRegisters());
expected.set(r1, oldValue1 - oldValue2);
cpu.executeOne(new Instruction(Opcode.SUB, r1, r2));
assertEquals(
expected,
cpu.getRegisters(),
() -> String.format("Expected register file to be '%s' but was '%s'.", expected, cpu.getRegisters()));
}

@ParameterizedTest
@MethodSource("pairs")
void xor(final Register64 r1, final Register64 r2) {
final long oldValue1 = cpu.getRegisters().get(r1);
final long oldValue2 = cpu.getRegisters().get(r2);
final X86RegisterFile expected = new X86RegisterFile(cpu.getRegisters());
expected.set(r1, oldValue1 ^ oldValue2);
cpu.executeOne(new Instruction(Opcode.XOR, r1, r2));
assertEquals(
expected,
cpu.getRegisters(),
() -> String.format("Expected register file to be '%s' but was '%s'.", expected, cpu.getRegisters()));
}

@ParameterizedTest
@MethodSource("pairs")
void and(final Register64 r1, final Register64 r2) {
final long oldValue1 = cpu.getRegisters().get(r1);
final long oldValue2 = cpu.getRegisters().get(r2);
final X86RegisterFile expected = new X86RegisterFile(cpu.getRegisters());
expected.set(r1, oldValue1 & oldValue2);
cpu.executeOne(new Instruction(Opcode.AND, r1, r2));
assertEquals(
expected,
cpu.getRegisters(),
() -> String.format("Expected register file to be '%s' but was '%s'.", expected, cpu.getRegisters()));
}
}

0 comments on commit 975f77f

Please sign in to comment.