mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Implement a correct generation of Fibonacci numbers.
* doc/body.texi: Change documentation to no longer say it is a variant of the Fibonacci sequence, and document a proper implementation. Thanks to Jon Arintok for pointing out that the Fibonacci sequence generation was incorrect. It was documented, but still confusing. * check/fib.tst, check/fib.ok, check/bp.tst, check/bp.ok, doc/ifib.c, doc/rbif.c: Implement a proper Fibonacci sequence implementation.
This commit is contained in:
parent
fd57359498
commit
76876dd7bf
9 changed files with 80 additions and 65 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2015-11-30 Paulo Andrade <pcpa@gnu.org>
|
||||
|
||||
* doc/body.texi: Change documentation to no longer say
|
||||
it is a variant of the Fibonacci sequence, and document
|
||||
a proper implementation.
|
||||
Thanks to Jon Arintok for pointing out that the Fibonacci
|
||||
sequence generation was incorrect. It was documented, but
|
||||
still confusing.
|
||||
|
||||
* check/fib.tst, check/fib.ok, check/bp.tst, check/bp.ok,
|
||||
doc/ifib.c, doc/rbif.c: Implement a proper Fibonacci
|
||||
sequence implementation.
|
||||
|
||||
2015-07-03 Paulo Andrade <pcpa@gnu.org>
|
||||
|
||||
* lib/jit_mips-cpu.c: Correct definition of htonr_ul.
|
||||
|
|
1
THANKS
1
THANKS
|
@ -16,3 +16,4 @@ Trent Nelson <trent@snakebite.org>
|
|||
Vitaly Magerya <vmagerya@gmail.com>
|
||||
Brandon Invergo <brandon@gnu.org>
|
||||
Holger Hans Peter Freyther <holger@moiji-mobile.com>
|
||||
Jon Arintok <jon.arintok@gmail.com>
|
||||
|
|
|
@ -1 +1 @@
|
|||
nfibs(32) = 7049155
|
||||
nfibs(32) = 2178309
|
||||
|
|
16
check/bp.tst
16
check/bp.tst
|
@ -9,9 +9,11 @@ fmt:
|
|||
rfibs:
|
||||
prolog
|
||||
arg $in
|
||||
getarg %v0 $in /* V0 = N */
|
||||
|
||||
blti_u out %v0 2
|
||||
getarg %r0 $in /* R0 = N */
|
||||
beqi out %r0 0
|
||||
movr %v0 %r0 /* V0 = R0 */
|
||||
movi %r0 1
|
||||
blei_u out %v0 2
|
||||
subi %v1 %v0 1 /* V1 = N-1 */
|
||||
subi %v2 %v0 2 /* V1 = N-2 */
|
||||
prepare
|
||||
|
@ -21,12 +23,10 @@ rfibs:
|
|||
prepare
|
||||
pushargr %v2
|
||||
finishi rfibs
|
||||
retval %v2 /* V2 = rfibs(N-2) */
|
||||
addi %v1 %v1 1
|
||||
addr %r0 %v1 %v2
|
||||
retr %r0
|
||||
retval %r0 /* R0 = rfibs(N-2) */
|
||||
addr %r0 %r0 %v1
|
||||
out:
|
||||
reti 1
|
||||
retr %r0
|
||||
epilog
|
||||
|
||||
name main
|
||||
|
|
|
@ -1 +1 @@
|
|||
nfibs(32) = 7049155
|
||||
nfibs(32) = 2178309
|
||||
|
|
|
@ -9,19 +9,21 @@ format:
|
|||
nfibs:
|
||||
prolog
|
||||
arg $in
|
||||
getarg %r2 $in // R2 = n
|
||||
movi %r1 1
|
||||
blti_u ref %r2 2
|
||||
subi %r2 %r2 1
|
||||
getarg %r0 $in // R0 = n
|
||||
beqi ref %r0 0
|
||||
movr %r1 %r0
|
||||
movi %r0 1
|
||||
blti_u ref %r1 2
|
||||
subi %r2 %r1 2
|
||||
movr %r1 %r0
|
||||
loop:
|
||||
subi %r2 %r2 1 // decr. counter
|
||||
addr %v0 %r0 %r1 // V0 = R0 + R1
|
||||
movr %r0 %r1 // R0 = R1
|
||||
addi %r1 %v0 1 // R1 = V0 + 1
|
||||
movr %v0 %r0 // V0 = R0
|
||||
addr %r0 %r0 %r1 // R0 = R0 + R1
|
||||
movr %r1 %v0 // R1 = V0
|
||||
bnei loop %r2 0 // if (R2) goto loop
|
||||
ref:
|
||||
retr %r1 // RET = R1
|
||||
retr %r0 // RET = R0
|
||||
epilog
|
||||
|
||||
name main
|
||||
|
|
|
@ -1291,25 +1291,14 @@ generation so powerful.
|
|||
@node Fibonacci
|
||||
@section Fibonacci numbers
|
||||
|
||||
The code in this section calculates a variant of the Fibonacci sequence.
|
||||
While the traditional Fibonacci sequence is modeled by the recurrence
|
||||
relation:
|
||||
The code in this section calculates the Fibonacci sequence. That is
|
||||
modeled by the recurrence relation:
|
||||
@display
|
||||
f(0) = f(1) = 1
|
||||
f(0) = 0
|
||||
f(1) = f(2) = 1
|
||||
f(n) = f(n-1) + f(n-2)
|
||||
@end display
|
||||
|
||||
@noindent
|
||||
the functions in this section calculates the following sequence, which
|
||||
is more interesting as a benchmark@footnote{That's because, as is
|
||||
easily seen, the sequence represents the number of activations of the
|
||||
@code{nfibs} procedure that are needed to compute its value through
|
||||
recursion.}:
|
||||
@display
|
||||
fib(0) = fib(1) = 1
|
||||
fib(n) = fib(n-1) + fib(n-2) + 1
|
||||
@end display
|
||||
|
||||
The purpose of this example is to introduce branches. There are two
|
||||
kind of branches: backward branches and forward branches. We'll
|
||||
present the calculation in a recursive and iterative form; the
|
||||
|
@ -1330,6 +1319,7 @@ int main(int argc, char *argv[])
|
|||
jit_node_t *call;
|
||||
jit_node_t *in; @rem{/* offset of the argument */}
|
||||
jit_node_t *ref; @rem{/* to patch the forward reference */}
|
||||
jit_node_t *zero; @rem{/* to patch the forward reference */}
|
||||
|
||||
init_jit(argv[0]);
|
||||
_jit = jit_new_state();
|
||||
|
@ -1337,8 +1327,11 @@ int main(int argc, char *argv[])
|
|||
label = jit_label();
|
||||
jit_prolog ();
|
||||
in = jit_arg ();
|
||||
jit_getarg (JIT_V0, in); @rem{/* V0 = n */}
|
||||
ref = jit_blti (JIT_V0, 2);
|
||||
jit_getarg (JIT_V0, in); @rem{/* R0 = n */}
|
||||
zero = jit_beqi (JIT_R0, 0);
|
||||
jit_movr (JIT_V0, JIT_R0); /* V0 = R0 */
|
||||
jit_movi (JIT_R0, 1);
|
||||
ref = jit_blei (JIT_V0, 2);
|
||||
jit_subi (JIT_V1, JIT_V0, 1); @rem{/* V1 = n-1 */}
|
||||
jit_subi (JIT_V2, JIT_V0, 2); @rem{/* V2 = n-2 */}
|
||||
jit_prepare();
|
||||
|
@ -1350,13 +1343,11 @@ int main(int argc, char *argv[])
|
|||
jit_pushargr(JIT_V2);
|
||||
call = jit_finishi(NULL);
|
||||
jit_patch_at(call, label);
|
||||
jit_retval(JIT_V2); @rem{/* V2 = fib(n-2) */}
|
||||
jit_addi(JIT_V1, JIT_V1, 1);
|
||||
jit_addr(JIT_R0, JIT_V1, JIT_V2); @rem{/* R0 = V1 + V2 + 1 */}
|
||||
jit_retr(JIT_R0);
|
||||
jit_retval(JIT_R0); @rem{/* R0 = fib(n-2) */}
|
||||
jit_addr(JIT_R0, JIT_R0, JIT_V1); @rem{/* R0 = R0 + V1 */}
|
||||
|
||||
jit_patch(ref); @rem{/* patch jump */}
|
||||
jit_movi(JIT_R0, 1); @rem{/* R0 = 1 */}
|
||||
jit_patch(zero); @rem{/* patch jump */}
|
||||
jit_retr(JIT_R0);
|
||||
|
||||
@rem{/* call the generated code@comma{} passing 32 as an argument */}
|
||||
|
@ -1403,6 +1394,7 @@ int main(int argc, char *argv[])
|
|||
pifi fib;
|
||||
jit_node_t *in; @rem{/* offset of the argument */}
|
||||
jit_node_t *ref; @rem{/* to patch the forward reference */}
|
||||
jit_node_t *zero; @rem{/* to patch the forward reference */}
|
||||
jit_node_t *jump; @rem{/* jump to start of loop */}
|
||||
jit_node_t *loop; @rem{/* start of the loop */}
|
||||
|
||||
|
@ -1411,22 +1403,24 @@ int main(int argc, char *argv[])
|
|||
|
||||
jit_prolog ();
|
||||
in = jit_arg ();
|
||||
jit_getarg (JIT_R2, in); @rem{/* R2 = n */}
|
||||
jit_movi (JIT_R1, 1);
|
||||
ref = jit_blti (JIT_R2, 2);
|
||||
jit_subi (JIT_R2, JIT_R2, 1);
|
||||
jit_getarg (JIT_R0, in); @rem{/* R0 = n */}
|
||||
zero = jit_beqi (JIT_R0, 0);
|
||||
jit_movr (JIT_R1, JIT_R0);
|
||||
jit_movi (JIT_R0, 1);
|
||||
ref = jit_blti (JIT_R1, 2);
|
||||
jit_subi (JIT_R2, JIT_R2, 2);
|
||||
jit_movr (JIT_R1, JIT_R0);
|
||||
|
||||
loop= jit_label();
|
||||
jit_subi (JIT_R2, JIT_R2, 1); @rem{/* decr. counter */}
|
||||
jit_addr (JIT_V0, JIT_R0, JIT_R1); @rem{/* V0 = R0 + R1 */}
|
||||
jit_movr (JIT_R0, JIT_R1); @rem{/* R0 = R1 */}
|
||||
jit_addi (JIT_R1, JIT_V0, 1); @rem{/* R1 = V0 + 1 */}
|
||||
jump= jit_bnei (JIT_R2, 0); @rem{/* if (R2) goto loop; */}
|
||||
jit_patch_at(jump, label);
|
||||
jit_movr (JIT_V0, JIT_R0); /* V0 = R0 */
|
||||
jit_addr (JIT_R0, JIT_R0, JIT_R1); /* R0 = R0 + R1 */
|
||||
jit_movr (JIT_R1, JIT_V0); /* R1 = V0 */
|
||||
jump= jit_bnei (JIT_R2, 0); /* if (R2) goto loop; */
|
||||
jit_patch_at(jump, loop);
|
||||
|
||||
jit_patch(ref); @rem{/* patch forward jump */}
|
||||
jit_movr (JIT_R0, JIT_R1); @rem{/* R0 = R1 */}
|
||||
jit_patch(zero); @rem{/* patch forward jump */}
|
||||
jit_retr (JIT_R0);
|
||||
|
||||
@rem{/* call the generated code@comma{} passing 36 as an argument */}
|
||||
|
|
19
doc/ifib.c
19
doc/ifib.c
|
@ -10,6 +10,7 @@ int main(int argc, char *argv[])
|
|||
pifi fib;
|
||||
jit_node_t *in; /* offset of the argument */
|
||||
jit_node_t *ref; /* to patch the forward reference */
|
||||
jit_node_t *zero; /* to patch the forward reference */
|
||||
jit_node_t *jump; /* jump to start of loop */
|
||||
jit_node_t *loop; /* start of the loop */
|
||||
|
||||
|
@ -18,22 +19,24 @@ int main(int argc, char *argv[])
|
|||
|
||||
jit_prolog ();
|
||||
in = jit_arg ();
|
||||
jit_getarg (JIT_R2, in); /* R2 = n */
|
||||
jit_movi (JIT_R1, 1);
|
||||
ref = jit_blti (JIT_R2, 2);
|
||||
jit_subi (JIT_R2, JIT_R2, 1);
|
||||
jit_getarg (JIT_R0, in); /* R0 = n */
|
||||
zero = jit_beqi (JIT_R0, 0);
|
||||
jit_movr (JIT_R1, JIT_R0);
|
||||
jit_movi (JIT_R0, 1);
|
||||
ref = jit_blei (JIT_R1, 2);
|
||||
jit_subi (JIT_R2, JIT_R1, 2);
|
||||
jit_movr (JIT_R1, JIT_R0);
|
||||
|
||||
loop= jit_label();
|
||||
jit_subi (JIT_R2, JIT_R2, 1); /* decr. counter */
|
||||
jit_addr (JIT_V0, JIT_R0, JIT_R1); /* V0 = R0 + R1 */
|
||||
jit_movr (JIT_R0, JIT_R1); /* R0 = R1 */
|
||||
jit_addi (JIT_R1, JIT_V0, 1); /* R1 = V0 + 1 */
|
||||
jit_movr (JIT_V0, JIT_R0); /* V0 = R0 */
|
||||
jit_addr (JIT_R0, JIT_R0, JIT_R1); /* R0 = R0 + R1 */
|
||||
jit_movr (JIT_R1, JIT_V0); /* R1 = V0 */
|
||||
jump= jit_bnei (JIT_R2, 0); /* if (R2) goto loop; */
|
||||
jit_patch_at(jump, loop);
|
||||
|
||||
jit_patch(ref); /* patch forward jump */
|
||||
jit_movr (JIT_R0, JIT_R1); /* R0 = R1 */
|
||||
jit_patch(zero); /* patch forward jump */
|
||||
jit_retr (JIT_R0);
|
||||
|
||||
/* call the generated code, passing 36 as an argument */
|
||||
|
|
16
doc/rfib.c
16
doc/rfib.c
|
@ -12,6 +12,7 @@ int main(int argc, char *argv[])
|
|||
jit_node_t *call;
|
||||
jit_node_t *in; /* offset of the argument */
|
||||
jit_node_t *ref; /* to patch the forward reference */
|
||||
jit_node_t *zero; /* to patch the forward reference */
|
||||
|
||||
init_jit(argv[0]);
|
||||
_jit = jit_new_state();
|
||||
|
@ -19,8 +20,11 @@ int main(int argc, char *argv[])
|
|||
label = jit_label();
|
||||
jit_prolog ();
|
||||
in = jit_arg ();
|
||||
jit_getarg (JIT_V0, in); /* V0 = n */
|
||||
ref = jit_blti (JIT_V0, 2);
|
||||
jit_getarg (JIT_R0, in); /* R0 = n */
|
||||
zero = jit_beqi (JIT_R0, 0);
|
||||
jit_movr (JIT_V0, JIT_R0); /* V0 = R0 */
|
||||
jit_movi (JIT_R0, 1);
|
||||
ref = jit_blei (JIT_V0, 2);
|
||||
jit_subi (JIT_V1, JIT_V0, 1); /* V1 = n-1 */
|
||||
jit_subi (JIT_V2, JIT_V0, 2); /* V2 = n-2 */
|
||||
jit_prepare();
|
||||
|
@ -32,13 +36,11 @@ int main(int argc, char *argv[])
|
|||
jit_pushargr(JIT_V2);
|
||||
call = jit_finishi(NULL);
|
||||
jit_patch_at(call, label);
|
||||
jit_retval(JIT_V2); /* V2 = fib(n-2) */
|
||||
jit_addi(JIT_V1, JIT_V1, 1);
|
||||
jit_addr(JIT_R0, JIT_V1, JIT_V2); /* R0 = V1 + V2 + 1 */
|
||||
jit_retr(JIT_R0);
|
||||
jit_retval(JIT_R0); /* R0 = fib(n-2) */
|
||||
jit_addr(JIT_R0, JIT_R0, JIT_V1); /* R0 = R0 + V1 */
|
||||
|
||||
jit_patch(ref); /* patch jump */
|
||||
jit_movi(JIT_R0, 1); /* R0 = 1 */
|
||||
jit_patch(zero); /* patch jump */
|
||||
jit_retr(JIT_R0);
|
||||
|
||||
/* call the generated code, passing 32 as an argument */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue