2 # -----------------------------------------------------------------------
4 # Copyright 2007-2008 rPath, Inc. - All Rights Reserved
6 # This file is part of the Linux kernel, and is made available under
7 # the terms of the GNU General Public License version 2 or (at your
8 # option) any later version; incorporated herein by reference.
10 # -----------------------------------------------------------------------
14 # Usage: timeconst.pl HZ > timeconst.h
17 # Precomputed values for systems without Math::BigInt
19 # timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
22 '0xa6aaaaab','0x2aaaaaa',26,
24 '0xc49ba5e4','0x1fbe76c8b4',37,
26 '0xa2c2aaab','0xaaaa',16,
28 '0xc9539b89','0x7fffbce4217d',47,
31 '0xfa000000','0x6000000',27,
33 '0x83126e98','0xfdf3b645a',36,
35 '0xf4240000','0x0',17,
37 '0x8637bd06','0x3fff79c842fa',46,
40 '0xa6aaaaab','0x6aaaaaa',27,
42 '0xc49ba5e4','0xfdf3b645a',36,
44 '0xa2c2aaab','0x15555',17,
46 '0xc9539b89','0x3fffbce4217d',46,
49 '0xfa000000','0xe000000',28,
51 '0x83126e98','0x7ef9db22d',35,
53 '0xf4240000','0x0',18,
55 '0x8637bd06','0x1fff79c842fa',45,
58 '0xa0000000','0x0',28,
60 '0xcccccccd','0x733333333',35,
62 '0x9c400000','0x0',18,
64 '0xd1b71759','0x1fff2e48e8a7',45,
67 '0x8325c53f','0xfbcda3a',28,
69 '0xf9db22d1','0x7fbe76c8b',35,
71 '0x8012e2a0','0x3ef36',18,
73 '0xffda4053','0x1ffffbce4217',45,
76 '0xfa000000','0x1e000000',29,
78 '0x83126e98','0x3f7ced916',34,
80 '0xf4240000','0x40000',19,
82 '0x8637bd06','0xfffbce4217d',44,
85 '0xa0000000','0x0',29,
87 '0xcccccccd','0x333333333',34,
89 '0x9c400000','0x0',19,
91 '0xd1b71759','0xfff2e48e8a7',44,
94 '0x80000000','0x0',29,
96 '0x80000000','0x180000000',33,
98 '0xfa000000','0x0',20,
100 '0x83126e98','0x7ff7ced9168',43,
103 '0xfa000000','0x3e000000',30,
105 '0x83126e98','0x1fbe76c8b',33,
107 '0xf4240000','0xc0000',20,
109 '0x8637bd06','0x7ffde7210be',43,
112 '0xd5555556','0x2aaaaaaa',30,
114 '0x9999999a','0x1cccccccc',33,
116 '0xd0555556','0xaaaaa',20,
118 '0x9d495183','0x7ffcb923a29',43,
121 '0xfa000000','0x7e000000',31,
123 '0x83126e98','0xfdf3b645',32,
125 '0xf4240000','0x1c0000',21,
127 '0x8637bd06','0x3ffef39085f',42,
130 '0x80000000','0x0',31,
132 '0x80000000','0x0',31,
134 '0xfa000000','0x0',22,
136 '0x83126e98','0x1ff7ced9168',41,
139 '0xfa000000','0xfe000000',32,
141 '0x83126e98','0x7ef9db22',31,
143 '0xf4240000','0x3c0000',22,
145 '0x8637bd06','0x1fff79c842f',41,
148 '0xd5555556','0xd5555555',32,
150 '0x9999999a','0x66666666',31,
152 '0xd0555556','0x2aaaaa',22,
154 '0x9d495183','0x1ffcb923a29',41,
159 $has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
164 return Math::BigInt->new($x);
168 # Constants for division by reciprocal multiplication.
169 # (bits, numerator, denominator)
178 return scalar (($n << $b)+$d-bint(1))/$d;
188 $d = $d/bgcd($n, $d);
189 return scalar (($d-bint(1)) << $b)/$d;
195 my($thres) = bint(1) << ($b-1);
200 for ($s = 0; 1; $s++) {
202 return $s if ($m >= $thres);
207 # Generate a hex value if the result fits in 64 bits;
211 my $s = $x->as_hex();
213 return (length($s) > 18) ? undef : $s;
216 # Provides mul, adj, and shr factors for a specific
217 # (bit, time, hz) combination
219 my($b, $t, $hz) = @_;
220 my $s = fmuls($b, $t, $hz);
221 my $m = fmul($s, $t, $hz);
222 my $a = fadj($s, $t, $hz);
223 return (bignum_hex($m), bignum_hex($a), $s);
226 # Provides numerator, denominator values
229 my $g = bgcd($n, $d);
230 return ($n/$g, $d/$g);
233 # All values for a specific (time, hz) combo
234 sub conversions($$) {
239 push(@val, muladj(32, $t, $hz));
240 push(@val, numden($t, $hz));
243 push(@val, muladj(32, $hz, $t));
244 push(@val, numden($hz, $t));
249 sub compute_values($) {
255 die "$0: HZ == $hz not canned and ".
256 "Math::BigInt not available\n";
260 push(@val, conversions(1000, $hz));
263 push(@val, conversions(1000000, $hz));
270 my($name, $val) = @_;
274 if ($name !~ /SHR/) {
275 $val = "U64_C($val)";
277 printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
284 my $pfx, $bit, $suf, $s, $m, $a;
286 print "/* Automatically generated by kernel/timeconst.pl */\n";
287 print "/* Conversion constants for HZ == $hz */\n";
289 print "#ifndef KERNEL_TIMECONST_H\n";
290 print "#define KERNEL_TIMECONST_H\n";
293 print "#include <linux/param.h>\n";
294 print "#include <linux/types.h>\n";
297 print "#if HZ != $hz\n";
298 print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
302 foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
303 'HZ_TO_USEC','USEC_TO_HZ') {
305 foreach $suf ('MUL', 'ADJ', 'SHR') {
306 outputval("${pfx}_$suf$bit", shift(@val));
309 foreach $suf ('NUM', 'DEN') {
310 outputval("${pfx}_$suf", shift(@val));
315 print "#endif /* KERNEL_TIMECONST_H */\n";
318 # Pretty-print Perl values
326 } elsif ($v =~ /^0x/) {
327 push(@l, "\'".$v."\'");
332 return join(',', @l);
337 # Use this to generate the %canned_values structure
338 if ($hz eq '--can') {
340 @hzlist = sort {$a <=> $b} (@ARGV);
342 print "# Precomputed values for systems without Math::BigInt\n";
343 print "# Generated by:\n";
344 print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
345 print "\%canned_values = (\n";
347 foreach $hz (@hzlist) {
348 my @values = compute_values($hz);
349 print "$pf$hz => [\n";
350 while (scalar(@values)) {
353 my $m = shift(@values);
354 my $a = shift(@values);
355 my $s = shift(@values);
356 print "\t\t", perlvals($m,$a,$s), ",\n";
358 my $n = shift(@values);
359 my $d = shift(@values);
360 print "\t\t", perlvals($n,$d), ",\n";
367 $hz += 0; # Force to number
369 die "Usage: $0 HZ\n";
372 @val = @{$canned_values{$hz}};
373 if (!defined(@val)) {
374 @val = compute_values($hz);