435 lines
10 KiB
C
435 lines
10 KiB
C
#include <ultra64.h>
|
|
#include "lib/lib_0bfb0.h"
|
|
|
|
char *strcpy(char *dst, char *src)
|
|
{
|
|
char *ptr = dst;
|
|
char c;
|
|
|
|
if (dst == NULL) {
|
|
func0000bfd0("s1", "str.c", 44);
|
|
}
|
|
|
|
if (src == NULL) {
|
|
func0000bfd0("s2", "str.c", 45);
|
|
}
|
|
|
|
*ptr = c = *src;
|
|
ptr++;
|
|
src++;
|
|
|
|
while (c != '\0') {
|
|
*ptr = c = *src;
|
|
ptr++;
|
|
src++;
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
char *strncpy(char *dst, char *src, s32 len)
|
|
{
|
|
char *ptr = dst;
|
|
char c;
|
|
|
|
*ptr = c = *src;
|
|
ptr++;
|
|
src++;
|
|
|
|
while (c != '\0') {
|
|
len--;
|
|
|
|
if (len == 0) {
|
|
break;
|
|
}
|
|
|
|
*ptr = c = *src;
|
|
ptr++;
|
|
src++;
|
|
}
|
|
|
|
while (len--) {
|
|
*ptr = '\0';
|
|
ptr++;
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
char *strcat(char *dst, char *src)
|
|
{
|
|
char *ptr = dst;
|
|
char c;
|
|
|
|
while (*ptr != '\0') {
|
|
ptr++;
|
|
}
|
|
|
|
*ptr = c = *src;
|
|
ptr++;
|
|
src++;
|
|
|
|
while (c != '\0') {
|
|
*ptr = c = *src;
|
|
ptr++;
|
|
src++;
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
s32 strcmp(char *s1, char *s2)
|
|
{
|
|
if (*s1 != *s2) {
|
|
if (*s1 < *s2) {
|
|
return -1;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (*s1 == '\0') {
|
|
return 0;
|
|
}
|
|
|
|
return strcmp(s1 + 1, s2 + 1);
|
|
}
|
|
|
|
s32 strncmp(char *s1, char *s2, s32 len)
|
|
{
|
|
if (len == 0) {
|
|
return 0;
|
|
}
|
|
|
|
len--;
|
|
|
|
if (*s1 != *s2) {
|
|
if (*s1 < *s2) {
|
|
return -1;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (*s1 == '\0') {
|
|
return 0;
|
|
}
|
|
|
|
return strncmp(s1 + 1, s2 + 1, len);
|
|
}
|
|
|
|
char toupper(char c)
|
|
{
|
|
if (c >= 'a' && c <= 'z') {
|
|
return c - 0x20;
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
s32 isdigit(char c)
|
|
{
|
|
return c >= '0' && c <= '9';
|
|
}
|
|
|
|
s32 isalpha(char c)
|
|
{
|
|
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
|
}
|
|
|
|
s32 isspace(char c)
|
|
{
|
|
return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v';
|
|
}
|
|
|
|
GLOBAL_ASM(
|
|
glabel strtol
|
|
/* 13408: 27bdffa0 */ addiu $sp,$sp,-96
|
|
/* 1340c: afb30024 */ sw $s3,0x24($sp)
|
|
/* 13410: 00c09825 */ or $s3,$a2,$zero
|
|
/* 13414: afbf002c */ sw $ra,0x2c($sp)
|
|
/* 13418: afb40028 */ sw $s4,0x28($sp)
|
|
/* 1341c: afb20020 */ sw $s2,0x20($sp)
|
|
/* 13420: afb1001c */ sw $s1,0x1c($sp)
|
|
/* 13424: afb00018 */ sw $s0,0x18($sp)
|
|
/* 13428: afa50064 */ sw $a1,0x64($sp)
|
|
/* 1342c: 04c00006 */ bltz $a2,.L00013448
|
|
/* 13430: 00803825 */ or $a3,$a0,$zero
|
|
/* 13434: 24010001 */ addiu $at,$zero,0x1
|
|
/* 13438: 10c10003 */ beq $a2,$at,.L00013448
|
|
/* 1343c: 28c10025 */ slti $at,$a2,0x25
|
|
/* 13440: 54200003 */ bnezl $at,.L00013450
|
|
/* 13444: 90e40000 */ lbu $a0,0x0($a3)
|
|
.L00013448:
|
|
/* 13448: 2413000a */ addiu $s3,$zero,0xa
|
|
/* 1344c: 90e40000 */ lbu $a0,0x0($a3)
|
|
.L00013450:
|
|
/* 13450: 00e09025 */ or $s2,$a3,$zero
|
|
/* 13454: 0c004ced */ jal isspace
|
|
/* 13458: afa70060 */ sw $a3,0x60($sp)
|
|
/* 1345c: 50400007 */ beqzl $v0,.L0001347c
|
|
/* 13460: 92420000 */ lbu $v0,0x0($s2)
|
|
/* 13464: 26520001 */ addiu $s2,$s2,0x1
|
|
.L00013468:
|
|
/* 13468: 0c004ced */ jal isspace
|
|
/* 1346c: 92440000 */ lbu $a0,0x0($s2)
|
|
/* 13470: 5440fffd */ bnezl $v0,.L00013468
|
|
/* 13474: 26520001 */ addiu $s2,$s2,0x1
|
|
/* 13478: 92420000 */ lbu $v0,0x0($s2)
|
|
.L0001347c:
|
|
/* 1347c: 2401002d */ addiu $at,$zero,0x2d
|
|
/* 13480: 50400075 */ beqzl $v0,.L00013658
|
|
/* 13484: 8fa20064 */ lw $v0,0x64($sp)
|
|
/* 13488: 14410004 */ bne $v0,$at,.L0001349c
|
|
/* 1348c: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* 13490: afae005c */ sw $t6,0x5c($sp)
|
|
/* 13494: 10000008 */ b .L000134b8
|
|
/* 13498: 26520001 */ addiu $s2,$s2,0x1
|
|
.L0001349c:
|
|
/* 1349c: 2401002b */ addiu $at,$zero,0x2b
|
|
/* 134a0: 54410005 */ bnel $v0,$at,.L000134b8
|
|
/* 134a4: afa0005c */ sw $zero,0x5c($sp)
|
|
/* 134a8: afa0005c */ sw $zero,0x5c($sp)
|
|
/* 134ac: 10000002 */ b .L000134b8
|
|
/* 134b0: 26520001 */ addiu $s2,$s2,0x1
|
|
/* 134b4: afa0005c */ sw $zero,0x5c($sp)
|
|
.L000134b8:
|
|
/* 134b8: 24010010 */ addiu $at,$zero,0x10
|
|
/* 134bc: 1661000b */ bne $s3,$at,.L000134ec
|
|
/* 134c0: 00000000 */ nop
|
|
/* 134c4: 924f0000 */ lbu $t7,0x0($s2)
|
|
/* 134c8: 24010030 */ addiu $at,$zero,0x30
|
|
/* 134cc: 15e10007 */ bne $t7,$at,.L000134ec
|
|
/* 134d0: 00000000 */ nop
|
|
/* 134d4: 0c004cc8 */ jal toupper
|
|
/* 134d8: 92440001 */ lbu $a0,0x1($s2)
|
|
/* 134dc: 24010058 */ addiu $at,$zero,0x58
|
|
/* 134e0: 14410002 */ bne $v0,$at,.L000134ec
|
|
/* 134e4: 00000000 */ nop
|
|
/* 134e8: 26520002 */ addiu $s2,$s2,0x2
|
|
.L000134ec:
|
|
/* 134ec: 1660000e */ bnez $s3,.L00013528
|
|
/* 134f0: 92420000 */ lbu $v0,0x0($s2)
|
|
/* 134f4: 24010030 */ addiu $at,$zero,0x30
|
|
/* 134f8: 1441000b */ bne $v0,$at,.L00013528
|
|
/* 134fc: 2413000a */ addiu $s3,$zero,0xa
|
|
/* 13500: 0c004cc8 */ jal toupper
|
|
/* 13504: 92440001 */ lbu $a0,0x1($s2)
|
|
/* 13508: 24010058 */ addiu $at,$zero,0x58
|
|
/* 1350c: 14410004 */ bne $v0,$at,.L00013520
|
|
/* 13510: 24130008 */ addiu $s3,$zero,0x8
|
|
/* 13514: 26520002 */ addiu $s2,$s2,0x2
|
|
/* 13518: 10000001 */ b .L00013520
|
|
/* 1351c: 24130010 */ addiu $s3,$zero,0x10
|
|
.L00013520:
|
|
/* 13520: 10000001 */ b .L00013528
|
|
/* 13524: 92420000 */ lbu $v0,0x0($s2)
|
|
.L00013528:
|
|
/* 13528: 305000ff */ andi $s0,$v0,0xff
|
|
/* 1352c: afb20044 */ sw $s2,0x44($sp)
|
|
/* 13530: afa00040 */ sw $zero,0x40($sp)
|
|
/* 13534: 00008825 */ or $s1,$zero,$zero
|
|
/* 13538: 12000033 */ beqz $s0,.L00013608
|
|
/* 1353c: 02001825 */ or $v1,$s0,$zero
|
|
/* 13540: 2414ffff */ addiu $s4,$zero,-1
|
|
.L00013544:
|
|
/* 13544: 320400ff */ andi $a0,$s0,0xff
|
|
/* 13548: 0c004cd6 */ jal isdigit
|
|
/* 1354c: afa30034 */ sw $v1,0x34($sp)
|
|
/* 13550: 10400005 */ beqz $v0,.L00013568
|
|
/* 13554: 8fa30034 */ lw $v1,0x34($sp)
|
|
/* 13558: 2470ffd0 */ addiu $s0,$v1,-48
|
|
/* 1355c: 321800ff */ andi $t8,$s0,0xff
|
|
/* 13560: 1000000a */ b .L0001358c
|
|
/* 13564: 03008025 */ or $s0,$t8,$zero
|
|
.L00013568:
|
|
/* 13568: 0c004cde */ jal isalpha
|
|
/* 1356c: 320400ff */ andi $a0,$s0,0xff
|
|
/* 13570: 50400026 */ beqzl $v0,.L0001360c
|
|
/* 13574: 8faa0044 */ lw $t2,0x44($sp)
|
|
/* 13578: 0c004cc8 */ jal toupper
|
|
/* 1357c: 320400ff */ andi $a0,$s0,0xff
|
|
/* 13580: 2450ffc9 */ addiu $s0,$v0,-55
|
|
/* 13584: 321900ff */ andi $t9,$s0,0xff
|
|
/* 13588: 03208025 */ or $s0,$t9,$zero
|
|
.L0001358c:
|
|
/* 1358c: 0213082a */ slt $at,$s0,$s3
|
|
/* 13590: 1020001d */ beqz $at,.L00013608
|
|
/* 13594: 24090001 */ addiu $t1,$zero,0x1
|
|
/* 13598: 0293001b */ divu $zero,$s4,$s3
|
|
/* 1359c: 00001012 */ mflo $v0
|
|
/* 135a0: 0051082b */ sltu $at,$v0,$s1
|
|
/* 135a4: 16600002 */ bnez $s3,.L000135b0
|
|
/* 135a8: 00000000 */ nop
|
|
/* 135ac: 0007000d */ break 0x7
|
|
.L000135b0:
|
|
/* 135b0: 1420000b */ bnez $at,.L000135e0
|
|
/* 135b4: 00000000 */ nop
|
|
/* 135b8: 1622000b */ bne $s1,$v0,.L000135e8
|
|
/* 135bc: 00000000 */ nop
|
|
/* 135c0: 0293001b */ divu $zero,$s4,$s3
|
|
/* 135c4: 00004010 */ mfhi $t0
|
|
/* 135c8: 0110082b */ sltu $at,$t0,$s0
|
|
/* 135cc: 16600002 */ bnez $s3,.L000135d8
|
|
/* 135d0: 00000000 */ nop
|
|
/* 135d4: 0007000d */ break 0x7
|
|
.L000135d8:
|
|
/* 135d8: 10200003 */ beqz $at,.L000135e8
|
|
/* 135dc: 00000000 */ nop
|
|
.L000135e0:
|
|
/* 135e0: 10000005 */ b .L000135f8
|
|
/* 135e4: afa90040 */ sw $t1,0x40($sp)
|
|
.L000135e8:
|
|
/* 135e8: 02330019 */ multu $s1,$s3
|
|
/* 135ec: 00008812 */ mflo $s1
|
|
/* 135f0: 02308821 */ addu $s1,$s1,$s0
|
|
/* 135f4: 00000000 */ nop
|
|
.L000135f8:
|
|
/* 135f8: 92500001 */ lbu $s0,0x1($s2)
|
|
/* 135fc: 26520001 */ addiu $s2,$s2,0x1
|
|
/* 13600: 1600ffd0 */ bnez $s0,.L00013544
|
|
/* 13604: 02001825 */ or $v1,$s0,$zero
|
|
.L00013608:
|
|
/* 13608: 8faa0044 */ lw $t2,0x44($sp)
|
|
.L0001360c:
|
|
/* 1360c: 8fa20064 */ lw $v0,0x64($sp)
|
|
/* 13610: 524a0011 */ beql $s2,$t2,.L00013658
|
|
/* 13614: 8fa20064 */ lw $v0,0x64($sp)
|
|
/* 13618: 50400003 */ beqzl $v0,.L00013628
|
|
/* 1361c: 8fab0040 */ lw $t3,0x40($sp)
|
|
/* 13620: ac520000 */ sw $s2,0x0($v0)
|
|
/* 13624: 8fab0040 */ lw $t3,0x40($sp)
|
|
.L00013628:
|
|
/* 13628: 8fac005c */ lw $t4,0x5c($sp)
|
|
/* 1362c: 11600003 */ beqz $t3,.L0001363c
|
|
/* 13630: 00000000 */ nop
|
|
/* 13634: 1000000d */ b .L0001366c
|
|
/* 13638: 2402ffff */ addiu $v0,$zero,-1
|
|
.L0001363c:
|
|
/* 1363c: 11800003 */ beqz $t4,.L0001364c
|
|
/* 13640: 02201825 */ or $v1,$s1,$zero
|
|
/* 13644: 10000009 */ b .L0001366c
|
|
/* 13648: 00111023 */ negu $v0,$s1
|
|
.L0001364c:
|
|
/* 1364c: 10000007 */ b .L0001366c
|
|
/* 13650: 00601025 */ or $v0,$v1,$zero
|
|
/* 13654: 8fa20064 */ lw $v0,0x64($sp)
|
|
.L00013658:
|
|
/* 13658: 8fad0060 */ lw $t5,0x60($sp)
|
|
/* 1365c: 50400003 */ beqzl $v0,.L0001366c
|
|
/* 13660: 00001025 */ or $v0,$zero,$zero
|
|
/* 13664: ac4d0000 */ sw $t5,0x0($v0)
|
|
/* 13668: 00001025 */ or $v0,$zero,$zero
|
|
.L0001366c:
|
|
/* 1366c: 8fbf002c */ lw $ra,0x2c($sp)
|
|
/* 13670: 8fb00018 */ lw $s0,0x18($sp)
|
|
/* 13674: 8fb1001c */ lw $s1,0x1c($sp)
|
|
/* 13678: 8fb20020 */ lw $s2,0x20($sp)
|
|
/* 1367c: 8fb30024 */ lw $s3,0x24($sp)
|
|
/* 13680: 8fb40028 */ lw $s4,0x28($sp)
|
|
/* 13684: 03e00008 */ jr $ra
|
|
/* 13688: 27bd0060 */ addiu $sp,$sp,0x60
|
|
);
|
|
|
|
// Mismatch: The below moves c from s0 to v1 near 590 for the compare with
|
|
// cutlim and the add to value, while goal keeps it in s0. Also tried verbatim
|
|
// strtol from glibc 1995 (commit 28f540f45b) which has the same codegen.
|
|
//s32 strtol(char *src, char **endptr, s32 base)
|
|
//{
|
|
// bool negative;
|
|
// u32 cutoff;
|
|
// u32 cutlim;
|
|
// u32 value;
|
|
// char *ptr;
|
|
// char c;
|
|
// char *save;
|
|
// bool overflow;
|
|
//
|
|
// if (base < 0 || base == 1 || base > 36) {
|
|
// base = 10;
|
|
// }
|
|
//
|
|
// ptr = src;
|
|
//
|
|
// while (isspace(*ptr)) {
|
|
// ptr++;
|
|
// }
|
|
//
|
|
// if (*ptr != '\0') {
|
|
// if (*ptr == '-') {
|
|
// negative = true;
|
|
// ptr++;
|
|
// } else if (*ptr == '+') {
|
|
// negative = false;
|
|
// ptr++;
|
|
// } else {
|
|
// negative = false;
|
|
// }
|
|
//
|
|
// if (base == 16 && ptr[0] == '0' && toupper(ptr[1]) == 'X') {
|
|
// ptr += 2;
|
|
// }
|
|
//
|
|
// if (base == 0) {
|
|
// if (*ptr == '0') {
|
|
// if (toupper(ptr[1]) == 'X') {
|
|
// ptr += 2;
|
|
// base = 16;
|
|
// } else {
|
|
// base = 8;
|
|
// }
|
|
// } else {
|
|
// base = 10;
|
|
// }
|
|
// }
|
|
//
|
|
// save = ptr;
|
|
//
|
|
// cutoff = U32_MAX / base;
|
|
// cutlim = U32_MAX % base;
|
|
// overflow = false;
|
|
// value = 0;
|
|
//
|
|
// for (c = *ptr; c != '\0'; c = *++ptr) {
|
|
// if (isdigit(c)) {
|
|
// c -= '0';
|
|
// } else if (isalpha(c)) {
|
|
// c = toupper(c) - 'A' + 10;
|
|
// } else {
|
|
// break;
|
|
// }
|
|
//
|
|
// // 590
|
|
// if (c >= base) {
|
|
// break;
|
|
// }
|
|
//
|
|
// // 5a4
|
|
// if (value > cutoff || (value == cutoff && c > cutlim)) {
|
|
// overflow = true;
|
|
// } else {
|
|
// value *= base;
|
|
// value += c;
|
|
// }
|
|
// }
|
|
//
|
|
// if (ptr != save) {
|
|
// if (endptr != NULL) {
|
|
// *endptr = ptr;
|
|
// }
|
|
//
|
|
// if (overflow) {
|
|
// return -1;
|
|
// }
|
|
//
|
|
// return negative ? -value : value;
|
|
// }
|
|
// }
|
|
//
|
|
// if (endptr != NULL) {
|
|
// *endptr = src;
|
|
// }
|
|
//
|
|
// return 0;
|
|
//}
|