Skip to content

Get emulator to correctly execute gcc -Os Fibonacci #313

@kevinacahalan

Description

@kevinacahalan
static int fib(int n)
{
    if (n <= 1)
        return n;
    return fib(n - 1) + fib(n - 2);
}
 
int main()
{
    int n = 6;
    int ans = fib(n);
    // return ans;
    return ans + 100;
}

The following code was partially generated with GCC using the -Os option. The return from main was replaced with a syscall to halt. Branch and load instructions were moved around as needed to undo GCC reorganization of instructions. GCC did instruction reorganization to fill the delay slots. Our emulator does not implement delay slots.

This code should result in 108 in register $2. Currently this code executes forever. There is some fishy bug that needs to be fixed.

fib(int):
        addiu   $sp,$sp,-40
        sw      $18,32($sp)
        sw      $17,28($sp)
        sw      $16,24($sp)
        sw      $31,36($sp)
        move    $16,$4
        move    $17,$4
        move    $18,$0
$L3:
        addi    $5,$zero, 2
        slt     $2,$17,$5
        andi    $2,$16,0x1
        bne     $2,$0,$L5

        addiu   $4,$17,-1
        jal     fib(int)

        addiu   $17,$17,-2
        addu    $18,$18,$2
        b       $L3

$L5:
        lw      $31,36($sp)
        lw      $17,28($sp)
        lw      $16,24($sp)
        addu    $2,$2,$18
        lw      $18,32($sp)
        addiu   $sp,$sp,40
        jr      $31

main:
        addiu   $sp,$sp,-32
        sw      $31,28($sp)
        li      $4,6                        # 0x6
        jal     fib(int)

        lw      $31,28($sp)
        addiu   $2,$2,100
        addiu   $sp,$sp,32
        syscall

Here's the initial GCC generated code:

fib(int):
        addiu   $sp,$sp,-40
        sw      $18,32($sp)
        sw      $17,28($sp)
        sw      $16,24($sp)
        sw      $31,36($sp)
        move    $16,$4
        move    $17,$4
        move    $18,$0
$L3:
        slt     $2,$17,2
        bne     $2,$0,$L5
        andi    $2,$16,0x1

        jal     fib(int)
        addiu   $4,$17,-1

        addiu   $17,$17,-2
        b       $L3
        addu    $18,$18,$2

$L5:
        lw      $31,36($sp)
        lw      $17,28($sp)
        lw      $16,24($sp)
        addu    $2,$2,$18
        lw      $18,32($sp)
        jr      $31
        addiu   $sp,$sp,40

main:
        addiu   $sp,$sp,-32
        sw      $31,28($sp)
        jal     fib(int)
        li      $4,6                        # 0x6

        lw      $31,28($sp)
        addiu   $2,$2,100
        jr      $31
        addiu   $sp,$sp,32

Bugs to look out for:

  • Emulation core doing something wrong
  • Some instruction being assembled wrong
  • Kevin messed up undoing GCC instruction reorganization (unlikely)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    🔖 Ready to Start

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions