diff --git a/Makefile b/Makefile index c5a4659d3..8cabb77b8 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,27 @@ else TOOLCHAIN := mips64-elf endif -CFLAGS := -Wo,-loopunroll,0 -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -woff 819,820,852,821 -signed -I . -I include -mips2 +ifeq ($(REGION),ntsc) + VERSION_CFLAGS := -DNTSC=1 -DPAL=0 -DJAP=0 +endif +ifeq ($(REGION),pal) + VERSION_CFLAGS := -DNTSC=0 -DPAL=1 -DJAP=0 +endif +ifeq ($(REGION),jap) + VERSION_CFLAGS := -DNTSC=0 -DPAL=0 -DJAP=1 +endif + +ifeq ($(RELEASE),beta) + RELEASE_CFLAGS := -DBETA=1 -DREL1_0 -DFINAL=0 +endif +ifeq ($(RELEASE),1.0) + RELEASE_CFLAGS := -DBETA=0 -DREL1_1 -DFINAL=0 +endif +ifeq ($(RELEASE),final) + RELEASE_CFLAGS := -DBETA=0 -DREL1_0 -DFINAL=1 +endif + +CFLAGS := $(VERSION_CFLAGS) $(RELEASE_CFLAGS) -Wo,-loopunroll,0 -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -woff 819,820,852,821 -signed -I . -I include -mips2 default: all @@ -111,6 +131,22 @@ $(B_DIR)/globals.elf: $(B_DIR)/globals.o $(B_DIR)/Uglobals: $(B_DIR)/globals.elf $(TOOLCHAIN)-objcopy $< $@ -O binary +################################################################################ +# Rarezip + +$(B_DIR)/ucode/rarezip.o: src/rarezip/rarezip.c + mkdir -p $(B_DIR)/ucode + python tools/asmpreproc/asm-processor.py -O2 $< | $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) tools/asmpreproc/include-stdin.c -o $@ -O2 + python tools/asmpreproc/asm-processor.py -O2 $< --post-process $@ --assembler "$(TOOLCHAIN)-as -march=vr4300 -mabi=32" --asm-prelude tools/asmpreproc/prelude.s + +$(B_DIR)/ucode/rarezip.elf: $(B_DIR)/ucode/rarezip.o + cp $< build/rarezip.tmp.o + $(TOOLCHAIN)-ld -T ld/rarezip.ld -o $@ + rm -f build/rarezip.tmp.o + +$(B_DIR)/ucode/rarezip.bin: $(B_DIR)/ucode/rarezip.elf + $(TOOLCHAIN)-objcopy $< $@ -O binary + ################################################################################ # Test related @@ -119,7 +155,9 @@ test: $(B_SETUP_BINZ_FILES) $(B_LANG_BINZ_FILES) @diff -rq --exclude='*.bin' \ --exclude=chrs \ --exclude=guns \ + --exclude=lang \ --exclude=props \ + --exclude=setup \ --exclude='A*' \ --exclude='C*' \ --exclude='G*' \ diff --git a/macros.inc b/macros.inc new file mode 100644 index 000000000..c97fd81f4 --- /dev/null +++ b/macros.inc @@ -0,0 +1,7 @@ +# Assembly Macros + +.macro glabel label + .global \label + \label: +.endm + diff --git a/src/rarezip/rarezip.c b/src/rarezip/rarezip.c new file mode 100644 index 000000000..54d998b2c --- /dev/null +++ b/src/rarezip/rarezip.c @@ -0,0 +1,1376 @@ +#include + +// 702012d0 +u8 *g_pSrc = 0; + +// 702012d4 +u8 *g_pDst = 0; + +u32 var702012d8 = 0; +u32 var702012dc = 0; +u8 *var702012e0 = 0; + +// 702012e4 +u8 border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* Tables for deflate from PKZIP's appnote.txt. */ +// 702012f8 +u16 cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + + /* actually lengths - 2; also see note #13 above about 258 */ +// 70201388 +u8 cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 128==invalid */ + +// 70201358 +u16 cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; + +// 70201394 +u8 cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +// 702013b4 +u32 bb = 0; + +// 702013b8 +u32 bk = 0; + +/* And'ing with mask[n] masks the lower n bits */ +// 702013bc +u16 inflate_mask[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +// 702013e0 +u32 lbits = 9; + +// 702013e4 +u32 dbits = 6; + +// 702013e8 +u32 hufts = 0; + +GLOBAL_ASM( +glabel func70200000 +.L70200000: +/* 70200000: 27bdfa18 */ addiu $sp,$sp,-1512 +/* 70200004: afb20010 */ sw $s2,0x10($sp) +/* 70200008: afb00008 */ sw $s0,0x8($sp) +/* 7020000c: 00808025 */ move $s0,$a0 +/* 70200010: 00a09025 */ move $s2,$a1 +/* 70200014: afbf002c */ sw $ra,0x2c($sp) +/* 70200018: afbe0028 */ sw $s8,0x28($sp) +/* 7020001c: afb70024 */ sw $s7,0x24($sp) +/* 70200020: afb60020 */ sw $s6,0x20($sp) +/* 70200024: afb5001c */ sw $s5,0x1c($sp) +/* 70200028: afb40018 */ sw $s4,0x18($sp) +/* 7020002c: afb30014 */ sw $s3,0x14($sp) +/* 70200030: afb1000c */ sw $s1,0xc($sp) +/* 70200034: afa605f0 */ sw $a2,0x5f0($sp) +/* 70200038: afa705f4 */ sw $a3,0x5f4($sp) +/* 7020003c: 27a305a0 */ addiu $v1,$sp,0x5a0 +/* 70200040: 27a205e4 */ addiu $v0,$sp,0x5e4 +.L70200044: +/* 70200044: 24630004 */ addiu $v1,$v1,0x4 +/* 70200048: 1462fffe */ bne $v1,$v0,.L70200044 +/* 7020004c: ac60fffc */ sw $zero,-0x4($v1) +/* 70200050: 0200f825 */ move $ra,$s0 +/* 70200054: 02406825 */ move $t5,$s2 +/* 70200058: 27a405a0 */ addiu $a0,$sp,0x5a0 +.L7020005c: +/* 7020005c: 8fee0000 */ lw $t6,0x0($ra) +/* 70200060: 25adffff */ addiu $t5,$t5,-1 +/* 70200064: 27ff0004 */ addiu $ra,$ra,0x4 +/* 70200068: 000e7880 */ sll $t7,$t6,0x2 +/* 7020006c: 008f1021 */ addu $v0,$a0,$t7 +/* 70200070: 8c580000 */ lw $t8,0x0($v0) +/* 70200074: 27190001 */ addiu $t9,$t8,0x1 +/* 70200078: 15a0fff8 */ bnez $t5,.L7020005c +/* 7020007c: ac590000 */ sw $t9,0x0($v0) +/* 70200080: 8fae05a0 */ lw $t6,0x5a0($sp) +/* 70200084: 8fa50600 */ lw $a1,0x600($sp) +/* 70200088: 24070001 */ li $a3,0x1 +/* 7020008c: 164e0007 */ bne $s2,$t6,.L702000ac +/* 70200090: 27a605a4 */ addiu $a2,$sp,0x5a4 +/* 70200094: 8fb605fc */ lw $s6,0x5fc($sp) +/* 70200098: 8fa50600 */ lw $a1,0x600($sp) +/* 7020009c: 00001025 */ move $v0,$zero +/* 702000a0: aec00000 */ sw $zero,0x0($s6) +/* 702000a4: 10000121 */ b .L7020052c +/* 702000a8: aca00000 */ sw $zero,0x0($a1) +.L702000ac: +/* 702000ac: 8cb10000 */ lw $s1,0x0($a1) +/* 702000b0: 24020011 */ li $v0,0x11 +.L702000b4: +/* 702000b4: 8ccf0000 */ lw $t7,0x0($a2) +/* 702000b8: 55e00005 */ bnezl $t7,.L702000d0 +/* 702000bc: 0227082b */ sltu $at,$s1,$a3 +/* 702000c0: 24e70001 */ addiu $a3,$a3,0x1 +/* 702000c4: 14e2fffb */ bne $a3,$v0,.L702000b4 +/* 702000c8: 24c60004 */ addiu $a2,$a2,0x4 +/* 702000cc: 0227082b */ sltu $at,$s1,$a3 +.L702000d0: +/* 702000d0: 10200002 */ beqz $at,.L702000dc +/* 702000d4: 00e09825 */ move $s3,$a3 +/* 702000d8: 00e08825 */ move $s1,$a3 +.L702000dc: +/* 702000dc: 240d0010 */ li $t5,0x10 +/* 702000e0: 27a205e0 */ addiu $v0,$sp,0x5e0 +.L702000e4: +/* 702000e4: 8c580000 */ lw $t8,0x0($v0) +/* 702000e8: 57000005 */ bnezl $t8,.L70200100 +/* 702000ec: 01b1082b */ sltu $at,$t5,$s1 +/* 702000f0: 25adffff */ addiu $t5,$t5,-1 +/* 702000f4: 15a0fffb */ bnez $t5,.L702000e4 +/* 702000f8: 2442fffc */ addiu $v0,$v0,-4 +/* 702000fc: 01b1082b */ sltu $at,$t5,$s1 +.L70200100: +/* 70200100: 10200002 */ beqz $at,.L7020010c +/* 70200104: afad0598 */ sw $t5,0x598($sp) +/* 70200108: 01a08825 */ move $s1,$t5 +.L7020010c: +/* 7020010c: 24190001 */ li $t9,0x1 +/* 70200110: 00ed082b */ sltu $at,$a3,$t5 +/* 70200114: acb10000 */ sw $s1,0x0($a1) +/* 70200118: 1020000b */ beqz $at,.L70200148 +/* 7020011c: 00f91804 */ sllv $v1,$t9,$a3 +/* 70200120: 000d7080 */ sll $t6,$t5,0x2 +/* 70200124: 27af05a0 */ addiu $t7,$sp,0x5a0 +/* 70200128: 01cf2821 */ addu $a1,$t6,$t7 +.L7020012c: +/* 7020012c: 8cd80000 */ lw $t8,0x0($a2) +/* 70200130: 24c60004 */ addiu $a2,$a2,0x4 +/* 70200134: 00c5082b */ sltu $at,$a2,$a1 +/* 70200138: 00781823 */ subu $v1,$v1,$t8 +/* 7020013c: 0003c840 */ sll $t9,$v1,0x1 +/* 70200140: 1420fffa */ bnez $at,.L7020012c +/* 70200144: 03201825 */ move $v1,$t9 +.L70200148: +/* 70200148: 8c460000 */ lw $a2,0x0($v0) +/* 7020014c: 2442fffc */ addiu $v0,$v0,-4 +/* 70200150: 27af05a0 */ addiu $t7,$sp,0x5a0 +/* 70200154: 00661823 */ subu $v1,$v1,$a2 +/* 70200158: 00c37021 */ addu $t6,$a2,$v1 +/* 7020015c: ac4e0004 */ sw $t6,0x4($v0) +/* 70200160: afa00070 */ sw $zero,0x70($sp) +/* 70200164: 00003825 */ move $a3,$zero +/* 70200168: 27bf05a4 */ addiu $ra,$sp,0x5a4 +/* 7020016c: 104f0009 */ beq $v0,$t7,.L70200194 +/* 70200170: 27a50074 */ addiu $a1,$sp,0x74 +/* 70200174: 27a605a0 */ addiu $a2,$sp,0x5a0 +.L70200178: +/* 70200178: 8ff80000 */ lw $t8,0x0($ra) +/* 7020017c: 2442fffc */ addiu $v0,$v0,-4 +/* 70200180: 24a50004 */ addiu $a1,$a1,0x4 +/* 70200184: 00f83821 */ addu $a3,$a3,$t8 +/* 70200188: aca7fffc */ sw $a3,-0x4($a1) +/* 7020018c: 1446fffa */ bne $v0,$a2,.L70200178 +/* 70200190: 27ff0004 */ addiu $ra,$ra,0x4 +.L70200194: +/* 70200194: 0200f825 */ move $ra,$s0 +/* 70200198: 00006825 */ move $t5,$zero +/* 7020019c: afb205ec */ sw $s2,0x5ec($sp) +/* 702001a0: 02404825 */ move $t1,$s2 +/* 702001a4: 27a8006c */ addiu $t0,$sp,0x6c +/* 702001a8: 27a600b4 */ addiu $a2,$sp,0xb4 +/* 702001ac: 8fe70000 */ lw $a3,0x0($ra) +.L702001b0: +/* 702001b0: 27ff0004 */ addiu $ra,$ra,0x4 +/* 702001b4: 10e00008 */ beqz $a3,.L702001d8 +/* 702001b8: 0007c880 */ sll $t9,$a3,0x2 +/* 702001bc: 01191021 */ addu $v0,$t0,$t9 +/* 702001c0: 8c450000 */ lw $a1,0x0($v0) +/* 702001c4: 00057080 */ sll $t6,$a1,0x2 +/* 702001c8: 00ce7821 */ addu $t7,$a2,$t6 +/* 702001cc: aded0000 */ sw $t5,0x0($t7) +/* 702001d0: 24b80001 */ addiu $t8,$a1,0x1 +/* 702001d4: ac580000 */ sw $t8,0x0($v0) +.L702001d8: +/* 702001d8: 25ad0001 */ addiu $t5,$t5,0x1 +/* 702001dc: 01a9082b */ sltu $at,$t5,$t1 +/* 702001e0: 5420fff3 */ bnezl $at,.L702001b0 +/* 702001e4: 8fe70000 */ lw $a3,0x0($ra) +/* 702001e8: 8fb90598 */ lw $t9,0x598($sp) +/* 702001ec: afa30064 */ sw $v1,0x64($sp) +/* 702001f0: 00006825 */ move $t5,$zero +/* 702001f4: 0333082a */ slt $at,$t9,$s3 +/* 702001f8: afa0006c */ sw $zero,0x6c($sp) +/* 702001fc: 00c0f825 */ move $ra,$a2 +/* 70200200: 240cffff */ li $t4,-1 +/* 70200204: 00115023 */ negu $t2,$s1 +/* 70200208: afa00534 */ sw $zero,0x534($sp) +/* 7020020c: 00002825 */ move $a1,$zero +/* 70200210: 142000bf */ bnez $at,.L70200510 +/* 70200214: 00004025 */ move $t0,$zero +/* 70200218: 00137080 */ sll $t6,$s3,0x2 +/* 7020021c: 27af05a0 */ addiu $t7,$sp,0x5a0 +/* 70200220: 01cfc021 */ addu $t8,$t6,$t7 +/* 70200224: 3c1e7020 */ lui $s8,0x7020 +/* 70200228: 3c147020 */ lui $s4,0x7020 +/* 7020022c: 269413e8 */ addiu $s4,$s4,0x13e8 +/* 70200230: 27de12e0 */ addiu $s8,$s8,0x12e0 +/* 70200234: afb80050 */ sw $t8,0x50($sp) +/* 70200238: 8fb605fc */ lw $s6,0x5fc($sp) +/* 7020023c: 27b50574 */ addiu $s5,$sp,0x574 +.L70200240: +/* 70200240: 8fb90050 */ lw $t9,0x50($sp) +/* 70200244: 8faf05ec */ lw $t7,0x5ec($sp) +/* 70200248: 000c8080 */ sll $s0,$t4,0x2 +/* 7020024c: 8f370000 */ lw $s7,0x0($t9) +/* 70200250: 27ae006c */ addiu $t6,$sp,0x6c +/* 70200254: 000fc080 */ sll $t8,$t7,0x2 +/* 70200258: 02e03025 */ move $a2,$s7 +/* 7020025c: 12e000a4 */ beqz $s7,.L702004f0 +/* 70200260: 26f7ffff */ addiu $s7,$s7,-1 +/* 70200264: 020e5821 */ addu $t3,$s0,$t6 +/* 70200268: 27b900b4 */ addiu $t9,$sp,0xb4 +/* 7020026c: 03197021 */ addu $t6,$t8,$t9 +/* 70200270: 24180001 */ li $t8,0x1 +/* 70200274: 266f001f */ addiu $t7,$s3,0x1f +/* 70200278: 01f8c804 */ sllv $t9,$t8,$t7 +/* 7020027c: afb90034 */ sw $t9,0x34($sp) +/* 70200280: afae0038 */ sw $t6,0x38($sp) +.L70200284: +/* 70200284: 01511821 */ addu $v1,$t2,$s1 +/* 70200288: 0073082a */ slt $at,$v1,$s3 +/* 7020028c: 10200047 */ beqz $at,.L702003ac +/* 70200290: 26f20001 */ addiu $s2,$s7,0x1 +/* 70200294: 27ae0534 */ addiu $t6,$sp,0x534 +/* 70200298: 020e4821 */ addu $t1,$s0,$t6 +/* 7020029c: 8fb80598 */ lw $t8,0x598($sp) +.L702002a0: +/* 702002a0: 258c0001 */ addiu $t4,$t4,0x1 +/* 702002a4: 26100004 */ addiu $s0,$s0,0x4 +/* 702002a8: 03034023 */ subu $t0,$t8,$v1 +/* 702002ac: 0228082b */ sltu $at,$s1,$t0 +/* 702002b0: 25290004 */ addiu $t1,$t1,0x4 +/* 702002b4: 256b0004 */ addiu $t3,$t3,0x4 +/* 702002b8: 10200002 */ beqz $at,.L702002c4 +/* 702002bc: 00605025 */ move $t2,$v1 +/* 702002c0: 02204025 */ move $t0,$s1 +.L702002c4: +/* 702002c4: 026a1023 */ subu $v0,$s3,$t2 +/* 702002c8: 240f0001 */ li $t7,0x1 +/* 702002cc: 004f2004 */ sllv $a0,$t7,$v0 +/* 702002d0: 0244082b */ sltu $at,$s2,$a0 +/* 702002d4: 10200013 */ beqz $at,.L70200324 +/* 702002d8: 00403825 */ move $a3,$v0 +/* 702002dc: 24470001 */ addiu $a3,$v0,0x1 +/* 702002e0: 00971823 */ subu $v1,$a0,$s7 +/* 702002e4: 0013c880 */ sll $t9,$s3,0x2 +/* 702002e8: 27ae05a0 */ addiu $t6,$sp,0x5a0 +/* 702002ec: 00e8082b */ sltu $at,$a3,$t0 +/* 702002f0: 2463ffff */ addiu $v1,$v1,-1 +/* 702002f4: 1020000b */ beqz $at,.L70200324 +/* 702002f8: 032e2821 */ addu $a1,$t9,$t6 +.L702002fc: +/* 702002fc: 8ca40004 */ lw $a0,0x4($a1) +/* 70200300: 00031040 */ sll $v0,$v1,0x1 +/* 70200304: 24a50004 */ addiu $a1,$a1,0x4 +/* 70200308: 0082082b */ sltu $at,$a0,$v0 +/* 7020030c: 50200006 */ beqzl $at,.L70200328 +/* 70200310: 8e830000 */ lw $v1,0x0($s4) +/* 70200314: 24e70001 */ addiu $a3,$a3,0x1 +/* 70200318: 00e8082b */ sltu $at,$a3,$t0 +/* 7020031c: 1420fff7 */ bnez $at,.L702002fc +/* 70200320: 00441823 */ subu $v1,$v0,$a0 +.L70200324: +/* 70200324: 8e830000 */ lw $v1,0x0($s4) +.L70200328: +/* 70200328: 8fd90000 */ lw $t9,0x0($s8) +/* 7020032c: 24180001 */ li $t8,0x1 +/* 70200330: 00f84004 */ sllv $t0,$t8,$a3 +/* 70200334: 000378c0 */ sll $t7,$v1,0x3 +/* 70200338: 00687021 */ addu $t6,$v1,$t0 +/* 7020033c: 25d80001 */ addiu $t8,$t6,0x1 +/* 70200340: 01f92821 */ addu $a1,$t7,$t9 +/* 70200344: ae980000 */ sw $t8,0x0($s4) +/* 70200348: 24a40008 */ addiu $a0,$a1,0x8 +/* 7020034c: aec40000 */ sw $a0,0x0($s6) +/* 70200350: aca00004 */ sw $zero,0x4($a1) +/* 70200354: 24b60004 */ addiu $s6,$a1,0x4 +/* 70200358: 00802825 */ move $a1,$a0 +/* 7020035c: 1180000f */ beqz $t4,.L7020039c +/* 70200360: ad240000 */ sw $a0,0x0($t1) +/* 70200364: ad6d0000 */ sw $t5,0x0($t3) +/* 70200368: 24ef0010 */ addiu $t7,$a3,0x10 +/* 7020036c: a3b10575 */ sb $s1,0x575($sp) +/* 70200370: a3af0574 */ sb $t7,0x574($sp) +/* 70200374: afa40578 */ sw $a0,0x578($sp) +/* 70200378: 8d39fffc */ lw $t9,-0x4($t1) +/* 7020037c: 01517023 */ subu $t6,$t2,$s1 +/* 70200380: 8ea10000 */ lw $at,0x0($s5) +/* 70200384: 01cdc006 */ srlv $t8,$t5,$t6 +/* 70200388: 001878c0 */ sll $t7,$t8,0x3 +/* 7020038c: 032f7021 */ addu $t6,$t9,$t7 +/* 70200390: adc10000 */ sw $at,0x0($t6) +/* 70200394: 8eaf0004 */ lw $t7,0x4($s5) +/* 70200398: adcf0004 */ sw $t7,0x4($t6) +.L7020039c: +/* 7020039c: 01511821 */ addu $v1,$t2,$s1 +/* 702003a0: 0073082a */ slt $at,$v1,$s3 +/* 702003a4: 5420ffbe */ bnezl $at,.L702002a0 +/* 702003a8: 8fb80598 */ lw $t8,0x598($sp) +.L702003ac: +/* 702003ac: 8fb80038 */ lw $t8,0x38($sp) +/* 702003b0: 24190001 */ li $t9,0x1 +/* 702003b4: 026a1823 */ subu $v1,$s3,$t2 +/* 702003b8: 01593004 */ sllv $a2,$t9,$t2 +/* 702003bc: 03f8082b */ sltu $at,$ra,$t8 +/* 702003c0: a3a30575 */ sb $v1,0x575($sp) +/* 702003c4: 14200004 */ bnez $at,.L702003d8 +/* 702003c8: 24c6ffff */ addiu $a2,$a2,-1 +/* 702003cc: 240e0063 */ li $t6,0x63 +/* 702003d0: 10000020 */ b .L70200454 +/* 702003d4: a3ae0574 */ sb $t6,0x574($sp) +.L702003d8: +/* 702003d8: 8fe20000 */ lw $v0,0x0($ra) +/* 702003dc: 8faf05f0 */ lw $t7,0x5f0($sp) +/* 702003e0: 8fa405f0 */ lw $a0,0x5f0($sp) +/* 702003e4: 8fb905f8 */ lw $t9,0x5f8($sp) +/* 702003e8: 004f082b */ sltu $at,$v0,$t7 +/* 702003ec: 1020000b */ beqz $at,.L7020041c +/* 702003f0: 2c410100 */ sltiu $at,$v0,0x100 +/* 702003f4: 10200004 */ beqz $at,.L70200408 +/* 702003f8: 2418000f */ li $t8,0xf +/* 702003fc: 24190010 */ li $t9,0x10 +/* 70200400: 10000002 */ b .L7020040c +/* 70200404: a3b90574 */ sb $t9,0x574($sp) +.L70200408: +/* 70200408: a3b80574 */ sb $t8,0x574($sp) +.L7020040c: +/* 7020040c: 8fee0000 */ lw $t6,0x0($ra) +/* 70200410: 27ff0004 */ addiu $ra,$ra,0x4 +/* 70200414: 1000000f */ b .L70200454 +/* 70200418: a7ae0578 */ sh $t6,0x578($sp) +.L7020041c: +/* 7020041c: 00447823 */ subu $t7,$v0,$a0 +/* 70200420: 01f9c021 */ addu $t8,$t7,$t9 +/* 70200424: 930e0000 */ lbu $t6,0x0($t8) +/* 70200428: 8faf05f4 */ lw $t7,0x5f4($sp) +/* 7020042c: 27ff0004 */ addiu $ra,$ra,0x4 +/* 70200430: a3ae0574 */ sb $t6,0x574($sp) +/* 70200434: 8ff9fffc */ lw $t9,-0x4($ra) +/* 70200438: 0019c040 */ sll $t8,$t9,0x1 +/* 7020043c: 0004c840 */ sll $t9,$a0,0x1 +/* 70200440: 01f87021 */ addu $t6,$t7,$t8 +/* 70200444: 00197823 */ negu $t7,$t9 +/* 70200448: 01cfc021 */ addu $t8,$t6,$t7 +/* 7020044c: 97190000 */ lhu $t9,0x0($t8) +/* 70200450: a7b90578 */ sh $t9,0x578($sp) +.L70200454: +/* 70200454: 014d3806 */ srlv $a3,$t5,$t2 +/* 70200458: 00e8082b */ sltu $at,$a3,$t0 +/* 7020045c: 1020000b */ beqz $at,.L7020048c +/* 70200460: 240e0001 */ li $t6,0x1 +/* 70200464: 006e1004 */ sllv $v0,$t6,$v1 +.L70200468: +/* 70200468: 8ea10000 */ lw $at,0x0($s5) +/* 7020046c: 000778c0 */ sll $t7,$a3,0x3 +/* 70200470: 00afc021 */ addu $t8,$a1,$t7 +/* 70200474: af010000 */ sw $at,0x0($t8) +/* 70200478: 8eae0004 */ lw $t6,0x4($s5) +/* 7020047c: 00e23821 */ addu $a3,$a3,$v0 +/* 70200480: 00e8082b */ sltu $at,$a3,$t0 +/* 70200484: 1420fff8 */ bnez $at,.L70200468 +/* 70200488: af0e0004 */ sw $t6,0x4($t8) +.L7020048c: +/* 7020048c: 8fa70034 */ lw $a3,0x34($sp) +/* 70200490: 8d620000 */ lw $v0,0x0($t3) +/* 70200494: 01a77824 */ and $t7,$t5,$a3 +/* 70200498: 11e00005 */ beqz $t7,.L702004b0 +.L7020049c: +/* 7020049c: 0007c842 */ srl $t9,$a3,0x1 +/* 702004a0: 01a76826 */ xor $t5,$t5,$a3 +/* 702004a4: 01b9c024 */ and $t8,$t5,$t9 +/* 702004a8: 1700fffc */ bnez $t8,.L7020049c +/* 702004ac: 03203825 */ move $a3,$t9 +.L702004b0: +/* 702004b0: 01a76826 */ xor $t5,$t5,$a3 +/* 702004b4: 01a67024 */ and $t6,$t5,$a2 +/* 702004b8: 11c2000b */ beq $t6,$v0,.L702004e8 +/* 702004bc: 02e03025 */ move $a2,$s7 +.L702004c0: +/* 702004c0: 01515023 */ subu $t2,$t2,$s1 +/* 702004c4: 240f0001 */ li $t7,0x1 +/* 702004c8: 014fc804 */ sllv $t9,$t7,$t2 +/* 702004cc: 8d6ffffc */ lw $t7,-0x4($t3) +/* 702004d0: 2738ffff */ addiu $t8,$t9,-1 +/* 702004d4: 01b87024 */ and $t6,$t5,$t8 +/* 702004d8: 258cffff */ addiu $t4,$t4,-1 +/* 702004dc: 2610fffc */ addiu $s0,$s0,-4 +/* 702004e0: 15cffff7 */ bne $t6,$t7,.L702004c0 +/* 702004e4: 256bfffc */ addiu $t3,$t3,-4 +.L702004e8: +/* 702004e8: 16e0ff66 */ bnez $s7,.L70200284 +/* 702004ec: 26f7ffff */ addiu $s7,$s7,-1 +.L702004f0: +/* 702004f0: 8fb90050 */ lw $t9,0x50($sp) +/* 702004f4: 8fae0598 */ lw $t6,0x598($sp) +/* 702004f8: 26730001 */ addiu $s3,$s3,0x1 +/* 702004fc: 27380004 */ addiu $t8,$t9,0x4 +/* 70200500: 01d3082a */ slt $at,$t6,$s3 +/* 70200504: 1020ff4e */ beqz $at,.L70200240 +/* 70200508: afb80050 */ sw $t8,0x50($sp) +/* 7020050c: afb605fc */ sw $s6,0x5fc($sp) +.L70200510: +/* 70200510: 8fa20064 */ lw $v0,0x64($sp) +/* 70200514: 0002782b */ sltu $t7,$zero,$v0 +/* 70200518: 11e00004 */ beqz $t7,.L7020052c +/* 7020051c: 01e01025 */ move $v0,$t7 +/* 70200520: 8fa20598 */ lw $v0,0x598($sp) +/* 70200524: 38590001 */ xori $t9,$v0,0x1 +/* 70200528: 0019102b */ sltu $v0,$zero,$t9 +.L7020052c: +/* 7020052c: 8fbf002c */ lw $ra,0x2c($sp) +/* 70200530: 8fb00008 */ lw $s0,0x8($sp) +/* 70200534: 8fb1000c */ lw $s1,0xc($sp) +/* 70200538: 8fb20010 */ lw $s2,0x10($sp) +/* 7020053c: 8fb30014 */ lw $s3,0x14($sp) +/* 70200540: 8fb40018 */ lw $s4,0x18($sp) +/* 70200544: 8fb5001c */ lw $s5,0x1c($sp) +/* 70200548: 8fb60020 */ lw $s6,0x20($sp) +/* 7020054c: 8fb70024 */ lw $s7,0x24($sp) +/* 70200550: 8fbe0028 */ lw $s8,0x28($sp) +/* 70200554: 03e00008 */ jr $ra +/* 70200558: 27bd05e8 */ addiu $sp,$sp,0x5e8 +); + +GLOBAL_ASM( +glabel func7020055c +/* 7020055c: 27bdfff0 */ addiu $sp,$sp,-16 +/* 70200560: 3c0a7020 */ lui $t2,0x7020 +/* 70200564: 254a13bc */ addiu $t2,$t2,0x13bc +/* 70200568: afb00004 */ sw $s0,0x4($sp) +/* 7020056c: 00067040 */ sll $t6,$a2,0x1 +/* 70200570: 00c08025 */ move $s0,$a2 +/* 70200574: afa40010 */ sw $a0,0x10($sp) +/* 70200578: 0007c040 */ sll $t8,$a3,0x1 +/* 7020057c: afb10008 */ sw $s1,0x8($sp) +/* 70200580: 3c087020 */ lui $t0,0x7020 +/* 70200584: 3c037020 */ lui $v1,0x7020 +/* 70200588: 3c097020 */ lui $t1,0x7020 +/* 7020058c: 014e7821 */ addu $t7,$t2,$t6 +/* 70200590: 0158c821 */ addu $t9,$t2,$t8 +/* 70200594: 3c047020 */ lui $a0,0x7020 +/* 70200598: 3c067020 */ lui $a2,0x7020 +/* 7020059c: 00e08825 */ move $s1,$a3 +/* 702005a0: afb2000c */ sw $s2,0xc($sp) +/* 702005a4: afa50014 */ sw $a1,0x14($sp) +/* 702005a8: 8d0813b4 */ lw $t0,0x13b4($t0) +/* 702005ac: 8c6313b8 */ lw $v1,0x13b8($v1) +/* 702005b0: 8d2912dc */ lw $t1,0x12dc($t1) +/* 702005b4: 95eb0000 */ lhu $t3,0x0($t7) +/* 702005b8: 972c0000 */ lhu $t4,0x0($t9) +/* 702005bc: 24c612d4 */ addiu $a2,$a2,0x12d4 +/* 702005c0: 248412d8 */ addiu $a0,$a0,0x12d8 +.L702005c4: +/* 702005c4: 0070082b */ sltu $at,$v1,$s0 +.L702005c8: +/* 702005c8: 1020000c */ beqz $at,.L702005fc +/* 702005cc: 3c127020 */ lui $s2,0x7020 +/* 702005d0: 8e5212d0 */ lw $s2,0x12d0($s2) +.L702005d4: +/* 702005d4: 8c8d0000 */ lw $t5,0x0($a0) +/* 702005d8: 024d7021 */ addu $t6,$s2,$t5 +/* 702005dc: 91cf0000 */ lbu $t7,0x0($t6) +/* 702005e0: 25b90001 */ addiu $t9,$t5,0x1 +/* 702005e4: ac990000 */ sw $t9,0x0($a0) +/* 702005e8: 006fc004 */ sllv $t8,$t7,$v1 +/* 702005ec: 24630008 */ addiu $v1,$v1,0x8 +/* 702005f0: 0070082b */ sltu $at,$v1,$s0 +/* 702005f4: 1420fff7 */ bnez $at,.L702005d4 +/* 702005f8: 01184025 */ or $t0,$t0,$t8 +.L702005fc: +/* 702005fc: 8fb80010 */ lw $t8,0x10($sp) +/* 70200600: 010b7024 */ and $t6,$t0,$t3 +/* 70200604: 000e78c0 */ sll $t7,$t6,0x3 +/* 70200608: 01f82821 */ addu $a1,$t7,$t8 +/* 7020060c: 90a20000 */ lbu $v0,0x0($a1) +/* 70200610: 2c410011 */ sltiu $at,$v0,0x11 +/* 70200614: 5420001f */ bnezl $at,.L70200694 +/* 70200618: 90ad0001 */ lbu $t5,0x1($a1) +/* 7020061c: 90ad0001 */ lbu $t5,0x1($a1) +.L70200620: +/* 70200620: 2442fff0 */ addiu $v0,$v0,-16 +/* 70200624: 3c127020 */ lui $s2,0x7020 +/* 70200628: 006d1823 */ subu $v1,$v1,$t5 +/* 7020062c: 0062082b */ sltu $at,$v1,$v0 +/* 70200630: 1020000c */ beqz $at,.L70200664 +/* 70200634: 01a84006 */ srlv $t0,$t0,$t5 +/* 70200638: 8e5212d0 */ lw $s2,0x12d0($s2) +.L7020063c: +/* 7020063c: 8c8d0000 */ lw $t5,0x0($a0) +/* 70200640: 024dc821 */ addu $t9,$s2,$t5 +/* 70200644: 932e0000 */ lbu $t6,0x0($t9) +/* 70200648: 25b80001 */ addiu $t8,$t5,0x1 +/* 7020064c: ac980000 */ sw $t8,0x0($a0) +/* 70200650: 006e7804 */ sllv $t7,$t6,$v1 +/* 70200654: 24630008 */ addiu $v1,$v1,0x8 +/* 70200658: 0062082b */ sltu $at,$v1,$v0 +/* 7020065c: 1420fff7 */ bnez $at,.L7020063c +/* 70200660: 010f4025 */ or $t0,$t0,$t7 +.L70200664: +/* 70200664: 0002c840 */ sll $t9,$v0,0x1 +/* 70200668: 01597021 */ addu $t6,$t2,$t9 +/* 7020066c: 95cf0000 */ lhu $t7,0x0($t6) +/* 70200670: 8cae0004 */ lw $t6,0x4($a1) +/* 70200674: 01e8c024 */ and $t8,$t7,$t0 +/* 70200678: 0018c8c0 */ sll $t9,$t8,0x3 +/* 7020067c: 032e2821 */ addu $a1,$t9,$t6 +/* 70200680: 90a20000 */ lbu $v0,0x0($a1) +/* 70200684: 2c410011 */ sltiu $at,$v0,0x11 +/* 70200688: 5020ffe5 */ beqzl $at,.L70200620 +/* 7020068c: 90ad0001 */ lbu $t5,0x1($a1) +/* 70200690: 90ad0001 */ lbu $t5,0x1($a1) +.L70200694: +/* 70200694: 24010010 */ li $at,0x10 +/* 70200698: 3c127020 */ lui $s2,0x7020 +/* 7020069c: 01a84006 */ srlv $t0,$t0,$t5 +/* 702006a0: 14410007 */ bne $v0,$at,.L702006c0 +/* 702006a4: 006d1823 */ subu $v1,$v1,$t5 +/* 702006a8: 8cd80000 */ lw $t8,0x0($a2) +/* 702006ac: 94af0004 */ lhu $t7,0x4($a1) +/* 702006b0: 0309c821 */ addu $t9,$t8,$t1 +/* 702006b4: 25290001 */ addiu $t1,$t1,0x1 +/* 702006b8: 1000ffc2 */ b .L702005c4 +/* 702006bc: a32f0000 */ sb $t7,0x0($t9) +.L702006c0: +/* 702006c0: 2401000f */ li $at,0xf +/* 702006c4: 10410072 */ beq $v0,$at,.L70200890 +/* 702006c8: 0062082b */ sltu $at,$v1,$v0 +/* 702006cc: 5020000d */ beqzl $at,.L70200704 +/* 702006d0: 00027040 */ sll $t6,$v0,0x1 +/* 702006d4: 8e5212d0 */ lw $s2,0x12d0($s2) +.L702006d8: +/* 702006d8: 8c8d0000 */ lw $t5,0x0($a0) +/* 702006dc: 024d7021 */ addu $t6,$s2,$t5 +/* 702006e0: 91d80000 */ lbu $t8,0x0($t6) +/* 702006e4: 25b90001 */ addiu $t9,$t5,0x1 +/* 702006e8: ac990000 */ sw $t9,0x0($a0) +/* 702006ec: 00787804 */ sllv $t7,$t8,$v1 +/* 702006f0: 24630008 */ addiu $v1,$v1,0x8 +/* 702006f4: 0062082b */ sltu $at,$v1,$v0 +/* 702006f8: 1420fff7 */ bnez $at,.L702006d8 +/* 702006fc: 010f4025 */ or $t0,$t0,$t7 +/* 70200700: 00027040 */ sll $t6,$v0,0x1 +.L70200704: +/* 70200704: 014ec021 */ addu $t8,$t2,$t6 +/* 70200708: 970f0000 */ lhu $t7,0x0($t8) +/* 7020070c: 94ae0004 */ lhu $t6,0x4($a1) +/* 70200710: 00621823 */ subu $v1,$v1,$v0 +/* 70200714: 0071082b */ sltu $at,$v1,$s1 +/* 70200718: 01e8c824 */ and $t9,$t7,$t0 +/* 7020071c: 00484006 */ srlv $t0,$t0,$v0 +/* 70200720: 1020000d */ beqz $at,.L70200758 +/* 70200724: 032e3821 */ addu $a3,$t9,$t6 +/* 70200728: 3c127020 */ lui $s2,0x7020 +/* 7020072c: 8e5212d0 */ lw $s2,0x12d0($s2) +.L70200730: +/* 70200730: 8c8d0000 */ lw $t5,0x0($a0) +/* 70200734: 024dc021 */ addu $t8,$s2,$t5 +/* 70200738: 930f0000 */ lbu $t7,0x0($t8) +/* 7020073c: 25ae0001 */ addiu $t6,$t5,0x1 +/* 70200740: ac8e0000 */ sw $t6,0x0($a0) +/* 70200744: 006fc804 */ sllv $t9,$t7,$v1 +/* 70200748: 24630008 */ addiu $v1,$v1,0x8 +/* 7020074c: 0071082b */ sltu $at,$v1,$s1 +/* 70200750: 1420fff7 */ bnez $at,.L70200730 +/* 70200754: 01194025 */ or $t0,$t0,$t9 +.L70200758: +/* 70200758: 8fb90014 */ lw $t9,0x14($sp) +/* 7020075c: 010cc024 */ and $t8,$t0,$t4 +/* 70200760: 001878c0 */ sll $t7,$t8,0x3 +/* 70200764: 01f92821 */ addu $a1,$t7,$t9 +/* 70200768: 90a20000 */ lbu $v0,0x0($a1) +/* 7020076c: 2c410011 */ sltiu $at,$v0,0x11 +/* 70200770: 5420001f */ bnezl $at,.L702007f0 +/* 70200774: 90ad0001 */ lbu $t5,0x1($a1) +/* 70200778: 90ad0001 */ lbu $t5,0x1($a1) +.L7020077c: +/* 7020077c: 2442fff0 */ addiu $v0,$v0,-16 +/* 70200780: 3c127020 */ lui $s2,0x7020 +/* 70200784: 006d1823 */ subu $v1,$v1,$t5 +/* 70200788: 0062082b */ sltu $at,$v1,$v0 +/* 7020078c: 1020000c */ beqz $at,.L702007c0 +/* 70200790: 01a84006 */ srlv $t0,$t0,$t5 +/* 70200794: 8e5212d0 */ lw $s2,0x12d0($s2) +.L70200798: +/* 70200798: 8c8d0000 */ lw $t5,0x0($a0) +/* 7020079c: 024d7021 */ addu $t6,$s2,$t5 +/* 702007a0: 91d80000 */ lbu $t8,0x0($t6) +/* 702007a4: 25b90001 */ addiu $t9,$t5,0x1 +/* 702007a8: ac990000 */ sw $t9,0x0($a0) +/* 702007ac: 00787804 */ sllv $t7,$t8,$v1 +/* 702007b0: 24630008 */ addiu $v1,$v1,0x8 +/* 702007b4: 0062082b */ sltu $at,$v1,$v0 +/* 702007b8: 1420fff7 */ bnez $at,.L70200798 +/* 702007bc: 010f4025 */ or $t0,$t0,$t7 +.L702007c0: +/* 702007c0: 00027040 */ sll $t6,$v0,0x1 +/* 702007c4: 014ec021 */ addu $t8,$t2,$t6 +/* 702007c8: 970f0000 */ lhu $t7,0x0($t8) +/* 702007cc: 8cb80004 */ lw $t8,0x4($a1) +/* 702007d0: 01e8c824 */ and $t9,$t7,$t0 +/* 702007d4: 001970c0 */ sll $t6,$t9,0x3 +/* 702007d8: 01d82821 */ addu $a1,$t6,$t8 +/* 702007dc: 90a20000 */ lbu $v0,0x0($a1) +/* 702007e0: 2c410011 */ sltiu $at,$v0,0x11 +/* 702007e4: 5020ffe5 */ beqzl $at,.L7020077c +/* 702007e8: 90ad0001 */ lbu $t5,0x1($a1) +/* 702007ec: 90ad0001 */ lbu $t5,0x1($a1) +.L702007f0: +/* 702007f0: 3c127020 */ lui $s2,0x7020 +/* 702007f4: 006d1823 */ subu $v1,$v1,$t5 +/* 702007f8: 0062082b */ sltu $at,$v1,$v0 +/* 702007fc: 1020000c */ beqz $at,.L70200830 +/* 70200800: 01a84006 */ srlv $t0,$t0,$t5 +/* 70200804: 8e5212d0 */ lw $s2,0x12d0($s2) +.L70200808: +/* 70200808: 8c8d0000 */ lw $t5,0x0($a0) +/* 7020080c: 024d7821 */ addu $t7,$s2,$t5 +/* 70200810: 91f90000 */ lbu $t9,0x0($t7) +/* 70200814: 25b80001 */ addiu $t8,$t5,0x1 +/* 70200818: ac980000 */ sw $t8,0x0($a0) +/* 7020081c: 00797004 */ sllv $t6,$t9,$v1 +/* 70200820: 24630008 */ addiu $v1,$v1,0x8 +/* 70200824: 0062082b */ sltu $at,$v1,$v0 +/* 70200828: 1420fff7 */ bnez $at,.L70200808 +/* 7020082c: 010e4025 */ or $t0,$t0,$t6 +.L70200830: +/* 70200830: 94af0004 */ lhu $t7,0x4($a1) +/* 70200834: 00027040 */ sll $t6,$v0,0x1 +/* 70200838: 014ec021 */ addu $t8,$t2,$t6 +/* 7020083c: 012fc823 */ subu $t9,$t1,$t7 +/* 70200840: 970f0000 */ lhu $t7,0x0($t8) +/* 70200844: 00621823 */ subu $v1,$v1,$v0 +/* 70200848: 01e87024 */ and $t6,$t7,$t0 +/* 7020084c: 032e6823 */ subu $t5,$t9,$t6 +/* 70200850: 00484006 */ srlv $t0,$t0,$v0 +/* 70200854: 00e01025 */ move $v0,$a3 +.L70200858: +/* 70200858: 00003825 */ move $a3,$zero +.L7020085c: +/* 7020085c: 8cc50000 */ lw $a1,0x0($a2) +/* 70200860: 2442ffff */ addiu $v0,$v0,-1 +/* 70200864: 01a5c021 */ addu $t8,$t5,$a1 +/* 70200868: 930f0000 */ lbu $t7,0x0($t8) +/* 7020086c: 00a9c821 */ addu $t9,$a1,$t1 +/* 70200870: 25290001 */ addiu $t1,$t1,0x1 +/* 70200874: 25ad0001 */ addiu $t5,$t5,0x1 +/* 70200878: 1440fff8 */ bnez $v0,.L7020085c +/* 7020087c: a32f0000 */ sb $t7,0x0($t9) +/* 70200880: 54e0fff5 */ bnezl $a3,.L70200858 +/* 70200884: 00e01025 */ move $v0,$a3 +/* 70200888: 1000ff4f */ b .L702005c8 +/* 7020088c: 0070082b */ sltu $at,$v1,$s0 +.L70200890: +/* 70200890: 3c017020 */ lui $at,0x7020 +/* 70200894: ac2912dc */ sw $t1,0x12dc($at) +/* 70200898: 3c017020 */ lui $at,0x7020 +/* 7020089c: ac2813b4 */ sw $t0,0x13b4($at) +/* 702008a0: 3c017020 */ lui $at,0x7020 +/* 702008a4: 8fb00004 */ lw $s0,0x4($sp) +/* 702008a8: 8fb10008 */ lw $s1,0x8($sp) +/* 702008ac: 8fb2000c */ lw $s2,0xc($sp) +/* 702008b0: ac2313b8 */ sw $v1,0x13b8($at) +/* 702008b4: 27bd0010 */ addiu $sp,$sp,0x10 +/* 702008b8: 03e00008 */ jr $ra +/* 702008bc: 00001025 */ move $v0,$zero +); + +GLOBAL_ASM( +glabel func702008c0 +/* 702008c0: 3c097020 */ lui $t1,0x7020 +/* 702008c4: 252913b8 */ addiu $t1,$t1,0x13b8 +/* 702008c8: 8d240000 */ lw $a0,0x0($t1) +/* 702008cc: 3c087020 */ lui $t0,0x7020 +/* 702008d0: 250813b4 */ addiu $t0,$t0,0x13b4 +/* 702008d4: 30820007 */ andi $v0,$a0,0x7 +/* 702008d8: 8d030000 */ lw $v1,0x0($t0) +/* 702008dc: 3c0a7020 */ lui $t2,0x7020 +/* 702008e0: 00822023 */ subu $a0,$a0,$v0 +/* 702008e4: 254a12dc */ addiu $t2,$t2,0x12dc +/* 702008e8: 2c810010 */ sltiu $at,$a0,0x10 +/* 702008ec: 8d450000 */ lw $a1,0x0($t2) +/* 702008f0: 1020000f */ beqz $at,.L70200930 +/* 702008f4: 00431806 */ srlv $v1,$v1,$v0 +/* 702008f8: 3c067020 */ lui $a2,0x7020 +/* 702008fc: 3c0b7020 */ lui $t3,0x7020 +/* 70200900: 256b12d8 */ addiu $t3,$t3,0x12d8 +/* 70200904: 8cc612d0 */ lw $a2,0x12d0($a2) +.L70200908: +/* 70200908: 8d670000 */ lw $a3,0x0($t3) +/* 7020090c: 00c77021 */ addu $t6,$a2,$a3 +/* 70200910: 91cf0000 */ lbu $t7,0x0($t6) +/* 70200914: 24f90001 */ addiu $t9,$a3,0x1 +/* 70200918: ad790000 */ sw $t9,0x0($t3) +/* 7020091c: 008fc004 */ sllv $t8,$t7,$a0 +/* 70200920: 24840008 */ addiu $a0,$a0,0x8 +/* 70200924: 2c810010 */ sltiu $at,$a0,0x10 +/* 70200928: 1420fff7 */ bnez $at,.L70200908 +/* 7020092c: 00781825 */ or $v1,$v1,$t8 +.L70200930: +/* 70200930: 2484fff0 */ addiu $a0,$a0,-16 +/* 70200934: 3c0b7020 */ lui $t3,0x7020 +/* 70200938: 3062ffff */ andi $v0,$v1,0xffff +/* 7020093c: 00036c02 */ srl $t5,$v1,0x10 +/* 70200940: 2c810010 */ sltiu $at,$a0,0x10 +/* 70200944: 256b12d8 */ addiu $t3,$t3,0x12d8 +/* 70200948: 1020000d */ beqz $at,.L70200980 +/* 7020094c: 01a01825 */ move $v1,$t5 +/* 70200950: 3c067020 */ lui $a2,0x7020 +/* 70200954: 8cc612d0 */ lw $a2,0x12d0($a2) +.L70200958: +/* 70200958: 8d670000 */ lw $a3,0x0($t3) +/* 7020095c: 00c77021 */ addu $t6,$a2,$a3 +/* 70200960: 91cf0000 */ lbu $t7,0x0($t6) +/* 70200964: 24f90001 */ addiu $t9,$a3,0x1 +/* 70200968: ad790000 */ sw $t9,0x0($t3) +/* 7020096c: 008fc004 */ sllv $t8,$t7,$a0 +/* 70200970: 24840008 */ addiu $a0,$a0,0x8 +/* 70200974: 2c810010 */ sltiu $at,$a0,0x10 +/* 70200978: 1420fff7 */ bnez $at,.L70200958 +/* 7020097c: 00781825 */ or $v1,$v1,$t8 +.L70200980: +/* 70200980: 00403025 */ move $a2,$v0 +/* 70200984: 00036c02 */ srl $t5,$v1,0x10 +/* 70200988: 01a01825 */ move $v1,$t5 +/* 7020098c: 2484fff0 */ addiu $a0,$a0,-16 +/* 70200990: 1040001b */ beqz $v0,.L70200a00 +/* 70200994: 2442ffff */ addiu $v0,$v0,-1 +/* 70200998: 3c0c7020 */ lui $t4,0x7020 +/* 7020099c: 258c12d4 */ addiu $t4,$t4,0x12d4 +.L702009a0: +/* 702009a0: 2c810008 */ sltiu $at,$a0,0x8 +/* 702009a4: 1020000c */ beqz $at,.L702009d8 +/* 702009a8: 3c067020 */ lui $a2,0x7020 +/* 702009ac: 8cc612d0 */ lw $a2,0x12d0($a2) +.L702009b0: +/* 702009b0: 8d670000 */ lw $a3,0x0($t3) +/* 702009b4: 00c77021 */ addu $t6,$a2,$a3 +/* 702009b8: 91cf0000 */ lbu $t7,0x0($t6) +/* 702009bc: 24f90001 */ addiu $t9,$a3,0x1 +/* 702009c0: ad790000 */ sw $t9,0x0($t3) +/* 702009c4: 008fc004 */ sllv $t8,$t7,$a0 +/* 702009c8: 24840008 */ addiu $a0,$a0,0x8 +/* 702009cc: 2c810008 */ sltiu $at,$a0,0x8 +/* 702009d0: 1420fff7 */ bnez $at,.L702009b0 +/* 702009d4: 00781825 */ or $v1,$v1,$t8 +.L702009d8: +/* 702009d8: 8d8d0000 */ lw $t5,0x0($t4) +/* 702009dc: 00403025 */ move $a2,$v0 +/* 702009e0: 00037a02 */ srl $t7,$v1,0x8 +/* 702009e4: 01a57021 */ addu $t6,$t5,$a1 +/* 702009e8: a1c30000 */ sb $v1,0x0($t6) +/* 702009ec: 24a50001 */ addiu $a1,$a1,0x1 +/* 702009f0: 01e01825 */ move $v1,$t7 +/* 702009f4: 2484fff8 */ addiu $a0,$a0,-8 +/* 702009f8: 1440ffe9 */ bnez $v0,.L702009a0 +/* 702009fc: 2442ffff */ addiu $v0,$v0,-1 +.L70200a00: +/* 70200a00: ad450000 */ sw $a1,0x0($t2) +/* 70200a04: ad030000 */ sw $v1,0x0($t0) +/* 70200a08: ad240000 */ sw $a0,0x0($t1) +/* 70200a0c: 03e00008 */ jr $ra +/* 70200a10: 00001025 */ move $v0,$zero +); + +GLOBAL_ASM( +glabel func70200a14 +/* 70200a14: 27bdfb40 */ addiu $sp,$sp,-1216 +/* 70200a18: afbf0024 */ sw $ra,0x24($sp) +/* 70200a1c: 27a2002c */ addiu $v0,$sp,0x2c +/* 70200a20: 27a3026c */ addiu $v1,$sp,0x26c +/* 70200a24: 24050008 */ li $a1,0x8 +.L70200a28: +/* 70200a28: 24420004 */ addiu $v0,$v0,0x4 +/* 70200a2c: 1443fffe */ bne $v0,$v1,.L70200a28 +/* 70200a30: ac45fffc */ sw $a1,-0x4($v0) +/* 70200a34: 27ae042c */ addiu $t6,$sp,0x42c +/* 70200a38: 004e082b */ sltu $at,$v0,$t6 +/* 70200a3c: 10200007 */ beqz $at,.L70200a5c +/* 70200a40: 27af048c */ addiu $t7,$sp,0x48c +/* 70200a44: 27a4042c */ addiu $a0,$sp,0x42c +/* 70200a48: 24030009 */ li $v1,0x9 +.L70200a4c: +/* 70200a4c: 24420004 */ addiu $v0,$v0,0x4 +/* 70200a50: 0044082b */ sltu $at,$v0,$a0 +/* 70200a54: 1420fffd */ bnez $at,.L70200a4c +/* 70200a58: ac43fffc */ sw $v1,-0x4($v0) +.L70200a5c: +/* 70200a5c: 004f082b */ sltu $at,$v0,$t7 +/* 70200a60: 10200007 */ beqz $at,.L70200a80 +/* 70200a64: 27b804ac */ addiu $t8,$sp,0x4ac +/* 70200a68: 27a4048c */ addiu $a0,$sp,0x48c +/* 70200a6c: 24030007 */ li $v1,0x7 +.L70200a70: +/* 70200a70: 24420004 */ addiu $v0,$v0,0x4 +/* 70200a74: 0044082b */ sltu $at,$v0,$a0 +/* 70200a78: 1420fffd */ bnez $at,.L70200a70 +/* 70200a7c: ac43fffc */ sw $v1,-0x4($v0) +.L70200a80: +/* 70200a80: 0058082b */ sltu $at,$v0,$t8 +/* 70200a84: 10200006 */ beqz $at,.L70200aa0 +/* 70200a88: 24190007 */ li $t9,0x7 +/* 70200a8c: 27a304ac */ addiu $v1,$sp,0x4ac +.L70200a90: +/* 70200a90: 24420004 */ addiu $v0,$v0,0x4 +/* 70200a94: 0043082b */ sltu $at,$v0,$v1 +/* 70200a98: 1420fffd */ bnez $at,.L70200a90 +/* 70200a9c: ac45fffc */ sw $a1,-0x4($v0) +.L70200aa0: +/* 70200aa0: 3c087020 */ lui $t0,0x7020 +/* 70200aa4: 25081338 */ addiu $t0,$t0,0x1338 +/* 70200aa8: 3c077020 */ lui $a3,0x7020 +/* 70200aac: 27a904b8 */ addiu $t1,$sp,0x4b8 +/* 70200ab0: 27aa04b0 */ addiu $t2,$sp,0x4b0 +/* 70200ab4: afb904b0 */ sw $t9,0x4b0($sp) +/* 70200ab8: afaa0018 */ sw $t2,0x18($sp) +/* 70200abc: afa90014 */ sw $t1,0x14($sp) +/* 70200ac0: 24e712f8 */ addiu $a3,$a3,0x12f8 +/* 70200ac4: afa80010 */ sw $t0,0x10($sp) +/* 70200ac8: 27a4002c */ addiu $a0,$sp,0x2c +/* 70200acc: 24050120 */ li $a1,0x120 +/* 70200ad0: 0c080000 */ jal .L70200000 +/* 70200ad4: 24060101 */ li $a2,0x101 +/* 70200ad8: 27a2002c */ addiu $v0,$sp,0x2c +/* 70200adc: 27a400a4 */ addiu $a0,$sp,0xa4 +/* 70200ae0: 24030005 */ li $v1,0x5 +.L70200ae4: +/* 70200ae4: 24420004 */ addiu $v0,$v0,0x4 +/* 70200ae8: 1444fffe */ bne $v0,$a0,.L70200ae4 +/* 70200aec: ac43fffc */ sw $v1,-0x4($v0) +/* 70200af0: 3c0c7020 */ lui $t4,0x7020 +/* 70200af4: 240b0005 */ li $t3,0x5 +/* 70200af8: 258c1394 */ addiu $t4,$t4,0x1394 +/* 70200afc: 3c077020 */ lui $a3,0x7020 +/* 70200b00: 27ad04b4 */ addiu $t5,$sp,0x4b4 +/* 70200b04: 27ae04ac */ addiu $t6,$sp,0x4ac +/* 70200b08: afab04ac */ sw $t3,0x4ac($sp) +/* 70200b0c: afae0018 */ sw $t6,0x18($sp) +/* 70200b10: afad0014 */ sw $t5,0x14($sp) +/* 70200b14: 24e71358 */ addiu $a3,$a3,0x1358 +/* 70200b18: afac0010 */ sw $t4,0x10($sp) +/* 70200b1c: 27a4002c */ addiu $a0,$sp,0x2c +/* 70200b20: 2405001e */ li $a1,0x1e +/* 70200b24: 0c080000 */ jal .L70200000 +/* 70200b28: 00003025 */ move $a2,$zero +/* 70200b2c: 8fa404b8 */ lw $a0,0x4b8($sp) +/* 70200b30: 8fa504b4 */ lw $a1,0x4b4($sp) +/* 70200b34: 8fa604b0 */ lw $a2,0x4b0($sp) +/* 70200b38: 0c080157 */ jal func7020055c +/* 70200b3c: 8fa704ac */ lw $a3,0x4ac($sp) +/* 70200b40: 8fbf0024 */ lw $ra,0x24($sp) +/* 70200b44: 27bd04c0 */ addiu $sp,$sp,0x4c0 +/* 70200b48: 00001025 */ move $v0,$zero +/* 70200b4c: 03e00008 */ jr $ra +/* 70200b50: 00000000 */ nop +); + +GLOBAL_ASM( +glabel func70200b54 +/* 70200b54: 3c087020 */ lui $t0,0x7020 +/* 70200b58: 8d0813b8 */ lw $t0,0x13b8($t0) +/* 70200b5c: 27bdfa98 */ addiu $sp,$sp,-1384 +/* 70200b60: 3c097020 */ lui $t1,0x7020 +/* 70200b64: 2d010005 */ sltiu $at,$t0,0x5 +/* 70200b68: afbf002c */ sw $ra,0x2c($sp) +/* 70200b6c: afb00028 */ sw $s0,0x28($sp) +/* 70200b70: 1020000f */ beqz $at,.L70200bb0 +/* 70200b74: 8d2913b4 */ lw $t1,0x13b4($t1) +/* 70200b78: 3c037020 */ lui $v1,0x7020 +/* 70200b7c: 3c0a7020 */ lui $t2,0x7020 +/* 70200b80: 254a12d8 */ addiu $t2,$t2,0x12d8 +/* 70200b84: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200b88: +/* 70200b88: 8d420000 */ lw $v0,0x0($t2) +/* 70200b8c: 00627021 */ addu $t6,$v1,$v0 +/* 70200b90: 91cf0000 */ lbu $t7,0x0($t6) +/* 70200b94: 24590001 */ addiu $t9,$v0,0x1 +/* 70200b98: ad590000 */ sw $t9,0x0($t2) +/* 70200b9c: 010fc004 */ sllv $t8,$t7,$t0 +/* 70200ba0: 25080008 */ addiu $t0,$t0,0x8 +/* 70200ba4: 2d010005 */ sltiu $at,$t0,0x5 +/* 70200ba8: 1420fff7 */ bnez $at,.L70200b88 +/* 70200bac: 01384825 */ or $t1,$t1,$t8 +.L70200bb0: +/* 70200bb0: 312e001f */ andi $t6,$t1,0x1f +/* 70200bb4: 2508fffb */ addiu $t0,$t0,-5 +/* 70200bb8: 3c0a7020 */ lui $t2,0x7020 +/* 70200bbc: 25cf0101 */ addiu $t7,$t6,0x101 +/* 70200bc0: 0009c142 */ srl $t8,$t1,0x5 +/* 70200bc4: 2d010005 */ sltiu $at,$t0,0x5 +/* 70200bc8: 254a12d8 */ addiu $t2,$t2,0x12d8 +/* 70200bcc: afaf053c */ sw $t7,0x53c($sp) +/* 70200bd0: 1020000d */ beqz $at,.L70200c08 +/* 70200bd4: 03004825 */ move $t1,$t8 +/* 70200bd8: 3c037020 */ lui $v1,0x7020 +/* 70200bdc: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200be0: +/* 70200be0: 8d420000 */ lw $v0,0x0($t2) +/* 70200be4: 0062c821 */ addu $t9,$v1,$v0 +/* 70200be8: 932e0000 */ lbu $t6,0x0($t9) +/* 70200bec: 24580001 */ addiu $t8,$v0,0x1 +/* 70200bf0: ad580000 */ sw $t8,0x0($t2) +/* 70200bf4: 010e7804 */ sllv $t7,$t6,$t0 +/* 70200bf8: 25080008 */ addiu $t0,$t0,0x8 +/* 70200bfc: 2d010005 */ sltiu $at,$t0,0x5 +/* 70200c00: 1420fff7 */ bnez $at,.L70200be0 +/* 70200c04: 012f4825 */ or $t1,$t1,$t7 +.L70200c08: +/* 70200c08: 3139001f */ andi $t9,$t1,0x1f +/* 70200c0c: 2508fffb */ addiu $t0,$t0,-5 +/* 70200c10: 272e0001 */ addiu $t6,$t9,0x1 +/* 70200c14: 00097942 */ srl $t7,$t1,0x5 +/* 70200c18: 2d010004 */ sltiu $at,$t0,0x4 +/* 70200c1c: afae0538 */ sw $t6,0x538($sp) +/* 70200c20: 1020000d */ beqz $at,.L70200c58 +/* 70200c24: 01e04825 */ move $t1,$t7 +/* 70200c28: 3c037020 */ lui $v1,0x7020 +/* 70200c2c: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200c30: +/* 70200c30: 8d420000 */ lw $v0,0x0($t2) +/* 70200c34: 0062c021 */ addu $t8,$v1,$v0 +/* 70200c38: 93190000 */ lbu $t9,0x0($t8) +/* 70200c3c: 244f0001 */ addiu $t7,$v0,0x1 +/* 70200c40: ad4f0000 */ sw $t7,0x0($t2) +/* 70200c44: 01197004 */ sllv $t6,$t9,$t0 +/* 70200c48: 25080008 */ addiu $t0,$t0,0x8 +/* 70200c4c: 2d010004 */ sltiu $at,$t0,0x4 +/* 70200c50: 1420fff7 */ bnez $at,.L70200c30 +/* 70200c54: 012e4825 */ or $t1,$t1,$t6 +.L70200c58: +/* 70200c58: 3126000f */ andi $a2,$t1,0xf +/* 70200c5c: 24c60004 */ addiu $a2,$a2,0x4 +/* 70200c60: 0009c102 */ srl $t8,$t1,0x4 +/* 70200c64: 03004825 */ move $t1,$t8 +/* 70200c68: 2508fffc */ addiu $t0,$t0,-4 +/* 70200c6c: 10c0001d */ beqz $a2,.L70200ce4 +/* 70200c70: 00002025 */ move $a0,$zero +/* 70200c74: 3c057020 */ lui $a1,0x7020 +/* 70200c78: 24a512e4 */ addiu $a1,$a1,0x12e4 +/* 70200c7c: 27b00040 */ addiu $s0,$sp,0x40 +.L70200c80: +/* 70200c80: 2d010003 */ sltiu $at,$t0,0x3 +/* 70200c84: 1020000d */ beqz $at,.L70200cbc +/* 70200c88: 24840001 */ addiu $a0,$a0,0x1 +/* 70200c8c: 3c037020 */ lui $v1,0x7020 +/* 70200c90: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200c94: +/* 70200c94: 8d420000 */ lw $v0,0x0($t2) +/* 70200c98: 0062c821 */ addu $t9,$v1,$v0 +/* 70200c9c: 932e0000 */ lbu $t6,0x0($t9) +/* 70200ca0: 24580001 */ addiu $t8,$v0,0x1 +/* 70200ca4: ad580000 */ sw $t8,0x0($t2) +/* 70200ca8: 010e7804 */ sllv $t7,$t6,$t0 +/* 70200cac: 25080008 */ addiu $t0,$t0,0x8 +/* 70200cb0: 2d010003 */ sltiu $at,$t0,0x3 +/* 70200cb4: 1420fff7 */ bnez $at,.L70200c94 +/* 70200cb8: 012f4825 */ or $t1,$t1,$t7 +.L70200cbc: +/* 70200cbc: 90ae0000 */ lbu $t6,0x0($a1) +/* 70200cc0: 31390007 */ andi $t9,$t1,0x7 +/* 70200cc4: 24a50001 */ addiu $a1,$a1,0x1 +/* 70200cc8: 000e7880 */ sll $t7,$t6,0x2 +/* 70200ccc: 020fc021 */ addu $t8,$s0,$t7 +/* 70200cd0: 000970c2 */ srl $t6,$t1,0x3 +/* 70200cd4: af190000 */ sw $t9,0x0($t8) +/* 70200cd8: 01c04825 */ move $t1,$t6 +/* 70200cdc: 1486ffe8 */ bne $a0,$a2,.L70200c80 +/* 70200ce0: 2508fffd */ addiu $t0,$t0,-3 +.L70200ce4: +/* 70200ce4: 2c810013 */ sltiu $at,$a0,0x13 +/* 70200ce8: 1020000d */ beqz $at,.L70200d20 +/* 70200cec: 27b00040 */ addiu $s0,$sp,0x40 +/* 70200cf0: 3c0f7020 */ lui $t7,0x7020 +/* 70200cf4: 25ef12e4 */ addiu $t7,$t7,0x12e4 +/* 70200cf8: 3c027020 */ lui $v0,0x7020 +/* 70200cfc: 244212f7 */ addiu $v0,$v0,0x12f7 +/* 70200d00: 008f2821 */ addu $a1,$a0,$t7 +.L70200d04: +/* 70200d04: 90b90000 */ lbu $t9,0x0($a1) +/* 70200d08: 24a50001 */ addiu $a1,$a1,0x1 +/* 70200d0c: 00a2082b */ sltu $at,$a1,$v0 +/* 70200d10: 0019c080 */ sll $t8,$t9,0x2 +/* 70200d14: 02187021 */ addu $t6,$s0,$t8 +/* 70200d18: 1420fffa */ bnez $at,.L70200d04 +/* 70200d1c: adc00000 */ sw $zero,0x0($t6) +.L70200d20: +/* 70200d20: 240f0007 */ li $t7,0x7 +/* 70200d24: 27b90550 */ addiu $t9,$sp,0x550 +/* 70200d28: 27b80548 */ addiu $t8,$sp,0x548 +/* 70200d2c: afaf0548 */ sw $t7,0x548($sp) +/* 70200d30: afb80018 */ sw $t8,0x18($sp) +/* 70200d34: afb90014 */ sw $t9,0x14($sp) +/* 70200d38: 02002025 */ move $a0,$s0 +/* 70200d3c: 24050013 */ li $a1,0x13 +/* 70200d40: 24060013 */ li $a2,0x13 +/* 70200d44: 00003825 */ move $a3,$zero +/* 70200d48: afa00010 */ sw $zero,0x10($sp) +/* 70200d4c: afa80534 */ sw $t0,0x534($sp) +/* 70200d50: 0c080000 */ jal .L70200000 +/* 70200d54: afa90530 */ sw $t1,0x530($sp) +/* 70200d58: 8fb90548 */ lw $t9,0x548($sp) +/* 70200d5c: 8fae053c */ lw $t6,0x53c($sp) +/* 70200d60: 8faf0538 */ lw $t7,0x538($sp) +/* 70200d64: 3c0b7020 */ lui $t3,0x7020 +/* 70200d68: 0019c040 */ sll $t8,$t9,0x1 +/* 70200d6c: 3c0a7020 */ lui $t2,0x7020 +/* 70200d70: 01785821 */ addu $t3,$t3,$t8 +/* 70200d74: 01cf3821 */ addu $a3,$t6,$t7 +/* 70200d78: 254a12d8 */ addiu $t2,$t2,0x12d8 +/* 70200d7c: 8fa80534 */ lw $t0,0x534($sp) +/* 70200d80: 8fa90530 */ lw $t1,0x530($sp) +/* 70200d84: 956b13bc */ lhu $t3,0x13bc($t3) +/* 70200d88: 00003025 */ move $a2,$zero +/* 70200d8c: 10e0008a */ beqz $a3,.L70200fb8 +/* 70200d90: 00002825 */ move $a1,$zero +/* 70200d94: 240d0011 */ li $t5,0x11 +/* 70200d98: 240c0010 */ li $t4,0x10 +/* 70200d9c: 8fae0548 */ lw $t6,0x548($sp) +.L70200da0: +/* 70200da0: 3c037020 */ lui $v1,0x7020 +/* 70200da4: 010e082b */ sltu $at,$t0,$t6 +/* 70200da8: 5020000e */ beqzl $at,.L70200de4 +/* 70200dac: 8fae0550 */ lw $t6,0x550($sp) +/* 70200db0: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200db4: +/* 70200db4: 8d420000 */ lw $v0,0x0($t2) +/* 70200db8: 00627821 */ addu $t7,$v1,$v0 +/* 70200dbc: 91f90000 */ lbu $t9,0x0($t7) +/* 70200dc0: 8faf0548 */ lw $t7,0x548($sp) +/* 70200dc4: 244e0001 */ addiu $t6,$v0,0x1 +/* 70200dc8: 0119c004 */ sllv $t8,$t9,$t0 +/* 70200dcc: 25080008 */ addiu $t0,$t0,0x8 +/* 70200dd0: 010f082b */ sltu $at,$t0,$t7 +/* 70200dd4: 01384825 */ or $t1,$t1,$t8 +/* 70200dd8: 1420fff6 */ bnez $at,.L70200db4 +/* 70200ddc: ad4e0000 */ sw $t6,0x0($t2) +/* 70200de0: 8fae0550 */ lw $t6,0x550($sp) +.L70200de4: +/* 70200de4: 012bc824 */ and $t9,$t1,$t3 +/* 70200de8: 0019c0c0 */ sll $t8,$t9,0x3 +/* 70200dec: 030e7821 */ addu $t7,$t8,$t6 +/* 70200df0: afaf054c */ sw $t7,0x54c($sp) +/* 70200df4: 91e40001 */ lbu $a0,0x1($t7) +/* 70200df8: 0005c880 */ sll $t9,$a1,0x2 +/* 70200dfc: 0219c021 */ addu $t8,$s0,$t9 +/* 70200e00: 00894806 */ srlv $t1,$t1,$a0 +/* 70200e04: 01044023 */ subu $t0,$t0,$a0 +/* 70200e08: 95e40004 */ lhu $a0,0x4($t7) +/* 70200e0c: 2c810010 */ sltiu $at,$a0,0x10 +/* 70200e10: 10200005 */ beqz $at,.L70200e28 +/* 70200e14: 00000000 */ nop +/* 70200e18: 00803025 */ move $a2,$a0 +/* 70200e1c: af040000 */ sw $a0,0x0($t8) +/* 70200e20: 10000062 */ b .L70200fac +/* 70200e24: 24a50001 */ addiu $a1,$a1,0x1 +.L70200e28: +/* 70200e28: 148c0020 */ bne $a0,$t4,.L70200eac +/* 70200e2c: 2d010002 */ sltiu $at,$t0,0x2 +/* 70200e30: 1020000c */ beqz $at,.L70200e64 +/* 70200e34: 3c037020 */ lui $v1,0x7020 +/* 70200e38: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200e3c: +/* 70200e3c: 8d420000 */ lw $v0,0x0($t2) +/* 70200e40: 00627021 */ addu $t6,$v1,$v0 +/* 70200e44: 91cf0000 */ lbu $t7,0x0($t6) +/* 70200e48: 24580001 */ addiu $t8,$v0,0x1 +/* 70200e4c: ad580000 */ sw $t8,0x0($t2) +/* 70200e50: 010fc804 */ sllv $t9,$t7,$t0 +/* 70200e54: 25080008 */ addiu $t0,$t0,0x8 +/* 70200e58: 2d010002 */ sltiu $at,$t0,0x2 +/* 70200e5c: 1420fff7 */ bnez $at,.L70200e3c +/* 70200e60: 01394825 */ or $t1,$t1,$t9 +.L70200e64: +/* 70200e64: 31240003 */ andi $a0,$t1,0x3 +/* 70200e68: 24840003 */ addiu $a0,$a0,0x3 +/* 70200e6c: 00801825 */ move $v1,$a0 +/* 70200e70: 00097082 */ srl $t6,$t1,0x2 +/* 70200e74: 01c04825 */ move $t1,$t6 +/* 70200e78: 2508fffe */ addiu $t0,$t0,-2 +/* 70200e7c: 1080004b */ beqz $a0,.L70200fac +/* 70200e80: 2484ffff */ addiu $a0,$a0,-1 +/* 70200e84: 00057880 */ sll $t7,$a1,0x2 +/* 70200e88: 020f1021 */ addu $v0,$s0,$t7 +.L70200e8c: +/* 70200e8c: 00801825 */ move $v1,$a0 +/* 70200e90: ac460000 */ sw $a2,0x0($v0) +/* 70200e94: 24a50001 */ addiu $a1,$a1,0x1 +/* 70200e98: 24420004 */ addiu $v0,$v0,0x4 +/* 70200e9c: 1480fffb */ bnez $a0,.L70200e8c +/* 70200ea0: 2484ffff */ addiu $a0,$a0,-1 +/* 70200ea4: 10000042 */ b .L70200fb0 +/* 70200ea8: 00a7082b */ sltu $at,$a1,$a3 +.L70200eac: +/* 70200eac: 148d0021 */ bne $a0,$t5,.L70200f34 +/* 70200eb0: 00003025 */ move $a2,$zero +/* 70200eb4: 2d010003 */ sltiu $at,$t0,0x3 +/* 70200eb8: 1020000c */ beqz $at,.L70200eec +/* 70200ebc: 3c037020 */ lui $v1,0x7020 +/* 70200ec0: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200ec4: +/* 70200ec4: 8d420000 */ lw $v0,0x0($t2) +/* 70200ec8: 0062c821 */ addu $t9,$v1,$v0 +/* 70200ecc: 93380000 */ lbu $t8,0x0($t9) +/* 70200ed0: 244f0001 */ addiu $t7,$v0,0x1 +/* 70200ed4: ad4f0000 */ sw $t7,0x0($t2) +/* 70200ed8: 01187004 */ sllv $t6,$t8,$t0 +/* 70200edc: 25080008 */ addiu $t0,$t0,0x8 +/* 70200ee0: 2d010003 */ sltiu $at,$t0,0x3 +/* 70200ee4: 1420fff7 */ bnez $at,.L70200ec4 +/* 70200ee8: 012e4825 */ or $t1,$t1,$t6 +.L70200eec: +/* 70200eec: 31240007 */ andi $a0,$t1,0x7 +/* 70200ef0: 24840003 */ addiu $a0,$a0,0x3 +/* 70200ef4: 00801825 */ move $v1,$a0 +/* 70200ef8: 0009c8c2 */ srl $t9,$t1,0x3 +/* 70200efc: 03204825 */ move $t1,$t9 +/* 70200f00: 2508fffd */ addiu $t0,$t0,-3 +/* 70200f04: 10800029 */ beqz $a0,.L70200fac +/* 70200f08: 2484ffff */ addiu $a0,$a0,-1 +/* 70200f0c: 0005c080 */ sll $t8,$a1,0x2 +/* 70200f10: 02181021 */ addu $v0,$s0,$t8 +.L70200f14: +/* 70200f14: 00801825 */ move $v1,$a0 +/* 70200f18: ac400000 */ sw $zero,0x0($v0) +/* 70200f1c: 24a50001 */ addiu $a1,$a1,0x1 +/* 70200f20: 24420004 */ addiu $v0,$v0,0x4 +/* 70200f24: 1480fffb */ bnez $a0,.L70200f14 +/* 70200f28: 2484ffff */ addiu $a0,$a0,-1 +/* 70200f2c: 10000020 */ b .L70200fb0 +/* 70200f30: 00a7082b */ sltu $at,$a1,$a3 +.L70200f34: +/* 70200f34: 2d010007 */ sltiu $at,$t0,0x7 +/* 70200f38: 1020000c */ beqz $at,.L70200f6c +/* 70200f3c: 3c037020 */ lui $v1,0x7020 +/* 70200f40: 8c6312d0 */ lw $v1,0x12d0($v1) +.L70200f44: +/* 70200f44: 8d420000 */ lw $v0,0x0($t2) +/* 70200f48: 00627021 */ addu $t6,$v1,$v0 +/* 70200f4c: 91cf0000 */ lbu $t7,0x0($t6) +/* 70200f50: 24580001 */ addiu $t8,$v0,0x1 +/* 70200f54: ad580000 */ sw $t8,0x0($t2) +/* 70200f58: 010fc804 */ sllv $t9,$t7,$t0 +/* 70200f5c: 25080008 */ addiu $t0,$t0,0x8 +/* 70200f60: 2d010007 */ sltiu $at,$t0,0x7 +/* 70200f64: 1420fff7 */ bnez $at,.L70200f44 +/* 70200f68: 01394825 */ or $t1,$t1,$t9 +.L70200f6c: +/* 70200f6c: 3124007f */ andi $a0,$t1,0x7f +/* 70200f70: 2484000b */ addiu $a0,$a0,0xb +/* 70200f74: 00801825 */ move $v1,$a0 +/* 70200f78: 000971c2 */ srl $t6,$t1,0x7 +/* 70200f7c: 01c04825 */ move $t1,$t6 +/* 70200f80: 2508fff9 */ addiu $t0,$t0,-7 +/* 70200f84: 10800009 */ beqz $a0,.L70200fac +/* 70200f88: 2484ffff */ addiu $a0,$a0,-1 +/* 70200f8c: 00057880 */ sll $t7,$a1,0x2 +/* 70200f90: 020f1021 */ addu $v0,$s0,$t7 +.L70200f94: +/* 70200f94: 00801825 */ move $v1,$a0 +/* 70200f98: ac400000 */ sw $zero,0x0($v0) +/* 70200f9c: 24a50001 */ addiu $a1,$a1,0x1 +/* 70200fa0: 24420004 */ addiu $v0,$v0,0x4 +/* 70200fa4: 1480fffb */ bnez $a0,.L70200f94 +/* 70200fa8: 2484ffff */ addiu $a0,$a0,-1 +.L70200fac: +/* 70200fac: 00a7082b */ sltu $at,$a1,$a3 +.L70200fb0: +/* 70200fb0: 5420ff7b */ bnezl $at,.L70200da0 +/* 70200fb4: 8fae0548 */ lw $t6,0x548($sp) +.L70200fb8: +/* 70200fb8: 3c017020 */ lui $at,0x7020 +/* 70200fbc: 3c197020 */ lui $t9,0x7020 +/* 70200fc0: 8f3913e0 */ lw $t9,0x13e0($t9) +/* 70200fc4: ac2913b4 */ sw $t1,0x13b4($at) +/* 70200fc8: 3c187020 */ lui $t8,0x7020 +/* 70200fcc: 3c017020 */ lui $at,0x7020 +/* 70200fd0: 27181338 */ addiu $t8,$t8,0x1338 +/* 70200fd4: 3c077020 */ lui $a3,0x7020 +/* 70200fd8: 27ae0550 */ addiu $t6,$sp,0x550 +/* 70200fdc: 27af0548 */ addiu $t7,$sp,0x548 +/* 70200fe0: ac2813b8 */ sw $t0,0x13b8($at) +/* 70200fe4: afaf0018 */ sw $t7,0x18($sp) +/* 70200fe8: afae0014 */ sw $t6,0x14($sp) +/* 70200fec: 24e712f8 */ addiu $a3,$a3,0x12f8 +/* 70200ff0: afb80010 */ sw $t8,0x10($sp) +/* 70200ff4: 02002025 */ move $a0,$s0 +/* 70200ff8: 8fa5053c */ lw $a1,0x53c($sp) +/* 70200ffc: 24060101 */ li $a2,0x101 +/* 70201000: 0c080000 */ jal .L70200000 +/* 70201004: afb90548 */ sw $t9,0x548($sp) +/* 70201008: 3c197020 */ lui $t9,0x7020 +/* 7020100c: 8f3913e4 */ lw $t9,0x13e4($t9) +/* 70201010: 8fb8053c */ lw $t8,0x53c($sp) +/* 70201014: 3c0f7020 */ lui $t7,0x7020 +/* 70201018: afb90544 */ sw $t9,0x544($sp) +/* 7020101c: 00187080 */ sll $t6,$t8,0x2 +/* 70201020: 27b80544 */ addiu $t8,$sp,0x544 +/* 70201024: 27b9054c */ addiu $t9,$sp,0x54c +/* 70201028: 25ef1394 */ addiu $t7,$t7,0x1394 +/* 7020102c: 3c077020 */ lui $a3,0x7020 +/* 70201030: 24e71358 */ addiu $a3,$a3,0x1358 +/* 70201034: afaf0010 */ sw $t7,0x10($sp) +/* 70201038: afb90014 */ sw $t9,0x14($sp) +/* 7020103c: afb80018 */ sw $t8,0x18($sp) +/* 70201040: 020e2021 */ addu $a0,$s0,$t6 +/* 70201044: 8fa50538 */ lw $a1,0x538($sp) +/* 70201048: 0c080000 */ jal .L70200000 +/* 7020104c: 00003025 */ move $a2,$zero +/* 70201050: 8fa40550 */ lw $a0,0x550($sp) +/* 70201054: 8fa5054c */ lw $a1,0x54c($sp) +/* 70201058: 8fa60548 */ lw $a2,0x548($sp) +/* 7020105c: 0c080157 */ jal func7020055c +/* 70201060: 8fa70544 */ lw $a3,0x544($sp) +/* 70201064: 8fbf002c */ lw $ra,0x2c($sp) +/* 70201068: 8fb00028 */ lw $s0,0x28($sp) +/* 7020106c: 27bd0568 */ addiu $sp,$sp,0x568 +/* 70201070: 03e00008 */ jr $ra +/* 70201074: 00001025 */ move $v0,$zero +); + +GLOBAL_ASM( +glabel inflate_block +/* 70201078: 3c097020 */ lui $t1,0x7020 +/* 7020107c: 252913b8 */ addiu $t1,$t1,0x13b8 +/* 70201080: 8d230000 */ lw $v1,0x0($t1) +/* 70201084: 3c087020 */ lui $t0,0x7020 +/* 70201088: 250813b4 */ addiu $t0,$t0,0x13b4 +/* 7020108c: 27bdffe8 */ addiu $sp,$sp,-24 +/* 70201090: afbf0014 */ sw $ra,0x14($sp) +/* 70201094: 00803825 */ move $a3,$a0 +/* 70201098: 1460000e */ bnez $v1,.L702010d4 +/* 7020109c: 8d050000 */ lw $a1,0x0($t0) +/* 702010a0: 3c067020 */ lui $a2,0x7020 +/* 702010a4: 3c047020 */ lui $a0,0x7020 +/* 702010a8: 248412d8 */ addiu $a0,$a0,0x12d8 +/* 702010ac: 8cc612d0 */ lw $a2,0x12d0($a2) +.L702010b0: +/* 702010b0: 8c820000 */ lw $v0,0x0($a0) +/* 702010b4: 00c27021 */ addu $t6,$a2,$v0 +/* 702010b8: 91cf0000 */ lbu $t7,0x0($t6) +/* 702010bc: 24590001 */ addiu $t9,$v0,0x1 +/* 702010c0: ac990000 */ sw $t9,0x0($a0) +/* 702010c4: 006fc004 */ sllv $t8,$t7,$v1 +/* 702010c8: 24630008 */ addiu $v1,$v1,0x8 +/* 702010cc: 1060fff8 */ beqz $v1,.L702010b0 +/* 702010d0: 00b82825 */ or $a1,$a1,$t8 +.L702010d4: +/* 702010d4: 2463ffff */ addiu $v1,$v1,-1 +/* 702010d8: 3c047020 */ lui $a0,0x7020 +/* 702010dc: 30aa0001 */ andi $t2,$a1,0x1 +/* 702010e0: 00055842 */ srl $t3,$a1,0x1 +/* 702010e4: 2c610002 */ sltiu $at,$v1,0x2 +/* 702010e8: 248412d8 */ addiu $a0,$a0,0x12d8 +/* 702010ec: acea0000 */ sw $t2,0x0($a3) +/* 702010f0: 1020000d */ beqz $at,.L70201128 +/* 702010f4: 01602825 */ move $a1,$t3 +/* 702010f8: 3c067020 */ lui $a2,0x7020 +/* 702010fc: 8cc612d0 */ lw $a2,0x12d0($a2) +.L70201100: +/* 70201100: 8c820000 */ lw $v0,0x0($a0) +/* 70201104: 00c26021 */ addu $t4,$a2,$v0 +/* 70201108: 918d0000 */ lbu $t5,0x0($t4) +/* 7020110c: 244f0001 */ addiu $t7,$v0,0x1 +/* 70201110: ac8f0000 */ sw $t7,0x0($a0) +/* 70201114: 006d7004 */ sllv $t6,$t5,$v1 +/* 70201118: 24630008 */ addiu $v1,$v1,0x8 +/* 7020111c: 2c610002 */ sltiu $at,$v1,0x2 +/* 70201120: 1420fff7 */ bnez $at,.L70201100 +/* 70201124: 00ae2825 */ or $a1,$a1,$t6 +.L70201128: +/* 70201128: 30a20003 */ andi $v0,$a1,0x3 +/* 7020112c: 0005c082 */ srl $t8,$a1,0x2 +/* 70201130: 2463fffe */ addiu $v1,$v1,-2 +/* 70201134: 24010002 */ li $at,0x2 +/* 70201138: ad180000 */ sw $t8,0x0($t0) +/* 7020113c: 14410005 */ bne $v0,$at,.L70201154 +/* 70201140: ad230000 */ sw $v1,0x0($t1) +/* 70201144: 0c0802d5 */ jal func70200b54 +/* 70201148: 00000000 */ nop +/* 7020114c: 1000000f */ b .L7020118c +/* 70201150: 8fbf0014 */ lw $ra,0x14($sp) +.L70201154: +/* 70201154: 14400005 */ bnez $v0,.L7020116c +/* 70201158: 24010001 */ li $at,0x1 +/* 7020115c: 0c080230 */ jal func702008c0 +/* 70201160: 00000000 */ nop +/* 70201164: 10000009 */ b .L7020118c +/* 70201168: 8fbf0014 */ lw $ra,0x14($sp) +.L7020116c: +/* 7020116c: 54410006 */ bnel $v0,$at,.L70201188 +/* 70201170: 24020002 */ li $v0,0x2 +/* 70201174: 0c080285 */ jal func70200a14 +/* 70201178: 00000000 */ nop +/* 7020117c: 10000003 */ b .L7020118c +/* 70201180: 8fbf0014 */ lw $ra,0x14($sp) +/* 70201184: 24020002 */ li $v0,0x2 +.L70201188: +/* 70201188: 8fbf0014 */ lw $ra,0x14($sp) +.L7020118c: +/* 7020118c: 27bd0018 */ addiu $sp,$sp,0x18 +/* 70201190: 03e00008 */ jr $ra +/* 70201194: 00000000 */ nop +); + +// 70201198 +u32 inflate(void) +{ + u32 sp52; + u32 r; + u32 s1; + + var702012dc = 0; + bk = 0; + bb = 0; + s1 = 0; + + do { + hufts = 0; + r = inflate_block(&sp52); + + if (r != 0) { + return r; + } + + if (s1 < hufts) { + s1 = hufts; + } + } while (sp52 == 0); + + while (bk >= 8) { + bk -= 8; + var702012d8--; + } + + return 0; +} + +// 70201268 +u32 rarezip_inflate(void *src, void *dst, void *buffer) +{ + g_pSrc = src; + g_pDst = dst; + var702012e0 = buffer; + g_pSrc += 2; + g_pSrc += 3; + var702012dc = 0; + var702012d8 = 0; + + inflate(); + + return var702012dc; +} diff --git a/tools/asmpreproc/asm-processor.py b/tools/asmpreproc/asm-processor.py new file mode 100755 index 000000000..cbfd6b8b1 --- /dev/null +++ b/tools/asmpreproc/asm-processor.py @@ -0,0 +1,806 @@ +#!/usr/bin/env python3 +import argparse +import tempfile +import struct +import copy +import sys +import re +import os + +EI_NIDENT = 16 +EI_CLASS = 4 +EI_DATA = 5 +EI_VERSION = 6 +EI_OSABI = 7 +EI_ABIVERSION = 8 +STN_UNDEF = 0 + +SHN_UNDEF = 0 +SHN_ABS = 0xfff1 +SHN_COMMON = 0xfff2 +SHN_XINDEX = 0xffff +SHN_LORESERVE = 0xff00 + +STT_NOTYPE = 0 +STT_OBJECT = 1 +STT_FUNC = 2 +STT_SECTION = 3 +STT_FILE = 4 +STT_COMMON = 5 +STT_TLS = 6 + +STB_LOCAL = 0 +STB_GLOBAL = 1 +STB_WEAK = 2 + +STV_DEFAULT = 0 +STV_INTERNAL = 1 +STV_HIDDEN = 2 +STV_PROTECTED = 3 + +SHT_NULL = 0 +SHT_PROGBITS = 1 +SHT_SYMTAB = 2 +SHT_STRTAB = 3 +SHT_RELA = 4 +SHT_HASH = 5 +SHT_DYNAMIC = 6 +SHT_NOTE = 7 +SHT_NOBITS = 8 +SHT_REL = 9 +SHT_SHLIB = 10 +SHT_DYNSYM = 11 +SHT_INIT_ARRAY = 14 +SHT_FINI_ARRAY = 15 +SHT_PREINIT_ARRAY = 16 +SHT_GROUP = 17 +SHT_SYMTAB_SHNDX = 18 +SHT_MIPS_GPTAB = 0x70000003 +SHT_MIPS_DEBUG = 0x70000005 +SHT_MIPS_REGINFO = 0x70000006 +SHT_MIPS_OPTIONS = 0x7000000d + +SHF_WRITE = 0x1 +SHF_ALLOC = 0x2 +SHF_EXECINSTR = 0x4 +SHF_MERGE = 0x10 +SHF_STRINGS = 0x20 +SHF_INFO_LINK = 0x40 +SHF_LINK_ORDER = 0x80 +SHF_OS_NONCONFORMING = 0x100 +SHF_GROUP = 0x200 +SHF_TLS = 0x400 + +R_MIPS_32 = 2 +R_MIPS_26 = 4 +R_MIPS_HI16 = 5 +R_MIPS_LO16 = 6 + + +class ElfHeader: + """ + typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; + } Elf32_Ehdr; + """ + + def __init__(self, data): + self.e_ident = data[:EI_NIDENT] + self.e_type, self.e_machine, self.e_version, self.e_entry, self.e_phoff, self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx = struct.unpack('>HHIIIIIHHHHHH', data[EI_NIDENT:]) + assert self.e_ident[EI_CLASS] == 1 # 32-bit + assert self.e_ident[EI_DATA] == 2 # big-endian + assert self.e_type == 1 # relocatable + assert self.e_machine == 8 # MIPS I Architecture + assert self.e_phoff == 0 # no program header + assert self.e_shoff != 0 # section header + assert self.e_shstrndx != SHN_UNDEF + + def to_bin(self): + return self.e_ident + struct.pack('>HHIIIIIHHHHHH', self.e_type, + self.e_machine, self.e_version, self.e_entry, self.e_phoff, + self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize, + self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx) + + +class Symbol: + """ + typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; + } Elf32_Sym; + """ + + def __init__(self, data, strtab): + self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = struct.unpack('>IIIBBH', data) + assert self.st_shndx != SHN_XINDEX, "too many sections (SHN_XINDEX not supported)" + self.bind = st_info >> 4 + self.type = st_info & 15 + self.name = strtab.lookup_str(self.st_name) + self.visibility = self.st_other & 3 + + def to_bin(self): + st_info = (self.bind << 4) | self.type + return struct.pack('>IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx) + + +class Relocation: + def __init__(self, data, sh_type): + self.sh_type = sh_type + if sh_type == SHT_REL: + self.r_offset, self.r_info = struct.unpack('>II', data) + else: + self.r_offset, self.r_info, self.r_addend = struct.unpack('>III', data) + self.sym_index = self.r_info >> 8 + self.rel_type = self.r_info & 0xff + + def to_bin(self): + self.r_info = (self.sym_index << 8) | self.rel_type + if self.sh_type == SHT_REL: + return struct.pack('>II', self.r_offset, self.r_info) + else: + return struct.pack('>III', self.r_offset, self.r_info, self.r_addend) + + +class Section: + """ + typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; + } Elf32_Shdr; + """ + + def __init__(self, header, data, index): + self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize = struct.unpack('>IIIIIIIIII', header) + assert not self.sh_flags & SHF_LINK_ORDER + if self.sh_entsize != 0: + assert self.sh_size % self.sh_entsize == 0 + if self.sh_type == SHT_NOBITS: + self.data = '' + else: + self.data = data[self.sh_offset:self.sh_offset + self.sh_size] + self.index = index + self.relocated_by = [] + + @staticmethod + def from_parts(sh_name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data, index): + header = struct.pack('>IIIIIIIIII', sh_name, sh_type, sh_flags, 0, 0, len(data), sh_link, sh_info, sh_addralign, sh_entsize) + return Section(header, data, index) + + def lookup_str(self, index): + assert self.sh_type == SHT_STRTAB + to = self.data.find(b'\0', index) + assert to != -1 + return self.data[index:to].decode('utf-8') + + def add_str(self, string): + assert self.sh_type == SHT_STRTAB + ret = len(self.data) + self.data += bytes(string, 'utf-8') + b'\0' + return ret + + def is_rel(self): + return self.sh_type == SHT_REL or self.sh_type == SHT_RELA + + def header_to_bin(self): + if self.sh_type != SHT_NOBITS: + self.sh_size = len(self.data) + return struct.pack('>IIIIIIIIII', self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize) + + def late_init(self, sections): + if self.sh_type == SHT_SYMTAB: + self.init_symbols(sections) + elif self.is_rel(): + self.rel_target = sections[self.sh_info] + self.rel_target.relocated_by.append(self) + self.init_relocs() + + def find_symbol(self, name): + assert self.sh_type == SHT_SYMTAB + for s in self.symbol_entries: + if s.name == name: + return (s.st_shndx, s.st_value) + return None + + def init_symbols(self, sections): + assert self.sh_type == SHT_SYMTAB + assert self.sh_entsize == 16 + self.strtab = sections[self.sh_link] + entries = [] + for i in range(0, self.sh_size, self.sh_entsize): + entries.append(Symbol(self.data[i:i+self.sh_entsize], self.strtab)) + self.symbol_entries = entries + + def init_relocs(self): + assert self.is_rel() + entries = [] + for i in range(0, self.sh_size, self.sh_entsize): + entries.append(Relocation(self.data[i:i+self.sh_entsize], self.sh_type)) + self.relocations = entries + + def local_symbols(self): + assert self.sh_type == SHT_SYMTAB + return self.symbol_entries[:self.sh_info] + + def global_symbols(self): + assert self.sh_type == SHT_SYMTAB + return self.symbol_entries[self.sh_info:] + + +class ElfFile: + def __init__(self, data): + self.data = data + assert data[:4] == b'\x7fELF', "not an ELF file" + + self.elf_header = ElfHeader(data[0:52]) + + offset, size = self.elf_header.e_shoff, self.elf_header.e_shentsize + null_section = Section(data[offset:offset + size], data, 0) + num_sections = self.elf_header.e_shnum or null_section.sh_size + + self.sections = [null_section] + for i in range(1, num_sections): + ind = offset + i * size + self.sections.append(Section(data[ind:ind + size], data, i)) + + symtab = None + for s in self.sections: + if s.sh_type == SHT_SYMTAB: + assert not symtab + symtab = s + assert symtab is not None + self.symtab = symtab + + shstr = self.sections[self.elf_header.e_shstrndx] + for s in self.sections: + s.name = shstr.lookup_str(s.sh_name) + s.late_init(self.sections) + + def find_section(self, name): + for s in self.sections: + if s.name == name: + return s + return None + + def add_section(self, name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data): + shstr = self.sections[self.elf_header.e_shstrndx] + sh_name = shstr.add_str(name) + s = Section.from_parts(sh_name=sh_name, sh_type=sh_type, + sh_flags=sh_flags, sh_link=sh_link, sh_info=sh_info, + sh_addralign=sh_addralign, sh_entsize=sh_entsize, data=data, + index=len(self.sections)) + self.sections.append(s) + s.name = name + s.late_init(self.sections) + return s + + def drop_irrelevant_sections(self): + # We can only drop sections at the end, since otherwise section + # references might be wrong. Luckily, these sections typically are. + while self.sections[-1].sh_type in [SHT_MIPS_DEBUG, SHT_MIPS_GPTAB]: + self.sections.pop() + + def write(self, filename): + outfile = open(filename, 'wb') + outidx = 0 + def write_out(data): + nonlocal outidx + outfile.write(data) + outidx += len(data) + def pad_out(align): + if align and outidx % align: + write_out(b'\0' * (align - outidx % align)) + + self.elf_header.e_shnum = len(self.sections) + write_out(self.elf_header.to_bin()) + + for s in self.sections: + if s.sh_type != SHT_NOBITS and s.sh_type != SHT_NULL: + pad_out(s.sh_addralign) + s.sh_offset = outidx + write_out(s.data) + + pad_out(4) + self.elf_header.e_shoff = outidx + for s in self.sections: + write_out(s.header_to_bin()) + + outfile.seek(0) + outfile.write(self.elf_header.to_bin()) + outfile.close() + + +def is_temp_name(name): + return name.startswith('_asmpp_') + +def parse_source(f, print_source, optimized, framepointer): + if optimized: + if framepointer: + min_instr_count = 6 + skip_instr_count = 5 + else: + min_instr_count = 2 + skip_instr_count = 1 + else: + if framepointer: + min_instr_count = 7 + skip_instr_count = 7 + else: + min_instr_count = 4 + skip_instr_count = 4 + MAX_FN_SIZE = 100 + SECTIONS = ['.data', '.text', '.rodata', '.late_rodata', '.bss'] + + in_asm = False + fn_section_sizes = None + fn_ins_inds = None + asm_conts = [] + late_rodata_asm_conts = None + first_fn_name = None + cur_section = None + start_index = None + asm_functions = [] + output_lines = [] + + # A value that hopefully never appears as a 32-bit rodata constant (or we + # miscompile late rodata). Increases by 1 in each step. + cur_late_rodata_hex = 0xE0123456 + + namectr = 0 + def make_name(cat): + nonlocal namectr + namectr += 1 + return '_asmpp_{}{}'.format(cat, namectr) + + for raw_line in f: + raw_line = raw_line.rstrip() + line = raw_line.lstrip() + output_line = '' + + def add_sized(size): + if cur_section in ['.text', '.late_rodata']: + assert size % 4 == 0, "size must be a multiple of 4 on line: " + raw_line + assert size >= 0 + fn_section_sizes[cur_section] += size + if cur_section == '.text': + assert first_fn_name is not None, ".text block without an initial glabel" + fn_ins_inds.append((len(output_lines), size // 4)) + + if in_asm: + if line.startswith(')'): + in_asm = False + late_rodata = [] + late_rodata_fn_output = [] + if fn_section_sizes['.late_rodata'] > 0: + # Generate late rodata by emitting unique float constants. + # This requires 3 instructions for each 4 bytes of rodata. + # Doubles would increase 4 to 8, but unfortunately we know + # too little about alignment to be able to use them. + size = fn_section_sizes['.late_rodata'] // 4 + for i in range(0, size*3, 3): + if (cur_late_rodata_hex & 0xffff) == 0: + # Avoid lui + cur_late_rodata_hex += 1 + dummy_bytes = struct.pack('>I', cur_late_rodata_hex) + cur_late_rodata_hex += 1 + late_rodata.append(dummy_bytes) + fval, = struct.unpack('>f', dummy_bytes) + late_rodata_fn_output.append('*(volatile float*)0 = {}f;'.format(fval)) + late_rodata_fn_output.append('') + late_rodata_fn_output.append('') + temp_fn_name = None + if fn_section_sizes['.text'] > 0 or late_rodata_fn_output: + temp_fn_name = make_name('func') + output_lines[start_index] = 'void {}(void) {{'.format(temp_fn_name) + instr_count = fn_section_sizes['.text'] // 4 + assert instr_count >= min_instr_count, "too short .text block" + available_instr_count = 0 + tot_emitted = 0 + tot_skipped = 0 + fn_emitted = 0 + fn_skipped = 0 + rodata_stack = late_rodata_fn_output[::-1] + for (line, count) in fn_ins_inds: + for _ in range(count): + if (fn_emitted > MAX_FN_SIZE and instr_count - tot_emitted > min_instr_count and + (not rodata_stack or rodata_stack[-1])): + # Don't let functions become too large. When a function reaches 284 + # instructions, and -O2 -framepointer flags are passed, the IRIX + # compiler decides it is a great idea to start optimizing more. + fn_emitted = 0 + fn_skipped = 0 + output_lines[line] += ' }} void {}(void) {{ '.format(make_name('large_func')) + if fn_skipped < skip_instr_count: + fn_skipped += 1 + tot_skipped += 1 + elif rodata_stack: + output_lines[line] += rodata_stack.pop() + else: + available_instr_count += 1 + output_lines[line] += '*(volatile int*)0 = 0;' + tot_emitted += 1 + fn_emitted += 1 + if rodata_stack: + size = len(late_rodata_fn_output) // 3 + available = instr_count - tot_skipped + print("late rodata to text ratio is too high: {} / {} must be <= 1/3" + .format(size, available), file=sys.stderr) + exit(1) + output_line = '}' + rodata_name = None + if fn_section_sizes['.rodata'] > 0: + rodata_name = make_name('rodata') + output_line += ' const char {}[{}] = {{1}};'.format(rodata_name, fn_section_sizes['.rodata']) + data_name = None + if fn_section_sizes['.data'] > 0: + data_name = make_name('data') + output_line += ' char {}[{}] = {{1}};'.format(data_name, fn_section_sizes['.data']) + bss_name = None + if fn_section_sizes['.bss'] > 0: + bss_name = make_name('bss') + output_line += ' char {}[{}];'.format(bss_name, fn_section_sizes['.bss']) + asm_functions.append((first_fn_name, asm_conts, late_rodata, late_rodata_asm_conts, { + '.text': (temp_fn_name, fn_section_sizes['.text']), + '.data': (data_name, fn_section_sizes['.data']), + '.rodata': (rodata_name, fn_section_sizes['.rodata']), + '.bss': (bss_name, fn_section_sizes['.bss']), + })) + else: + line = re.sub(r'/\*.*?\*/', '', line) + line = re.sub(r'#.*', '', line) + line = line.strip() + changed_section = False + if line.startswith('glabel ') and first_fn_name is None and cur_section == '.text': + first_fn_name = line.split()[1] + if not line: + pass # empty line + elif line.startswith('glabel ') or (' ' not in line and line.endswith(':')): + pass # label + elif line.startswith('.section') or line in ['.text', '.data', '.rdata', '.rodata', '.bss', '.late_rodata']: + # section change + cur_section = '.rodata' if line == '.rdata' else line.split(',')[0].split()[-1] + changed_section = True + assert cur_section in SECTIONS, "unrecognized .section directive" + elif line.startswith('.incbin'): + add_sized(int(line.split(',')[-1].strip(), 0)) + elif line.startswith('.word') or line.startswith('.float'): + add_sized(4 * len(line.split(','))) + elif line.startswith('.double'): + add_sized(8 * len(line.split(','))) + elif line.startswith('.space'): + add_sized(int(line.split()[1], 0)) + elif line.startswith('.'): + # .macro, .ascii, .asciiz, .balign, .align, ... + assert False, 'not supported yet: ' + line + else: + # Unfortunately, macros are hard to support for .rodata -- + # we don't know how how space they will expand to before + # running the assembler, but we need that information to + # construct the C code. So if we need that we'll either + # need to run the assembler twice (at least in some rare + # cases), or change how this program is invoked. + # Similarly, we can't currently deal with pseudo-instructions + # that expand to several real instructions. + assert cur_section == '.text', "instruction or macro call in non-.text section? not supported: " + line + add_sized(4) + if cur_section == '.late_rodata': + if not changed_section: + late_rodata_asm_conts.append(line) + else: + asm_conts.append(line) + else: + if line.startswith('GLOBAL_ASM('): + in_asm = True + cur_section = '.text' + asm_conts = [] + late_rodata_asm_conts = [] + start_index = len(output_lines) + first_fn_name = None + fn_section_sizes = { + '.text': 0, + '.data': 0, + '.bss': 0, + '.rodata': 0, + '.late_rodata': 0, + } + fn_ins_inds = [] + else: + output_line = raw_line + + # Print exactly one output line per source line, to make compiler + # errors have correct line numbers. + output_lines.append(output_line) + + if print_source: + for line in output_lines: + print(line) + + return asm_functions + +def fixup_objfile(objfile_name, functions, asm_prelude, assembler): + SECTIONS = ['.data', '.text', '.rodata', '.bss'] + + with open(objfile_name, 'rb') as f: + objfile = ElfFile(f.read()) + + prev_locs = { + '.text': 0, + '.data': 0, + '.rodata': 0, + '.bss': 0, + } + to_copy = { + '.text': [], + '.data': [], + '.rodata': [], + } + asm = [] + late_rodata = [] + late_rodata_asm = [] + late_rodata_source_name = None + + # Generate an assembly file with all the assembly we need to fill in. For + # simplicity we pad with nops/.space so that addresses match exactly, so we + # don't have to fix up relocations/symbol references. + first_fn_names = set() + for (first_fn_name, body, fn_late_rodata, fn_late_rodata_body, data) in functions: + ifdefed = False + for sectype, (temp_name, size) in data.items(): + if temp_name is None: + continue + assert size > 0 + loc = objfile.symtab.find_symbol(temp_name) + if loc is None: + ifdefed = True + break + loc = loc[1] + prev_loc = prev_locs[sectype] + assert loc >= prev_loc + if loc != prev_loc: + asm.append('.section ' + sectype) + if sectype == '.text': + for i in range((loc - prev_loc) // 4): + asm.append('nop') + else: + asm.append('.space {}'.format(loc - prev_loc)) + if sectype != '.bss': + to_copy[sectype].append((loc, size)) + prev_locs[sectype] = loc + size + if not ifdefed: + if first_fn_name: + first_fn_names.add(first_fn_name) + late_rodata.extend(fn_late_rodata) + late_rodata_asm.extend(fn_late_rodata_body) + asm.append('.text') + for line in body: + asm.append(line) + if late_rodata_asm: + late_rodata_source_name = '_asmpp_late_rodata' + asm.append('.rdata') + asm.append('glabel {}'.format(late_rodata_source_name)) + asm.extend(late_rodata_asm) + + o_file = tempfile.NamedTemporaryFile(prefix='asm-processor', suffix='.o', delete=False) + o_name = o_file.name + o_file.close() + s_file = tempfile.NamedTemporaryFile(prefix='asm-processor', suffix='.s', delete=False) + s_name = s_file.name + try: + s_file.write(asm_prelude + b'\n') + for line in asm: + s_file.write(line.encode('utf-8') + b'\n') + s_file.close() + ret = os.system(assembler + " " + s_name + " -o " + o_name) + if ret != 0: + raise Exception("failed to assemble") + with open(o_name, 'rb') as f: + asm_objfile = ElfFile(f.read()) + + # Remove some clutter from objdump output + objfile.drop_irrelevant_sections() + + # Unify reginfo sections + target_reginfo = objfile.find_section('.reginfo') + source_reginfo_data = list(asm_objfile.find_section('.reginfo').data) + data = list(target_reginfo.data) + for i in range(20): + data[i] |= source_reginfo_data[i] + target_reginfo.data = bytes(data) + + # Move over section contents + modified_text_positions = set() + last_rodata_pos = 0 + for sectype in SECTIONS: + if sectype == '.bss': + continue + source = asm_objfile.find_section(sectype) + target = objfile.find_section(sectype) + if source is None or not to_copy[sectype]: + continue + assert target is not None, "must have a section to overwrite: " + sectype + data = list(target.data) + for (pos, count) in to_copy[sectype]: + data[pos:pos + count] = source.data[pos:pos + count] + if sectype == '.text': + assert count % 4 == 0 + assert pos % 4 == 0 + for i in range(count // 4): + modified_text_positions.add(pos + 4 * i) + elif sectype == '.rodata': + last_rodata_pos = pos + count + target.data = bytes(data) + + # Move over late rodata. This is heuristic, sadly, since I can't think + # of another way of doing it. + moved_late_rodata = {} + if late_rodata: + source = asm_objfile.find_section('.rodata') + target = objfile.find_section('.rodata') + source_pos = asm_objfile.symtab.find_symbol(late_rodata_source_name) + assert source_pos is not None and source_pos[0] == source.index + source_pos = source_pos[1] + new_data = list(target.data) + for dummy_bytes in late_rodata: + pos = target.data.index(dummy_bytes, last_rodata_pos) + new_data[pos:pos+4] = source.data[source_pos:source_pos+4] + moved_late_rodata[source_pos] = pos + last_rodata_pos = pos + 4 + source_pos += 4 + target.data = bytes(new_data) + + # Merge strtab data. + strtab_adj = len(objfile.symtab.strtab.data) + objfile.symtab.strtab.data += asm_objfile.symtab.strtab.data + + # Find relocated symbols + relocated_symbols = set() + for sectype in SECTIONS: + for obj in [asm_objfile, objfile]: + sec = obj.find_section(sectype) + if sec is None: + continue + for reltab in sec.relocated_by: + for rel in reltab.relocations: + relocated_symbols.add(obj.symtab.symbol_entries[rel.sym_index]) + + # Move over symbols, deleting the temporary function labels. + # Sometimes this naive procedure results in duplicate symbols, or UNDEF + # symbols that are also defined the same .o file. Hopefully that's fine. + # Skip over local symbols that aren't used relocated against, to avoid + # conflicts. + new_local_syms = [s for s in objfile.symtab.local_symbols() if not is_temp_name(s.name)] + new_global_syms = [s for s in objfile.symtab.global_symbols() if not is_temp_name(s.name)] + for i, s in enumerate(asm_objfile.symtab.symbol_entries): + is_local = (i < asm_objfile.symtab.sh_info) + if is_local and s not in relocated_symbols: + continue + if is_temp_name(s.name): + continue + if s.st_shndx != SHN_UNDEF: + section_name = asm_objfile.sections[s.st_shndx].name + assert section_name in SECTIONS, "Generated assembly .o must only have symbols for .text, .data, .rodata and UNDEF, but found {}".format(section_name) + s.st_shndx = objfile.find_section(section_name).index + # glabel's aren't marked as functions, making objdump output confusing. Fix that. + if s.name in first_fn_names: + s.type = STT_FUNC + if objfile.sections[s.st_shndx].name == '.rodata' and s.st_value in moved_late_rodata: + s.st_value = moved_late_rodata[s.st_value] + s.st_name += strtab_adj + if is_local: + new_local_syms.append(s) + else: + new_global_syms.append(s) + new_syms = new_local_syms + new_global_syms + for i, s in enumerate(new_syms): + s.new_index = i + objfile.symtab.data = b''.join(s.to_bin() for s in new_syms) + objfile.symtab.sh_info = len(new_local_syms) + + # Move over relocations + for sectype in SECTIONS: + source = asm_objfile.find_section(sectype) + target = objfile.find_section(sectype) + + if target is not None: + # fixup relocation symbol indices, since we butchered them above + for reltab in target.relocated_by: + nrels = [] + for rel in reltab.relocations: + if sectype == '.text' and rel.r_offset in modified_text_positions: + # don't include relocations for late_rodata dummy code + continue + # hopefully we don't have relocations for local or + # temporary symbols, so new_index exists + rel.sym_index = objfile.symtab.symbol_entries[rel.sym_index].new_index + nrels.append(rel) + reltab.relocations = nrels + reltab.data = b''.join(rel.to_bin() for rel in nrels) + + if not source: + continue + + target_reltab = objfile.find_section('.rel' + sectype) + target_reltaba = objfile.find_section('.rela' + sectype) + for reltab in source.relocated_by: + for rel in reltab.relocations: + rel.sym_index = asm_objfile.symtab.symbol_entries[rel.sym_index].new_index + if sectype == '.rodata' and rel.r_offset in moved_late_rodata: + rel.r_offset = moved_late_rodata[rel.r_offset] + new_data = b''.join(rel.to_bin() for rel in reltab.relocations) + if reltab.sh_type == SHT_REL: + if not target_reltab: + target_reltab = objfile.add_section('.rel' + sectype, + sh_type=SHT_REL, sh_flags=0, + sh_link=objfile.symtab.index, sh_info=target.index, + sh_addralign=4, sh_entsize=8, data=b'') + target_reltab.data += new_data + else: + if not target_reltaba: + target_reltaba = objfile.add_section('.rela' + sectype, + sh_type=SHT_RELA, sh_flags=0, + sh_link=objfile.symtab.index, sh_info=target.index, + sh_addralign=4, sh_entsize=12, data=b'') + target_reltaba.data += new_data + + objfile.write(objfile_name) + finally: + s_file.close() + os.remove(s_name) + try: + os.remove(o_name) + except: + pass + +def main(): + parser = argparse.ArgumentParser(description="Pre-process .c files and post-process .o files to enable embedding assembly into C.") + parser.add_argument('filename', help="path to .c code") + parser.add_argument('--post-process', dest='objfile', help="path to .o file to post-process") + parser.add_argument('--assembler', dest='assembler', help="assembler command (e.g. \"mips-linux-gnu-as -march=vr4300 -mabi=32\")") + parser.add_argument('--asm-prelude', dest='asm_prelude', help="path to a file containing a prelude to the assembly file (with .set and .macro directives, e.g.)") + parser.add_argument('-framepointer', dest='framepointer', action='store_true') + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-O2', dest='optimized', action='store_true') + group.add_argument('-g', dest='optimized', action='store_false') + args = parser.parse_args() + + if args.objfile is None: + with open(args.filename) as f: + parse_source(f, print_source=True, optimized=args.optimized, framepointer=args.framepointer) + else: + assert args.assembler is not None, "must pass assembler command" + with open(args.filename) as f: + functions = parse_source(f, print_source=False, optimized=args.optimized, framepointer=args.framepointer) + if not functions: + return + asm_prelude = b'' + if args.asm_prelude: + with open(args.asm_prelude, 'rb') as f: + asm_prelude = f.read() + fixup_objfile(args.objfile, functions, asm_prelude, args.assembler) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tools/asmpreproc/compile.sh b/tools/asmpreproc/compile.sh new file mode 100644 index 000000000..7136161b1 --- /dev/null +++ b/tools/asmpreproc/compile.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +INPUT="$1" +OUTPUT="${INPUT%.c}.o" +INCLUDE="-I include -I include/libultra" + +CC="$QEMU_IRIX -silent -L $IRIX_ROOT $IRIX_ROOT/usr/bin/cc" +CFLAGS="-Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -fullwarn -wlint -woff 819,820,852,821 -signed $INCLUDE -mips2" +AS="mips-linux-gnu-as" +ASFLAGS="-march=vr4300 -mabi=32 $INCLUDE" + +python3 tools/asmpreproc/asm-processor.py -O2 "$INPUT" | $CC -c $CFLAGS tools/asmpreproc/include-stdin.c -o "$OUTPUT" -O2 +python3 tools/asmpreproc/asm-processor.py -O2 "$INPUT" --post-process "$OUTPUT" --assembler "$AS $ASFLAGS" --asm-prelude tools/asmpreproc/prelude.s + +mv $OUTPUT ${OUTPUT/src/build} diff --git a/tools/asmpreproc/include-stdin.c b/tools/asmpreproc/include-stdin.c new file mode 100644 index 000000000..c21aa6f65 --- /dev/null +++ b/tools/asmpreproc/include-stdin.c @@ -0,0 +1,2 @@ +// (this is used for piping input to the IRIX compiler without needing to make a temporary .c file) +#include "/dev/stdin" diff --git a/tools/asmpreproc/prelude.s b/tools/asmpreproc/prelude.s new file mode 100644 index 000000000..0c111a2a9 --- /dev/null +++ b/tools/asmpreproc/prelude.s @@ -0,0 +1,5 @@ +.set noat +.set noreorder +.set gp=64 +.include "macros.inc" + diff --git a/tools/extract b/tools/extract index 24d6302af..7e0eaea5c 100755 --- a/tools/extract +++ b/tools/extract @@ -161,7 +161,7 @@ class Extractor: self.write('ucode/rspboot.bin', self.rom[0x40:0x1000]) self.write('ucode/boot.bin', self.rom[0x1000:0x3050]) self.write('ucode/library.bin', self.decompress(self.rom[0x3050:])) - self.write('ucode/decompressor.bin', self.rom[0x4e850:0x4fc30]) + self.write('ucode/rarezip.bin', self.rom[0x4e850:0x4fc40]) self.extract_ucode_game() def extract_ucode_game(self):