Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EABI support #149

Open
tge-was-taken opened this issue Oct 3, 2021 · 1 comment
Open

Add EABI support #149

tge-was-taken opened this issue Oct 3, 2021 · 1 comment

Comments

@tge-was-taken
Copy link

Argument registers are considered "unset" despite the given function prototype.

Context

void* dds3StartProcess(char *namestr, int priority, s16 starttimer, s16 shutdowntimer, void* processfunc, void* shutdownfunc, void* data);
s32 fun_100760(void* a1);
s32 fun_1009A0(void* a1);
s32 fun_2A8AF8(s32 a1);

Assembly (ee-gcc)

glabel dds3StartProcess
addiu $sp, $sp, -0x50
sd $s1, 0x8($sp)
move $s1, $a0
addiu $a0, $zero, 0x50
sd $s0, 0x0($sp)
sd $s2, 0x10($sp)
move $s2, $a1
sd $s3, 0x18($sp)
move $s3, $a2
sd $s4, 0x20($sp)
move $s4, $a3
sd $s5, 0x28($sp)
move $s5, $a4
sd $s6, 0x30($sp)
move $s6, $a5
sd $s7, 0x38($sp)
sd $ra, 0x40($sp)
jal fun_2a8af8
move $s7, $a6
move $s0, $v0
beqz $s0, .lbl_1016c0
move $a3, $zero
sw $zero, 0x18($s0)
lbu $v0, 0x0($s1)
sll $v1, $v0, 0x18
beqz $v1, .lbl_101660
sb $v0, 0x0($s0)
move $a2, $s1
lb $a0, 0x0($a2)
nop 
.lbl_101628:
addiu $a3, $a3, 0x1
lw $v1, 0x18($s0)
addu $v0, $s1, $a3
move $a2, $v0
addu $a1, $s0, $a3
addu $v1, $v1, $a0
slti $a0, $a3, 0x18
sw $v1, 0x18($s0)
lbu $v0, 0x0($a2)
sll $v1, $v0, 0x18
beqz $v1, .lbl_101660
sb $v0, 0x0($a1)
bnel $a0, $zero, .lbl_101628
lb $a0, 0x0($a2)
.lbl_101660:
addiu $v0, $zero, 0x1
sw $s2, 0x20($s0)
sw $v0, 0x1c($s0)
move $a0, $s0
sh $s3, 0x2c($s0)
sh $s4, 0x2e($s0)
sw $s5, 0x30($s0)
sw $s6, 0x34($s0)
sw $s7, 0x38($s0)
sb $zero, 0x17($s0)
sw $zero, 0x24($s0)
sw $zero, 0x28($s0)
sw $zero, 0x3c($s0)
sw $zero, 0x40($s0)
sw $zero, 0x44($s0)
sw $zero, 0x48($s0)
jal fun_100760
sw $zero, 0x4c($s0)
lh $v0, 0x2c($s0)
bnez $v0, .lbl_1016c0
move $v0, $s0
jal fun_1009a0
move $a0, $s0
move $v0, $s0
.lbl_1016c0:
ld $s0, 0x0($sp)
ld $s1, 0x8($sp)
ld $s2, 0x10($sp)
ld $s3, 0x18($sp)
ld $s4, 0x20($sp)
ld $s5, 0x28($sp)
ld $s6, 0x30($sp)
ld $s7, 0x38($sp)
ld $ra, 0x40($sp)
jr $ra
addiu $sp, $sp, 0x50
nop 

mips_to_c output

? fun_1009a0(void *); // extern
void *fun_2a8af8(?); // extern

void *dds3StartProcess(s8 *namestr, s32 priority, s16 starttimer, s16 shutdowntimer, void *processfunc, void *shutdownfunc, void *data) {
    s32 temp_a3;
    s8 *temp_v0_3;
    u8 temp_v0_2;
    u8 temp_v0_4;
    void *temp_ret;
    void *temp_v0;
    s8 phi_a0;
    s32 phi_a3;

    temp_ret = fun_2a8af8(0x50);
    temp_v0 = temp_ret;
    phi_a3 = 0;
    if (temp_v0 != 0) {
        temp_v0->unk18 = 0;
        temp_v0_2 = (u8) *namestr;
        temp_v0->unk0 = temp_v0_2;
        if ((temp_v0_2 << 0x18) != 0) {
            phi_a0 = *namestr;
loop_3:
            temp_a3 = phi_a3 + 1;
            temp_v0_3 = &namestr[temp_a3];
            temp_v0->unk18 = (s32) (temp_v0->unk18 + phi_a0);
            temp_v0_4 = (u8) *temp_v0_3;
            *(temp_v0 + temp_a3) = temp_v0_4;
            phi_a3 = temp_a3;
            if ((temp_v0_4 << 0x18) != 0) {
                if (temp_a3 < 0x18) {
                    phi_a0 = *temp_v0_3;
                    goto loop_3;
                }
            }
        }
        temp_v0->unk20 = priority;
        temp_v0->unk1C = 1;
        temp_v0->unk2C = starttimer;
        temp_v0->unk2E = shutdowntimer;
        temp_v0->unk30 = (s32) MIPS2C_ERROR(Read from unset register $a4);
        temp_v0->unk34 = (s32) MIPS2C_ERROR(Read from unset register $a5);
        temp_v0->unk38 = (s32) MIPS2C_ERROR(Read from unset register $a6);
        temp_v0->unk17 = 0;
        temp_v0->unk24 = 0;
        temp_v0->unk28 = 0;
        temp_v0->unk3C = 0;
        temp_v0->unk40 = 0;
        temp_v0->unk44 = 0;
        temp_v0->unk48 = 0;
        temp_v0->unk4C = 0;
        fun_100760(temp_v0);
        if (temp_v0->unk2C == 0) {
            fun_1009a0(temp_v0);
        }
    }
    return temp_ret;
}
@tge-was-taken
Copy link
Author

To provide further context, this code uses the EABI64 ABI in single float mode, which is described as follows:

I8/I16 arguments promoted to I32
Integer arguments are passed in integer registers: $a0, $a1, $a2, $a3, $t0 ($a4), $t1 ($a5), $t2 ($a6), $t3 ($a7)
If single float mode, single FP arguments are passed in pairs within 32-bit mode: $f12, $f13, $f14, $f15, $f16, $f17, $f18, $f19
otherwise: $f12, $f14, $f16, $f18
If not single float mode, the first 4 double fp arguments are passed in single FP registers: $d6, $d7, $d8, $d9
I32, F32 values get stored in stack slots that are 4 bytes in size and 4-byte aligned
F64 values get stored in stack slots that are 8 bytes in size and 8-byte aligned
I32 are returned in registers: $v0, $v1
F32 are returned in registers: $f0, $f1
If not single float mode, F64 are returned in register: $d0

@tge-was-taken tge-was-taken changed the title Argument registers are considered "unset" despite given function prototype Add EABI support Oct 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant