/* 
 * File:        fact.s
 * Description: An iterative factorial function.
 */
        .arch   armv8-a

        .global factorial

        .text
        .align  2

factorial:                              // The factorial function
        stp     fp, lr, [sp,-16]!       
        mov     fp, sp
        sub     sp, sp, #32             // Allocate stack space for three local variables

        // Initialize variables
        // n is the argument, stored at [fp, -8]
        // f accumulates the product, stored at [fp, -16]
        // i is the loop control, stored at [fp, -24]
        
        str     x0, [fp, -8]            // Store n
        mov     x0, #1                  // Store f
        str     x0, [fp, -16]
        mov     x0, #2                  // Store i
        str     x0, [fp, -24]

loop:   
        ldr     x0, [fp, -24]           // Compare i to n
        ldr     x1, [fp, -8]
        cmp     x0, x1
        bgt     done

        ldr     x0, [fp, -24]           // Multiply f by i
        ldr     x1, [fp, -16]
        mul     x1, x1, x0
        str     x1, [fp, -16]

        ldr     x0, [sp, 16]            // Increment i
        mov     x1, #1                  
        add     x0, x0, #1              
        str     x0, [fp, -24]
        b       loop                    // Jump to the top of the loop

done:
        
        ldr     x0, [fp, -16]           // Return from fact
        add     sp, sp, #32
        ldp     fp, lr, [sp], 16
        ret
