|
Nugget
Bare-metal libraries and examples for the original PlayStation
|
Functions | |
| copy_fn (B, U, timed=True) | |
| set_fn (U, timed=True) | |
| thunk_fn (target) | |
| build () | |
Variables | |
| str | LICENSE |
| list | COPIES = [(2, 2), (4, 4), (8, 8), (8, 16), (8, 32), (2, 32), (4, 32), (16, 16), (16, 32)] |
| list | SETS = [1, 2, 4, 8, 16, 32, 64] |
| list | TREGS = ["$t%d" % i for i in range(8)] |
| list | SREGS = ["$s%d" % i for i in range(8)] |
| list | TIMER_START = [" lui $t9, 0x1f80", " lhu $t8, 0x1120($t9)"] |
| list | TIMER_STOP |
| list | BARE_COPIES = [(8, 8)] |
| list | BARE_SETS = [4] |
| list | THUNKS = ["__wrap_memcpy", "__wrap_memset", "copy_b8_u8_bare", "set_u4_bare"] |
| text = build() | |
| cur = open("kernels.s").read() | |
Regenerates kernels.s.
The sweep is a grid, so its assembly is data: nine copy kernels crossing batch
depth with unroll depth, seven set kernels, and an icache-sized block of nops.
Writing those by hand is 1700 lines of transcription and every one of them is a
chance to get an offset wrong - which is the bug the whole test exists to find.
Edit the COPIES and SETS lists below and re-run; do not hand-edit kernels.s.
./gen.py rewrite kernels.s
./gen.py --check exit non-zero if kernels.s is not what this would write
| gen.build | ( | ) |
| gen.copy_fn | ( | B, | |
| U, | |||
timed = True |
|||
| ) |
B words loaded before any is stored, U words per loop iteration. Both pointers are bumped at the top and the block is addressed with negative displacements, so the branch delay slot can carry the block's final store and the loop tail is 2 addiu + 1 bltu with nothing wasted. The loop ends on start + count-with-remainder-removed; see the note in memory-s.s about why it must not be written as end - blocksize.
| gen.set_fn | ( | U, | |
timed = True |
|||
| ) |
| gen.thunk_fn | ( | target | ) |
time_<target>(a0, a1, a2): calls target directly, returns its ticks. For routines that cannot carry their own bracket: the shipped crt0 ones, and untimed copies of the bare kernels they are compared against, so that both sides of that comparison sit inside the same bracket. The start count is spilled because the callee may clobber $t8.
| list gen.BARE_COPIES = [(8, 8)] |
| list gen.BARE_SETS = [4] |
| list gen.COPIES = [(2, 2), (4, 4), (8, 8), (8, 16), (8, 32), (2, 32), (4, 32), (16, 16), (16, 32)] |
| gen.cur = open("kernels.s").read() |
| str gen.LICENSE |
| list gen.SETS = [1, 2, 4, 8, 16, 32, 64] |
| gen.text = build() |
| list gen.THUNKS = ["__wrap_memcpy", "__wrap_memset", "copy_b8_u8_bare", "set_u4_bare"] |
| list gen.TIMER_START = [" lui $t9, 0x1f80", " lhu $t8, 0x1120($t9)"] |
| list gen.TIMER_STOP |