From beb76e4dd362374b8f42cd971d394bba1074cd8d Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sat, 5 Jul 2025 02:34:11 +0200 Subject: Replace .include with #include For some reason, both mipsel-unknown-elf-gcc 8.2.0 and mipsel-non-elf 15.1.0 were unable to resolve .include assembler directives. As a workaround, it is still possible to use the preprocessor, and therefore the usual #include preprocessor directive. However, this requires the assembly files to use the uppercase .S file extension. --- libpsn00b/libc/_start.S | 18 ++++++++ libpsn00b/libc/_start.s | 18 -------- libpsn00b/libc/clz.S | 53 +++++++++++++++++++++ libpsn00b/libc/clz.s | 53 --------------------- libpsn00b/libc/memset.S | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ libpsn00b/libc/memset.s | 119 ------------------------------------------------ libpsn00b/libc/setjmp.S | 50 ++++++++++++++++++++ libpsn00b/libc/setjmp.s | 50 -------------------- 8 files changed, 240 insertions(+), 240 deletions(-) create mode 100644 libpsn00b/libc/_start.S delete mode 100644 libpsn00b/libc/_start.s create mode 100644 libpsn00b/libc/clz.S delete mode 100644 libpsn00b/libc/clz.s create mode 100644 libpsn00b/libc/memset.S delete mode 100644 libpsn00b/libc/memset.s create mode 100644 libpsn00b/libc/setjmp.S delete mode 100644 libpsn00b/libc/setjmp.s (limited to 'libpsn00b/libc') diff --git a/libpsn00b/libc/_start.S b/libpsn00b/libc/_start.S new file mode 100644 index 0000000..35a4eaa --- /dev/null +++ b/libpsn00b/libc/_start.S @@ -0,0 +1,18 @@ +# PSn00bSDK _start() trampoline +# (C) 2022 spicyjpeg - MPL licensed +# +# This file provides a weak function that can be easily overridden to e.g. set +# $sp or perform additional initialization before the "real" _start() function +# (_start_inner()) is called. + +.set noreorder + +.section .text._start, "ax", @progbits +.global _start +.type _start, @function +.weak _start + +_start: + la $gp, _gp + j _start_inner + nop diff --git a/libpsn00b/libc/_start.s b/libpsn00b/libc/_start.s deleted file mode 100644 index 35a4eaa..0000000 --- a/libpsn00b/libc/_start.s +++ /dev/null @@ -1,18 +0,0 @@ -# PSn00bSDK _start() trampoline -# (C) 2022 spicyjpeg - MPL licensed -# -# This file provides a weak function that can be easily overridden to e.g. set -# $sp or perform additional initialization before the "real" _start() function -# (_start_inner()) is called. - -.set noreorder - -.section .text._start, "ax", @progbits -.global _start -.type _start, @function -.weak _start - -_start: - la $gp, _gp - j _start_inner - nop diff --git a/libpsn00b/libc/clz.S b/libpsn00b/libc/clz.S new file mode 100644 index 0000000..1ccff2e --- /dev/null +++ b/libpsn00b/libc/clz.S @@ -0,0 +1,53 @@ +# PSn00bSDK leading zero count intrinsics +# (C) 2022-2023 spicyjpeg - MPL licensed +# +# libgcc provides two functions used internally by GCC to count the number of +# leading zeroes in a value, __clzsi2() (32-bit) and __clzdi2() (64-bit). This +# file overrides them with smaller implementations that make use of the GTE's +# LZCS/LZCR registers. + +.set noreorder + +.set LZCS, $30 +.set LZCR, $31 + +.section .text.__clzsi2, "ax", @progbits +.global __clzsi2 +.type __clzsi2, @function + +__clzsi2: + mtc2 $a0, LZCS + bltz $a0, .Lreturn # if (value & (1 << 31)) return 0 + li $v0, 0 + mfc2 $v0, LZCR # else return GTE_CLZ(value) + +.Lreturn: + jr $ra + nop + +.section .text.__clzdi2, "ax", @progbits +.global __clzdi2 +.type __clzdi2, @function + +__clzdi2: + mtc2 $a1, LZCS + bltz $a1, .Lreturn2 # if (msb & (1 << 31)) return 0 + li $v0, 0 + bnez $a1, .LreturnMSB # else if (msb) return GTE_CLZ(msb) + nop + +.LnoMSB: + mtc2 $a0, LZCS + bltz $a0, .Lreturn2 # else if (lsb & (1 << 31)) return 32 + li $v0, 32 + mfc2 $v0, LZCR # else return 32 + GTE_CLZ(lsb) + + jr $ra + addiu $v0, 32 + +.LreturnMSB: + mfc2 $v0, LZCR + +.Lreturn2: + jr $ra + nop diff --git a/libpsn00b/libc/clz.s b/libpsn00b/libc/clz.s deleted file mode 100644 index 1ccff2e..0000000 --- a/libpsn00b/libc/clz.s +++ /dev/null @@ -1,53 +0,0 @@ -# PSn00bSDK leading zero count intrinsics -# (C) 2022-2023 spicyjpeg - MPL licensed -# -# libgcc provides two functions used internally by GCC to count the number of -# leading zeroes in a value, __clzsi2() (32-bit) and __clzdi2() (64-bit). This -# file overrides them with smaller implementations that make use of the GTE's -# LZCS/LZCR registers. - -.set noreorder - -.set LZCS, $30 -.set LZCR, $31 - -.section .text.__clzsi2, "ax", @progbits -.global __clzsi2 -.type __clzsi2, @function - -__clzsi2: - mtc2 $a0, LZCS - bltz $a0, .Lreturn # if (value & (1 << 31)) return 0 - li $v0, 0 - mfc2 $v0, LZCR # else return GTE_CLZ(value) - -.Lreturn: - jr $ra - nop - -.section .text.__clzdi2, "ax", @progbits -.global __clzdi2 -.type __clzdi2, @function - -__clzdi2: - mtc2 $a1, LZCS - bltz $a1, .Lreturn2 # if (msb & (1 << 31)) return 0 - li $v0, 0 - bnez $a1, .LreturnMSB # else if (msb) return GTE_CLZ(msb) - nop - -.LnoMSB: - mtc2 $a0, LZCS - bltz $a0, .Lreturn2 # else if (lsb & (1 << 31)) return 32 - li $v0, 32 - mfc2 $v0, LZCR # else return 32 + GTE_CLZ(lsb) - - jr $ra - addiu $v0, 32 - -.LreturnMSB: - mfc2 $v0, LZCR - -.Lreturn2: - jr $ra - nop diff --git a/libpsn00b/libc/memset.S b/libpsn00b/libc/memset.S new file mode 100644 index 0000000..59cb10b --- /dev/null +++ b/libpsn00b/libc/memset.S @@ -0,0 +1,119 @@ +# PSn00bSDK optimized memset +# (C) 2022 spicyjpeg - MPL licensed + +.set noreorder + +.section .text.memset, "ax", @progbits +.global memset +.type memset, @function + +memset: + # If more than 16 bytes have to be written then take the "large" path, + # otherwise use the code below. + addiu $t0, $a2, -16 + bgtz $t0, .Llarge_fill + move $v0, $a0 # return_value = dest + + # Jump to one of the sb opcodes below. This is basically a cut-down Duff's + # device implementation with no looping. + la $t0, .Lsmall_duff + 0x40 # jump_addr = &small_duff[(16 - count) * 4] + sll $t1, $a2, 2 + subu $t0, $t1 + addu $a0, $a2 # dest -= 16 - count + jr $t0 + addiu $a0, -16 + +.Lsmall_duff: + sb $a1, 0x0($a0) + sb $a1, 0x1($a0) + sb $a1, 0x2($a0) + sb $a1, 0x3($a0) + sb $a1, 0x4($a0) + sb $a1, 0x5($a0) + sb $a1, 0x6($a0) + sb $a1, 0x7($a0) + sb $a1, 0x8($a0) + sb $a1, 0x9($a0) + sb $a1, 0xa($a0) + sb $a1, 0xb($a0) + sb $a1, 0xc($a0) + sb $a1, 0xd($a0) + sb $a1, 0xe($a0) + sb $a1, 0xf($a0) + jr $ra + nop + +.Llarge_fill: + # Initialize fast filling by repeating the fill byte 4 times, so it can be + # written 32 bits at a time. + andi $a1, 0xff # ch &= 0xff + sll $t0, $a1, 8 # ch |= (ch << 8) | (ch << 16) | (ch << 24) + or $a1, $t0 + sll $t0, $a1, 16 + or $a1, $t0 + + # Fill the first 1-4 bytes (here the swr instruction does all the magic) + # and update dest and count accordingly. + swr $a1, 0($a0) + andi $t0, $a0, 3 # align = 4 - (dest % 4) + addiu $t0, -4 + addu $a2, $t0 # count -= align + subu $a0, $t0 # dest += align + + la $t1, .Llarge_duff + andi $t2, $a2, 3 # remainder = count % 4 + subu $a2, $t2 # count -= remainder + +.Llarge_fill_loop: + # If 128 bytes or more still have to be written, skip calculating the jump + # offset and execute the whole block of sw opcodes. + addiu $a2, -0x80 # count -= 0x80 + bgez $a2, .Llarge_duff + #nop + + # Jump to one of the sw opcodes below. This is the "full" Duff's device. + subu $t0, $t1, $a2 # jump_addr = &large_duff[0x80 - (count + 0x80)] + jr $t0 + addu $a0, $a2 # dest -= 0x80 - (count + 0x80) + +.Llarge_duff: + sw $a1, 0x00($a0) + sw $a1, 0x04($a0) + sw $a1, 0x08($a0) + sw $a1, 0x0c($a0) + sw $a1, 0x10($a0) + sw $a1, 0x14($a0) + sw $a1, 0x18($a0) + sw $a1, 0x1c($a0) + sw $a1, 0x20($a0) + sw $a1, 0x24($a0) + sw $a1, 0x28($a0) + sw $a1, 0x2c($a0) + sw $a1, 0x30($a0) + sw $a1, 0x34($a0) + sw $a1, 0x38($a0) + sw $a1, 0x3c($a0) + sw $a1, 0x40($a0) + sw $a1, 0x44($a0) + sw $a1, 0x48($a0) + sw $a1, 0x4c($a0) + sw $a1, 0x50($a0) + sw $a1, 0x54($a0) + sw $a1, 0x58($a0) + sw $a1, 0x5c($a0) + sw $a1, 0x60($a0) + sw $a1, 0x64($a0) + sw $a1, 0x68($a0) + sw $a1, 0x6c($a0) + sw $a1, 0x70($a0) + sw $a1, 0x74($a0) + sw $a1, 0x78($a0) + sw $a1, 0x7c($a0) + + bgtz $a2, .Llarge_fill_loop + addiu $a0, 0x80 # dest += 0x80 + + # Fill the remaining 1-4 bytes, using (again) an unaligned store. + addu $a0, $t2 # last_byte = dest + remainder - 1 + jr $ra + swl $a1, -1($a0) diff --git a/libpsn00b/libc/memset.s b/libpsn00b/libc/memset.s deleted file mode 100644 index 59cb10b..0000000 --- a/libpsn00b/libc/memset.s +++ /dev/null @@ -1,119 +0,0 @@ -# PSn00bSDK optimized memset -# (C) 2022 spicyjpeg - MPL licensed - -.set noreorder - -.section .text.memset, "ax", @progbits -.global memset -.type memset, @function - -memset: - # If more than 16 bytes have to be written then take the "large" path, - # otherwise use the code below. - addiu $t0, $a2, -16 - bgtz $t0, .Llarge_fill - move $v0, $a0 # return_value = dest - - # Jump to one of the sb opcodes below. This is basically a cut-down Duff's - # device implementation with no looping. - la $t0, .Lsmall_duff + 0x40 # jump_addr = &small_duff[(16 - count) * 4] - sll $t1, $a2, 2 - subu $t0, $t1 - addu $a0, $a2 # dest -= 16 - count - jr $t0 - addiu $a0, -16 - -.Lsmall_duff: - sb $a1, 0x0($a0) - sb $a1, 0x1($a0) - sb $a1, 0x2($a0) - sb $a1, 0x3($a0) - sb $a1, 0x4($a0) - sb $a1, 0x5($a0) - sb $a1, 0x6($a0) - sb $a1, 0x7($a0) - sb $a1, 0x8($a0) - sb $a1, 0x9($a0) - sb $a1, 0xa($a0) - sb $a1, 0xb($a0) - sb $a1, 0xc($a0) - sb $a1, 0xd($a0) - sb $a1, 0xe($a0) - sb $a1, 0xf($a0) - jr $ra - nop - -.Llarge_fill: - # Initialize fast filling by repeating the fill byte 4 times, so it can be - # written 32 bits at a time. - andi $a1, 0xff # ch &= 0xff - sll $t0, $a1, 8 # ch |= (ch << 8) | (ch << 16) | (ch << 24) - or $a1, $t0 - sll $t0, $a1, 16 - or $a1, $t0 - - # Fill the first 1-4 bytes (here the swr instruction does all the magic) - # and update dest and count accordingly. - swr $a1, 0($a0) - andi $t0, $a0, 3 # align = 4 - (dest % 4) - addiu $t0, -4 - addu $a2, $t0 # count -= align - subu $a0, $t0 # dest += align - - la $t1, .Llarge_duff - andi $t2, $a2, 3 # remainder = count % 4 - subu $a2, $t2 # count -= remainder - -.Llarge_fill_loop: - # If 128 bytes or more still have to be written, skip calculating the jump - # offset and execute the whole block of sw opcodes. - addiu $a2, -0x80 # count -= 0x80 - bgez $a2, .Llarge_duff - #nop - - # Jump to one of the sw opcodes below. This is the "full" Duff's device. - subu $t0, $t1, $a2 # jump_addr = &large_duff[0x80 - (count + 0x80)] - jr $t0 - addu $a0, $a2 # dest -= 0x80 - (count + 0x80) - -.Llarge_duff: - sw $a1, 0x00($a0) - sw $a1, 0x04($a0) - sw $a1, 0x08($a0) - sw $a1, 0x0c($a0) - sw $a1, 0x10($a0) - sw $a1, 0x14($a0) - sw $a1, 0x18($a0) - sw $a1, 0x1c($a0) - sw $a1, 0x20($a0) - sw $a1, 0x24($a0) - sw $a1, 0x28($a0) - sw $a1, 0x2c($a0) - sw $a1, 0x30($a0) - sw $a1, 0x34($a0) - sw $a1, 0x38($a0) - sw $a1, 0x3c($a0) - sw $a1, 0x40($a0) - sw $a1, 0x44($a0) - sw $a1, 0x48($a0) - sw $a1, 0x4c($a0) - sw $a1, 0x50($a0) - sw $a1, 0x54($a0) - sw $a1, 0x58($a0) - sw $a1, 0x5c($a0) - sw $a1, 0x60($a0) - sw $a1, 0x64($a0) - sw $a1, 0x68($a0) - sw $a1, 0x6c($a0) - sw $a1, 0x70($a0) - sw $a1, 0x74($a0) - sw $a1, 0x78($a0) - sw $a1, 0x7c($a0) - - bgtz $a2, .Llarge_fill_loop - addiu $a0, 0x80 # dest += 0x80 - - # Fill the remaining 1-4 bytes, using (again) an unaligned store. - addu $a0, $t2 # last_byte = dest + remainder - 1 - jr $ra - swl $a1, -1($a0) diff --git a/libpsn00b/libc/setjmp.S b/libpsn00b/libc/setjmp.S new file mode 100644 index 0000000..fb0dc6b --- /dev/null +++ b/libpsn00b/libc/setjmp.S @@ -0,0 +1,50 @@ +# PSn00bSDK setjmp/longjmp +# (C) 2023 spicyjpeg - MPL licensed +# +# This is not a "proper" implementation of setjmp/longjmp as it does not save +# COP0 and GTE registers, but it is fully compatible with the version found in +# the BIOS. + +.set noreorder + +.section .text.setjmp, "ax", @progbits +.global setjmp +.type setjmp, @function + +setjmp: + sw $ra, 0x00($a0) + sw $sp, 0x04($a0) + sw $fp, 0x08($a0) + sw $s0, 0x0c($a0) + sw $s1, 0x10($a0) + sw $s2, 0x14($a0) + sw $s3, 0x18($a0) + sw $s4, 0x1c($a0) + sw $s5, 0x20($a0) + sw $s6, 0x24($a0) + sw $s7, 0x28($a0) + sw $gp, 0x2c($a0) + + jr $ra + li $v0, 0 + +.section .text.longjmp, "ax", @progbits +.global longjmp +.type longjmp, @function + +longjmp: + lw $ra, 0x00($a0) + lw $sp, 0x04($a0) + lw $fp, 0x08($a0) + lw $s0, 0x0c($a0) + lw $s1, 0x10($a0) + lw $s2, 0x14($a0) + lw $s3, 0x18($a0) + lw $s4, 0x1c($a0) + lw $s5, 0x20($a0) + lw $s6, 0x24($a0) + lw $s7, 0x28($a0) + lw $gp, 0x2c($a0) + + jr $ra + move $v0, $a1 diff --git a/libpsn00b/libc/setjmp.s b/libpsn00b/libc/setjmp.s deleted file mode 100644 index fb0dc6b..0000000 --- a/libpsn00b/libc/setjmp.s +++ /dev/null @@ -1,50 +0,0 @@ -# PSn00bSDK setjmp/longjmp -# (C) 2023 spicyjpeg - MPL licensed -# -# This is not a "proper" implementation of setjmp/longjmp as it does not save -# COP0 and GTE registers, but it is fully compatible with the version found in -# the BIOS. - -.set noreorder - -.section .text.setjmp, "ax", @progbits -.global setjmp -.type setjmp, @function - -setjmp: - sw $ra, 0x00($a0) - sw $sp, 0x04($a0) - sw $fp, 0x08($a0) - sw $s0, 0x0c($a0) - sw $s1, 0x10($a0) - sw $s2, 0x14($a0) - sw $s3, 0x18($a0) - sw $s4, 0x1c($a0) - sw $s5, 0x20($a0) - sw $s6, 0x24($a0) - sw $s7, 0x28($a0) - sw $gp, 0x2c($a0) - - jr $ra - li $v0, 0 - -.section .text.longjmp, "ax", @progbits -.global longjmp -.type longjmp, @function - -longjmp: - lw $ra, 0x00($a0) - lw $sp, 0x04($a0) - lw $fp, 0x08($a0) - lw $s0, 0x0c($a0) - lw $s1, 0x10($a0) - lw $s2, 0x14($a0) - lw $s3, 0x18($a0) - lw $s4, 0x1c($a0) - lw $s5, 0x20($a0) - lw $s6, 0x24($a0) - lw $s7, 0x28($a0) - lw $gp, 0x2c($a0) - - jr $ra - move $v0, $a1 -- cgit v1.2.3