Skip to content

Instantly share code, notes, and snippets.

@inequation
Created May 14, 2012 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inequation/2695267 to your computer and use it in GitHub Desktop.
Save inequation/2695267 to your computer and use it in GitHub Desktop.
Lab AK - SPARC
#include <stdio.h>
#include <stdlib.h>
extern int f(int start, int end, int step);
// a(n) = n * a(n - 1) * (a(n - 2))^2
// a(1) = 3
// a(2) = 4
extern int a(int n);
int f_ref(int start, int end, int step) {
int result = start;
int i;
if (start < 1 || end < start || step < 1)
return 0;
for (i = start + step; i <= end; i += step)
result *= i;
return result;
}
int a_ref(int n) {
int prev[2] = {3, 4};
int i, a_nm2;
if (n < 1)
return -1;
for (i = 3; i <= n; ++i) {
a_nm2 = prev[(i - 3) % 2]; // a(n - 2)
prev[(i - 1) % 2] = i * prev[(i - 2) % 2] * a_nm2 * a_nm2;
}
return prev[(n - 1) % 2];
}
#define F_START 1
#define F_OFFSET 9
#define F_STEP 3
#define F_END 20
#define A_START 1
#define A_END 10
int main() {
int i, r_c, r_a;
for (i = F_START; i < F_END; ++i) {
r_c = f_ref (i, i + F_OFFSET, F_STEP);
r_a = f (i, i + F_OFFSET, F_STEP);
printf("f(%d -> %d, %d) = %d (C) vs %d (asm)\n", i, i + F_OFFSET, F_STEP, r_c, r_a);
}
printf("\n");
for (i = A_START; i < A_END; ++i) {
r_c = a_ref (i);
r_a = a (i);
printf("a(%d) = %d (C) vs %d (asm)\n", i, r_c, r_a);
}
return 0;
}
! extern int f(int n);
.global f
.proc 4
f: ! %i0 - start, %i1 - end, %i2 - step
save %sp, -96, %sp ! save register window
! bail if arguments out of range
cmp %i0, 1
bl f_ret_zero
nop
cmp %i1, %i0
ble f_ret_zero
nop
cmp %i2, 1
bl f_ret_zero
nop
! start the loop
! %l0 - result
! %l1 - loop counter
mov %i0, %l0
mov %l0, %l1
f_loop:
add %l1, %i2, %l1
cmp %l1, %i1 ! are we past the end?
bg f_end ! yes, return it
mov %l0, %i0
ba f_loop ! nope, make another iteration
umul %l0, %l1, %l0
f_ret_zero:
ba f_end
mov 0, %i0
f_end:
ret
restore ! restore register window
! extern int a(int n);
! a(n) = n * a(n - 1) * (a(n - 2))^2
! a(1) = 3
! a(2) = 4
.global a
.proc 4
a: ! %i0 - n
save %sp, -96, %sp ! save register window
! save off original argument
mov %i0, %l4
! bail if n out of range
cmp %l4, 1
bl a_end
mov 0, %i0
! return a(1)
cmp %l4, 1
be a_end
mov 3, %i0
! return a(2)
cmp %l4, 2
be a_end
mov 4, %i0
! start the loop
! %l0 - a(n)
! %l1 - a(n - 1)
! %l2 - a(n - 2)
! %l3 - loop counter
! %l4 - original n
! %l5 - [a(n - 2)] ^ 2
mov 3, %l3
mov 3, %l2
mov 4, %l1
a_loop:
cmp %l3, %l4
bg a_end
mov %l1, %i0 ! return result from last iteration
! calculate a(n)
umul %l2, %l2, %l5 ! [a(n - 2)] ^ 2
umul %l3, %l1, %l0 ! a(n) = n * a(n - 1) * ...
umul %l0, %l5, %l0 ! ... * [a(n - 2)] ^ 2
! push the sequence elements down
mov %l1, %l2
mov %l0, %l1
ba a_loop
add 1, %l3, %l3
a_end:
ret
restore ! restore register window
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment