xref: /netbsd-src/external/public-domain/xz/dist/tests/bcj_test.c (revision 4d1abfb29e19727d8dfeef21d710fb741c73ec34)
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       bcj_test.c
4 /// \brief      Source code of compress_prepared_bcj_*
5 ///
6 /// This is a simple program that should make the compiler to generate
7 /// PC-relative branches, jumps, and calls. The compiled files can then
8 /// be used to test the branch conversion filters. Note that this program
9 /// itself does nothing useful.
10 ///
11 /// Compiling: gcc -std=c99 -fPIC -c bcj_test.c
12 /// Don't optimize or strip.
13 //
14 //  Author:     Lasse Collin
15 //
16 //  This file has been put into the public domain.
17 //  You can do whatever you want with this file.
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20 
21 extern int jump(int a, int b);
22 
23 
24 extern int
call(int a,int b)25 call(int a, int b)
26 {
27 	if (a < b)
28 		a = jump(a, b);
29 
30 	return a;
31 }
32 
33 
34 extern int
jump(int a,int b)35 jump(int a, int b)
36 {
37 	// The loop generates conditional jump backwards.
38 	while (1) {
39 		if (a < b) {
40 			a *= 2;
41 			a += 3 * b;
42 			break;
43 		} else {
44 			// Put enough code here to prevent JMP SHORT on x86.
45 			a += b;
46 			a /= 2;
47 			b += b % 5;
48 			a -= b / 3;
49 			b = 2 * b + a - 1;
50 			a *= b + a + 1;
51 			b += a - 1;
52 			a += b * 2 - a / 5;
53 		}
54 	}
55 
56 	return a;
57 }
58 
59 
60 int
main(int argc,char ** argv)61 main(int argc, char **argv)
62 {
63 	int a = call(argc, argc + 1);
64 	return a == 0;
65 }
66