diff options
| author | Tharo <17233964+Thar0@users.noreply.github.com> | 2024-12-28 20:18:45 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-28 15:18:45 -0500 |
| commit | 7e082f0c4f6b34820b4dbf6285d05adf423c091b (patch) | |
| tree | 5b2f1d322eafd4afd6b30109eab12ae36d2b72bf /src | |
| parent | ba6a83533ac3dcbd6c0c70c9857572ed1ef1d009 (diff) | |
Use IDO for assembling handwritten asm files in src (#2390)
* as0
* Fix ASOPTFLAGS for src/libc, remove unnecessary noreorder region in kanread
* Suggested changes
* Use %half to load the boot bss size for matching
Co-authored-by: cadmic <cadmic24@gmail.com>
* Wrap all of __osProbeTLB in noreorder
---------
Co-authored-by: cadmic <cadmic24@gmail.com>
Diffstat (limited to 'src')
46 files changed, 1868 insertions, 2165 deletions
diff --git a/src/boot/mio0.s b/src/boot/mio0.s index a3fb8eba2..a6c2eee6b 100644 --- a/src/boot/mio0.s +++ b/src/boot/mio0.s @@ -1,10 +1,7 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noreorder - -.section .text - -.balign 16 +.text /** * void Mio0_Decompress(void* src, void* dst); @@ -12,53 +9,56 @@ * Decompress Mio0 chunk */ LEAF(Mio0_Decompress) - lw $a3, 8($a0) // compressed offset - lw $t9, 0xC($a0) // uncompressed offset - lw $t8, 4($a0) // decompressed length - add $a3, $a3, $a0 // compressed start - add $t9, $t9, $a0 // uncompressed start - move $a2, $zero // 0 - addi $a0, $a0, 0x10 // move past header - add $t8, $t8, $a1 // dst + decompressed length = end + lw a3, 0x08(a0) /* compressed offset */ + lw t9, 0x0C(a0) /* uncompressed offset */ + lw t8, 0x04(a0) /* decompressed length */ + add a3, a3, a0 /* compressed start */ + add t9, t9, a0 /* uncompressed start */ + move a2, zero /* 0 */ + addi a0, a0, 0x10 /* move past header */ + add t8, t8, a1 /* dst + decompressed length = end */ mainloop: - bnez $a2, 1f - nop - lw $t0, ($a0) - li $a2, 32 - addi $a0, $a0, 4 + bnez a2, 1f + + lw t0, (a0) + li a2, 32 + addi a0, a0, 4 1: - slt $t1, $t0, $zero - beqz $t1, read_comp - nop - lb $t2, ($t9) // read 1 byte from uncompressed data - addi $t9, $t9, 1 // advance uncompressed start - addi $a1, $a1, 1 + slt t1, t0, zero + beqz t1, read_comp + + lb t2, (t9) /* read 1 byte from uncompressed data */ + sb t2, (a1) /* store uncompressed byte */ + addi t9, t9, 1 /* advance uncompressed start */ + addi a1, a1, 1 b next_iter - sb $t2, -1($a1) // store uncompressed byte + read_comp: - lhu $t2, ($a3) // read 2 bytes from compressed data - addi $a3, $a3, 2 // advance compressed start - srl $t3, $t2, 0xC - andi $t2, $t2, 0xFFF - beqz $t3, 3f - sub $t1, $a1, $t2 - addi $t3, $t3, 2 + lhu t2, (a3) /* read 2 bytes from compressed data */ + addi a3, a3, 2 /* advance compressed start */ + srl t3, t2, 0xC + andi t2, t2, 0xFFF + sub t1, a1, t2 + beqz t3, 3f + + addi t3, t3, 2 2: - lb $t2, -1($t1) - addi $t3, $t3, -1 - addi $t1, $t1, 1 - addi $a1, $a1, 1 - bnez $t3, 2b - sb $t2, -1($a1) + lb t2, -1(t1) + addi t3, t3, -1 + addi t1, t1, 1 + sb t2, (a1) + addi a1, a1, 1 + bnez t3, 2b + next_iter: - sll $t0, $t0, 1 - bne $a1, $t8, mainloop // continue until decompressed length is reached - addi $a2, $a2, -1 - jr $ra - nop + sll t0, t0, 1 + addi a2, a2, -1 + bne a1, t8, mainloop /* continue until decompressed length is reached */ + + jr ra 3: - lbu $t3, ($t9) - addi $t9, $t9, 1 + lbu t3, (t9) + addi t9, t9, 1 + addi t3, t3, 0x12 b 2b - addi $t3, $t3, 0x12 END(Mio0_Decompress) diff --git a/src/code/kanread.s b/src/code/kanread.s index a163f9ead..fdf69ed9b 100644 --- a/src/code/kanread.s +++ b/src/code/kanread.s @@ -1,11 +1,7 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text /** * s32 Kanji_OffsetFromShiftJIS(s32 sjis); @@ -26,64 +22,57 @@ * @remark Almost identical to "LeoGetKadr" from libleo. */ LEAF(Kanji_OffsetFromShiftJIS) - // Characters with codepoints >= 0x8800 are kanji. Arrangement is regular, - // so convert index directly. - li $at, 0x8800 - slt $at, $a0, $at - bnez $at, .nonkanji - // 0xBC is number of glyphs in one block in the `kanji` file: - // 0x100 possible codepoints with the same byte1 - // - 0x40 unused at beginning - // - 1 unused at 0x7F - // - 3 unused at 0xFD, 0xFE, 0xFF - li $a2, 0xBC - // Get byte1 and adjust so starts at 0 - srl $a1, $a0, 8 - addi $a1, $a1, -0x88 - multu $a2, $a1 - // Get byte2 and adjust so starts at 0 - andi $a3, $a0, 0xFF - addi $a3, $a3, -0x40 - slti $at, $a3, (0x80 - 0x40) - mflo $a2 - // 0x__7F is always empty and elided in the file, so decrement if larger - bnezl $at, .kanji_lower_halfblock - mflo $a2 - addi $a3, $a3, -1 - mflo $a2 + /* Characters with codepoints >= 0x8800 are kanji. Arrangement is regular, */ + /* so convert index directly. */ + li a2, 0xBC + blt a0, 0x8800, .nonkanji + /* 0xBC is number of glyphs in one block in the `kanji` file: */ + /* 0x100 possible codepoints with the same byte1 */ + /* - 0x40 unused at beginning */ + /* - 1 unused at 0x7F */ + /* - 3 unused at 0xFD, 0xFE, 0xFF */ + /* Get byte1 and adjust so starts at 0 */ + srl a1, a0, 8 + addi a1, a1, -0x88 + /* Get byte2 and adjust so starts at 0 */ + andi a3, a0, 0xFF + addi a3, a3, -0x40 + mul a2, a2, a1 + blt a3, 0x40, .kanji_lower_halfblock + + /* 0x__7F is always empty and elided in the file, so decrement if larger */ + addi a3, a3, -1 .kanji_lower_halfblock: - addi $a3, $a3, 0x30A - add $a3, $a3, $a2 - jr $ra - sll $v0, $a3, 7 - // returns (0x30A + (adjusted byte2) + (adjusted byte1) * 0xBC) * FONT_CHAR_TEX_SIZE + mflo a2 /* Unncessary mflo: the pseudo-op `mul` already performs mflo */ + addi a3, a3, 0x30A + add a3, a3, a2 + /* returns (0x30A + (adjusted byte2) + (adjusted byte1) * 0xBC) * FONT_CHAR_TEX_SIZE */ + sll v0, a3, 7 + jr ra -// Non-kanji are arranged with irregular gaps, use the lookup table. +/* Non-kanji are arranged with irregular gaps, use the lookup table. */ .nonkanji: - // Get byte1 and adjust so starts at 0 - srl $a1, $a0, 8 - addi $a1, $a1, -0x81 - multu $a2, $a1 - // Get byte2 and adjust so starts at 0 - andi $a3, $a0, 0xFF - addi $a3, $a3, -0x40 - slti $at, $a3, (0x80 - 0x40) - mflo $a2 - // 0x__7F is always empty and elided in the file, so decrement if larger - bnezl $at, .nonkanji_lower_halfblock - mflo $a2 - addi $a3, $a3, -1 - mflo $a2 + /* Get byte1 and adjust so starts at 0 */ + srl a1, a0, 8 + addi a1, a1, -0x81 + /* Get byte2 and adjust so starts at 0 */ + andi a3, a0, 0xFF + addi a3, a3, -0x40 + mul a2, a2, a1 + blt a3, 0x40, .nonkanji_lower_halfblock + + /* 0x__7F is always empty and elided in the file, so decrement if larger */ + addi a3, a3, -1 .nonkanji_lower_halfblock: - add $a3, $a3, $a2 - lui $a2, %hi(sNonKanjiIndices) - sll $a3, $a3, 1 - addiu $a2, %lo(sNonKanjiIndices) - add $a3, $a3, $a2 - lh $a2, ($a3) - jr $ra - sll $v0, $a2, 7 - // returns sNonKanjiIndices[(adjusted byte2) + (adjusted byte1) * 0xBC] * FONT_CHAR_TEX_SIZE + mflo a2 /* Unncessary mflo: the pseudo-op `mul` already performs mflo */ + add a3, a3, a2 + sll a3, a3, 1 + la a2, sNonKanjiIndices + add a3, a3, a2 + lh a2, (a3) + /* returns sNonKanjiIndices[(adjusted byte2) + (adjusted byte1) * 0xBC] * FONT_CHAR_TEX_SIZE */ + sll v0, a2, 7 + jr ra END(Kanji_OffsetFromShiftJIS) /** @@ -116,7 +105,7 @@ END(Kanji_OffsetFromShiftJIS) * into blocks by high byte. */ DATA(sNonKanjiIndices) -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x814_ */ .half 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F /* 0x815_ */ .half 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F /* 0x816_ */ .half 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F @@ -130,7 +119,7 @@ DATA(sNonKanjiIndices) /* 0x81E_ */ .half 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x81F_ */ .half 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0000, 0x0000, 0x0000, 0x0000, 0x0091 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x824_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0092 /* 0x825_ */ .half 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x826_ */ .half 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB @@ -144,7 +133,7 @@ DATA(sNonKanjiIndices) /* 0x82E_ */ .half 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F, 0x0120 /* 0x82F_ */ .half 0x0121, 0x0122, 0x0123, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x834_ */ .half 0x0124, 0x0125, 0x0126, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F, 0x0130, 0x0131, 0x0132, 0x0133 /* 0x835_ */ .half 0x0134, 0x0135, 0x0136, 0x0137, 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F, 0x0140, 0x0141, 0x0142, 0x0143 /* 0x836_ */ .half 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149, 0x014A, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F, 0x0150, 0x0151, 0x0152, 0x0153 @@ -158,7 +147,7 @@ DATA(sNonKanjiIndices) /* 0x83E_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x83F_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x844_ */ .half 0x01AB, 0x01AC, 0x01AD, 0x01AE, 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01BA /* 0x845_ */ .half 0x01BB, 0x01BC, 0x01BD, 0x01BE, 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7, 0x01C8, 0x01C9, 0x01CA /* 0x846_ */ .half 0x01CB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 @@ -172,7 +161,7 @@ DATA(sNonKanjiIndices) /* 0x84E_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x84F_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x854_ */ .half 0x020E, 0x020F, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D /* 0x855_ */ .half 0x021E, 0x021F, 0x0220, 0x0221, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0222, 0x0223 /* 0x856_ */ .half 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233 @@ -186,7 +175,7 @@ DATA(sNonKanjiIndices) /* 0x85E_ */ .half 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, 0x027B /* 0x85F_ */ .half 0x027C, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x864_ */ .half 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, 0x0291 /* 0x865_ */ .half 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x0000, 0x0000 /* 0x866_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 @@ -200,7 +189,7 @@ DATA(sNonKanjiIndices) /* 0x86E_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x86F_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x874_ */ .half 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7, 0x02C8, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02CF /* 0x875_ */ .half 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7, 0x02D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x876_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 diff --git a/src/code/z_vimode.c b/src/code/z_vimode.c index 59fa5df2d..0d2f5716f 100644 --- a/src/code/z_vimode.c +++ b/src/code/z_vimode.c @@ -86,7 +86,7 @@ void ViMode_Configure(ViMode* viMode, s32 type, s32 tvType, s32 loRes, s32 antia yScaleHiOddField = modeF ? (loResInterlaced ? (F210(0.75) << 16) : (F210(0.5) << 16)) : 0; viMode->customViMode.type = type; - viMode->customViMode.comRegs.ctrl = VI_CTRL_PIXEL_ADV_3 | VI_CTRL_GAMMA_ON | VI_CTRL_GAMMA_DITHER_ON | + viMode->customViMode.comRegs.ctrl = VI_CTRL_PIXEL_ADV(3) | VI_CTRL_GAMMA_ON | VI_CTRL_GAMMA_DITHER_ON | (!loResDeinterlaced ? VI_CTRL_SERRATE_ON : 0) | (antialiasOn ? VI_CTRL_DIVOT_ON : 0) | (fb32Bit ? VI_CTRL_TYPE_32 : VI_CTRL_TYPE_16); diff --git a/src/libc/absf.s b/src/libc/absf.s index b42333461..58450e779 100644 --- a/src/libc/absf.s +++ b/src/libc/absf.s @@ -1,15 +1,9 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -#if DEBUG_FEATURES -.set noreorder -#endif - -.section .text - -.balign 16 +.text LEAF(absf) - abs.s $f0, $f12 - jr $ra - nop + abs.s fv0, fa0 + jr ra END(absf) diff --git a/src/libc/sqrt.s b/src/libc/sqrt.s index 6ffb2b708..1d69d3adb 100644 --- a/src/libc/sqrt.s +++ b/src/libc/sqrt.s @@ -1,15 +1,9 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -#if DEBUG_FEATURES -.set noreorder -#endif - -.section .text - -.balign 16 +.text LEAF(sqrt) - sqrt.d $f0, $f12 - jr $ra - nop + sqrt.d fv0, fa0 + jr ra END(sqrt) diff --git a/src/libc64/fp.s b/src/libc64/fp.s index 117e7815e..32c084ef5 100644 --- a/src/libc64/fp.s +++ b/src/libc64/fp.s @@ -1,12 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noreorder - -.section .data - -.balign 16 +.data #if !PLATFORM_N64 + DATA(gPositiveInfinity) .word 0x7F800000 ENDDATA(gPositiveInfinity) @@ -34,150 +32,135 @@ ENDDATA(qNaN0x10000) DATA(sNaN0x3FFFFF) .word 0x7FFFFFFF ENDDATA(sNaN0x3FFFFF) -#endif -.section .text +#endif -.balign 16 +.text LEAF(floorf) - floor.w.s $f12, $f12 - jr $ra - cvt.s.w $f0, $f12 + floor.w.s fa0, fa0 + cvt.s.w fv0, fa0 + jr ra END(floorf) LEAF(floor) - floor.w.d $f12, $f12 - jr $ra - cvt.d.w $f0, $f12 + floor.w.d fa0, fa0 + cvt.d.w fv0, fa0 + jr ra END(floor) LEAF(lfloorf) - floor.w.s $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + floor.w.s ft0, fa0 + mfc1 v0, ft0 + jr ra END(lfloorf) LEAF(lfloor) - floor.w.d $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + floor.w.d ft0, fa0 + mfc1 v0, ft0 + jr ra END(lfloor) LEAF(ceilf) - ceil.w.s $f12, $f12 - jr $ra - cvt.s.w $f0, $f12 + ceil.w.s fa0, fa0 + cvt.s.w fv0, fa0 + jr ra END(ceilf) LEAF(ceil) - ceil.w.d $f12, $f12 - jr $ra - cvt.d.w $f0, $f12 + ceil.w.d fa0, fa0 + cvt.d.w fv0, fa0 + jr ra END(ceil) LEAF(lceilf) - ceil.w.s $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + ceil.w.s ft0, fa0 + mfc1 v0, ft0 + jr ra END(lceilf) LEAF(lceil) - ceil.w.d $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + ceil.w.d ft0, fa0 + mfc1 v0, ft0 + jr ra END(lceil) LEAF(truncf) - trunc.w.s $f12, $f12 - jr $ra - cvt.s.w $f0, $f12 + trunc.w.s fa0, fa0 + cvt.s.w fv0, fa0 + jr ra END(truncf) LEAF(trunc) - trunc.w.d $f12, $f12 - jr $ra - cvt.d.w $f0, $f12 + trunc.w.d fa0, fa0 + cvt.d.w fv0, fa0 + jr ra END(trunc) LEAF(ltruncf) - trunc.w.s $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + trunc.w.s ft0, fa0 + mfc1 v0, ft0 + jr ra END(ltruncf) LEAF(ltrunc) - trunc.w.d $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + trunc.w.d ft0, fa0 + mfc1 v0, ft0 + jr ra END(ltrunc) LEAF(nearbyintf) - round.w.s $f12, $f12 - jr $ra - cvt.s.w $f0, $f12 + round.w.s fa0, fa0 + cvt.s.w fv0, fa0 + jr ra END(nearbyintf) LEAF(nearbyint) - round.w.d $f12, $f12 - jr $ra - cvt.d.w $f0, $f12 + round.w.d fa0, fa0 + cvt.d.w fv0, fa0 + jr ra END(nearbyint) LEAF(lnearbyintf) - round.w.s $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + round.w.s ft0, fa0 + mfc1 v0, ft0 + jr ra END(lnearbyintf) LEAF(lnearbyint) - round.w.d $f4, $f12 - mfc1 $v0, $f4 - jr $ra - nop + round.w.d ft0, fa0 + mfc1 v0, ft0 + jr ra END(lnearbyint) LEAF(roundf) - li.s $f4, 0.5 - nop - add.s $f0, $f12, $f4 - floor.w.s $f0, $f0 - jr $ra - cvt.s.w $f0, $f0 + li.s ft0, 0.5 + add.s fv0, fa0, ft0 + floor.w.s fv0, fv0 + cvt.s.w fv0, fv0 + jr ra END(roundf) LEAF(round) - li.d $f4, 0.5 - nop - add.d $f0, $f12, $f4 - floor.w.d $f0, $f0 - jr $ra - cvt.d.w $f0, $f0 + li.d ft0, 0.5 + add.d fv0, fa0, ft0 + floor.w.d fv0, fv0 + cvt.d.w fv0, fv0 + jr ra END(round) LEAF(lroundf) - li.s $f4, 0.5 - nop - add.s $f0, $f12, $f4 - floor.w.s $f0, $f0 - mfc1 $v0, $f0 - jr $ra - nop + li.s ft0, 0.5 + add.s fv0, fa0, ft0 + floor.w.s fv0, fv0 + mfc1 v0, fv0 + jr ra END(lroundf) LEAF(lround) - li.d $f4, 0.5 - nop - add.d $f0, $f12, $f4 - floor.w.d $f0, $f0 - mfc1 $v0, $f0 - jr $ra - nop + li.d ft0, 0.5 + add.d fv0, fa0, ft0 + floor.w.d fv0, fv0 + mfc1 v0, fv0 + jr ra END(lround) diff --git a/src/libleo/api/getaadr.s b/src/libleo/api/getaadr.s index a36d27a5b..95c1cfb14 100644 --- a/src/libleo/api/getaadr.s +++ b/src/libleo/api/getaadr.s @@ -1,42 +1,33 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text LEAF(LeoGetAAdr) - bltz $a0, .out_of_range - slti $at, $a0, 0x908 - beqz $at, .out_of_range - nop - lui $v1, %hi(asc2tbl) - sll $t0, $a0, 2 - addiu $v1, %lo(asc2tbl) - add $t1, $t0, $v1 - lbu $t8, 2($t1) - lhu $t9, 0($t1) - li $at, 0x70000 - andi $t2, $t8, 0xF - addi $t3, $t2, 1 - sw $t3, ($a2) - lb $t0, 3($t1) - srl $t4, $t8, 4 - ori $at, $at, 0xEE80 - andi $t5, $t0, 1 - sll $t6, $t5, 4 - or $t7, $t6, $t4 - sw $t7, ($a1) - sll $v0, $t9, 1 - sra $v1, $t0, 1 - sw $v1, ($a3) - jr $ra - add $v0, $v0, $at + bltz a0, .out_of_range + bge a0, 0x908, .out_of_range + sll t0, a0, 2 + la v1, asc2tbl + add t1, t0, v1 + lbu t8, 2(t1) + lhu t9, 0(t1) + andi t2, t8, 0xF + addi t3, t2, 1 + sw t3, (a2) + lb t0, 3(t1) + srl t4, t8, 4 + andi t5, t0, 1 + sll t6, t5, 4 + or t7, t6, t4 + sw t7, (a1) + sll v0, t9, 1 + sra v1, t0, 1 + sw v1, (a3) + add v0, v0, 0x7EE80 + jr ra .out_of_range: - jr $ra - li $v0, -1 + li v0, -1 + jr ra END(LeoGetAAdr) DATA(asc2tbl) diff --git a/src/libleo/api/getaadr2.s b/src/libleo/api/getaadr2.s index e3ea0868b..cac52cd90 100644 --- a/src/libleo/api/getaadr2.s +++ b/src/libleo/api/getaadr2.s @@ -1,33 +1,25 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text LEAF(LeoGetAAdr2) - li $at, 0x10000 - srl $t8, $a0, 0xF - ori $at, $at, 0xFFFE - and $v1, $t8, $at - li $at, 0x70000 - ori $at, $at, 0xEE80 - srl $t2, $a0, 0x8 - add $v0, $v1, $at - andi $t3, $t2, 0xF - andi $t5, $a0, 0xFE - addi $t4, $t3, 1 - sll $t6, $t5, 0x18 - andi $t9, $a0, 0x1 - srl $v1, $a0, 0xC - sw $t4, ($a2) - sra $t7, $t6, 0x19 - sll $t8, $t9, 0x4 - andi $t1, $v1, 0xF - sw $t7, ($a3) - or $t2, $t1, $t8 - jr $ra - sw $t2, ($a1) + srl t8, a0, 15 + and v1, t8, 0x1FFFE + add v0, v1, 0x7EE80 + srl t2, a0, 8 + andi t3, t2, 0xF + andi t5, a0, 0xFE + addi t4, t3, 1 + sll t6, t5, 24 + andi t9, a0, 1 + srl v1, a0, 12 + sw t4, (a2) + sra t7, t6, 25 + sll t8, t9, 4 + andi t1, v1, 0xF + sw t7, (a3) + or t2, t1, t8 + sw t2, (a1) + jr ra END(LeoGetAAdr2) diff --git a/src/libleo/api/getkadr.s b/src/libleo/api/getkadr.s index 22d85cb59..d71719525 100644 --- a/src/libleo/api/getkadr.s +++ b/src/libleo/api/getkadr.s @@ -1,11 +1,7 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text /** * int LeoGetKAdr(int sjis); @@ -22,74 +18,61 @@ * @return int Storage offset address into the N64 Disk Drive mask ROM. */ LEAF(LeoGetKAdr) - // Check if the codepoint is in the range 0x8140 to 0x9872. - li $at, 0x8140 - slt $at, $a0, $at - bnez $at, .out_of_range - li $at, 0x9873 - slt $at, $a0, $at - beqz $at, .out_of_range - // Characters with codepoints >= 0x8800 are kanji. Arrangement is regular, - // so convert index directly. - li $at, 0x8800 - slt $at, $a0, $at - bnez $at, .nonkanji - // 0xBC is number of glyphs in one block in the `kanji` file: - // 0x100 possible codepoints with the same byte1 - // - 0x40 unused at beginning - // - 1 unused at 0x7F - // - 3 unused at 0xFD, 0xFE, 0xFF - li $a2, 0xBC - // Get byte1 and adjust so starts at 0 - srl $a1, $a0, 8 - addi $a1, $a1, -0x88 - multu $a2, $a1 - // Get byte2 and adjust so starts at 0 - andi $a3, $a0, 0xFF - addi $a3, $a3, -0x40 - slti $at, $a3, (0x80 - 0x40) - mflo $a2 - // 0x__7F is always empty and elided in the file, so decrement if larger - bnezl $at, .kanji_lower_halfblock - mflo $a2 - addi $a3, $a3, -1 - mflo $a2 + /* Check if the codepoint is in the range 0x8140 to 0x9872. */ + blt a0, 0x8140, .out_of_range + bge a0, 0x9873, .out_of_range + /* Characters with codepoints >= 0x8800 are kanji. Arrangement is regular, + * so convert index directly. */ + li a2, 0xBC + blt a0, 0x8800, .nonkanji + /* 0xBC is number of glyphs in one block in the `kanji` file: + * 0x100 possible codepoints with the same byte1 + * - 0x40 unused at beginning + * - 1 unused at 0x7F + * - 3 unused at 0xFD, 0xFE, 0xFF */ + /* Get byte1 and adjust so starts at 0 */ + srl a1, a0, 8 + addi a1, a1, -0x88 + mul a2, a2, a1 + /* Get byte2 and adjust so starts at 0 */ + andi a3, a0, 0xFF + addi a3, a3, -0x40 + /* 0x__7F is always empty and elided in the file, so decrement if larger */ + blt a3, 0x40, .kanji_lower_halfblock + addi a3, a3, -1 .kanji_lower_halfblock: - addi $a3, $a3, 0x30A - add $a3, $a3, $a2 - jr $ra - sll $v0, $a3, 7 - // returns (0x30A + (adjusted byte2) + (adjusted byte1) * 0xBC) * FONT_CHAR_TEX_SIZE + mflo a2 + addi a3, a3, 0x30A + add a3, a3, a2 + sll v0, a3, 7 + jr ra + /* returns (0x30A + (adjusted byte2) + (adjusted byte1) * 0xBC) * FONT_CHAR_TEX_SIZE */ -// Non-kanji are arranged with irregular gaps, use the lookup table. +/* Non-kanji are arranged with irregular gaps, use the lookup table. */ .nonkanji: - // Get byte1 and adjust so starts at 0 - srl $a1, $a0, 8 - addi $a1, $a1, -0x81 - multu $a2, $a1 - // Get byte2 and adjust so starts at 0 - andi $a3, $a0, 0xFF - addi $a3, $a3, -0x40 - slti $at, $a3, (0x80 - 0x40) - mflo $a2 - // 0x__7F is always empty and elided in the file, so decrement if larger - bnezl $at, .nonkanji_lower_halfblock - mflo $a2 - addi $a3, $a3, -1 - mflo $a2 + /* Get byte1 and adjust so starts at 0 */ + srl a1, a0, 8 + addi a1, a1, -0x81 + mul a2, a2, a1 + /* Get byte2 and adjust so starts at 0 */ + andi a3, a0, 0xFF + addi a3, a3, -0x40 + /* 0x__7F is always empty and elided in the file, so decrement if larger */ + blt a3, 0x40, .nonkanji_lower_halfblock + addi a3, a3, -1 .nonkanji_lower_halfblock: - add $a3, $a3, $a2 - lui $a2, %hi(kantbl) - sll $a3, $a3, 1 - addiu $a2, %lo(kantbl) - add $a3, $a3, $a2 - lh $a2, ($a3) - jr $ra - sll $v0, $a2, 7 - // returns kantbl[(adjusted byte2) + (adjusted byte1) * 0xBC] * FONT_CHAR_TEX_SIZE + mflo a2 + add a3, a3, a2 + sll a3, a3, 1 + la a2, kantbl + add a3, a3, a2 + lh a2, (a3) + sll v0, a2, 7 + jr ra + /* returns kantbl[(adjusted byte2) + (adjusted byte1) * 0xBC] * FONT_CHAR_TEX_SIZE */ .out_of_range: - jr $ra - li $v0, -1 + li v0, -1 + jr ra END(LeoGetKAdr) /** @@ -129,7 +112,7 @@ END(LeoGetKAdr) * into blocks by high byte. */ DATA(kantbl) -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x814_ */ .half 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F /* 0x815_ */ .half 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F /* 0x816_ */ .half 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F @@ -143,7 +126,7 @@ DATA(kantbl) /* 0x81E_ */ .half 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x81F_ */ .half 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0000, 0x0000, 0x0000, 0x0000, 0x0091 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x824_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0092 /* 0x825_ */ .half 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x826_ */ .half 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB @@ -157,7 +140,7 @@ DATA(kantbl) /* 0x82E_ */ .half 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F, 0x0120 /* 0x82F_ */ .half 0x0121, 0x0122, 0x0123, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x834_ */ .half 0x0124, 0x0125, 0x0126, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F, 0x0130, 0x0131, 0x0132, 0x0133 /* 0x835_ */ .half 0x0134, 0x0135, 0x0136, 0x0137, 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F, 0x0140, 0x0141, 0x0142, 0x0143 /* 0x836_ */ .half 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149, 0x014A, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F, 0x0150, 0x0151, 0x0152, 0x0153 @@ -171,7 +154,7 @@ DATA(kantbl) /* 0x83E_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x83F_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x844_ */ .half 0x01AB, 0x01AC, 0x01AD, 0x01AE, 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01BA /* 0x845_ */ .half 0x01BB, 0x01BC, 0x01BD, 0x01BE, 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7, 0x01C8, 0x01C9, 0x01CA /* 0x846_ */ .half 0x01CB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 @@ -185,7 +168,7 @@ DATA(kantbl) /* 0x84E_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x84F_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x854_ */ .half 0x020E, 0x020F, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D /* 0x855_ */ .half 0x021E, 0x021F, 0x0220, 0x0221, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0222, 0x0223 /* 0x856_ */ .half 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233 @@ -199,7 +182,7 @@ DATA(kantbl) /* 0x85E_ */ .half 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, 0x027B /* 0x85F_ */ .half 0x027C, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x864_ */ .half 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, 0x0291 /* 0x865_ */ .half 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x0000, 0x0000 /* 0x866_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 @@ -213,7 +196,7 @@ DATA(kantbl) /* 0x86E_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x86F_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -// 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F +/* 0x___0 0x___1 0x___2 0x___3 0x___4 0x___5 0x___6 0x___7 0x___8 0x___9 0x___A 0x___B 0x___C 0x___D 0x___E 0x___F */ /* 0x874_ */ .half 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7, 0x02C8, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02CF /* 0x875_ */ .half 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7, 0x02D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /* 0x876_ */ .half 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 diff --git a/src/libultra/gu/libm_vals.s b/src/libultra/gu/libm_vals.s index 18de1ae4f..91f2cadb3 100644 --- a/src/libultra/gu/libm_vals.s +++ b/src/libultra/gu/libm_vals.s @@ -1,8 +1,6 @@ #include "ultra64/asm.h" -.section .rodata - -.balign 16 +.rdata DATA(__libm_qnan_f) .word 0x7F810000 diff --git a/src/libultra/io/vimodefpallan1.c b/src/libultra/io/vimodefpallan1.c index 37cb5ff55..5fb019cdf 100644 --- a/src/libultra/io/vimodefpallan1.c +++ b/src/libultra/io/vimodefpallan1.c @@ -16,15 +16,15 @@ OSViMode osViModeFpalLan1 = { { // comRegs VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | - VI_CTRL_PIXEL_ADV_3, // ctrl - WIDTH(320), // width - BURST(58, 30, 4, 69), // burst - VSYNC(625), // vSync - HSYNC(3177, 23), // hSync - LEAP(3183, 3181), // leap - HSTART(128, 768), // hStart - SCALE(2, 0), // xScale - VCURRENT(0), // vCurrent + VI_CTRL_PIXEL_ADV(3), // ctrl + WIDTH(320), // width + BURST(58, 30, 4, 69), // burst + VSYNC(625), // vSync + HSYNC(3177, 23), // hSync + LEAP(3183, 3181), // leap + HSTART(128, 768), // hStart + SCALE(2, 0), // xScale + VCURRENT(0), // vCurrent }, { // fldRegs { diff --git a/src/libultra/io/vimodempallan1.c b/src/libultra/io/vimodempallan1.c index bcc4273af..23d53987b 100644 --- a/src/libultra/io/vimodempallan1.c +++ b/src/libultra/io/vimodempallan1.c @@ -16,15 +16,15 @@ OSViMode osViModeMpalLan1 = { { // comRegs VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | - VI_CTRL_PIXEL_ADV_3, // ctrl - WIDTH(320), // width - BURST(57, 30, 5, 70), // burst - VSYNC(525), // vSync - HSYNC(3089, 4), // hSync - LEAP(3097, 3098), // leap - HSTART(108, 748), // hStart - SCALE(2, 0), // xScale - VCURRENT(0), // vCurrent + VI_CTRL_PIXEL_ADV(3), // ctrl + WIDTH(320), // width + BURST(57, 30, 5, 70), // burst + VSYNC(525), // vSync + HSYNC(3089, 4), // hSync + LEAP(3097, 3098), // leap + HSTART(108, 748), // hStart + SCALE(2, 0), // xScale + VCURRENT(0), // vCurrent }, { // fldRegs { diff --git a/src/libultra/io/vimodentsclan1.c b/src/libultra/io/vimodentsclan1.c index a29d15129..19a7160ac 100644 --- a/src/libultra/io/vimodentsclan1.c +++ b/src/libultra/io/vimodentsclan1.c @@ -16,15 +16,15 @@ OSViMode osViModeNtscLan1 = { { // comRegs VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | - VI_CTRL_PIXEL_ADV_3, // ctrl - WIDTH(320), // width - BURST(57, 34, 5, 62), // burst - VSYNC(525), // vSync - HSYNC(3093, 0), // hSync - LEAP(3093, 3093), // leap - HSTART(108, 748), // hStart - SCALE(2, 0), // xScale - VCURRENT(0), // vCurrent + VI_CTRL_PIXEL_ADV(3), // ctrl + WIDTH(320), // width + BURST(57, 34, 5, 62), // burst + VSYNC(525), // vSync + HSYNC(3093, 0), // hSync + LEAP(3093, 3093), // leap + HSTART(108, 748), // hStart + SCALE(2, 0), // xScale + VCURRENT(0), // vCurrent }, { // fldRegs { diff --git a/src/libultra/io/vimodepallan1.c b/src/libultra/io/vimodepallan1.c index d656dc4f9..7a8db603f 100644 --- a/src/libultra/io/vimodepallan1.c +++ b/src/libultra/io/vimodepallan1.c @@ -16,15 +16,15 @@ OSViMode osViModePalLan1 = { { // comRegs VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | - VI_CTRL_PIXEL_ADV_3, // ctrl - WIDTH(320), // width - BURST(58, 30, 4, 69), // burst - VSYNC(625), // vSync - HSYNC(3177, 23), // hSync - LEAP(3183, 3181), // leap - HSTART(128, 768), // hStart - SCALE(2, 0), // xScale - VCURRENT(0), // vCurrent + VI_CTRL_PIXEL_ADV(3), // ctrl + WIDTH(320), // width + BURST(58, 30, 4, 69), // burst + VSYNC(625), // vSync + HSYNC(3177, 23), // hSync + LEAP(3183, 3181), // leap + HSTART(128, 768), // hStart + SCALE(2, 0), // xScale + VCURRENT(0), // vCurrent }, { // fldRegs { diff --git a/src/libultra/libc/bcmp.s b/src/libultra/libc/bcmp.s index df6692feb..dcd5bc002 100644 --- a/src/libultra/libc/bcmp.s +++ b/src/libultra/libc/bcmp.s @@ -1,93 +1,89 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder +.text -.section .text +LEAF(bcmp) + xor v0, a0, a1 + blt a2, 0x10, bytecmp -.balign 16 + and v0, v0, 3 + negu t8, a0 + bnez v0, unaligncmp + + and t8, t8, 3 + subu a2, a2, t8 + beqz t8, wordcmp + + move v0, v1 + lwl v0, (a0) + lwl v1, (a1) + addu a0, a0, t8 + addu a1, a1, t8 + bne v0, v1, cmpne -LEAF(bcmp) - slti $at, $a2, 0x10 - bnez $at, bytecmp - xor $v0, $a0, $a1 - andi $v0, $v0, 3 - bnez $v0, unaligncmp - negu $t8, $a0 - andi $t8, $t8, 3 - beqz $t8, wordcmp - subu $a2, $a2, $t8 - move $v0, $v1 - lwl $v0, ($a0) - lwl $v1, ($a1) - addu $a0, $a0, $t8 - addu $a1, $a1, $t8 - bne $v0, $v1, cmpne wordcmp: - li $at, ~3 - and $a3, $a2, $at - beqz $a3, bytecmp - subu $a2, $a2, $a3 - addu $a3, $a3, $a0 - lw $v0, ($a0) + and a3, a2, ~3 + subu a2, a2, a3 + beqz a3, bytecmp + + addu a3, a3, a0 1: - lw $v1, ($a1) - addiu $a0, $a0, 4 - addiu $a1, $a1, 4 - bne $v0, $v1, cmpne - nop - bnel $a0, $a3, 1b - lw $v0, ($a0) + lw v0, (a0) + lw v1, (a1) + addu a0, a0, 4 + addu a1, a1, 4 + bne v0, v1, cmpne + bne a0, a3, 1b + b bytecmp - nop + unaligncmp: - negu $a3, $a1 - andi $a3, $a3, 3 - beqz $a3, partaligncmp - subu $a2, $a2, $a3 - addu $a3, $a3, $a0 - lbu $v0, ($a0) + negu a3, a1 + and a3, a3, 3 + subu a2, a2, a3 + beqz a3, partaligncmp + + addu a3, a3, a0 1: - lbu $v1, ($a1) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - bne $v0, $v1, cmpne - nop - bnel $a0, $a3, 1b - lbu $v0, ($a0) + lbu v0, (a0) + lbu v1, (a1) + addu a0, a0, 1 + addu a1, a1, 1 + bne v0, v1, cmpne + bne a0, a3, 1b + partaligncmp: - li $at, ~3 - and $a3, $a2, $at - beqz $a3, bytecmp - subu $a2, $a2, $a3 - addu $a3, $a3, $a0 - lwl $v0, ($a0) + and a3, a2, ~3 + subu a2, a2, a3 + beqz a3, bytecmp + + addu a3, a3, a0 1: - lw $v1, ($a1) - lwr $v0, 3($a0) - addiu $a0, $a0, 4 - addiu $a1, $a1, 4 - bne $v0, $v1, cmpne - nop - bnel $a0, $a3, 1b - lwl $v0, ($a0) + lwl v0, (a0) + lw v1, (a1) + lwr v0, 3(a0) + addu a0, a0, 4 + addu a1, a1, 4 + bne v0, v1, cmpne + bne a0, a3, 1b + bytecmp: - blez $a2, cmpdone - addu $a3, $a2, $a0 - lbu $v0, ($a0) + addu a3, a2, a0 + blez a2, cmpdone 1: - lbu $v1, ($a1) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - bne $v0, $v1, cmpne - nop - bnel $a0, $a3, 1b - lbu $v0, ($a0) + lbu v0, (a0) + lbu v1, (a1) + addu a0, a0, 1 + addu a1, a1, 1 + bne v0, v1, cmpne + bne a0, a3, 1b + cmpdone: - jr $ra - move $v0, $zero + move v0, zero + jr ra cmpne: - jr $ra - li $v0, 1 + li v0, 1 + jr ra END(bcmp) diff --git a/src/libultra/libc/bcopy.s b/src/libultra/libc/bcopy.s index e1240f113..dcb6ad13c 100644 --- a/src/libultra/libc/bcopy.s +++ b/src/libultra/libc/bcopy.s @@ -1,233 +1,211 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text LEAF(bcopy) - beqz $a2, ret - move $a3, $a1 - beq $a0, $a1, ret - slt $at, $a1, $a0 - bnezl $at, goforwards - slti $at, $a2, 0x10 - add $v0, $a0, $a2 - slt $at, $a1, $v0 - beql $at, $zero, goforwards - slti $at, $a2, 0x10 + move a3, a1 + beqz a2, ret + beq a0, a1, ret + blt a1, a0, goforwards + add v0, a0, a2 + bge a1, v0, goforwards b gobackwards - slti $at, $a2, 0x10 - slti $at, $a2, 0x10 + goforwards: - bnez $at, forwards_bytecopy - nop - andi $v0, $a0, 3 - andi $v1, $a1, 3 - beq $v0, $v1, forwalignable - nop + blt a2, 0x10, forwards_bytecopy + and v0, a0, 3 + and v1, a1, 3 + beq v0, v1, forwalignable + forwards_bytecopy: - beqz $a2, ret - nop - addu $v1, $a0, $a2 + beqz a2, ret + addu v1, a0, a2 99: - lb $v0, ($a0) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - bne $a0, $v1, 99b - sb $v0, -1($a1) + lb v0, (a0) + addu a0, a0, 1 + sb v0, (a1) + addu a1, a1, 1 + bne a0, v1, 99b ret: - jr $ra - move $v0, $a3 + move v0, a3 + jr ra forwalignable: - beqz $v0, forwards_32 - li $at, 1 - beq $v0, $at, forw_copy3 - li $at, 2 - beql $v0, $at, forw_copy2 - lh $v0, ($a0) - lb $v0, ($a0) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - addiu $a2, $a2, -1 + beqz v0, forwards_32 + beq v0, 1, forw_copy3 + beq v0, 2, forw_copy2 + + lb v0, (a0) + addu a0, a0, 1 + sb v0, (a1) + addu a1, a1, 1 + addu a2, a2, -1 b forwards_32 - sb $v0, -1($a1) - lh $v0, ($a0) + forw_copy2: - addiu $a0, $a0, 2 - addiu $a1, $a1, 2 - addiu $a2, $a2, -2 + lh v0, (a0) + addu a0, a0, 2 + sh v0, (a1) + addu a1, a1, 2 + addu a2, a2, -2 b forwards_32 - sh $v0, -2($a1) + forw_copy3: - lb $v0, ($a0) - lh $v1, 1($a0) - addiu $a0, $a0, 3 - addiu $a1, $a1, 3 - addiu $a2, $a2, -3 - sb $v0, -3($a1) - sh $v1, -2($a1) + lb v0, (a0) + lh v1, 1(a0) + addiu a0, a0, 3 + sb v0, (a1) + sh v1, 1(a1) + addiu a1, a1, 3 + addiu a2, a2, -3 forwards: forwards_32: - slti $at, $a2, 0x20 - bnezl $at, forwards_16_ - slti $at, $a2, 0x10 - lw $v0, ($a0) - lw $v1, 4($a0) - lw $t0, 8($a0) - lw $t1, 0xC($a0) - lw $t2, 0x10($a0) - lw $t3, 0x14($a0) - lw $t4, 0x18($a0) - lw $t5, 0x1C($a0) - addiu $a0, $a0, 0x20 - addiu $a1, $a1, 0x20 - addiu $a2, $a2, -0x20 - sw $v0, -0x20($a1) - sw $v1, -0x1C($a1) - sw $t0, -0x18($a1) - sw $t1, -0x14($a1) - sw $t2, -0x10($a1) - sw $t3, -0xC($a1) - sw $t4, -8($a1) + blt a2, 32, forwards_16 + lw v0, 0(a0) + lw v1, 4(a0) + lw t0, 8(a0) + lw t1, 12(a0) + lw t2, 16(a0) + lw t3, 20(a0) + lw t4, 24(a0) + lw t5, 28(a0) + addiu a0, a0, 32 + sw v0, 0(a1) + sw v1, 4(a1) + sw t0, 8(a1) + sw t1, 12(a1) + sw t2, 16(a1) + sw t3, 20(a1) + sw t4, 24(a1) + sw t5, 28(a1) + addiu a1, a1, 32 + addiu a2, a2, -32 b forwards_32 - sw $t5, -4($a1) + forwards_16: - slti $at, $a2, 0x10 -forwards_16_: // fake label due to branch likely optimization - bnezl $at, forwards_4_ - slti $at, $a2, 4 - lw $v0, ($a0) - lw $v1, 4($a0) - lw $t0, 8($a0) - lw $t1, 0xC($a0) - addiu $a0, $a0, 0x10 - addiu $a1, $a1, 0x10 - addiu $a2, $a2, -0x10 - sw $v0, -0x10($a1) - sw $v1, -0xC($a1) - sw $t0, -8($a1) + blt a2, 16, forwards_4 + lw v0, 0(a0) + lw v1, 4(a0) + lw t0, 8(a0) + lw t1, 12(a0) + addiu a0, a0, 16 + sw v0, 0(a1) + sw v1, 4(a1) + sw t0, 8(a1) + sw t1, 12(a1) + addiu a1, a1, 16 + addiu a2, a2, -16 b forwards_16 - sw $t1, -4($a1) + forwards_4: - slti $at, $a2, 4 -forwards_4_: // fake label due to branch likely optimization - bnez $at, forwards_bytecopy - nop - lw $v0, ($a0) - addiu $a0, $a0, 4 - addiu $a1, $a1, 4 - addiu $a2, $a2, -4 + blt a2, 4, forwards_bytecopy + + lw v0, 0(a0) + addiu a0, a0, 4 + sw v0, 0(a1) + addiu a1, a1, 4 + addiu a2, a2, -4 b forwards_4 - sw $v0, -4($a1) - slti $at, $a2, 0x10 + gobackwards: - add $a0, $a0, $a2 - bnez $at, backwards_bytecopy - add $a1, $a1, $a2 - andi $v0, $a0, 3 - andi $v1, $a1, 3 - beq $v0, $v1, backalignable - nop + add a0, a0,a2 + add a1, a1,a2 + blt a2, 16, backwards_bytecopy + + andi v0, a0, 0x3 + andi v1, a1, 0x3 + beq v0, v1, backalignable + backwards_bytecopy: - beqz $a2, ret - nop - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - subu $v1, $a0, $a2 + beqz a2, ret + addiu a0, a0, -1 + addiu a1, a1, -1 + subu v1, a0,a2 99: - lb $v0, ($a0) - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - bne $a0, $v1, 99b - sb $v0, 1($a1) - jr $ra - move $v0, $a3 + lb v0, 0(a0) + addiu a0, a0, -1 + sb v0, 0(a1) + addiu a1, a1, -1 + bne a0, v1,99b + + move v0, a3 + jr ra backalignable: - beqz $v0, backwards_32 - li $at, 3 - beq $v0, $at, back_copy3 - li $at, 2 - beql $v0, $at, back_copy2 - lh $v0, -2($a0) - lb $v0, -1($a0) - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - addiu $a2, $a2, -1 - b backwards_32 - sb $v0, ($a1) - lh $v0, -2($a0) + beqz v0, backwards + beq v0, 3, back_copy3 + beq v0, 2, back_copy2 + lb v0, -1(a0) + addiu a0, a0, -1 + sb v0, -1(a1) + addiu a1, a1, -1 + addiu a2, a2, -1 + b backwards + back_copy2: - addiu $a0, $a0, -2 - addiu $a1, $a1, -2 - addiu $a2, $a2, -2 - b backwards_32 - sh $v0, ($a1) + lh v0, -2(a0) + addiu a0, a0, -2 + sh v0, -2(a1) + addiu a1, a1, -2 + addiu a2, a2, -2 + b backwards + back_copy3: - lb $v0, -1($a0) - lh $v1, -3($a0) - addiu $a0, $a0, -3 - addiu $a1, $a1, -3 - addiu $a2, $a2, -3 - sb $v0, 2($a1) - sh $v1, ($a1) + lb v0, -1(a0) + lh v1, -3(a0) + addiu a0, a0, -3 + sb v0, -1(a1) + sh v1, -3(a1) + addiu a1, a1, -3 + addiu a2, a2, -3 backwards: backwards_32: - slti $at, $a2, 0x20 - bnezl $at, backwards_16_ - slti $at, $a2, 0x10 - lw $v0, -4($a0) - lw $v1, -8($a0) - lw $t0, -0xc($a0) - lw $t1, -0x10($a0) - lw $t2, -0x14($a0) - lw $t3, -0x18($a0) - lw $t4, -0x1c($a0) - lw $t5, -0x20($a0) - addiu $a0, $a0, -0x20 - addiu $a1, $a1, -0x20 - addiu $a2, $a2, -0x20 - sw $v0, 0x1C($a1) - sw $v1, 0x18($a1) - sw $t0, 0x14($a1) - sw $t1, 0x10($a1) - sw $t2, 0xC($a1) - sw $t3, 8($a1) - sw $t4, 4($a1) + blt a2, 32, backwards_16 + lw v0, -4(a0) + lw v1, -8(a0) + lw t0, -12(a0) + lw t1, -16(a0) + lw t2, -20(a0) + lw t3, -24(a0) + lw t4, -28(a0) + lw t5, -32(a0) + addiu a0, a0, -32 + sw v0, -4(a1) + sw v1, -8(a1) + sw t0, -12(a1) + sw t1, -16(a1) + sw t2, -20(a1) + sw t3, -24(a1) + sw t4, -28(a1) + sw t5, -32(a1) + addiu a1, a1, -32 + addiu a2, a2, -32 b backwards_32 - sw $t5, ($a1) + backwards_16: - slti $at, $a2, 0x10 -backwards_16_: // fake label due to branch likely optimization - bnezl $at, backwards_4_ - slti $at, $a2, 4 - lw $v0, -4($a0) - lw $v1, -8($a0) - lw $t0, -0xC($a0) - lw $t1, -0x10($a0) - addiu $a0, $a0, -0x10 - addiu $a1, $a1, -0x10 - addiu $a2, $a2, -0x10 - sw $v0, 0xC($a1) - sw $v1, 8($a1) - sw $t0, 4($a1) + blt a2, 16, backwards_4 + lw v0, -4(a0) + lw v1, -8(a0) + lw t0, -12(a0) + lw t1, -16(a0) + addiu a0, a0, -16 + sw v0, -4(a1) + sw v1, -8(a1) + sw t0, -12(a1) + sw t1, -16(a1) + addiu a1, a1, -16 + addiu a2, a2, -16 b backwards_16 - sw $t1, ($a1) + backwards_4: - slti $at, $a2, 4 -backwards_4_: // fake label due to branch likely optimization - bnez $at, backwards_bytecopy - nop - lw $v0, -4($a0) - addiu $a0, $a0, -4 - addiu $a1, $a1, -4 - addiu $a2, $a2, -4 + blt a2, 4, backwards_bytecopy + lw v0, -4(a0) + addiu a0, a0, -4 + sw v0, -4(a1) + addiu a1, a1, -4 + addiu a2, a2, -4 b backwards_4 - sw $v0, ($a1) END(bcopy) diff --git a/src/libultra/libc/bzero.s b/src/libultra/libc/bzero.s index 5323a92d7..9c6552f65 100644 --- a/src/libultra/libc/bzero.s +++ b/src/libultra/libc/bzero.s @@ -1,65 +1,59 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder +.text -.section .text +LEAF(bzero) + negu v1, a0 + blt a1, 0xC, bytezero -.balign 16 + and v1, v1, 3 + subu a1, a1, v1 + beqz v1, blkzero -LEAF(bzero) - slti $at, $a1, 0xC - bnez $at, bytezero - negu $v1, $a0 - andi $v1, $v1, 3 - beqz $v1, blkzero - subu $a1, $a1, $v1 - swl $zero, ($a0) - addu $a0, $a0, $v1 + swl zero, (a0) + addu a0, a0, v1 blkzero: - // align backwards to 0x20 - li $at, ~0x1F - and $a3, $a1, $at - // If the result is zero, the amount to zero is less than 0x20 bytes - beqz $a3, wordzero - subu $a1, $a1, $a3 - // zero in blocks of 0x20 at a time - addu $a3, $a3, $a0 + /* align backwards to 0x20 */ + and a3, a1, ~(0x20 - 1) + /* If the result is zero, the amount to zero is less than 0x20 bytes */ + subu a1, a1, a3 + beqz a3, wordzero + /* zero in blocks of 0x20 at a time */ + addu a3, a3, a0 1: - addiu $a0, $a0, 0x20 - sw $zero, -0x20($a0) - sw $zero, -0x1C($a0) - sw $zero, -0x18($a0) - sw $zero, -0x14($a0) - sw $zero, -0x10($a0) - sw $zero, -0xC($a0) - sw $zero, -8($a0) - bne $a0, $a3, 1b - sw $zero, -4($a0) + sw zero, 0(a0) + sw zero, 4(a0) + sw zero, 8(a0) + sw zero, 12(a0) + addiu a0, a0, 0x20 + sw zero, -16(a0) + sw zero, -12(a0) + sw zero, -8(a0) + sw zero, -4(a0) + bne a0, a3, 1b + wordzero: - // align backwards to 0x4 - li $at, ~3 - and $a3, $a1, $at - // If the result is zero, the amount to zero is less than 0x4 bytes - beqz $a3, bytezero - subu $a1, $a1, $a3 - // zero one word at a time - addu $a3, $a3, $a0 + /* align backwards to 0x4 */ + and a3, a1, ~3 + /* If the result is zero, the amount to zero is less than 0x4 bytes */ + subu a1, a1, a3 + beqz a3, bytezero + /* zero one word at a time */ + addu a3, a3, a0 1: - addiu $a0, $a0, 4 - bne $a0, $a3, 1b - sw $zero, -4($a0) + addu a0, a0, 4 + sw zero, -4(a0) + bne a0, a3, 1b bytezero: - // test if nothing left to zero - blez $a1, zerodone - nop - // zero one byte at a time - addu $a1, $a1, $a0 + /* test if nothing left to zero */ + blez a1, zerodone + /* zero one byte at a time */ + addu a1, a1, a0 1: - addiu $a0, $a0, 1 - bne $a0, $a1, 1b - sb $zero, -1($a0) + sb zero, (a0) + addiu a0, a0, 1 + bne a0, a1, 1b zerodone: - jr $ra - nop + jr ra END(bzero) diff --git a/src/libultra/mgu/mtxf2l.s b/src/libultra/mgu/mtxf2l.s index edbb675a8..1fada6b53 100644 --- a/src/libultra/mgu/mtxf2l.s +++ b/src/libultra/mgu/mtxf2l.s @@ -1,40 +1,36 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 32 +.text +.align 5 #define MTX_INTPART 0 #define MTX_FRACPART 0x20 LEAF(guMtxF2L) - li $at, 0x47800000 // 65536.0f - mtc1 $at, $f0 - li $t9, 0xFFFF0000 - addiu $t8, $a1, MTX_FRACPART + li.s fv0, 65536.0 + li t9, 0xFFFF0000 + addu t8, a1, MTX_FRACPART 1: - lwc1 $f4, ($a0) - lwc1 $f10, 4($a0) - addiu $a1, $a1, 4 - mul.s $f6, $f4, $f0 - addiu $a0, $a0, 8 - mul.s $f16, $f10, $f0 - trunc.w.s $f8, $f6 - trunc.w.s $f18, $f16 - mfc1 $t0, $f8 - mfc1 $t1, $f18 - and $t2, $t0, $t9 - sll $t5, $t0, 0x10 - srl $t3, $t1, 0x10 - andi $t6, $t1, 0xFFFF - or $t4, $t2, $t3 - or $t7, $t5, $t6 - sw $t4, (MTX_INTPART-4)($a1) - bne $a1, $t8, 1b - sw $t7, (MTX_FRACPART-4)($a1) - jr $ra - nop + lwc1 ft0, 0(a0) + lwc1 ft3, 4(a0) + mul.s ft1, ft0, fv0 + mul.s ft4, ft3, fv0 + trunc.w.s ft2, ft1 + trunc.w.s ft5, ft4 + mfc1 t0, ft2 + mfc1 t1, ft5 + srl t3, t1, 0x10 + and t6, t1, 0xFFFF + and t2, t0, t9 + sll t5, t0, 0x10 + or t4, t2, t3 + or t7, t5, t6 + sw t4, (MTX_INTPART)(a1) + sw t7, (MTX_FRACPART)(a1) + addu a0, a0, 8 + addu a1, a1, 4 + bne a1, t8, 1b + + jr ra END(guMtxF2L) diff --git a/src/libultra/mgu/mtxident.s b/src/libultra/mgu/mtxident.s index fb0e4c44a..7f074a552 100644 --- a/src/libultra/mgu/mtxident.s +++ b/src/libultra/mgu/mtxident.s @@ -1,29 +1,27 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noreorder - -.section .text - -.balign 32 +.text +.align 5 LEAF(guMtxIdent) - addi $t0, $zero, 1 - sll $t1, $t0, 0x10 - sw $t1, ($a0) - sw $zero, 4($a0) - sw $t0, 8($a0) - sw $zero, 0xc($a0) - sw $zero, 0x10($a0) - sw $t1, 0x14($a0) - sw $zero, 0x18($a0) - sw $t0, 0x1C($a0) - sw $zero, 0x20($a0) - sw $zero, 0x24($a0) - sw $zero, 0x28($a0) - sw $zero, 0x2c($a0) - sw $zero, 0x30($a0) - sw $zero, 0x34($a0) - sw $zero, 0x38($a0) - jr $ra - sw $zero, 0x3C($a0) + add t0, zero, 1 + sll t1, t0, 0x10 + sw t1, 0x00(a0) + sw zero, 0x04(a0) + sw t0, 0x08(a0) + sw zero, 0x0C(a0) + sw zero, 0x10(a0) + sw t1, 0x14(a0) + sw zero, 0x18(a0) + sw t0, 0x1C(a0) + sw zero, 0x20(a0) + sw zero, 0x24(a0) + sw zero, 0x28(a0) + sw zero, 0x2c(a0) + sw zero, 0x30(a0) + sw zero, 0x34(a0) + sw zero, 0x38(a0) + sw zero, 0x3C(a0) + jr ra END(guMtxIdent) diff --git a/src/libultra/mgu/mtxidentf.s b/src/libultra/mgu/mtxidentf.s index 583fc2218..490b79e4b 100644 --- a/src/libultra/mgu/mtxidentf.s +++ b/src/libultra/mgu/mtxidentf.s @@ -1,28 +1,26 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noreorder - -.section .text - -.balign 32 +.text +.align 5 LEAF(guMtxIdentF) - li $t0, 0x3F800000 // 1.0f - sw $t0, ($a0) - sw $zero, 4($a0) - sw $zero, 8($a0) - sw $zero, 0xC($a0) - sw $zero, 0x10($a0) - sw $t0, 0x14($a0) - sw $zero, 0x18($a0) - sw $zero, 0x1C($a0) - sw $zero, 0x20($a0) - sw $zero, 0x24($a0) - sw $t0, 0x28($a0) - sw $zero, 0x2C($a0) - sw $zero, 0x30($a0) - sw $zero, 0x34($a0) - sw $zero, 0x38($a0) - jr $ra - sw $t0, 0x3C($a0) + li.s t0, 1.0 + sw t0, 0x00(a0) + sw zero, 0x04(a0) + sw zero, 0x08(a0) + sw zero, 0x0C(a0) + sw zero, 0x10(a0) + sw t0, 0x14(a0) + sw zero, 0x18(a0) + sw zero, 0x1C(a0) + sw zero, 0x20(a0) + sw zero, 0x24(a0) + sw t0, 0x28(a0) + sw zero, 0x2C(a0) + sw zero, 0x30(a0) + sw zero, 0x34(a0) + sw zero, 0x38(a0) + sw t0, 0x3C(a0) + jr ra END(guMtxIdentF) diff --git a/src/libultra/mgu/mtxl2f.s b/src/libultra/mgu/mtxl2f.s index 9298da37c..b95e3aca7 100644 --- a/src/libultra/mgu/mtxl2f.s +++ b/src/libultra/mgu/mtxl2f.s @@ -1,41 +1,43 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder - -.section .text - -.balign 32 +.text +.align 5 #define MTX_INTPART 0 #define MTX_FRACPART 0x20 +#define FIXTOF 0.0000152587890625 /* 1.0f / 65536.0f */ + LEAF(guMtxL2F) - li $at, 0x37800000 // 1.0f / 65536.0f - mtc1 $at, $f0 - li $t9, 0xFFFF0000 - addiu $t8, $a1, MTX_FRACPART + li.s fv0, FIXTOF + li t9, 0xFFFF0000 + addiu t8, a1, MTX_FRACPART 1: - lw $t0, MTX_INTPART($a1) - lw $t1, MTX_FRACPART($a1) - addiu $a1, $a1, 4 - and $t2, $t0, $t9 - srl $t3, $t1, 0x10 - or $t4, $t2, $t3 - mtc1 $t4, $f4 - sll $t5, $t0, 0x10 - andi $t6, $t1, 0xFFFF - or $t7, $t5, $t6 - cvt.s.w $f6, $f4 - mtc1 $t7, $f10 - addiu $a0, $a0, 8 - cvt.s.w $f16, $f10 - mul.s $f8, $f6, $f0 - nop - mul.s $f18, $f16, $f0 - swc1 $f8, -8($a0) - bne $a1, $t8, 1b - swc1 $f18, -4($a0) - jr $ra - nop + lw t0, MTX_INTPART(a1) + lw t1, MTX_FRACPART(a1) + + and t2, t0, t9 + srl t3, t1, 0x10 + or t4, t2, t3 + + sll t5, t0, 0x10 + and t6, t1, 0xFFFF + or t7, t5, t6 + + mtc1 t4, ft0 + cvt.s.w ft1, ft0 + mul.s ft2, ft1, fv0 + + mtc1 t7, ft3 + cvt.s.w ft4, ft3 + mul.s ft5, ft4, fv0 + + swc1 ft2, 0(a0) + swc1 ft5, 4(a0) + addu a0, a0, 8 + addu a1, a1, 4 + bne a1, t8, 1b + + jr ra END(guMtxL2F) diff --git a/src/libultra/mgu/normalize.s b/src/libultra/mgu/normalize.s index 7686317ea..da10204d6 100644 --- a/src/libultra/mgu/normalize.s +++ b/src/libultra/mgu/normalize.s @@ -1,31 +1,27 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noreorder - -.section .text - -.balign 32 +.text +.align 5 LEAF(guNormalize) - lwc1 $f4, ($a0) - lwc1 $f6, ($a1) - lwc1 $f8, ($a2) - mul.s $f10, $f4, $f4 - li $t0, 0x3F800000 // 1.0f - mul.s $f16, $f6, $f6 - add.s $f18, $f10, $f16 - mul.s $f16, $f8, $f8 - add.s $f10, $f16, $f18 - mtc1 $t0, $f18 - sqrt.s $f16, $f10 - div.s $f10, $f18, $f16 - mul.s $f16, $f4, $f10 - nop - mul.s $f18, $f6, $f10 - nop - mul.s $f4, $f8, $f10 - swc1 $f16, ($a0) - swc1 $f18, ($a1) - jr $ra - swc1 $f4, ($a2) + lwc1 ft0, (a0) + lwc1 ft1, (a1) + lwc1 ft2, (a2) + li.s t0, 1.0 + mul.s ft3, ft0, ft0 + mul.s ft4, ft1, ft1 + add.s ft5, ft3, ft4 + mul.s ft4, ft2, ft2 + add.s ft3, ft4, ft5 + mtc1 t0, ft5 + sqrt.s ft4, ft3 + div.s ft3, ft5, ft4 + mul.s ft4, ft0, ft3 + mul.s ft5, ft1, ft3 + mul.s ft0, ft2, ft3 + swc1 ft4, (a0) + swc1 ft5, (a1) + swc1 ft0, (a2) + jr ra END(guNormalize) diff --git a/src/libultra/mgu/scale.s b/src/libultra/mgu/scale.s index 80199c062..5661b940c 100644 --- a/src/libultra/mgu/scale.s +++ b/src/libultra/mgu/scale.s @@ -1,52 +1,56 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder +.text +.align 5 -.section .text +LEAF(guScale) + li.s ft0, 65536.0 -.balign 32 + mtc1 a1, ft1 + mul.s ft2, ft1, ft0 + trunc.w.s ft3, ft2 + mfc1 t1, ft3 -LEAF(guScale) - li $at, 0x47800000 // 65536.0f - mtc1 $at, $f4 - mtc1 $a1, $f6 - sw $zero, 4($a0) - sw $zero, 0xC($a0) - mul.s $f8, $f6, $f4 - mtc1 $a2, $f6 - sw $zero, 0x10($a0) - sw $zero, 0x18($a0) - sw $zero, 0x24($a0) - sw $zero, 0x2C($a0) - sw $zero, 0x30($a0) - trunc.w.s $f10, $f8 - mul.s $f8, $f6, $f4 - mtc1 $a3, $f6 - sw $zero, 0x38($a0) - mfc1 $t1, $f10 - sw $zero, 0x3C($a0) - srl $t2, $t1, 0x10 - trunc.w.s $f10, $f8 - mul.s $f8, $f6, $f4 - sll $t0, $t2, 0x10 - sll $t2, $t1, 0x10 - mfc1 $t1, $f10 - sw $t0, ($a0) - sw $t2, 0x20($a0) - srl $t0, $t1, 0x10 - trunc.w.s $f10, $f8 - andi $t2, $t1, 0xFFFF - sw $t2, 0x28($a0) - sw $t0, 8($a0) - mfc1 $t1, $f10 - nop - srl $t2, $t1, 0x10 - sll $t0, $t2, 0x10 - sw $t0, 0x14($a0) - li $t0, 1 - sll $t2, $t1, 0x10 - sw $t2, 0x34($a0) - jr $ra - sw $t0, 0x1C($a0) + srl t2, t1, 0x10 + sll t0, t2, 0x10 + sw t0, 0x00(a0) + sll t2, t1, 0x10 + sw t2, 0x20(a0) + + mtc1 a2, ft1 + mul.s ft2, ft1, ft0 + trunc.w.s ft3, ft2 + mfc1 t1, ft3 + + srl t0, t1, 0x10 + sw t0, 0x08(a0) + andi t2, t1, 0xFFFF + sw t2, 0x28(a0) + + mtc1 a3, ft1 + mul.s ft2, ft1, ft0 + trunc.w.s ft3, ft2 + mfc1 t1, ft3 + + srl t2, t1, 0x10 + sll t0, t2, 0x10 + sw t0, 0x14(a0) + sll t2, t1, 0x10 + sw t2, 0x34(a0) + + li t0, 1 + sw t0, 0x1C(a0) + + sw zero, 0x04(a0) + sw zero, 0x0C(a0) + sw zero, 0x10(a0) + sw zero, 0x18(a0) + sw zero, 0x24(a0) + sw zero, 0x2C(a0) + sw zero, 0x30(a0) + sw zero, 0x38(a0) + sw zero, 0x3C(a0) + + jr ra END(guScale) diff --git a/src/libultra/mgu/translate.s b/src/libultra/mgu/translate.s index d059ad569..4ee630751 100644 --- a/src/libultra/mgu/translate.s +++ b/src/libultra/mgu/translate.s @@ -1,61 +1,68 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" -.set noat -.set noreorder +.text +.align 5 -.section .text +LEAF(guTranslate) + li.s ft0, 65536.0 -.balign 32 + mtc1 a1, ft1 + mul.s ft2, ft1, ft0 + trunc.w.s ft3, ft2 + mfc1 t1, ft3 -LEAF(guTranslate) - li $at, 0x47800000 // 65536.0f - mtc1 $at, $f4 - mtc1 $a1, $f6 - sw $zero, ($a0) - sw $zero, 0x14($a0) - mul.s $f8, $f6, $f4 - mtc1 $a2, $f6 - sw $zero, 8($a0) - sw $zero, 4($a0) - sw $zero, 0xC($a0) - sw $zero, 0x10($a0) - sw $zero, 0x20($a0) - trunc.w.s $f10, $f8 - mul.s $f8, $f6, $f4 - mtc1 $a3, $f6 - sw $zero, 0x24($a0) - mfc1 $t1, $f10 - sw $zero, 0x28($a0) - sw $zero, 0x2C($a0) - srl $t2, $t1, 0x10 - trunc.w.s $f10, $f8 - mul.s $f8, $f6, $f4 - sll $t0, $t2, 0x10 - sw $zero, 0x30($a0) - mfc1 $t3, $f10 - sw $zero, 0x34($a0) - srl $t2, $t3, 0x10 - trunc.w.s $f10, $f8 - or $t0, $t0, $t2 - sw $t0, 0x18($a0) - sll $t0, $t1, 0x10 - sll $t2, $t3, 0x10 - mfc1 $t1, $f10 - srl $t2, $t2, 0x10 - or $t0, $t0, $t2 - sw $t0, 0x38($a0) - srl $t2, $t1, 0x10 - sll $t0, $t2, 0x10 - addiu $t0, $t0, 1 - sw $t0, 0x1C($a0) - lui $t0, 1 - ori $t0, $t0, 0 - sw $t0, ($a0) - sw $t0, 0x14($a0) - lui $t0, (0x00000001 >> 16) - ori $t0, (0x00000001 & 0xFFFF) - sll $t2, $t1, 0x10 - sw $t2, 0x3C($a0) - jr $ra - sw $t0, 8($a0) + mtc1 a2, ft1 + mul.s ft2, ft1, ft0 + trunc.w.s ft3, ft2 + mfc1 t3, ft3 + + srl t2, t1, 0x10 + sll t0, t2, 0x10 + srl t2, t3, 0x10 + or t0, t0, t2 + sw t0, 0x18(a0) + + sll t2, t3, 0x10 + sll t0, t1, 0x10 + srl t2, t2, 0x10 + or t0, t0, t2 + sw t0, 0x38(a0) + + mtc1 a3, ft1 + mul.s ft2, ft1, ft0 + trunc.w.s ft3, ft2 + mfc1 t1, ft3 + + srl t2, t1, 0x10 + sll t0, t2, 0x10 + addiu t0, t0, 1 + sw t0, 0x1C(a0) + + sll t2, t1, 0x10 + sw t2, 0x3C(a0) + + sw zero, 0x00(a0) + sw zero, 0x04(a0) + sw zero, 0x08(a0) + sw zero, 0x0C(a0) + sw zero, 0x10(a0) + sw zero, 0x14(a0) + sw zero, 0x20(a0) + sw zero, 0x24(a0) + sw zero, 0x28(a0) + sw zero, 0x2C(a0) + sw zero, 0x30(a0) + sw zero, 0x34(a0) + + lui t0, (0x00010000 >> 16) + ori t0, (0x00010000 & 0xFFFF) + sw t0, (a0) + sw t0, 0x14(a0) + + lui t0, (0x00000001 >> 16) + ori t0, (0x00000001 & 0xFFFF) + sw t0, 8(a0) + + jr ra END(guTranslate) diff --git a/src/libultra/os/exceptasm.s b/src/libultra/os/exceptasm.s index 3c55d66ac..3c02267b9 100644 --- a/src/libultra/os/exceptasm.s +++ b/src/libultra/os/exceptasm.s @@ -1,4 +1,8 @@ +#ifdef __GNUC__ +.set gp=64 +#endif #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" #include "ultra64/rcp.h" #include "ultra64/message.h" @@ -6,17 +10,12 @@ #include "ultra64/exception.h" #include "ultra64/version.h" -.set noat -.set noreorder -.set gp=64 - -.section .data - -.balign 16 +.data +.align 2 DATA(__osHwIntTable) .word 0, 0 - .word 0, 0 // cart + .word 0, 0 /* cart */ .word 0, 0 .word 0, 0 .word 0, 0 @@ -26,9 +25,8 @@ DATA(__osPiIntTable) .word 0, 0 ENDDATA(__osPiIntTable) -.section .rodata - -.balign 16 +.rdata +.align 2 __osIntOffTable: .byte 0x00 /* redispatch */ @@ -75,215 +73,197 @@ __osIntTable: .word IP7_Hdlr .word counter -.section .text - -.balign 16 +.text /** - * The exception preamble is copied to the exception vectors at + * The 16-byte exception preamble is copied to the exception vectors at * UT_VEC, XUT_VEC, ECC_VEC, E_VEC, to direct execution to __osException */ LEAF(__osExceptionPreamble) - lui $k0, %hi(__osException) - addiu $k0, %lo(__osException) - jr $k0 - nop + la k0, __osException + jr k0 END(__osExceptionPreamble) LEAF(__osException) - // Load scratch space for thread saving - lui $k0, %hi(__osThreadSave) - addiu $k0, %lo(__osThreadSave) - // Save $at - sd $at, THREAD_AT($k0) - // Save sr - mfc0 $k1, C0_SR - sw $k1, THREAD_SR($k0) - // Disable interrupts - li $at, ~(SR_IE | SR_EXL) - and $k1, $k1, $at - mtc0 $k1, C0_SR - // Save some temp registers for use in the following - sd $t0, THREAD_T0($k0) - sd $t1, THREAD_T1($k0) - sd $t2, THREAD_T2($k0) - // Mark FPU as unused - sw $zero, THREAD_FP($k0) - // Left over from misplaced ifdef, immediately overwritten on next instruction - mfc0 $t0, C0_CAUSE +.set noat + /* Load scratch space for thread saving */ + la k0, __osThreadSave + /* Save at */ + sd AT, THREAD_AT(k0) +.set at + /* Save sr */ + MFC0( k1, C0_SR) + sw k1, THREAD_SR(k0) + /* Disable interrupts */ + and k1, k1, ~(SR_IE | SR_EXL) + MTC0( k1, C0_SR) + /* Save some temp registers for use in the following */ + sd t0, THREAD_T0(k0) + sd t1, THREAD_T1(k0) + sd t2, THREAD_T2(k0) + /* Mark FPU as unused */ + sw zero, THREAD_FP(k0) + /* Left over from misplaced ifdef, immediately overwritten on next instruction */ + MFC0( t0, C0_CAUSE) savecontext: - // Save the previously running thread's context to be restored when it resumes - move $t0, $k0 - lui $k0, %hi(__osRunningThread) - lw $k0, %lo(__osRunningThread)($k0) - ld $t1, THREAD_AT($t0) - sd $t1, THREAD_AT($k0) - ld $t1, THREAD_SR($t0) - sd $t1, THREAD_SR($k0) - ld $t1, THREAD_T0($t0) - sd $t1, THREAD_T0($k0) - ld $t1, THREAD_T1($t0) - sd $t1, THREAD_T1($k0) - ld $t1, THREAD_T2($t0) - sd $t1, THREAD_T2($k0) - lw $k1, THREAD_SR($k0) - mflo $t0 - sd $t0, THREAD_LO($k0) - mfhi $t0 - andi $t1, $k1, SR_IMASK - sd $v0, THREAD_V0($k0) - sd $v1, THREAD_V1($k0) - sd $a0, THREAD_A0($k0) - sd $a1, THREAD_A1($k0) - sd $a2, THREAD_A2($k0) - sd $a3, THREAD_A3($k0) - sd $t3, THREAD_T3($k0) - sd $t4, THREAD_T4($k0) - sd $t5, THREAD_T5($k0) - sd $t6, THREAD_T6($k0) - sd $t7, THREAD_T7($k0) - sd $s0, THREAD_S0($k0) - sd $s1, THREAD_S1($k0) - sd $s2, THREAD_S2($k0) - sd $s3, THREAD_S3($k0) - sd $s4, THREAD_S4($k0) - sd $s5, THREAD_S5($k0) - sd $s6, THREAD_S6($k0) - sd $s7, THREAD_S7($k0) - sd $t8, THREAD_T8($k0) - sd $t9, THREAD_T9($k0) - sd $gp, THREAD_GP($k0) - sd $sp, THREAD_SP($k0) - sd $fp, THREAD_S8($k0) - sd $ra, THREAD_RA($k0) - beqz $t1, savercp - sd $t0, THREAD_HI($k0) - // If any CPU interrupts are enabled in the previous thread's SR, bitwise-OR in the - // disabled CPU interrupts from the global interrupt mask. - // This is an attempt at reverting the effect of masking the thread's SR with the - // global interrupt mask. This is however broken, see comments for osSetIntMask. - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, ($t0) - li $at, ~0 - xor $t2, $t0, $at - lui $at, ((~SR_IMASK) >> 0x10) & 0xFFFF - andi $t2, $t2, SR_IMASK - ori $at, (~SR_IMASK) & 0xFFFF - or $t4, $t1, $t2 - and $t3, $k1, $at - andi $t0, $t0, SR_IMASK - or $t3, $t3, $t4 - and $t1, $t1, $t0 - and $k1, $k1, $at - sw $t3, THREAD_SR($k0) - or $k1, $k1, $t1 +.set noreorder + /* Save the previously running thread's context to be restored when it resumes */ + move t0, k0 + lw k0, __osRunningThread + ld t1, THREAD_AT(t0) + sd t1, THREAD_AT(k0) + ld t1, THREAD_SR(t0) + sd t1, THREAD_SR(k0) + ld t1, THREAD_T0(t0) + sd t1, THREAD_T0(k0) + ld t1, THREAD_T1(t0) + sd t1, THREAD_T1(k0) + ld t1, THREAD_T2(t0) + sd t1, THREAD_T2(k0) +.set reorder + sd $2, THREAD_V0(k0) + sd $3, THREAD_V1(k0) + sd $4, THREAD_A0(k0) + sd $5, THREAD_A1(k0) + sd $6, THREAD_A2(k0) + sd $7, THREAD_A3(k0) + sd $11, THREAD_T3(k0) + sd $12, THREAD_T4(k0) + sd $13, THREAD_T5(k0) + sd $14, THREAD_T6(k0) + sd $15, THREAD_T7(k0) + sd $16, THREAD_S0(k0) + sd $17, THREAD_S1(k0) + sd $18, THREAD_S2(k0) + sd $19, THREAD_S3(k0) + sd $20, THREAD_S4(k0) + sd $21, THREAD_S5(k0) + sd $22, THREAD_S6(k0) + sd $23, THREAD_S7(k0) + sd $24, THREAD_T8(k0) + sd $25, THREAD_T9(k0) + sd $28, THREAD_GP(k0) + sd $29, THREAD_SP(k0) + sd $30, THREAD_S8(k0) + sd $31, THREAD_RA(k0) + mflo t0 + sd t0, THREAD_LO(k0) + mfhi t0 + sd t0, THREAD_HI(k0) + lw k1, THREAD_SR(k0) + andi t1, k1, SR_IMASK + beqz t1, savercp + /* If any CPU interrupts are enabled in the previous thread's SR, bitwise-OR in the */ + /* disabled CPU interrupts from the global interrupt mask. */ + /* This is an attempt at reverting the effect of masking the thread's SR with the */ + /* global interrupt mask. This is however broken, see comments for osSetIntMask. */ + la t0, __OSGlobalIntMask + lw t0, (t0) + xor t2, t0, ~0 + andi t2, t2, SR_IMASK + or t4, t1, t2 + and t3, k1, ~SR_IMASK + andi t0, t0, SR_IMASK + or t3, t3, t4 + and t1, t1, t0 + and k1, k1, ~SR_IMASK + sw t3, THREAD_SR(k0) + or k1, k1, t1 savercp: - // Save the currently masked RCP interrupts. - lui $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1) - beqz $t1, endrcp - nop - // Similar to the above comment, but for RCP interrupt enable bits rather than CPU. - // This suffers from the same problem as above. - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, ($t0) - lw $t4, THREAD_RCP($k0) - li $at, ~0 - srl $t0, $t0, RCP_IMASKSHIFT - xor $t0, $t0, $at - andi $t0, $t0, (RCP_IMASK >> RCP_IMASKSHIFT) - and $t0, $t0, $t4 - or $t1, $t1, $t0 + /* Save the currently masked RCP interrupts. */ + lw t1, PHYS_TO_K1(MI_INTR_MASK_REG) + beqz t1, endrcp + /* Similar to the above comment, but for RCP interrupt enable bits rather than CPU. */ + /* This suffers from the same problem as above. */ + la t0, __OSGlobalIntMask + lw t0, (t0) + srl t0, t0, RCP_IMASKSHIFT + xor t0, t0, ~0 + andi t0, t0, (RCP_IMASK >> RCP_IMASKSHIFT) + lw t4, THREAD_RCP(k0) + and t0, t0, t4 + or t1, t1, t0 endrcp: - sw $t1, THREAD_RCP($k0) - mfc0 $t0, C0_EPC - sw $t0, THREAD_PC($k0) - lw $t0, THREAD_FP($k0) - beqz $t0, handle_interrupt - nop - // Save FP Registers if FPU was used by the thread - cfc1 $t0, C1_FPCSR + sw t1, THREAD_RCP(k0) + MFC0( t0, C0_EPC) + sw t0, THREAD_PC(k0) + lw t0, THREAD_FP(k0) + beqz t0, handle_interrupt + /* Save FP Registers if FPU was used by the thread */ +.set noreorder + cfc1 t0, C1_FPCSR nop - sw $t0, THREAD_FPCSR($k0) - sdc1 $f0, THREAD_FP0($k0) - sdc1 $f2, THREAD_FP2($k0) - sdc1 $f4, THREAD_FP4($k0) - sdc1 $f6, THREAD_FP6($k0) - sdc1 $f8, THREAD_FP8($k0) - sdc1 $f10, THREAD_FP10($k0) - sdc1 $f12, THREAD_FP12($k0) - sdc1 $f14, THREAD_FP14($k0) - sdc1 $f16, THREAD_FP16($k0) - sdc1 $f18, THREAD_FP18($k0) - sdc1 $f20, THREAD_FP20($k0) - sdc1 $f22, THREAD_FP22($k0) - sdc1 $f24, THREAD_FP24($k0) - sdc1 $f26, THREAD_FP26($k0) - sdc1 $f28, THREAD_FP28($k0) - sdc1 $f30, THREAD_FP30($k0) + sw t0, THREAD_FPCSR(k0) +.set reorder + sdc1 $f0, THREAD_FP0(k0) + sdc1 $f2, THREAD_FP2(k0) + sdc1 $f4, THREAD_FP4(k0) + sdc1 $f6, THREAD_FP6(k0) + sdc1 $f8, THREAD_FP8(k0) + sdc1 $f10, THREAD_FP10(k0) + sdc1 $f12, THREAD_FP12(k0) + sdc1 $f14, THREAD_FP14(k0) + sdc1 $f16, THREAD_FP16(k0) + sdc1 $f18, THREAD_FP18(k0) + sdc1 $f20, THREAD_FP20(k0) + sdc1 $f22, THREAD_FP22(k0) + sdc1 $f24, THREAD_FP24(k0) + sdc1 $f26, THREAD_FP26(k0) + sdc1 $f28, THREAD_FP28(k0) + sdc1 $f30, THREAD_FP30(k0) handle_interrupt: - // Determine the cause of the exception or interrupt and - // enter appropriate handling routine - mfc0 $t0, C0_CAUSE - sw $t0, THREAD_CAUSE($k0) - li $t1, OS_STATE_RUNNABLE - sh $t1, THREAD_STATE($k0) - andi $t1, $t0, CAUSE_EXCMASK - // Test for break exception - li $t2, EXC_BREAK - beq $t1, $t2, handle_break - nop - // Test for CpU (coprocessor unusable) exception - li $t2, EXC_CPU - beq $t1, $t2, handle_CpU - nop - // Test for interrupt, if it's not an interrupt, panic - li $t2, EXC_INT - bne $t1, $t2, panic - nop - and $s0, $k1, $t0 + /* Determine the cause of the exception or interrupt and */ + /* enter appropriate handling routine */ + MFC0( t0, C0_CAUSE) + sw t0, THREAD_CAUSE(k0) +label: + li t1, OS_STATE_RUNNABLE + sh t1, THREAD_STATE(k0) + andi t1, t0, CAUSE_EXCMASK + /* Test for break exception */ + li t2, EXC_BREAK + beq t1, t2, handle_break + /* Test for CpU (coprocessor unusable) exception */ + li t2, EXC_CPU + beq t1, t2, handle_CpU + /* Test for interrupt, if it's not an interrupt, panic */ + li t2, EXC_INT + bne t1, t2, panic + + and s0, k1, t0 next_interrupt: - // Handle external interrupt causes, using a jump table - // to enter into the appropriate handler - andi $t1, $s0, CAUSE_IPMASK - srl $t2, $t1, CAUSE_IPSHIFT + 4 - bnez $t2, 1f - nop - srl $t2, $t1, CAUSE_IPSHIFT - addi $t2, $t2, 0x10 + /* Handle external interrupt causes, using a jump table */ + /* to enter into the appropriate handler */ + andi t1, s0, CAUSE_IPMASK + srl t2, t1, CAUSE_IPSHIFT + 4 + bnez t2, 1f + + srl t2, t1, CAUSE_IPSHIFT + addi t2, t2, 0x10 1: - lui $at, %hi(__osIntOffTable) - addu $at, $at, $t2 - lbu $t2, %lo(__osIntOffTable)($at) - lui $at, %hi(__osIntTable) - addu $at, $at, $t2 - lw $t2, %lo(__osIntTable)($at) - jr $t2 - nop + lbu t2, __osIntOffTable(t2) + lw t2, __osIntTable(t2) + jr t2 /** * IP6 Interrupt * Only signalled by development hardware */ IP6_Hdlr: - // Mask out interrupt and continue - li $at, ~CAUSE_IP6 + /* Mask out interrupt and continue */ + and s0, s0, ~CAUSE_IP6 b next_interrupt - and $s0, $s0, $at /** * IP7 Interrupt * Only signalled by development hardware */ IP7_Hdlr: - // Mask out interrupt and continue - li $at, ~CAUSE_IP7 + /* Mask out interrupt and continue */ + and s0, s0, ~CAUSE_IP7 b next_interrupt - and $s0, $s0, $at /** * IP8/Counter Interrupt @@ -291,435 +271,368 @@ IP7_Hdlr: * cop0 compare register, this interrupt is triggered */ counter: - mfc0 $t1, C0_COMPARE - mtc0 $t1, C0_COMPARE - // Post counter message + MFC0( t1, C0_COMPARE) + MTC0( t1, C0_COMPARE) + /* Post counter message */ + li a0, OS_EVENT_COUNTER*8 jal send_mesg - li $a0, OS_EVENT_COUNTER*8 - // Mask out interrupt and continue - li $at, ~CAUSE_IP8 + /* Mask out interrupt and continue */ + and s0, s0, ~CAUSE_IP8 b next_interrupt - and $s0, $s0, $at /** * IP4/Cartridge Interrupt * Signalled by the N64 Disk Drive */ cart: - // Load cart callback set by __osSetHWIntrRoutine - lui $t1, %hi(__osHwIntTable) - addiu $t1, %lo(__osHwIntTable) - lw $t2, (OS_INTR_CART*HWINT_SIZE+HWINT_CALLBACK)($t1) - // Mask out interrupt - li $at, ~CAUSE_IP4 - and $s0, $s0, $at - // If the callback is NULL, handling is done - beqz $t2, send_cart_mesg - addi $t1, $t1, (OS_INTR_CART*HWINT_SIZE) - // Set up a stack and run the callback - jalr $t2 - lw $sp, HWINT_SP($t1) - beqz $v0, send_cart_mesg - nop - // Redispatch immediately if the callback returned nonzero + /* Load cart callback set by __osSetHWIntrRoutine */ + la t1, __osHwIntTable + lw t2, (OS_INTR_CART*HWINT_SIZE+HWINT_CALLBACK)(t1) + /* Mask out interrupt */ + and s0, s0, ~CAUSE_IP4 + /* If the callback is NULL, handling is done */ + addi t1, t1, (OS_INTR_CART*HWINT_SIZE) + beqz t2, send_cart_mesg + /* Set up a stack and run the callback */ + lw sp, HWINT_SP(t1) + jalr t2 + beqz v0, send_cart_mesg + /* Redispatch immediately if the callback returned nonzero */ b redispatch - nop send_cart_mesg: - // Post a cart event message + /* Post a cart event message */ + li a0, OS_EVENT_CART*8 jal send_mesg - li $a0, OS_EVENT_CART*8 - // Continue + /* Continue */ b next_interrupt - nop /** * IP3/RCP Interrupt * Signalled by the RCP for various reasons, described below */ rcp: - // Load the MI interrupts and mask with the RCP bits in the global interrupt mask - //! @bug this clobbers the t0 register which is expected to hold the value of the - //! C0_CAUSE register in the sw1 and sw2 handlers. If the sw1 or sw2 handler runs - //! after this, the interrupt will not be cleared properly. - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, ($t0) - lui $s1, %hi(PHYS_TO_K1(MI_INTR_REG)) - lw $s1, %lo(PHYS_TO_K1(MI_INTR_REG))($s1) - srl $t0, $t0, RCP_IMASKSHIFT - and $s1, $s1, $t0 + /* Load the MI interrupts and mask with the RCP bits in the global interrupt mask */ + /*! @bug this clobbers the t0 register which is expected to hold the value of the */ + /*! C0_CAUSE register in the sw1 and sw2 handlers. If the sw1 or sw2 handler runs */ + /*! after this, the interrupt will not be cleared properly. */ + la t0, __OSGlobalIntMask + lw t0, (t0) + srl t0, t0, RCP_IMASKSHIFT + lw s1, PHYS_TO_K1(MI_INTR_REG) + and s1, s1, t0 /** * Signal Processor (SP) Interrupt */ -sp: - // Test for sp interrupt - andi $t1, $s1, MI_INTR_SP - beqz $t1, vi - nop - // Test for yielded or done signals in particular - lui $t4, %hi(PHYS_TO_K1(SP_STATUS_REG)) - lw $t4, %lo(PHYS_TO_K1(SP_STATUS_REG))($t4) - li $t1, (SP_CLR_INTR | SP_CLR_SIG3) - lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) - andi $t4, $t4, (SP_STATUS_YIELDED | SP_STATUS_TASKDONE) - // Mask out SP interrupt - andi $s1, $s1, (MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) - beqz $t4, sp_other_break - // Clear interrupt and signal 3 - sw $t1, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) - // Post an SP event message + /* Test for sp interrupt */ + andi t1, s1, MI_INTR_SP + beqz t1, vi + /* Test for yielded or done signals in particular */ + lw t4, PHYS_TO_K1(SP_STATUS_REG) + li t1, (SP_CLR_INTR | SP_CLR_SIG3) + andi t4, t4, (SP_STATUS_YIELDED | SP_STATUS_TASKDONE) + /* Mask out SP interrupt */ + andi s1, s1, (MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) + sw t1, PHYS_TO_K1(SP_STATUS_REG) + beqz t4, sp_other_break + /* Clear interrupt and signal 3 */ + /* Post an SP event message */ + li a0, OS_EVENT_SP*8 jal send_mesg - li $a0, OS_EVENT_SP*8 - beqz $s1, NoMoreRcpInts - nop - // Step over sp_other_break handler + beqz s1, NoMoreRcpInts + /* Step over sp_other_break handler */ b vi - nop sp_other_break: - // An sp signal that is not due to yielding or task completion, such as - // an sp breakpoint. Post a different event message + /* An sp signal that is not due to yielding or task completion, such as */ + /* an sp breakpoint. Post a different event message */ + li a0, OS_EVENT_SP_BREAK*8 jal send_mesg - li $a0, OS_EVENT_SP_BREAK*8 - beqz $s1, NoMoreRcpInts - nop + beqz s1, NoMoreRcpInts /** * Video Interface (VI) Interrupt */ vi: - // Test for vi interrupt - andi $t1, $s1, MI_INTR_VI - beqz $t1, ai - lui $at, %hi(PHYS_TO_K1(VI_CURRENT_REG)) - // Mask out vi interrupt - andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_PI | MI_INTR_DP) - // Clear interrupt - sw $zero, %lo(PHYS_TO_K1(VI_CURRENT_REG))($at) - // Post vi event message + /* Test for vi interrupt */ + andi t1, s1, MI_INTR_VI + beqz t1, ai + /* Mask out vi interrupt */ + andi s1, s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_PI | MI_INTR_DP) + /* Clear interrupt */ + sw zero, PHYS_TO_K1(VI_CURRENT_REG) + /* Post vi event message */ + li a0, OS_EVENT_VI*8 jal send_mesg - li $a0, OS_EVENT_VI*8 - beqz $s1, NoMoreRcpInts - nop + beqz s1, NoMoreRcpInts /** * Audio Interface (AI) Interrupt */ ai: - // Test for ai interrupt - andi $t1, $s1, MI_INTR_AI - beqz $t1, si - nop - li $t1, 1 - lui $at, %hi(PHYS_TO_K1(AI_STATUS_REG)) - // Mask out ai interrupt - andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) - // Clear interrupt - sw $t1, %lo(PHYS_TO_K1(AI_STATUS_REG))($at) - // Post ai event message + /* Test for ai interrupt */ + andi t1, s1, MI_INTR_AI + beqz t1, si + + /* Mask out ai interrupt */ + andi s1, s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) + /* Clear interrupt */ + li t1, 1 + sw t1, PHYS_TO_K1(AI_STATUS_REG) + /* Post ai event message */ + li a0, OS_EVENT_AI*8 jal send_mesg - li $a0, OS_EVENT_AI*8 - beqz $s1, NoMoreRcpInts - nop + beqz s1, NoMoreRcpInts /** * Serial Interface (SI) Interrupt */ si: - // Test for si interrupt - andi $t1, $s1, MI_INTR_SI - beqz $t1, pi - lui $at, %hi(PHYS_TO_K1(SI_STATUS_REG)) - // Mask out si interrupt - andi $s1, $s1, (MI_INTR_SP | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) - // Clear interrupt - sw $zero, %lo(PHYS_TO_K1(SI_STATUS_REG))($at) - // Post si event message + /* Test for si interrupt */ + andi t1, s1, MI_INTR_SI + beqz t1, pi + + /* Mask out si interrupt */ + andi s1, s1, (MI_INTR_SP | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) + /* Clear interrupt */ + sw zero, PHYS_TO_K1(SI_STATUS_REG) + /* Post si event message */ + li a0, OS_EVENT_SI*8 jal send_mesg - li $a0, OS_EVENT_SI*8 - beqz $s1, NoMoreRcpInts - nop + beqz s1, NoMoreRcpInts /** * Parallel Interface (PI) Interrupt */ pi: - // Test for pi interrupt - andi $t1, $s1, MI_INTR_PI - beqz $t1, dp - nop + /* Test for pi interrupt */ + andi t1, s1, MI_INTR_PI + beqz t1, dp + + /* Clear and mask the interrupt */ #if LIBULTRA_VERSION < LIBULTRA_VERSION_J - // Clear interrupt and mask out pi interrupt - li $t1, PI_STATUS_CLR_INTR - lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) - andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_DP) - sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) + li t1, PI_STATUS_CLR_INTR + andi s1, s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_DP) + sw t1, PHYS_TO_K1(PI_STATUS_REG) #else - // Clear interrupt - li $t1, PI_STATUS_CLR_INTR - lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) - sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) - // Load pi callback - lui $t1, %hi(__osPiIntTable) - addiu $t1, %lo(__osPiIntTable) - lw $t2, HWINT_CALLBACK($t1) - // Mask out pi interrupt - andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_DP) - // Skip callback if NULL - beqz $t2, no_pi_callback - nop - // Set up a stack and run the callback - lw $sp, HWINT_SP($t1) - jalr $t2 - move $a0, $v0 - // If the callback returns non-zero, don't post a pi event message - bnez $v0, skip_pi_mesg - nop + /* Clear the interrupt */ + li t1, PI_STATUS_CLR_INTR + sw t1, PHYS_TO_K1(PI_STATUS_REG) + /* Load pi callback */ + la t1, __osPiIntTable + lw t2, HWINT_CALLBACK(t1) + /* Mask out pi interrupt */ + andi s1, s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_DP) + /* Skip callback if NULL */ + beqz t2, no_pi_callback + /* Set up a stack and run the callback */ + lw sp, HWINT_SP(t1) + move a0, v0 + jalr t2 + /* If the callback returns non-zero, don't post a pi event message */ + bnez v0, skip_pi_mesg #endif no_pi_callback: - // Post pi event message + /* Post pi event message */ + li a0, OS_EVENT_PI*8 jal send_mesg - li $a0, OS_EVENT_PI*8 skip_pi_mesg: - beqz $s1, NoMoreRcpInts - nop + beqz s1, NoMoreRcpInts /** * Display Processor (DP) Interrupt */ dp: - // Test for dp interrupt - andi $t1, $s1, MI_INTR_DP - beqz $t1, NoMoreRcpInts - nop - // Clear dp interrupt - li $t1, MI_CLR_DP_INTR - lui $at, %hi(PHYS_TO_K1(MI_INIT_MODE_REG)) - // Mask out dp interrupt - andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI) - sw $t1, %lo(PHYS_TO_K1(MI_INIT_MODE_REG))($at) - // Post dp event message + /* Test for dp interrupt */ + andi t1, s1, MI_INTR_DP + beqz t1, NoMoreRcpInts + + /* Mask out dp interrupt */ + andi s1, s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI) + /* Clear dp interrupt */ + li t1, MI_CLR_DP_INTR + sw t1, PHYS_TO_K1(MI_INIT_MODE_REG) + /* Post dp event message */ + li a0, OS_EVENT_DP*8 jal send_mesg - li $a0, OS_EVENT_DP*8 NoMoreRcpInts: - // Mask out interrupt and continue - li $at, ~CAUSE_IP3 + /* Mask out interrupt and continue */ + and s0, s0, ~CAUSE_IP3 b next_interrupt - and $s0, $s0, $at /** * IP5/PreNMI Interrupt * Reset button has been pressed */ prenmi: - // Disable IP5/PreNMI interrupt for the previously running thread - lw $k1, THREAD_SR($k0) - li $at, ~SR_IBIT5 - lui $t1, %hi(__osShutdown) - and $k1, $k1, $at - sw $k1, THREAD_SR($k0) - addiu $t1, %lo(__osShutdown) - // Test __osShutdown for first PreNMI event - lw $t2, ($t1) - beqz $t2, firstnmi - li $at, ~CAUSE_IP5 - // Mask out interrupt and redispatch immediately + /* Disable IP5/PreNMI interrupt for the previously running thread */ + lw k1, THREAD_SR(k0) + and k1, k1, ~SR_IBIT5 + sw k1, THREAD_SR(k0) + /* Test __osShutdown for first PreNMI event */ + la t1, __osShutdown + lw t2, (t1) + beqz t2, firstnmi + /* Mask out interrupt and redispatch immediately */ + and s0, s0, ~CAUSE_IP5 b redispatch - and $s0, $s0, $at firstnmi: - // Set __osShutdown - li $t2, 1 - sw $t2, ($t1) - // Post a PreNMI event message + /* Set __osShutdown */ + li t2, 1 + sw t2, (t1) + /* Post a PreNMI event message */ + li a0, OS_EVENT_PRENMI*8 jal send_mesg - li $a0, OS_EVENT_PRENMI*8 - // Mask out and disable IP5/PreNMI interrupt for the highest priority thread - lui $t2, %hi(__osRunQueue) - lw $t2, %lo(__osRunQueue)($t2) - li $at, ~SR_IBIT5 - and $s0, $s0, $at - lw $k1, THREAD_SR($t2) - and $k1, $k1, $at - // Redispatch immediately + /* Mask out and disable IP5/PreNMI interrupt for the highest priority thread */ + lw t2, __osRunQueue + and s0, s0, ~SR_IBIT5 + lw k1, THREAD_SR(t2) + and k1, k1, ~SR_IBIT5 + sw k1, THREAD_SR(t2) + /* Redispatch immediately */ b redispatch - sw $k1, THREAD_SR($t2) sw2: - // Mask out interrupt - li $at, ~CAUSE_SW2 - and $t0, $t0, $at - mtc0 $t0, C0_CAUSE - // Post sw2 event message + /* Mask out interrupt */ + and t0, t0, ~CAUSE_SW2 + MTC0( t0, C0_CAUSE) + /* Post sw2 event message */ + li a0, OS_EVENT_SW2*8 jal send_mesg - li $a0, OS_EVENT_SW2*8 - li $at, ~CAUSE_SW2 - // Mask out interrupt and continue + /* Mask out interrupt and continue */ + and s0, s0, ~CAUSE_SW2 b next_interrupt - and $s0, $s0, $at sw1: - // Mask out interrupt - li $at, ~CAUSE_SW1 - and $t0, $t0, $at - mtc0 $t0, C0_CAUSE - // Post sw1 event message + /* Mask out interrupt */ + and t0, t0, ~CAUSE_SW1 + MTC0( t0, C0_CAUSE) + /* Post sw1 event message */ + li a0, OS_EVENT_SW1*8 jal send_mesg - li $a0, OS_EVENT_SW1*8 - li $at, ~CAUSE_SW1 - // Mask out interrupt and continue + /* Mask out interrupt and continue */ + and s0, s0, ~CAUSE_SW1 b next_interrupt - and $s0, $s0, $at handle_break: - // Set last thread as having hit a break exception - li $t1, OS_FLAG_CPU_BREAK - sh $t1, THREAD_FLAGS($k0) - // Post a cpu break event message + /* Set last thread as having hit a break exception */ + li t1, OS_FLAG_CPU_BREAK + sh t1, THREAD_FLAGS(k0) + /* Post a cpu break event message */ + li a0, OS_EVENT_CPU_BREAK*8 jal send_mesg - li $a0, OS_EVENT_CPU_BREAK*8 - // Redispatch + /* Redispatch */ b redispatch - nop redispatch: - lui $t2, %hi(__osRunQueue) - lw $t2, %lo(__osRunQueue)($t2) - // Get priority of previously running thread - lw $t1, THREAD_PRI($k0) - // Get highest priority from waiting threads - lw $t3, THREAD_PRI($t2) - slt $at, $t1, $t3 - beqz $at, enqueueRunning - nop - // The previously running thread is no longer the highest priority, - // enqueue it to the run queue to wait its turn again - lui $a0, %hi(__osRunQueue) - move $a1, $k0 + lw t2, __osRunQueue + /* Get priority of previously running thread */ + lw t1, THREAD_PRI(k0) + /* Get highest priority from waiting threads */ + lw t3, THREAD_PRI(t2) + bge t1, t3, enqueueRunning + /* The previously running thread is no longer the highest priority, */ + /* enqueue it to the run queue to wait its turn again */ + move a1, k0 + la a0, __osRunQueue jal __osEnqueueThread - addiu $a0, $a0, %lo(__osRunQueue) + j __osDispatchThread - nop /** * Resume the previously running thread by placing it at the top of * the run queue and dispatching it */ enqueueRunning: - lui $t1, %hi(__osRunQueue) - addiu $t1, $t1, %lo(__osRunQueue) - lw $t2, ($t1) - sw $t2, THREAD_NEXT($k0) + la t1, __osRunQueue + lw t2, (t1) + sw t2, THREAD_NEXT(k0) + sw k0, (t1) j __osDispatchThread - sw $k0, ($t1) /** * Unhandled exceptions & interrupts end up here, * trap to software by posting a fault message */ panic: - // Mark the thread as having faulted - lui $at, %hi(__osFaultedThread) - sw $k0, %lo(__osFaultedThread)($at) - li $t1, OS_STATE_STOPPED - sh $t1, THREAD_STATE($k0) - li $t1, OS_FLAG_FAULT - sh $t1, THREAD_FLAGS($k0) - // Save C0_BADVADDR - mfc0 $t2, C0_BADVADDR - sw $t2, THREAD_BADVADDR($k0) - // Post the fault message + /* Mark the thread as having faulted */ + sw k0, __osFaultedThread + li t1, OS_STATE_STOPPED + sh t1, THREAD_STATE(k0) + li t1, OS_FLAG_FAULT + sh t1, THREAD_FLAGS(k0) + /* Save C0_BADVADDR */ + MFC0( t2, C0_BADVADDR) + sw t2, THREAD_BADVADDR(k0) + /* Post the fault message */ + li a0, OS_EVENT_FAULT*8 jal send_mesg - li $a0, OS_EVENT_FAULT*8 - // Dispatch next thread + /* Dispatch next thread */ j __osDispatchThread - nop /** * Handles posting event messages to the listening message queue, if there is one */ send_mesg: - // Load pointer to listening message queue - lui $t2, %hi(__osEventStateTab) - addiu $t2, %lo(__osEventStateTab) - addu $t2, $t2, $a0 - lw $t1, ($t2) - // Save return address - move $s2, $ra - // If there is no listening message queue, done - beqz $t1, send_done - nop - // Test if the message queue is full, if so don't post the message - lw $t3, MQ_VALIDCOUNT($t1) - lw $t4, MQ_MSGCOUNT($t1) - slt $at, $t3, $t4 - beqz $at, send_done - nop - // Add validcount to first and modulo with msgcount - lw $t5, MQ_FIRST($t1) - addu $t5, $t5, $t3 - // Modulo - div $zero, $t5, $t4 - bnez $t4, 1f - nop - break 7 // div0 -1: - li $at, -1 - bne $t4, $at, 2f - li $at, -0x80000000 - bne $t5, $at, 2f - nop - break 6 // overflow -2: - // End Modulo - lw $t4, MQ_MSG($t1) - mfhi $t5 - sll $t5, $t5, 2 - addu $t4, $t4, $t5 - // Fetch the message to post - lw $t5, 4($t2) - addiu $t2, $t3, 1 - // Post the message to the message queue - sw $t5, ($t4) - // Increment the validCount - sw $t2, MQ_VALIDCOUNT($t1) - // If there was a thread blocked on this message queue, - // wake it up - lw $t2, MQ_MTQUEUE($t1) - lw $t3, ($t2) - beqz $t3, send_done - nop + /* Load pointer to listening message queue */ + la t2, __osEventStateTab + addu t2, t2, a0 + lw t1, (t2) + /* Save return address */ + move s2, ra + /* If there is no listening message queue, done */ + beqz t1, send_done + + /* Test if the message queue is full, if so don't post the message */ + lw t3, MQ_VALIDCOUNT(t1) + lw t4, MQ_MSGCOUNT(t1) + bge t3, t4, send_done + + /* Add validcount to first and modulo with msgcount */ + lw t5, MQ_FIRST(t1) + addu t5, t5, t3 + rem t5, t5, t4 + lw t4, MQ_MSG(t1) + sll t5, t5, 2 + addu t4, t4, t5 + /* Fetch the message to post */ + lw t5, 4(t2) + addiu t2, t3, 1 + /* Post the message to the message queue */ + sw t5, (t4) + /* Increment the validCount */ + sw t2, MQ_VALIDCOUNT(t1) + /* If there was a thread blocked on this message queue, */ + /* wake it up */ + lw t2, MQ_MTQUEUE(t1) + lw t3, (t2) + beqz t3, send_done + move a0, t1 jal __osPopThread - move $a0, $t1 - move $t2, $v0 - lui $a0, %hi(__osRunQueue) - move $a1, $t2 + move t2, v0 + move a1, t2 + la a0, __osRunQueue jal __osEnqueueThread - addiu $a0, %lo(__osRunQueue) send_done: - jr $s2 - nop + jr s2 /** * Handle coprocessor unusable exception */ handle_CpU: - li $at, CAUSE_CEMASK - and $t1, $t0, $at - srl $t1, $t1, CAUSE_CESHIFT - li $t2, 1 // if not coprocessor 1, panic - bne $t1, $t2, panic - nop - // Mark cop1 as usable for previous thread - lw $k1, THREAD_SR($k0) - li $at, SR_CU1 - li $t1, 1 - or $k1, $k1, $at - sw $t1, THREAD_FP($k0) + and t1, t0, CAUSE_CEMASK + srl t1, t1, CAUSE_CESHIFT + li t2, 1 /* if not coprocessor 1, panic */ + bne t1, t2, panic + /* Mark cop1 as usable for previous thread */ + lw k1, THREAD_SR(k0) + li t1, 1 + or k1, k1, SR_CU1 + sw t1, THREAD_FP(k0) + sw k1, THREAD_SR(k0) b enqueueRunning - sw $k1, THREAD_SR($k0) END(__osException) /** @@ -731,83 +644,71 @@ END(__osException) * unblocked runnable thread. */ LEAF(__osEnqueueAndYield) - lui $a1, %hi(__osRunningThread) - lw $a1, %lo(__osRunningThread)($a1) - // Save SR - mfc0 $t0, C0_SR - lw $k1, THREAD_FP($a1) - ori $t0, $t0, SR_EXL - sw $t0, THREAD_SR($a1) - // Save callee-saved registers - sd $s0, THREAD_S0($a1) - sd $s1, THREAD_S1($a1) - sd $s2, THREAD_S2($a1) - sd $s3, THREAD_S3($a1) - sd $s4, THREAD_S4($a1) - sd $s5, THREAD_S5($a1) - sd $s6, THREAD_S6($a1) - sd $s7, THREAD_S7($a1) - sd $gp, THREAD_GP($a1) - sd $sp, THREAD_SP($a1) - sd $fp, THREAD_S8($a1) - sd $ra, THREAD_RA($a1) - // Save FPU callee-saved registers if the current thread has used the FPU - beqz $k1, 1f - sw $ra, THREAD_PC($a1) - cfc1 $k1, C1_FPCSR - sdc1 $f20, THREAD_FP20($a1) - sdc1 $f22, THREAD_FP22($a1) - sdc1 $f24, THREAD_FP24($a1) - sdc1 $f26, THREAD_FP26($a1) - sdc1 $f28, THREAD_FP28($a1) - sdc1 $f30, THREAD_FP30($a1) - sw $k1, THREAD_FPCSR($a1) + lw a1, __osRunningThread + /* Save SR */ + MFC0( t0, C0_SR) + lw k1, THREAD_FP(a1) + ori t0, t0, SR_EXL + sw t0, THREAD_SR(a1) + /* Save callee-saved registers */ + sd s0, THREAD_S0(a1) + sd s1, THREAD_S1(a1) + sd s2, THREAD_S2(a1) + sd s3, THREAD_S3(a1) + sd s4, THREAD_S4(a1) + sd s5, THREAD_S5(a1) + sd s6, THREAD_S6(a1) + sd s7, THREAD_S7(a1) + sd gp, THREAD_GP(a1) + sd sp, THREAD_SP(a1) + sd fp, THREAD_S8(a1) + sd ra, THREAD_RA(a1) + sw ra, THREAD_PC(a1) + /* Save FPU callee-saved registers if the current thread has used the FPU */ + beqz k1, 1f + cfc1 k1, C1_FPCSR + sdc1 $f20, THREAD_FP20(a1) + sdc1 $f22, THREAD_FP22(a1) + sdc1 $f24, THREAD_FP24(a1) + sdc1 $f26, THREAD_FP26(a1) + sdc1 $f28, THREAD_FP28(a1) + sdc1 $f30, THREAD_FP30(a1) + sw k1, THREAD_FPCSR(a1) 1: - lw $k1, THREAD_SR($a1) - andi $t1, $k1, SR_IMASK - beqz $t1, 2f - nop - // This code does the same thing as the block just above the `savercp` label. - // See the comment there for more about this. - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, ($t0) - li $at, ~0 - xor $t0, $t0, $at - lui $at, ((~SR_IMASK) >> 0x10) & 0xFFFF - andi $t0, $t0, SR_IMASK - ori $at, (~SR_IMASK) & 0xFFFF - or $t1, $t1, $t0 - and $k1, $k1, $at - or $k1, $k1, $t1 - sw $k1, THREAD_SR($a1) + lw k1, THREAD_SR(a1) + andi t1, k1, SR_IMASK + beqz t1, 2f + /* This code does the same thing as the block just above the `savercp` label. */ + /* See the comment there for more about this. */ + la t0, __OSGlobalIntMask + lw t0, (t0) + xor t0, t0, ~0 + andi t0, t0, SR_IMASK + or t1, t1, t0 + and k1, k1, ~SR_IMASK + or k1, k1, t1 + sw k1, THREAD_SR(a1) 2: - lui $k1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $k1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($k1) - beqz $k1, 3f - nop - // This code does the same thing as the block just below the `savercp` label. - // See the comment there for more about this. - lui $k0, %hi(__OSGlobalIntMask) - addiu $k0, %lo(__OSGlobalIntMask) - lw $k0, ($k0) - lw $t0, THREAD_RCP($a1) - li $at, ~0 - srl $k0, $k0, RCP_IMASKSHIFT - xor $k0, $k0, $at - andi $k0, $k0, (RCP_IMASK >> RCP_IMASKSHIFT) - and $k0, $k0, $t0 - or $k1, $k1, $k0 + lw k1, PHYS_TO_K1(MI_INTR_MASK_REG) + beqz k1, 3f + /* This code does the same thing as the block just below the `savercp` label. */ + /* See the comment there for more about this. */ + la k0, __OSGlobalIntMask + lw k0, (k0) + lw t0, THREAD_RCP(a1) + srl k0, k0, RCP_IMASKSHIFT + xor k0, k0, ~0 + andi k0, k0, (RCP_IMASK >> RCP_IMASKSHIFT) + and k0, k0, t0 + or k1, k1, k0 3: - // If the specified thread queue is null, skip - // straight to dispatching - beqz $a0, no_enqueue - sw $k1, THREAD_RCP($a1) + /* If the specified thread queue is null, skip */ + /* straight to dispatching */ + sw k1, THREAD_RCP(a1) + beqz a0, no_enqueue jal __osEnqueueThread - nop no_enqueue: j __osDispatchThread - nop END(__osEnqueueAndYield) /** @@ -816,31 +717,27 @@ END(__osEnqueueAndYield) * Enqueues `thread` to the thread queue `threadQueue`, inserted by priority */ LEAF(__osEnqueueThread) - lw $t8, ($a0) - lw $t7, THREAD_PRI($a1) - move $t9, $a0 - lw $t6, THREAD_PRI($t8) - slt $at, $t6, $t7 - // If the current highest priority thread is a lower priority than - // the new thread, skip searching the queue - bnez $at, 2f - nop + lw t8, (a0) + lw t7, THREAD_PRI(a1) + move t9, a0 + lw t6, THREAD_PRI(t8) + /* If the current highest priority thread is a lower priority than */ + /* the new thread, skip searching the queue */ + blt t6, t7, 2f 1: - // Search the queue for the position to insert the thread to maintain - // ordering by priority - move $t9, $t8 - lw $t8, THREAD_NEXT($t8) - lw $t6, THREAD_PRI($t8) - slt $at, $t6, $t7 - beqz $at, 1b - nop + /* Search the queue for the position to insert the thread to maintain */ + /* ordering by priority */ + move t9, t8 + lw t8, THREAD_NEXT(t8) + lw t6, THREAD_PRI(t8) + bge t6, t7, 1b 2: - // Insert the thread into the queue - lw $t8, ($t9) - sw $t8, THREAD_NEXT($a1) - sw $a1, ($t9) - jr $ra - sw $a0, THREAD_QUEUE($a1) + /* Insert the thread into the queue */ + lw t8, (t9) + sw t8, THREAD_NEXT(a1) + sw a1, (t9) + sw a0, THREAD_QUEUE(a1) + jr ra END(__osEnqueueThread) /** @@ -850,16 +747,15 @@ END(__osEnqueueThread) * thread queue `threadQueue` and returns it */ LEAF(__osPopThread) - lw $v0, ($a0) - lw $t9, THREAD_NEXT($v0) - jr $ra - sw $t9, ($a0) + lw v0, (a0) + lw t9, THREAD_NEXT(v0) + sw t9, (a0) + jr ra END(__osPopThread) #if LIBULTRA_VERSION >= LIBULTRA_VERSION_K LEAF(__osNop) - jr $ra - nop + jr ra END(__osNop) #endif @@ -869,113 +765,111 @@ END(__osNop) * Dispatches the next thread to run after restoring the context */ LEAF(__osDispatchThread) - // Obtain highest priority thread from the active run queue - lui $a0, %hi(__osRunQueue) + /* Obtain highest priority thread from the active run queue */ + la a0, __osRunQueue jal __osPopThread - addiu $a0, $a0, %lo(__osRunQueue) - // Set thread as running - lui $at, %hi(__osRunningThread) - sw $v0, %lo(__osRunningThread)($at) - li $t0, OS_STATE_RUNNING - sh $t0, THREAD_STATE($v0) - // Restore SR, masking out any interrupts that are not also - // enabled in the global interrupt mask - move $k0, $v0 - lui $t0, %hi(__OSGlobalIntMask) - lw $k1, THREAD_SR($k0) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, ($t0) - lui $at, ((~SR_IMASK) >> 0x10) & 0xFFFF - andi $t1, $k1, SR_IMASK - ori $at, (~SR_IMASK) & 0xFFFF - andi $t0, $t0, SR_IMASK - and $t1, $t1, $t0 - and $k1, $k1, $at - or $k1, $k1, $t1 - mtc0 $k1, C0_SR - // Restore GPRs - ld $k1, THREAD_LO($k0) - ld $at, THREAD_AT($k0) - ld $v0, THREAD_V0($k0) - mtlo $k1 - ld $k1, THREAD_HI($k0) - ld $v1, THREAD_V1($k0) - ld $a0, THREAD_A0($k0) - ld $a1, THREAD_A1($k0) - ld $a2, THREAD_A2($k0) - ld $a3, THREAD_A3($k0) - ld $t0, THREAD_T0($k0) - ld $t1, THREAD_T1($k0) - ld $t2, THREAD_T2($k0) - ld $t3, THREAD_T3($k0) - ld $t4, THREAD_T4($k0) - ld $t5, THREAD_T5($k0) - ld $t6, THREAD_T6($k0) - ld $t7, THREAD_T7($k0) - ld $s0, THREAD_S0($k0) - ld $s1, THREAD_S1($k0) - ld $s2, THREAD_S2($k0) - ld $s3, THREAD_S3($k0) - ld $s4, THREAD_S4($k0) - ld $s5, THREAD_S5($k0) - ld $s6, THREAD_S6($k0) - ld $s7, THREAD_S7($k0) - ld $t8, THREAD_T8($k0) - ld $t9, THREAD_T9($k0) - ld $gp, THREAD_GP($k0) - mthi $k1 - ld $sp, THREAD_SP($k0) - ld $fp, THREAD_S8($k0) - ld $ra, THREAD_RA($k0) - // Move thread pc to EPC so that eret will return execution to where the thread left off - lw $k1, THREAD_PC($k0) - mtc0 $k1, C0_EPC - // Check if the FPU was used by this thread and if so also restore the FPU registers - lw $k1, THREAD_FP($k0) - beqz $k1, 1f - nop - lw $k1, THREAD_FPCSR($k0) - ctc1 $k1, C1_FPCSR - ldc1 $f0, THREAD_FP0($k0) - ldc1 $f2, THREAD_FP2($k0) - ldc1 $f4, THREAD_FP4($k0) - ldc1 $f6, THREAD_FP6($k0) - ldc1 $f8, THREAD_FP8($k0) - ldc1 $f10, THREAD_FP10($k0) - ldc1 $f12, THREAD_FP12($k0) - ldc1 $f14, THREAD_FP14($k0) - ldc1 $f16, THREAD_FP16($k0) - ldc1 $f18, THREAD_FP18($k0) - ldc1 $f20, THREAD_FP20($k0) - ldc1 $f22, THREAD_FP22($k0) - ldc1 $f24, THREAD_FP24($k0) - ldc1 $f26, THREAD_FP26($k0) - ldc1 $f28, THREAD_FP28($k0) - ldc1 $f30, THREAD_FP30($k0) + /* Set thread as running */ + sw v0, __osRunningThread + li t0, OS_STATE_RUNNING + sh t0, THREAD_STATE(v0) + /* Restore SR, masking out any interrupts that are not also */ + /* enabled in the global interrupt mask */ + move k0, v0 + lw k1, THREAD_SR(k0) + la t0, __OSGlobalIntMask + lw t0, (t0) + andi t1, k1, SR_IMASK + andi t0, t0, SR_IMASK + and t1, t1, t0 + and k1, k1, ~SR_IMASK + or k1, k1, t1 + MTC0( k1, C0_SR) + /* Restore GPRs */ +.set noat + ld AT, THREAD_AT(k0) + ld v0, THREAD_V0(k0) + ld v1, THREAD_V1(k0) + ld a0, THREAD_A0(k0) + ld a1, THREAD_A1(k0) + ld a2, THREAD_A2(k0) + ld a3, THREAD_A3(k0) + ld t0, THREAD_T0(k0) + ld t1, THREAD_T1(k0) + ld t2, THREAD_T2(k0) + ld t3, THREAD_T3(k0) + ld t4, THREAD_T4(k0) + ld t5, THREAD_T5(k0) + ld t6, THREAD_T6(k0) + ld t7, THREAD_T7(k0) + ld s0, THREAD_S0(k0) + ld s1, THREAD_S1(k0) + ld s2, THREAD_S2(k0) + ld s3, THREAD_S3(k0) + ld s4, THREAD_S4(k0) + ld s5, THREAD_S5(k0) + ld s6, THREAD_S6(k0) + ld s7, THREAD_S7(k0) + ld t8, THREAD_T8(k0) + ld t9, THREAD_T9(k0) + ld gp, THREAD_GP(k0) + ld k1, THREAD_LO(k0) + mtlo k1 + ld k1, THREAD_HI(k0) + mthi k1 + ld sp, THREAD_SP(k0) + ld fp, THREAD_S8(k0) + ld ra, THREAD_RA(k0) + /* Move thread pc to EPC so that eret will return execution to where the thread left off */ + lw k1, THREAD_PC(k0) + MTC0( k1, C0_EPC) + /* Check if the FPU was used by this thread and if so also restore the FPU registers */ + lw k1, THREAD_FP(k0) + beqz k1, 1f + +.set noreorder + lw k1, THREAD_FPCSR(k0) + ctc1 k1, C1_FPCSR +.set reorder + ldc1 $f0, THREAD_FP0(k0) + ldc1 $f2, THREAD_FP2(k0) + ldc1 $f4, THREAD_FP4(k0) + ldc1 $f6, THREAD_FP6(k0) + ldc1 $f8, THREAD_FP8(k0) + ldc1 $f10, THREAD_FP10(k0) + ldc1 $f12, THREAD_FP12(k0) + ldc1 $f14, THREAD_FP14(k0) + ldc1 $f16, THREAD_FP16(k0) + ldc1 $f18, THREAD_FP18(k0) + ldc1 $f20, THREAD_FP20(k0) + ldc1 $f22, THREAD_FP22(k0) + ldc1 $f24, THREAD_FP24(k0) + ldc1 $f26, THREAD_FP26(k0) + ldc1 $f28, THREAD_FP28(k0) + ldc1 $f30, THREAD_FP30(k0) 1: - // Restore RCP interrupt mask, masking out any RCP interrupts that - // are not also enabled in the global interrupt mask - lw $k1, THREAD_RCP($k0) - lui $k0, %hi(__OSGlobalIntMask) - addiu $k0, %lo(__OSGlobalIntMask) - lw $k0, ($k0) - srl $k0, $k0, RCP_IMASKSHIFT - and $k1, $k1, $k0 - sll $k1, $k1, 1 - lui $k0, %hi(__osRcpImTable) - addiu $k0, %lo(__osRcpImTable) - addu $k1, $k1, $k0 - lhu $k1, ($k1) - lui $k0, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - addiu $k0, %lo(PHYS_TO_K1(MI_INTR_MASK_REG)) - sw $k1, ($k0) - // Empty pipeline + /* Restore RCP interrupt mask, masking out any RCP interrupts that */ + /* are not also enabled in the global interrupt mask */ +.set noreorder + lw k1, THREAD_RCP(k0) + la k0, __OSGlobalIntMask + lw k0, (k0) + srl k0, k0, RCP_IMASKSHIFT + and k1, k1, k0 + sll k1, k1, 1 + la k0, __osRcpImTable + addu k1, k1, k0 + lhu k1, (k1) + la k0, PHYS_TO_K1(MI_INTR_MASK_REG) + sw k1, (k0) + /* Empty pipeline */ nop nop nop nop - // Resume thread execution + /* Resume thread execution */ eret +.set reorder +.set at END(__osDispatchThread) /** @@ -986,7 +880,7 @@ END(__osDispatchThread) * current thread to be destroyed. */ LEAF(__osCleanupThread) + move a0, zero jal osDestroyThread - move $a0, $zero - // Despite being a jal, this function does not return as the thread will have been destroyed + /* Despite being a jal, this function does not return as the thread will have been destroyed */ END(__osCleanupThread) diff --git a/src/libultra/os/getcause.s b/src/libultra/os/getcause.s index a621e9736..b59c5c680 100644 --- a/src/libultra/os/getcause.s +++ b/src/libultra/os/getcause.s @@ -1,14 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osGetCause) - mfc0 $v0, C0_CAUSE - jr $ra - nop + MFC0( v0, C0_CAUSE) + jr ra END(__osGetCause) diff --git a/src/libultra/os/getcount.s b/src/libultra/os/getcount.s index 242c9da69..84552adb0 100644 --- a/src/libultra/os/getcount.s +++ b/src/libultra/os/getcount.s @@ -1,14 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(osGetCount) - mfc0 $v0, C0_COUNT - jr $ra - nop + MFC0( v0, C0_COUNT) + jr ra END(osGetCount) diff --git a/src/libultra/os/getfpccsr.s b/src/libultra/os/getfpccsr.s index 93d4e51b8..37c0e8c3b 100644 --- a/src/libultra/os/getfpccsr.s +++ b/src/libultra/os/getfpccsr.s @@ -1,14 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osGetFpcCsr) - cfc1 $v0, C1_FPCSR - jr $ra - nop + CFC1( v0, C1_FPCSR) + jr ra END(__osGetFpcCsr) diff --git a/src/libultra/os/getintmask.s b/src/libultra/os/getintmask.s index 2c6ddc86e..f73410393 100644 --- a/src/libultra/os/getintmask.s +++ b/src/libultra/os/getintmask.s @@ -1,14 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" #include "ultra64/rcp.h" #include "ultra64/exception.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text /** * OSIntMask osGetIntMask(void); @@ -23,38 +19,35 @@ * See the comment for osSetIntMask for more details. */ LEAF(osGetIntMask) - // Extract interrupt enable bits from current SR - mfc0 $v0, C0_SR - andi $v0, $v0, (SR_IMASK | SR_IE) - // Get value of __OSGlobalIntMask - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t1, 0($t0) - // Bitwise-OR in the disabled CPU bits of __OSGlobalIntMask - li $at, ~0 - xor $t0, $t1, $at - andi $t0, $t0, SR_IMASK - or $v0, $v0, $t0 - // Fetch MI_INTR_MASK_REG - lui $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1) - // If there are RCP interrupts masked - beqz $t1, 1f - // Get value of __OSGlobalIntMask - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, 0($t0) - // Bitwise-OR in the disabled RCP bits of __OSGlobalIntMask - srl $t0, $t0, RCP_IMASKSHIFT - li $at, ~0 - xor $t0, $t0, $at - andi $t0, $t0, (RCP_IMASK >> RCP_IMASKSHIFT) - or $t1, $t1, $t0 +.set noreorder + /* Extract interrupt enable bits from current SR */ + mfc0 v0, C0_SR + andi v0, v0, (SR_IMASK | SR_IE) + /* Get value of __OSGlobalIntMask */ + la t0, __OSGlobalIntMask + lw t1, (t0) + /* Bitwise-OR in the disabled CPU bits of __OSGlobalIntMask */ + xor t0, t1, ~0 + andi t0, t0, SR_IMASK + or v0, v0, t0 + /* Fetch MI_INTR_MASK_REG */ + lw t1, PHYS_TO_K1(MI_INTR_MASK_REG) + /* If there are RCP interrupts masked */ + beqz t1, 1f + /* Get value of __OSGlobalIntMask */ + la t0, __OSGlobalIntMask /* Note: macro expansion in delay slot */ + lw t0, (t0) + /* Bitwise-OR in the disabled RCP bits of __OSGlobalIntMask */ + srl t0, t0, RCP_IMASKSHIFT + xor t0, t0, ~0 + andi t0, t0, (RCP_IMASK >> RCP_IMASKSHIFT) + or t1, t1, t0 1: - // Shift the RCP bits to not conflict with the CPU bits - sll $t2, $t1, RCP_IMASKSHIFT - // OR the CPU and RCP bits together - or $v0, $v0, $t2 - jr $ra + /* Shift the RCP bits to not conflict with the CPU bits */ + sll t2, t1, RCP_IMASKSHIFT + /* OR the CPU and RCP bits together */ + or v0, v0, t2 + jr ra nop +.set reorder END(osGetIntMask) diff --git a/src/libultra/os/getsr.s b/src/libultra/os/getsr.s index dc6901b98..709075a7b 100644 --- a/src/libultra/os/getsr.s +++ b/src/libultra/os/getsr.s @@ -1,14 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osGetSR) - mfc0 $v0, C0_SR - jr $ra - nop + MFC0( v0, C0_SR) + jr ra END(__osGetSR) diff --git a/src/libultra/os/interrupt.s b/src/libultra/os/interrupt.s index 829377bb0..3a9102c57 100644 --- a/src/libultra/os/interrupt.s +++ b/src/libultra/os/interrupt.s @@ -1,53 +1,45 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" #include "ultra64/thread.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osDisableInt) - lui $t2, %hi(__OSGlobalIntMask) - addiu $t2, $t2, %lo(__OSGlobalIntMask) - lw $t3, ($t2) - andi $t3, $t3, SR_IMASK - mfc0 $t0, C0_SR - li $at, ~SR_IE - and $t1, $t0, $at - mtc0 $t1, C0_SR - andi $v0, $t0, SR_IE - lw $t0, ($t2) - andi $t0, $t0, SR_IMASK - beq $t0, $t3, No_Change_Global_Int - lui $t2, %hi(__osRunningThread) - //! @bug this addiu should be lw, it may never come up in practice as to reach this code - //! the CPU bits of __OSGlobalIntMask must have changed while this function is running. - addiu $t2, $t2, %lo(__osRunningThread) - lw $t1, THREAD_SR($t2) - andi $t2, $t1, SR_IMASK - and $t2, $t2, $t0 - li $at, ~SR_IMASK - and $t1, $t1, $at - or $t1, $t1, $t2 - li $at, ~SR_IE - and $t1, $t1, $at - mtc0 $t1, C0_SR - nop - nop + la t2, __OSGlobalIntMask + lw t3, (t2) + and t3, t3, SR_IMASK + MFC0( t0, C0_SR) + and t1, t0, ~SR_IE + MTC0( t1, C0_SR) + and v0, t0, SR_IE + lw t0, (t2) + and t0, t0, SR_IMASK +.set noreorder + beq t0, t3, No_Change_Global_Int + /*! @bug this la should be lw, it may never come up in practice as to reach this code + *! the CPU bits of __OSGlobalIntMask must have changed while this function is running. + */ + la t2, __osRunningThread + lw t1, THREAD_SR(t2) + and t2, t1, SR_IMASK + and t2, t2, t0 +.set reorder + and t1, t1, ~SR_IMASK + or t1, t1, t2 + and t1, t1, ~SR_IE + MTC0( t1, C0_SR) + NOP + NOP No_Change_Global_Int: - jr $ra - nop + jr ra END(__osDisableInt) LEAF(__osRestoreInt) - mfc0 $t0, C0_SR - or $t0, $t0, $a0 - mtc0 $t0, C0_SR - nop - nop - jr $ra - nop + MFC0( t0, C0_SR) + or t0, t0, a0 + MTC0( t0, C0_SR) + NOP + NOP + jr ra END(__osRestoreInt) diff --git a/src/libultra/os/invaldcache.s b/src/libultra/os/invaldcache.s index 9464a24da..22109e13a 100644 --- a/src/libultra/os/invaldcache.s +++ b/src/libultra/os/invaldcache.s @@ -1,12 +1,8 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text /** * void osInvalDCache(void* vaddr, s32 nbytes); @@ -24,71 +20,67 @@ * the entire data cache is invalidated. */ LEAF(osInvalDCache) - // If the amount to invalidate is less than or equal to 0, return immediately - blez $a1, 3f +.set noreorder + /* If the amount to invalidate is less than or equal to 0, return immediately */ + blez a1, 3f nop - // If the amount to invalidate is as large as or larger than - // the data cache size, invalidate all - li $t3, DCACHE_SIZE - sltu $at, $a1, $t3 - beqz $at, 4f + /* If the amount to invalidate is as large as or larger than + * the data cache size, invalidate all */ + li t3, DCACHE_SIZE + bgeu a1, t3, 4f nop - // Ensure end address doesn't wrap around and end up smaller - // than the start address - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, 3f + /* Ensure end address doesn't wrap around and end up smaller + * than the start address */ + move t0, a0 + addu t1, a0, a1 + bgeu t0, t1, 3f nop - // Mask start with cache line - andi $t2, $t0, DCACHE_LINEMASK - // If mask is not zero, the start is not cache aligned - beqz $t2, 1f - addiu $t1, $t1, -DCACHE_LINESIZE - // Subtract mask result to align to cache line - subu $t0, $t0, $t2 - // Hit-Writeback-Invalidate unaligned part - cache (CACH_PD | C_HWBINV), ($t0) - sltu $at, $t0, $t1 - // If that's all there is to do, return early - beqz $at, 3f + /* Mask start with cache line */ + andi t2, t0, DCACHE_LINEMASK + /* If mask is not zero, the start is not cache aligned */ + beqz t2, 1f + addiu t1, t1, -DCACHE_LINESIZE + /* Subtract mask result to align to cache line */ + subu t0, t0, t2 + /* Hit-Writeback-Invalidate unaligned part */ + cache (CACH_PD | C_HWBINV), (t0) + /* If that's all there is to do, return early */ + bgeu t0, t1, 3f nop - addiu $t0, $t0, DCACHE_LINESIZE + addiu t0, t0, DCACHE_LINESIZE 1: - // Mask end with cache line - andi $t2, $t1, DCACHE_LINEMASK - // If mask is not zero, the end is not cache aligned - beqz $t2, 1f + /* Mask end with cache line */ + andi t2, t1, DCACHE_LINEMASK + /* If mask is not zero, the end is not cache aligned */ + beqz t2, 1f nop - // Subtract mask result to align to cache line - subu $t1, $t1, $t2 - // Hit-Writeback-Invalidate unaligned part - cache (CACH_PD | C_HWBINV), DCACHE_LINESIZE($t1) - sltu $at, $t1, $t0 - // If that's all there is to do, return early - bnez $at, 3f + /* Subtract mask result to align to cache line */ + subu t1, t1, t2 + /* Hit-Writeback-Invalidate unaligned part */ + cache (CACH_PD | C_HWBINV), DCACHE_LINESIZE(t1) + /* If that's all there is to do, return early */ + bltu t1, t0, 3f nop - // Invalidate the rest + /* Invalidate the rest */ 1: - // Hit-Invalidate - cache (CACH_PD | C_HINV), ($t0) - sltu $at, $t0, $t1 - bnez $at, 1b - addiu $t0, $t0, DCACHE_LINESIZE + /* Hit-Invalidate */ + cache (CACH_PD | C_HINV), (t0) + bltu t0, t1, 1b + addiu t0, t0, DCACHE_LINESIZE 3: - jr $ra + jr ra nop 4: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -DCACHE_LINESIZE + li t0, K0BASE + addu t1, t0, t3 + addiu t1, t1, -DCACHE_LINESIZE 5: - // Index-Writeback-Invalidate - cache (CACH_PD | C_IWBINV), ($t0) - sltu $at, $t0, $t1 - bnez $at, 5b - addiu $t0, DCACHE_LINESIZE - jr $ra + /* Index-Writeback-Invalidate */ + cache (CACH_PD | C_IWBINV), (t0) + bltu t0, t1, 5b + addiu t0, DCACHE_LINESIZE + jr ra nop +.set reorder END(osInvalDCache) diff --git a/src/libultra/os/invalicache.s b/src/libultra/os/invalicache.s index 55f831238..757215cf1 100644 --- a/src/libultra/os/invalicache.s +++ b/src/libultra/os/invalicache.s @@ -1,52 +1,46 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text LEAF(osInvalICache) - // If the amount to invalidate is less than or equal to 0, return immediately - blez $a1, 2f +.set noreorder + /* If the amount to invalidate is less than or equal to 0, return immediately */ + blez a1, 2f nop - // If the amount to invalidate is as large as or larger than - // the instruction cache size, invalidate all - li $t3, ICACHE_SIZE - sltu $at, $a1, $t3 - beqz $at, 3f + /* If the amount to invalidate is as large as or larger than */ + /* the instruction cache size, invalidate all */ + li t3, ICACHE_SIZE + bgeu a1, t3, 3f nop - // ensure end address doesn't wrap around and end up smaller - // than the start address - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, 2f + /* ensure end address doesn't wrap around and end up smaller */ + /* than the start address */ + move t0, a0 + addu t1, a0, a1 + bgeu t0, t1, 2f nop - // Mask and subtract to align to cache line - andi $t2, $t0, ICACHE_LINEMASK - addiu $t1, $t1, -ICACHE_LINESIZE - subu $t0, $t0, $t2 + /* Mask and subtract to align to cache line */ + andi t2, t0, ICACHE_LINEMASK + addiu t1, t1, -ICACHE_LINESIZE + subu t0, t0, t2 1: - cache (CACH_PI | C_HINV), ($t0) - sltu $at, $t0, $t1 - bnez $at, 1b - addiu $t0, $t0, ICACHE_LINESIZE + cache (CACH_PI | C_HINV), (t0) + bltu t0, t1, 1b + addiu t0, t0, ICACHE_LINESIZE 2: - jr $ra + jr ra nop 3: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -ICACHE_LINESIZE + li t0, K0BASE + addu t1, t0, t3 + addiu t1, t1, -ICACHE_LINESIZE 4: - cache (CACH_PI | C_IINV), ($t0) - sltu $at, $t0, $t1 - bnez $at, 4b - addiu $t0, ICACHE_LINESIZE - jr $ra + cache (CACH_PI | C_IINV), (t0) + bltu t0, t1, 4b + addiu t0, ICACHE_LINESIZE + jr ra nop +.set reorder END(osInvalICache) diff --git a/src/libultra/os/maptlbrdb.s b/src/libultra/os/maptlbrdb.s index c3ac20948..43e7cc93a 100644 --- a/src/libultra/os/maptlbrdb.s +++ b/src/libultra/os/maptlbrdb.s @@ -1,36 +1,31 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" #include "ultra64/rdb.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(osMapTLBRdb) - mfc0 $t0, C0_ENTRYHI - li $t1, NTLBENTRIES - mtc0 $t1, C0_INX - mtc0 $zero, C0_PAGEMASK - li $t2, (TLBLO_UNCACHED | TLBLO_D | TLBLO_V | TLBLO_G) - li $t1, (RDB_BASE_REG & TLBHI_VPN2MASK) - mtc0 $t1, C0_ENTRYHI - // Possible bug? Virtual address instead of physical address - // set as page frame number - li $t1, RDB_BASE_VIRTUAL_ADDR - srl $t3, $t1, TLBLO_PFNSHIFT - or $t3, $t3, $t2 - mtc0 $t3, C0_ENTRYLO0 - li $t1, TLBLO_G - mtc0 $t1, C0_ENTRYLO1 - nop - tlbwi - nop - nop - nop - nop - mtc0 $t0, C0_ENTRYHI - jr $ra - nop + MFC0( t0, C0_ENTRYHI) + li t1, NTLBENTRIES + MTC0( t1, C0_INX) + MTC0( zero, C0_PAGEMASK) + li t2, (TLBLO_UNCACHED | TLBLO_D | TLBLO_V | TLBLO_G) + li t1, (RDB_BASE_REG & TLBHI_VPN2MASK) + MTC0( t1, C0_ENTRYHI) + /* Possible bug? Virtual address instead of physical address set as page frame number */ + li t1, RDB_BASE_VIRTUAL_ADDR + srl t3, t1, TLBLO_PFNSHIFT + or t3, t3, t2 + MTC0( t3, C0_ENTRYLO0) + li t1, TLBLO_G + MTC0( t1, C0_ENTRYLO1) + NOP + TLBWI + NOP + NOP + NOP + NOP + MTC0( t0, C0_ENTRYHI) + jr ra END(osMapTLBRdb) diff --git a/src/libultra/os/parameters.s b/src/libultra/os/parameters.s index c0020ddbe..b88114814 100644 --- a/src/libultra/os/parameters.s +++ b/src/libultra/os/parameters.s @@ -1,22 +1,29 @@ #include "ultra64/asm.h" -.section .text +.text -.macro IPL_SYMBOL name, address, size - .global \name - .set \name, \address - .type \name, @object - .size \name, \size -.endm +#ifdef __sgi +#define IPL_SYMBOL(name, address, size) \ + ABS(name, address) +#else +#define IPL_SYMBOL(name, address, sz) \ + ABS(name, address) ;\ + .type name, @object ;\ + .size name, sz +#endif -IPL_SYMBOL leoBootID, 0x800001A0, 4 -IPL_SYMBOL osTvType, 0x80000300, 4 -IPL_SYMBOL osRomType, 0x80000304, 4 -IPL_SYMBOL osRomBase, 0x80000308, 4 -IPL_SYMBOL osResetType, 0x8000030C, 4 -IPL_SYMBOL osCicId, 0x80000310, 4 -IPL_SYMBOL osVersion, 0x80000314, 4 -IPL_SYMBOL osMemSize, 0x80000318, 4 -IPL_SYMBOL osAppNMIBuffer, 0x8000031C, 0x40 -.fill 0x60 +IPL_SYMBOL(leoBootID, 0x800001A0, 4) +IPL_SYMBOL(osTvType, 0x80000300, 4) +IPL_SYMBOL(osRomType, 0x80000304, 4) +IPL_SYMBOL(osRomBase, 0x80000308, 4) +IPL_SYMBOL(osResetType, 0x8000030C, 4) +IPL_SYMBOL(osCicId, 0x80000310, 4) +IPL_SYMBOL(osVersion, 0x80000314, 4) +IPL_SYMBOL(osMemSize, 0x80000318, 4) +IPL_SYMBOL(osAppNMIBuffer, 0x8000031C, 0x40) + + +.repeat 0x60/4 + NOP +.endr diff --git a/src/libultra/os/probetlb.s b/src/libultra/os/probetlb.s index 7bc7856e1..4fa8abc38 100644 --- a/src/libultra/os/probetlb.s +++ b/src/libultra/os/probetlb.s @@ -1,12 +1,8 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text /** * u32 __osProbeTLB(void* vaddr); @@ -17,70 +13,71 @@ * Returns the physical address if found, or -1 if not found. */ LEAF(__osProbeTLB) - // Set C0_ENTRYHI based on supplied vaddr - mfc0 $t0, C0_ENTRYHI - andi $t1, $t0, TLBHI_PIDMASK - li $at, TLBHI_VPN2MASK - and $t2, $a0, $at - or $t1, $t1, $t2 - mtc0 $t1, C0_ENTRYHI +.set noreorder + /* Set C0_ENTRYHI based on supplied vaddr */ + mfc0 t0, C0_ENTRYHI + and t1, t0, TLBHI_PIDMASK + and t2, a0, TLBHI_VPN2MASK + or t1, t1, t2 + mtc0 t1, C0_ENTRYHI nop nop nop - // TLB probe, sets C0_INX to a value matching C0_ENTRYHI. - // If no match is found the TLBINX_PROBE bit is set to indicate this. + /* TLB probe, sets C0_INX to a value matching C0_ENTRYHI. */ + /* If no match is found the TLBINX_PROBE bit is set to indicate this. */ tlbp nop nop - // Read result - mfc0 $t3, C0_INX - li $at, TLBINX_PROBE - and $t3, $t3, $at - // Branch if no match was found - bnez $t3, 3f + /* Read result */ + mfc0 t3, C0_INX + and t3, t3, TLBINX_PROBE + /* Branch if no match was found */ + bnez t3, 3f nop - // Read TLB, sets C0_ENTRYHI, C0_ENTRYLO0, C0_ENTRYLO1 and C0_PAGEMASK for the TLB - // entry indicated by C0_INX + + /* Read TLB, sets C0_ENTRYHI, C0_ENTRYLO0, C0_ENTRYLO1 and C0_PAGEMASK for the TLB */ + /* entry indicated by C0_INX */ tlbr nop nop nop - // Calculate page size = (page mask + 0x2000) >> 1 - mfc0 $t3, C0_PAGEMASK - addi $t3, $t3, 0x2000 - srl $t3, $t3, 1 - // & with vaddr - and $t4, $t3, $a0 - // Select C0_ENTRYLO0 or C0_ENTRYLO1 - bnez $t4, 1f - addi $t3, $t3, -1 // make bitmask out of page size - mfc0 $v0, C0_ENTRYLO0 + /* Calculate page size = (page mask + 0x2000) >> 1 */ + mfc0 t3, C0_PAGEMASK + add t3, t3, 0x2000 + srl t3, t3, 1 + /* & with vaddr */ + and t4, t3, a0 + /* Select C0_ENTRYLO0 or C0_ENTRYLO1 */ + bnez t4, 1f + add t3, t3, -1 /* make bitmask out of page size */ + mfc0 v0, C0_ENTRYLO0 b 2f nop 1: - mfc0 $v0, C0_ENTRYLO1 + mfc0 v0, C0_ENTRYLO1 2: - // Check valid bit and branch if not valid - andi $t5, $v0, TLBLO_V - beqz $t5, 3f + /* Check valid bit and branch if not valid */ + and t5, v0, TLBLO_V + beqz t5, 3f nop - // Extract the Page Frame Number from the entry - li $at, TLBLO_PFNMASK - and $v0, $v0, $at - sll $v0, $v0, TLBLO_PFNSHIFT - // Mask vaddr with page size mask - and $t5, $a0, $t3 - // Add masked vaddr to pfn to obtain the physical address - add $v0, $v0, $t5 + + /* Extract the Page Frame Number from the entry */ + and v0, v0, TLBLO_PFNMASK + sll v0, v0, TLBLO_PFNSHIFT + /* Mask vaddr with page size mask */ + and t5, a0, t3 + /* Add masked vaddr to pfn to obtain the physical address */ + add v0, v0, t5 b 4f nop 3: - // No physical address for the supplied virtual address was found, - // return -1 - li $v0, -1 + /* No physical address for the supplied virtual address was found, */ + /* return -1 */ + li v0, -1 4: - // Restore original C0_ENTRYHI value before returning - mtc0 $t0, C0_ENTRYHI - jr $ra + /* Restore original C0_ENTRYHI value before returning */ + mtc0 t0, C0_ENTRYHI + jr ra nop +.set reorder END(__osProbeTLB) diff --git a/src/libultra/os/setcompare.s b/src/libultra/os/setcompare.s index bd1653377..3c175c494 100644 --- a/src/libultra/os/setcompare.s +++ b/src/libultra/os/setcompare.s @@ -1,14 +1,10 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osSetCompare) - mtc0 $a0, C0_COMPARE - jr $ra - nop + MTC0( a0, C0_COMPARE) + jr ra END(__osSetCompare) diff --git a/src/libultra/os/setfpccsr.s b/src/libultra/os/setfpccsr.s index 1aa0e7d29..e33355084 100644 --- a/src/libultra/os/setfpccsr.s +++ b/src/libultra/os/setfpccsr.s @@ -1,15 +1,11 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osSetFpcCsr) - cfc1 $v0, C1_FPCSR - ctc1 $a0, C1_FPCSR - jr $ra - nop + CFC1( v0, C1_FPCSR) + CTC1( a0, C1_FPCSR) + jr ra END(__osSetFpcCsr) diff --git a/src/libultra/os/setintmask.s b/src/libultra/os/setintmask.s index e48c1b376..bf6bec020 100644 --- a/src/libultra/os/setintmask.s +++ b/src/libultra/os/setintmask.s @@ -1,14 +1,11 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" #include "ultra64/rcp.h" #include "ultra64/exception.h" -.set noat -.set noreorder - -.section .rodata - -.balign 16 +.rdata +.align 2 /** * LUT to convert between an interrupt mask value and a value for MI_INTR_MASK_REG. @@ -82,9 +79,7 @@ DATA(__osRcpImTable) .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP ENDDATA(__osRcpImTable) -.section .text - -.balign 16 +.text /** * OSIntMask osSetIntMask(OSIntMask); @@ -113,56 +108,47 @@ ENDDATA(__osRcpImTable) * OS_IM_ALL, so the operation is usually simply (SR | 0). */ LEAF(osSetIntMask) - // Extract interrupt enable bits from current SR - mfc0 $t4, C0_SR - andi $v0, $t4, (SR_IMASK | SR_IE) - // Get value of __OSGlobalIntMask - lui $t0, %hi(__OSGlobalIntMask) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t3, ($t0) - // Bitwise-OR in the disabled CPU bits of __OSGlobalIntMask - li $at, ~0 - xor $t0, $t3, $at - andi $t0, $t0, SR_IMASK - or $v0, $v0, $t0 - // Fetch MI_INTR_MASK_REG - lui $t2, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $t2, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t2) - // If there are RCP interrupts masked - beqz $t2, 1f - srl $t1, $t3, RCP_IMASKSHIFT - // Bitwise-OR in the disabled RCP bits of __OSGlobalIntMask - li $at, ~0 - xor $t1, $t1, $at - andi $t1, $t1, (RCP_IMASK >> RCP_IMASKSHIFT) - or $t2, $t2, $t1 + /* Extract interrupt enable bits from current SR */ + MFC0( t4, C0_SR) +.set noreorder + and v0, t4, (SR_IMASK | SR_IE) + /* Get value of __OSGlobalIntMask */ + la t0, __OSGlobalIntMask + lw t3, (t0) + /* Bitwise-OR in the disabled CPU bits of __OSGlobalIntMask */ + xor t0, t3, ~0 + and t0, t0, SR_IMASK + or v0, v0, t0 + /* Fetch MI_INTR_MASK_REG */ + lw t2, PHYS_TO_K1(MI_INTR_MASK_REG) + /* If there are RCP interrupts masked */ + beqz t2, 1f + srl t1, t3, RCP_IMASKSHIFT + /* Bitwise-OR in the disabled RCP bits of __OSGlobalIntMask */ + xor t1, t1, ~0 + and t1, t1, (RCP_IMASK >> RCP_IMASKSHIFT) + or t2, t2, t1 1: - // Shift the RCP bits to not conflict with the CPU bits - sll $t2, $t2, RCP_IMASKSHIFT - // OR the CPU and RCP bits together - or $v0, $v0, $t2 - // Extract RCP interrupt enable bits from requested mask and mask with __OSGlobalIntMask - li $at, RCP_IMASK - and $t0, $a0, $at - and $t0, $t0, $t3 - // Convert to a value for MI_INTR_MASK_REG and set it - srl $t0, $t0, (RCP_IMASKSHIFT-1) - lui $t2, %hi(__osRcpImTable) - addu $t2, $t2, $t0 - lhu $t2, %lo(__osRcpImTable)($t2) - lui $at, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - sw $t2, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($at) - // Extract CPU interrupt enable bits from requested mask and mask with __OSGlobalIntMask - andi $t0, $a0, OS_IM_CPU - andi $t1, $t3, SR_IMASK - and $t0, $t0, $t1 - li $at, ~SR_IMASK - and $t4, $t4, $at - // Bitwise OR in the remaining bits of SR and set new SR - or $t4, $t4, $t0 - mtc0 $t4, C0_SR - nop - nop - jr $ra - nop + /* Shift the RCP bits to not conflict with the CPU bits */ + sll t2, t2, RCP_IMASKSHIFT + /* OR the CPU and RCP bits together */ + or v0, v0, t2 + /* Extract RCP interrupt enable bits from requested mask and mask with __OSGlobalIntMask */ + and t0, a0, RCP_IMASK + and t0, t0, t3 + /* Convert to a value for MI_INTR_MASK_REG and set it */ + srl t0, t0, (RCP_IMASKSHIFT-1) + lhu t2, __osRcpImTable(t0) + sw t2, PHYS_TO_K1(MI_INTR_MASK_REG) + /* Extract CPU interrupt enable bits from requested mask and mask with __OSGlobalIntMask */ + and t0, a0, OS_IM_CPU + and t1, t3, SR_IMASK + and t0, t0, t1 + and t4, t4, ~SR_IMASK + /* Bitwise OR in the remaining bits of SR and set new SR */ + or t4, t4, t0 + MTC0( t4, C0_SR) + NOP + NOP + jr ra END(osSetIntMask) diff --git a/src/libultra/os/setsr.s b/src/libultra/os/setsr.s index b754359ea..fb7a1586d 100644 --- a/src/libultra/os/setsr.s +++ b/src/libultra/os/setsr.s @@ -1,15 +1,11 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osSetSR) - mtc0 $a0, C0_SR - nop - jr $ra - nop + MTC0( a0, C0_SR) + NOP + jr ra END(__osSetSR) diff --git a/src/libultra/os/setwatchlo.s b/src/libultra/os/setwatchlo.s index aee3ad4d6..962513a48 100644 --- a/src/libultra/os/setwatchlo.s +++ b/src/libultra/os/setwatchlo.s @@ -1,15 +1,11 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(__osSetWatchLo) - mtc0 $a0, C0_WATCHLO - nop - jr $ra - nop + MTC0( a0, C0_WATCHLO) + NOP + jr ra END(__osSetWatchLo) diff --git a/src/libultra/os/unmaptlball.s b/src/libultra/os/unmaptlball.s index e1a03b1a2..8cd79984e 100644 --- a/src/libultra/os/unmaptlball.s +++ b/src/libultra/os/unmaptlball.s @@ -1,29 +1,25 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noreorder - -.section .text - -.balign 16 +.text LEAF(osUnmapTLBAll) - mfc0 $t0, C0_ENTRYHI - li $t1, (NTLBENTRIES - 1) - li $t2, (K0BASE & TLBHI_VPN2MASK) - mtc0 $t2, C0_ENTRYHI - mtc0 $zero, C0_ENTRYLO0 - mtc0 $zero, C0_ENTRYLO1 + MFC0( t0, C0_ENTRYHI) + li t1, (NTLBENTRIES - 1) + li t2, (K0BASE & TLBHI_VPN2MASK) + MTC0( t2, C0_ENTRYHI) + MTC0( zero, C0_ENTRYLO0) + MTC0( zero, C0_ENTRYLO1) 1: - mtc0 $t1, C0_INX - nop - tlbwi - nop - nop - addi $t1, $t1, -1 - bgez $t1, 1b - nop - mtc0 $t0, C0_ENTRYHI - jr $ra - nop + MTC0( t1, C0_INX) + NOP + TLBWI + NOP + NOP + addi t1, t1, -1 + bgez t1, 1b + + MTC0( t0, C0_ENTRYHI) + jr ra END(osUnmapTLBAll) diff --git a/src/libultra/os/writebackdcache.s b/src/libultra/os/writebackdcache.s index 829f6f4a0..c7207c7e5 100644 --- a/src/libultra/os/writebackdcache.s +++ b/src/libultra/os/writebackdcache.s @@ -1,12 +1,8 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text /** * void osWritebackDCache(void* vaddr, s32 nbytes); @@ -16,45 +12,43 @@ * written back. */ LEAF(osWritebackDCache) - // If the amount to write back is less than or equal to 0, return immediately - blez $a1, .ret - nop - // If the amount to write back is as large as or larger than - // the data cache size, write back all - li $t3, DCACHE_SIZE - sltu $at, $a1, $t3 - beqz $at, .all - nop - // ensure end address doesn't wrap around and end up smaller - // than the start address - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, .ret - nop - // Mask and subtract to align to cache line - andi $t2, $t0, DCACHE_LINEMASK - addiu $t1, $t1, -DCACHE_LINESIZE - subu $t0, $t0, $t2 + /* If the amount to write back is less than or equal to 0, return immediately */ + blez a1, .ret + + /* If the amount to write back is as large as or larger than */ + /* the data cache size, write back all */ + li t3, DCACHE_SIZE + bgeu a1, t3, .all + + /* ensure end address doesn't wrap around and end up smaller */ + /* than the start address */ + move t0, a0 + addu t1, a0, a1 + bgeu t0, t1, .ret + + /* Mask and subtract to align to cache line */ + andi t2, t0, DCACHE_LINEMASK + addiu t1, t1, -DCACHE_LINESIZE + subu t0, t0, t2 1: - cache (CACH_PD | C_HWB), ($t0) - sltu $at, $t0, $t1 - bnez $at, 1b - addiu $t0, $t0, DCACHE_LINESIZE +.set noreorder + cache (CACH_PD | C_HWB), (t0) + bltu t0, t1, 1b + addiu t0, t0, DCACHE_LINESIZE +.set reorder .ret: - jr $ra - nop + jr ra -// same as osWritebackDCacheAll in operation +/* same as osWritebackDCacheAll in operation */ .all: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -DCACHE_LINESIZE + li t0, K0BASE + addu t1, t0, t3 + addiu t1, t1, -DCACHE_LINESIZE 1: - cache (CACH_PD | C_IWBINV), ($t0) - sltu $at, $t0, $t1 - bnez $at, 1b - addiu $t0, DCACHE_LINESIZE - jr $ra - nop +.set noreorder + cache (CACH_PD | C_IWBINV), (t0) + bltu t0, t1, 1b + addiu t0, DCACHE_LINESIZE +.set reorder + jr ra END(osWritebackDCache) diff --git a/src/libultra/os/writebackdcacheall.s b/src/libultra/os/writebackdcacheall.s index 54a58dff8..a15ef4554 100644 --- a/src/libultra/os/writebackdcacheall.s +++ b/src/libultra/os/writebackdcacheall.s @@ -1,23 +1,19 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "ultra64/R4300.h" -.set noat -.set noreorder - -.section .text - -.balign 16 +.text LEAF(osWritebackDCacheAll) - li $t0, K0BASE - li $t2, DCACHE_SIZE - addu $t1, $t0, $t2 - addiu $t1, $t1, -DCACHE_LINESIZE + li t0, K0BASE + li t2, DCACHE_SIZE + addu t1, t0, t2 + addiu t1, t1, -DCACHE_LINESIZE 1: - cache (CACH_PD | C_IWBINV), ($t0) - sltu $at, $t0, $t1 - bnez $at, 1b - addiu $t0, DCACHE_LINESIZE - jr $ra - nop +.set noreorder + cache (CACH_PD | C_IWBINV), (t0) + bltu t0, t1, 1b + addiu t0, DCACHE_LINESIZE +.set reorder + jr ra END(osWritebackDCacheAll) diff --git a/src/makerom/entry.s b/src/makerom/entry.s index 6be493e6b..0a1233d80 100644 --- a/src/makerom/entry.s +++ b/src/makerom/entry.s @@ -1,34 +1,44 @@ #include "ultra64/asm.h" +#include "ultra64/regdef.h" #include "boot.h" -.set noreorder +.text -.section .text - -.balign 16 - -LEAF(entrypoint) - // Clear boot segment .bss - la $t0, _bootSegmentBssStart -#ifndef AVOID_UB - // UB: li only loads the lower 16 bits of _bootSegmentBssSize when it may be larger than this, - // so not all of bss may be cleared if it is too large - li $t1, _bootSegmentBssSize +#if defined(__sgi) && !defined(AVOID_UB) +/* IDO assembler workaround: The makerom tool in the N64 SDK was given the bss segment size as a const + * literal, and since this literal was < 0x10000 it was loaded in one instruction. We don't have access + * to the bss segment size until we link everything so we cannot do the same thing. Instead we must load + * only the lower 16 bits of the bss size for matching. + * When AVOID_UB is enabled, don't do this and instead load the full symbol value, otherwise not all of + * bss may be cleared. */ +#define LOAD_BSS_SIZE(reg) li reg, %half(_bootSegmentBssSize) #else - la $t1, _bootSegmentBssSize +#define LOAD_BSS_SIZE(reg) la reg, _bootSegmentBssSize #endif + +LEAF(entrypoint) + /* Clear boot segment .bss */ + la t0, _bootSegmentBssStart + LOAD_BSS_SIZE(t1) .clear_bss: - addi $t1, $t1, -8 - sw $zero, ($t0) - sw $zero, 4($t0) - bnez $t1, .clear_bss - addi $t0, $t0, 8 - // Set up stack and enter program code - lui $t2, %hi(bootproc) - lui $sp, %hi(sBootThreadStack + BOOT_STACK_SIZE) - addiu $t2, %lo(bootproc) - jr $t2 - addiu $sp, %lo(sBootThreadStack + BOOT_STACK_SIZE) + sw zero, 0(t0) + sw zero, 4(t0) + addi t0, t0, 8 + addi t1, t1, -8 + bnez t1, .clear_bss + + /* Set up stack and enter program code */ + la sp, sBootThreadStack + BOOT_STACK_SIZE + la t2, bootproc + jr t2 END(entrypoint) +#ifdef __GNUC__ +/* Pad to a total size of 0x60 */ .fill 0x60 - (. - entrypoint) +#else +/* IDO can't take absolute differences of symbols.. */ +.repeat (0x60 - 0x34) + .byte 0 +.endr +#endif diff --git a/src/makerom/ipl3.s b/src/makerom/ipl3.s deleted file mode 100644 index 45f1c8e6f..000000000 --- a/src/makerom/ipl3.s +++ /dev/null @@ -1,4 +0,0 @@ - -.section .text - -.incbin "incbin/ipl3" |
