xref: /openbmc/linux/kernel/time/timeconst.bc (revision 0da85d1e)
1scale=0
2
3define gcd(a,b) {
4	auto t;
5	while (b) {
6		t = b;
7		b = a % b;
8		a = t;
9	}
10	return a;
11}
12
13/* Division by reciprocal multiplication. */
14define fmul(b,n,d) {
15       return (2^b*n+d-1)/d;
16}
17
18/* Adjustment factor when a ceiling value is used.  Use as:
19   (imul * n) + (fmulxx * n + fadjxx) >> xx) */
20define fadj(b,n,d) {
21	auto v;
22	d = d/gcd(n,d);
23	v = 2^b*(d-1)/d;
24	return v;
25}
26
27/* Compute the appropriate mul/adj values as well as a shift count,
28   which brings the mul value into the range 2^b-1 <= x < 2^b.  Such
29   a shift value will be correct in the signed integer range and off
30   by at most one in the upper half of the unsigned range. */
31define fmuls(b,n,d) {
32	auto s, m;
33	for (s = 0; 1; s++) {
34		m = fmul(s,n,d);
35		if (m >= 2^(b-1))
36			return s;
37	}
38	return 0;
39}
40
41define timeconst(hz) {
42	print "/* Automatically generated by kernel/timeconst.bc */\n"
43	print "/* Time conversion constants for HZ == ", hz, " */\n"
44	print "\n"
45
46	print "#ifndef KERNEL_TIMECONST_H\n"
47	print "#define KERNEL_TIMECONST_H\n\n"
48
49	print "#include <linux/param.h>\n"
50	print "#include <linux/types.h>\n\n"
51
52	print "#if HZ != ", hz, "\n"
53	print "#error \qkernel/timeconst.h has the wrong HZ value!\q\n"
54	print "#endif\n\n"
55
56	if (hz < 2) {
57		print "#error Totally bogus HZ value!\n"
58	} else {
59		s=fmuls(32,1000,hz)
60		obase=16
61		print "#define HZ_TO_MSEC_MUL32\tU64_C(0x", fmul(s,1000,hz), ")\n"
62		print "#define HZ_TO_MSEC_ADJ32\tU64_C(0x", fadj(s,1000,hz), ")\n"
63		obase=10
64		print "#define HZ_TO_MSEC_SHR32\t", s, "\n"
65
66		s=fmuls(32,hz,1000)
67		obase=16
68		print "#define MSEC_TO_HZ_MUL32\tU64_C(0x", fmul(s,hz,1000), ")\n"
69		print "#define MSEC_TO_HZ_ADJ32\tU64_C(0x", fadj(s,hz,1000), ")\n"
70		obase=10
71		print "#define MSEC_TO_HZ_SHR32\t", s, "\n"
72
73		obase=10
74		cd=gcd(hz,1000)
75		print "#define HZ_TO_MSEC_NUM\t\t", 1000/cd, "\n"
76		print "#define HZ_TO_MSEC_DEN\t\t", hz/cd, "\n"
77		print "#define MSEC_TO_HZ_NUM\t\t", hz/cd, "\n"
78		print "#define MSEC_TO_HZ_DEN\t\t", 1000/cd, "\n"
79		print "\n"
80
81		s=fmuls(32,1000000,hz)
82		obase=16
83		print "#define HZ_TO_USEC_MUL32\tU64_C(0x", fmul(s,1000000,hz), ")\n"
84		print "#define HZ_TO_USEC_ADJ32\tU64_C(0x", fadj(s,1000000,hz), ")\n"
85		obase=10
86		print "#define HZ_TO_USEC_SHR32\t", s, "\n"
87
88		s=fmuls(32,hz,1000000)
89		obase=16
90		print "#define USEC_TO_HZ_MUL32\tU64_C(0x", fmul(s,hz,1000000), ")\n"
91		print "#define USEC_TO_HZ_ADJ32\tU64_C(0x", fadj(s,hz,1000000), ")\n"
92		obase=10
93		print "#define USEC_TO_HZ_SHR32\t", s, "\n"
94
95		obase=10
96		cd=gcd(hz,1000000)
97		print "#define HZ_TO_USEC_NUM\t\t", 1000000/cd, "\n"
98		print "#define HZ_TO_USEC_DEN\t\t", hz/cd, "\n"
99		print "#define USEC_TO_HZ_NUM\t\t", hz/cd, "\n"
100		print "#define USEC_TO_HZ_DEN\t\t", 1000000/cd, "\n"
101		print "\n"
102
103		print "#endif /* KERNEL_TIMECONST_H */\n"
104	}
105	halt
106}
107
108timeconst(hz)
109