#include #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; //}