diff options
author | Twinaphex | 2020-02-08 16:24:22 +0100 |
---|---|---|
committer | GitHub | 2020-02-08 16:24:22 +0100 |
commit | 0adc619b5a5705d16cc6caea64951776ababbb96 (patch) | |
tree | fbae9b1d18d04d8e7908aa1c3446782ebf6e8785 /deps/lightning/doc/fact.c | |
parent | 0204c39a68a1fd4bf667aa8ece5a769f2983b7d0 (diff) | |
parent | 6f1edc3c7fd1f7f58155107d0c99d0ac7d22443b (diff) | |
download | pcsx_rearmed-0adc619b5a5705d16cc6caea64951776ababbb96.tar.gz pcsx_rearmed-0adc619b5a5705d16cc6caea64951776ababbb96.tar.bz2 pcsx_rearmed-0adc619b5a5705d16cc6caea64951776ababbb96.zip |
Merge pull request #377 from pcercuei/libretro
Lightrec dynarec
Diffstat (limited to 'deps/lightning/doc/fact.c')
-rw-r--r-- | deps/lightning/doc/fact.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/deps/lightning/doc/fact.c b/deps/lightning/doc/fact.c new file mode 100644 index 0000000..375905b --- /dev/null +++ b/deps/lightning/doc/fact.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <lightning.h> + +static jit_state_t *_jit; + +typedef long (*pwfw_t)(long); /* Pointer to Long Function of Long */ + +int main(int argc, char *argv[]) +{ + pwfw_t factorial; + long arg; + jit_node_t *ac; /* Accumulator */ + jit_node_t *in; /* Argument */ + jit_node_t *call; + jit_node_t *fact; + jit_node_t *jump; + jit_node_t *fact_entry; + jit_node_t *fact_out; + + init_jit(argv[0]); + _jit = jit_new_state(); + + /* declare a forward label */ + fact = jit_forward(); + + jit_prolog(); /* Entry point of the factorial function */ + in = jit_arg(); /* Receive an integer argument */ + jit_getarg(JIT_R0, in); /* Move argument to RO */ + jit_prepare(); + jit_pushargi(1); /* This is the accumulator */ + jit_pushargr(JIT_R0); /* This is the argument */ + call = jit_finishi(NULL); /* Call the tail call optimized function */ + jit_patch_at(call, fact); /* Patch call to forward defined function */ + /* the above could have been written as: + * jit_patch_at(jit_finishi(NULL), fact); + */ + jit_retval(JIT_R0); /* Fetch the result */ + jit_retr(JIT_R0); /* Return it */ + jit_epilog(); /* Epilog *before* label before prolog */ + + /* define the forward label */ + jit_link(fact); /* Entry point of the helper function */ + jit_prolog(); + jit_frame(16); /* Reserve 16 bytes in the stack */ + fact_entry = jit_label(); /* This is the tail call entry point */ + ac = jit_arg(); /* The accumulator is the first argument */ + in = jit_arg(); /* The factorial argument */ + jit_getarg(JIT_R0, ac); /* Move the accumulator to R0 */ + jit_getarg(JIT_R1, in); /* Move the argument to R1 */ + fact_out = jit_blei(JIT_R1, 1); /* Done if argument is one or less */ + jit_mulr(JIT_R0, JIT_R0, JIT_R1); /* accumulator *= argument */ + jit_putargr(JIT_R0, ac); /* Update the accumulator */ + jit_subi(JIT_R1, JIT_R1, 1); /* argument -= 1 */ + jit_putargr(JIT_R1, in); /* Update the argument */ + jump = jit_jmpi(); + jit_patch_at(jump, fact_entry); /* Tail Call Optimize it! */ + jit_patch(fact_out); + jit_retr(JIT_R0); /* Return the accumulator */ + + factorial = jit_emit(); + /* no need to query information about resolved addresses */ + jit_clear_state(); + + if (argc == 2) + arg = atoi(argv[1]); + else + arg = 5; + + /* call the generated code */ + printf("factorial(%ld) = %ld\n", arg, factorial(arg)); + /* release all memory associated with the _jit identifier */ + jit_destroy_state(); + finish_jit(); + return 0; +} |