xref: /netbsd-src/sys/external/bsd/sljit/dist/doc/tutorial/loop.c (revision 99e10043c2d890154986b9f0cfb10c84949ba483)
1 #include "sljitLir.h"
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 
6 typedef long (*func2_t)(long a, long b);
7 
8 /*
9   This example, we generate a function like this:
10 
11 long func(long a, long b)
12 {
13 	long i;
14 	long ret = 0;
15 	for (i = 0; i < a; ++i) {
16 		ret += b;
17 	}
18 	return ret;
19 }
20 */
21 
loop(long a,long b)22 static int loop(long a, long b)
23 {
24 	void *code;
25 	unsigned long len;
26 	func2_t func;
27 
28 	struct sljit_label *loopstart;
29 	struct sljit_jump *out;
30 
31 	/* Create a SLJIT compiler */
32 	struct sljit_compiler *C = sljit_create_compiler();
33 
34 	/* 2 arg, 2 temp reg, 2 saved reg */
35 	sljit_emit_enter(C, 0, 2, 2, 2, 0, 0, 0);
36 
37 	/* R0 = 0 */
38 	sljit_emit_op2(C, SLJIT_XOR, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_R1, 0);
39 	/* RET = 0 */
40 	sljit_emit_op1(C, SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
41 	/* loopstart: */
42 	loopstart = sljit_emit_label(C);
43 	/* R1 >= a --> jump out */
44 	out = sljit_emit_cmp(C, SLJIT_GREATER_EQUAL, SLJIT_R1, 0, SLJIT_S0, 0);
45 	/* RET += b */
46 	sljit_emit_op2(C, SLJIT_ADD, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0, SLJIT_S1, 0);
47 	/* R1 += 1 */
48 	sljit_emit_op2(C, SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
49 	/* jump loopstart */
50 	sljit_set_label(sljit_emit_jump(C, SLJIT_JUMP), loopstart);
51 	/* out: */
52 	sljit_set_label(out, sljit_emit_label(C));
53 
54 	/* return RET */
55 	sljit_emit_return(C, SLJIT_MOV, SLJIT_RETURN_REG, 0);
56 
57 	/* Generate machine code */
58 	code = sljit_generate_code(C);
59 	len = sljit_get_generated_code_size(C);
60 
61 	/* Execute code */
62 	func = (func2_t)code;
63 	printf("func return %ld\n", func(a, b));
64 
65 	/* dump_code(code, len); */
66 
67 	/* Clean up */
68 	sljit_free_compiler(C);
69 	sljit_free_code(code);
70 	return 0;
71 }
72 
main()73 int main()
74 {
75 	return loop(4, 5);
76 }
77