Skip to content

Commit

Permalink
Merge pull request #1661 from nicolasnoble/more-cpu-tests
Browse files Browse the repository at this point in the history
More CPU tests
  • Loading branch information
nicolasnoble committed Jun 11, 2024
2 parents ac177b3 + 7efd6ba commit 4be370f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/mips/tests/cop0/cester-cop0.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ CESTER_BODY(
uint32_t cpu_LWR_LWL_half(uint32_t buff[], uint32_t initial);
uint32_t cpu_LWR_LWL_nodelay(uint32_t buff[], uint32_t initial);
uint32_t cpu_LWR_LWL_delayed(uint32_t buff[], uint32_t initial);
uint32_t cpu_LWR_LWL_load_different(uint32_t buff[], uint32_t initial);
uint32_t cpu_LW_LWR(uint32_t buff[], uint32_t initial);
uint32_t cpu_delayed_load(uint32_t buff[], uint32_t override);
uint32_t cpu_delayed_load_cancelled(uint32_t buff[], uint32_t override);
uint64_t cpu_delayed_load_load(uint32_t buff[], uint32_t override);
uint32_t linkandload();
uint32_t lwandlink();
uint32_t nolink();
Expand Down
23 changes: 22 additions & 1 deletion src/mips/tests/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ CESTER_TEST(cpu_LWR_LWL_delayed, cpu_tests,
cester_assert_uint_eq(0x88112233, out);
)

CESTER_TEST(cpu_LWR_LWL_load_different, cpu_tests,
uint32_t buff[3] = {0x11223344, 0x55667788, 0xaabbccdd};
uint32_t out = cpu_LWR_LWL_load_different(buff, 0xeeffeffe);
cester_assert_uint_eq(0x88556677, out);
)

CESTER_TEST(cpu_LW_LWR, cpu_tests,
uint32_t buff[3] = {0x11223344, 0x55667788, 0xaabbccdd};
uint32_t out = cpu_LW_LWR(buff, 0xeeffeffe);
cester_assert_uint_eq(0xaa112233, out);
)

CESTER_TEST(cpu_delayed_load, cpu_tests,
uint32_t buff[1] = {1};
// As lw has a delayed load, the old value of the loaded
Expand All @@ -100,10 +112,19 @@ CESTER_TEST(cpu_delayed_load_cancelled, cpu_tests,
// move into the same register, the delayed load is
// cancelled, and the register will contain the new
// value
uint32_t out = cpu_delayed_load(buff, 0);
uint32_t out = cpu_delayed_load_cancelled(buff, 0);
cester_assert_uint_eq(0, out);
)

CESTER_MAYBE_TEST(cpu_delayed_load_load, cpu_tests,
uint32_t buff[2] = {1, 2};
// The above becomes complicated once you have two
// lw instructions in a row loading the same register
uint64_t out = cpu_delayed_load_load(buff, 4);
out = ((out >> 16) | out) & 0xffffffff;
cester_assert_uint_eq(0x00020004, out);
)

CESTER_MAYBE_TEST(cpu_BRANCH_BRANCH_slot, cpu_tests,
// running a branch in a branch delay slot is technically
// not allowed, but some games still do this, and the
Expand Down
16 changes: 16 additions & 0 deletions src/mips/tests/cpu/loads.s
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SOFTWARE.
.type cpu_delayed_load, @function

/* This can happen. */
/* uint32_t cpu_delayed_load(uint32_t buff[], uint32_t override); */
cpu_delayed_load:
lw $a1, 0($a0)
move $v0, $a1
Expand All @@ -43,8 +44,23 @@ cpu_delayed_load:
.type cpu_delayed_load_cancelled, @function

/* This happens even more frequently. */
/* uint32_t cpu_delayed_load_cancelled(uint32_t buff[], uint32_t override); */
cpu_delayed_load_cancelled:
lw $v0, 0($a0)
move $v0, $a1
jr $ra
nop

.align 2
.global cpu_delayed_load_load
.type cpu_delayed_load_load, @function

/* This is extremely infrequent */
/* uint64_t cpu_delayed_load_load(uint32_t buff[], uint32_t override); */
cpu_delayed_load_load:
lw $a1, 0($a0)
lw $a1, 4($a0)
move $v0, $a1
move $v1, $a1
jr $ra
nop
24 changes: 24 additions & 0 deletions src/mips/tests/cpu/lwlr.s
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SOFTWARE.
.type cpu_LWR_LWL_half, @function

/* While this usage is rare, it is technically valid and allowed. */
/* uint32_t cpu_LWR_LWL_half(uint32_t buff[], uint32_t initial); */
cpu_LWR_LWL_half:
lwl $a1, 4($a0)
jr $ra
Expand All @@ -43,6 +44,7 @@ cpu_LWR_LWL_half:

/* This is technically invalid, and undefined behaviour. The result will be
deterministic however on the r3000a PSX CPU. */
/* uint32_t cpu_LWR_LWL_delayed(uint32_t buff[], uint32_t initial); */
cpu_LWR_LWL_nodelay:
lwl $a1, 4($a0)
lwr $a1, 1($a0)
Expand All @@ -55,8 +57,30 @@ cpu_LWR_LWL_nodelay:
.type cpu_LWR_LWL_delayed, @function

/* This is the proper usage of lwl / lwr. */
/* uint32_t cpu_LWR_LWL_delayed(uint32_t buff[], uint32_t initial); */
cpu_LWR_LWL_delayed:
lwl $a1, 4($a0)
lwr $a1, 1($a0)
j $ra
move $v0, $a1

.align 2
.global cpu_LWR_LWL_load_different
.type cpu_LWR_LWL_load_different, @function

/* uint32_t cpu_LWR_LWL_load_different(uint32_t buff[], uint32_t initial); */
cpu_LWR_LWL_load_different:
lwl $a1, 4($a0)
lwr $a1, 5($a0)
j $ra
move $v0, $a1

.align 2
.global cpu_LW_LWR
.type cpu_LW_LWL, @function
/* uint32_t cpu_LW_LWR(uint32_t buff[], uint32_t initial); */
cpu_LW_LWR:
lw $a1, 8($a0)
lwr $a1, 1($a0)
j $ra
move $v0, $a1

0 comments on commit 4be370f

Please sign in to comment.