Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753632AbdGULkz (ORCPT ); Fri, 21 Jul 2017 07:40:55 -0400 Received: from merlin.infradead.org ([205.233.59.134]:60416 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750777AbdGULky (ORCPT ); Fri, 21 Jul 2017 07:40:54 -0400 Date: Fri, 21 Jul 2017 13:40:39 +0200 From: Peter Zijlstra To: Linus Torvalds Cc: Anshul Garg , Davidlohr Bueso , Linux Kernel Mailing List , "anshul.g@samsung.com" , Thomas Gleixner , Joe Perches , Ingo Molnar , Will Deacon Subject: Re: [PATCH] lib/int_sqrt.c: Optimize square root function Message-ID: <20170721114039.dqip5wj2tha42mol@hirez.programming.kicks-ass.net> References: <1422897162-111998-1-git-send-email-aksgarg1989@gmail.com> <20170720112449.6xvc2ghaj3jh6w7l@hirez.programming.kicks-ass.net> <20170720223416.fxkgdtvuqwxxmf3y@hirez.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="23eu56dji7datv7c" Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 32686 Lines: 532 --23eu56dji7datv7c Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Jul 20, 2017 at 04:24:32PM -0700, Linus Torvalds wrote: > So mayube something like the attached? > > NOTE NOTE NOTE! This may be pure garbage. It's untested. But the code > generation looks ok even if gcc is being way too clever and turns that > first loop into a counted loop instead. Whatever, maybe it's the right > thing to do. It passes a -DVALIDATE=1 run (up to a billion or so), so it seems to work. I've made the test thing a bit more complicated in order to address your concerns for primed branch predictors (and once the branch predictors get wiped, the predictable input values don't matter anymore either I think, although I could easily LFSR generate them as well of course). Find it attached in a tarball. The results, from running ./test.sh (left SKL, right SNB): (values <100k) Cycles: EVENT=0 -DLINUS=1 event: 29.533080 +- 0.046261 36.800100 +- 0.046067 EVENT=0 -DLINUS=1 -DWIPE_BTB=1 event: 143.513440 +- 0.152651 153.054640 +- 0.099403 EVENT=0 -DNEW=1 -DANSHUL=1 event: 41.457300 +- 0.048409 55.046100 +- 0.044968 EVENT=0 -DNEW=1 -DANSHUL=1 -DWIPE_BTB=1 event: 128.351400 +- 0.366873 161.183690 +- 0.132301 EVENT=0 -DNEW=1 -DANSHUL=1 -DFLS=1 event: 21.433170 +- 0.043859 27.672700 +- 0.063982 EVENT=0 -DNEW=1 -DANSHUL=1 -DFLS=1 -DWIPE_BTB=1 event: 79.850210 +- 0.133646 112.422470 +- 0.101465 EVENT=0 -DNEW=1 -DANSHUL=1 -DFLS=1 -DSOFTFLS=1 event: 31.771680 +- 0.037655 37.515160 +- 0.080305 EVENT=0 -DNEW=1 -DANSHUL=1 -DFLS=1 -DSOFTFLS=1 -DWIPE_BTB=1 event: 129.673440 +- 0.430308 125.514390 +- 0.117590 Branches: EVENT=4 -DLINUS=1 event: 31.507740 +- 0.010470 31.507710 +- 0.010470 EVENT=4 -DLINUS=1 -DWIPE_BTB=1 event: 31.507720 +- 0.010470 31.507760 +- 0.010470 EVENT=4 -DNEW=1 -DANSHUL=1 event: 45.125510 +- 0.002696 45.125510 +- 0.002696 EVENT=4 -DNEW=1 -DANSHUL=1 -DWIPE_BTB=1 event: 45.125490 +- 0.002696 45.125540 +- 0.002697 EVENT=4 -DNEW=1 -DANSHUL=1 -DFLS=1 event: 21.252320 +- 0.005266 21.252330 +- 0.005266 EVENT=4 -DNEW=1 -DANSHUL=1 -DFLS=1 -DWIPE_BTB=1 event: 21.252320 +- 0.005266 21.252340 +- 0.005266 EVENT=4 -DNEW=1 -DANSHUL=1 -DFLS=1 -DSOFTFLS=1 event: 25.727940 +- 0.005975 25.727930 +- 0.005975 EVENT=4 -DNEW=1 -DANSHUL=1 -DFLS=1 -DSOFTFLS=1 -DWIPE_BTB=1 event: 25.727940 +- 0.005975 25.727930 +- 0.005975 Branch-Misses: EVENT=5 -DLINUS=1 event: 0.022670 +- 0.000789 0.020920 +- 0.000812 EVENT=5 -DLINUS=1 -DWIPE_BTB=1 event: 5.481750 +- 0.006930 5.955130 +- 0.005228 EVENT=5 -DNEW=1 -DANSHUL=1 event: 0.025990 +- 0.000798 0.017170 +- 0.000690 EVENT=5 -DNEW=1 -DANSHUL=1 -DWIPE_BTB=1 event: 3.343600 +- 0.004249 5.723570 +- 0.004876 EVENT=5 -DNEW=1 -DANSHUL=1 -DFLS=1 event: 0.019040 +- 0.000731 0.022570 +- 0.000829 EVENT=5 -DNEW=1 -DANSHUL=1 -DFLS=1 -DWIPE_BTB=1 event: 2.156350 +- 0.004643 4.297650 +- 0.004910 EVENT=5 -DNEW=1 -DANSHUL=1 -DFLS=1 -DSOFTFLS=1 event: 0.019800 +- 0.000747 0.016780 +- 0.000688 EVENT=5 -DNEW=1 -DANSHUL=1 -DFLS=1 -DSOFTFLS=1 -DWIPE_BTB=1 event: 4.481360 +- 0.005505 4.518300 +- 0.004877 Which still doesn't explain your hatred of fls(), as even with cold branches and a software fls, its faster than your latest proposal (as can be explained by the lower total number of branches for the software fls variant compared to your proposal). And when we start to look at larger values, the fls() one pulls even further ahead. So I'll stick with my proposal... I can write up a proper Changelog and maybe add my test to tools/testing/sqrt/ if you think its worth it. --- lib/int_sqrt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c index 1ef4cc344977..611933760225 100644 --- a/lib/int_sqrt.c +++ b/lib/int_sqrt.c @@ -7,12 +7,13 @@ #include #include +#include /** - * int_sqrt - rough approximation to sqrt + * int_sqrt - Computes the integer square root * @x: integer of which to calculate the sqrt * - * A very rough approximation to the sqrt() function. + * Computes: floor(sqrt(@x)) */ unsigned long int_sqrt(unsigned long x) { @@ -21,7 +22,11 @@ unsigned long int_sqrt(unsigned long x) if (x <= 1) return x; - m = 1UL << (BITS_PER_LONG - 2); + m = 1UL << (__fls(x) & ~1U); + + while (m > x) + m >>= 2; + while (m != 0) { b = y + m; y >>= 1; --23eu56dji7datv7c Content-Type: application/x-tar Content-Disposition: attachment; filename="sqrt.tar" Content-Transfer-Encoding: base64 c3FydC10ZXN0L2JhcnJpZXIuaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDA2NDQA MDAwMTc1MAAwMDAxNzUwADAwMDAwMDAyMzMyADEzMTM0MzM1MTI3ADAxNDIzMQAgMAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhciAgAHBldGVy egAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcGV0ZXJ6AAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjaWZuZGVmIF9CQVJSSUVSX0gKI2RlZmluZSBf QkFSUklFUl9ICgojZGVmaW5lIGxpa2VseSh4KQlfX2J1aWx0aW5fZXhwZWN0KCEhKHgpLCAx KQojZGVmaW5lIHVubGlrZWx5KHgpCV9fYnVpbHRpbl9leHBlY3QoISEoeCksIDApCgojZGVm aW5lIE5VTEwgKCh2b2lkICopMCkKCiNpZm5kZWYgX19hbHdheXNfaW5saW5lCiNkZWZpbmUg X19hbHdheXNfaW5saW5lCQlpbmxpbmUgX19hdHRyaWJ1dGVfXygoYWx3YXlzX2lubGluZSkp CiNlbmRpZgoKdHlwZWRlZiB1bnNpZ25lZCBjaGFyIHU4Owp0eXBlZGVmIHVuc2lnbmVkIHNo b3J0IHUxNjsKdHlwZWRlZiB1bnNpZ25lZCBpbnQgdTMyOwp0eXBlZGVmIHVuc2lnbmVkIGxv bmcgbG9uZyB1NjQ7Cgp0eXBlZGVmIHNpZ25lZCBjaGFyIHM4Owp0eXBlZGVmIHNpZ25lZCBz aG9ydCBzMTY7CnR5cGVkZWYgc2lnbmVkIGludCBzMzI7CnR5cGVkZWYgc2lnbmVkIGxvbmcg bG9uZyBzNjQ7Cgp0eXBlZGVmIF9Cb29sIGJvb2w7CgojZGVmaW5lIGZhbHNlICgwKQojZGVm aW5lIHRydWUgKDEpCgojIGRlZmluZSBVSU5UX01BWCAgICAgICAgICAgICAoNDI5NDk2NzI5 NVUpCgojZGVmaW5lIGJhcnJpZXIoKQlhc20gdm9sYXRpbGUoIiIgOiA6IDogIm1lbW9yeSIp CiNkZWZpbmUgbWIoKQkJYXNtIHZvbGF0aWxlKCJtZmVuY2UiIDo6OiAibWVtb3J5IikKI2Rl ZmluZSB3bWIoKQkJYXNtIHZvbGF0aWxlKCJzZmVuY2UiIDo6OiAibWVtb3J5IikKI2RlZmlu ZSBybWIoKQkJYXNtIHZvbGF0aWxlKCJsZmVuY2UiIDo6OiAibWVtb3J5IikKCiNkZWZpbmUg c21wX21iKCkJbWIoKQojZGVmaW5lIHNtcF93bWIoKQliYXJyaWVyKCkKI2RlZmluZSBzbXBf cm1iKCkJYmFycmllcigpCgojZGVmaW5lIEFDQ0VTU19PTkNFKHgpICgqKHZvbGF0aWxlIHR5 cGVvZih4KSAqKSYoeCkpCgojZGVmaW5lIHNtcF9zdG9yZV9yZWxlYXNlKHAsIHYpCQkJCQkJ XApkbyB7CQkJCQkJCQkJXAoJYmFycmllcigpOwkJCQkJCQlcCglBQ0NFU1NfT05DRSgqcCkg PSAodik7CQkJCQkJXAp9IHdoaWxlICgwKQoKI2RlZmluZSBzbXBfbG9hZF9hY3F1aXJlKHAp CQkJCQkJXAooewkJCQkJCQkJCVwKCXR5cGVvZigqcCkgX19fcDEgPSBBQ0NFU1NfT05DRSgq cCk7CQkJCVwKCWJhcnJpZXIoKTsJCQkJCQkJXAoJX19fcDE7CQkJCQkJCQlcCn0pCgojZGVm aW5lIGNwdV9yZWxheCgpCWFzbSB2b2xhdGlsZSAoInJlcDsgbm9wIiA6OjogIm1lbW9yeSIp CgojZW5kaWYgLyogX0JBUlJJRVJfSCAqLwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzcXJ0 LXRlc3QvbGZzci5oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDY0NAAwMDAx NzUwADAwMDE3NTAAMDAwMDAwMDMxMjQAMTMxMzQzNjM1MTQAMDEzNTUyACAwAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyICAAcGV0ZXJ6AAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwZXRlcnoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAACNpZm5kZWYgX0xGU1JfSAojZGVmaW5lIF9MRlNSX0gK CnN0YXRpYyBfX2Fsd2F5c19pbmxpbmUgdTMyIGxmc3JfdGFwcyhpbnQgYml0cykKewojZGVm aW5lIF9JRl9CSVRTX0VRKHgpIFwKICAgICAgIGlmICgoeCkgPT0gYml0cykKCiAgICAgICAv KgogICAgICAgICogRmVlZGJhY2sgdGVybXMgY29waWVkIGZyb20KICAgICAgICAqIGh0dHA6 Ly91c2Vycy5lY2UuY211LmVkdS9+a29vcG1hbi9sZnNyL2luZGV4Lmh0bWwKICAgICAgICAq LwogICAgICAgX0lGX0JJVFNfRVEoNCkgIHJldHVybiAweDAwMDk7CiAgICAgICBfSUZfQklU U19FUSg1KSAgcmV0dXJuIDB4MDAxMjsKICAgICAgIF9JRl9CSVRTX0VRKDYpICByZXR1cm4g MHgwMDIxOwogICAgICAgX0lGX0JJVFNfRVEoNykgIHJldHVybiAweDAwNDE7CiAgICAgICBf SUZfQklUU19FUSg4KSAgcmV0dXJuIDB4MDA4RTsKICAgICAgIF9JRl9CSVRTX0VRKDkpICBy ZXR1cm4gMHgwMTA4OwogICAgICAgX0lGX0JJVFNfRVEoMTApIHJldHVybiAweDAyMDQ7CiAg ICAgICBfSUZfQklUU19FUSgxMSkgcmV0dXJuIDB4MDQwMjsKICAgICAgIF9JRl9CSVRTX0VR KDEyKSByZXR1cm4gMHgwODI5OwogICAgICAgX0lGX0JJVFNfRVEoMTMpIHJldHVybiAweDEw MEQ7CiAgICAgICBfSUZfQklUU19FUSgxNCkgcmV0dXJuIDB4MjAxNTsKICAgICAgIF9JRl9C SVRTX0VRKDE1KSByZXR1cm4gMHg0MTIyOwogICAgICAgX0lGX0JJVFNfRVEoMTYpIHJldHVy biAweDgxMTI7CiAgICAgICBfSUZfQklUU19FUSgxNykgcmV0dXJuIDB4MTAyQzk7CiAgICAg ICBfSUZfQklUU19FUSgxOCkgcmV0dXJuIDB4MjAxOTU7CiAgICAgICBfSUZfQklUU19FUSgx OSkgcmV0dXJuIDB4NDAzRkU7CiAgICAgICBfSUZfQklUU19FUSgyMCkgcmV0dXJuIDB4ODA2 Mzc7CiAgICAgICBfSUZfQklUU19FUSgyMSkgcmV0dXJuIDB4MTAwNDc4OwogICAgICAgX0lG X0JJVFNfRVEoMjIpIHJldHVybiAweDIwMDY5RTsKICAgICAgIF9JRl9CSVRTX0VRKDIzKSBy ZXR1cm4gMHg0MDA0QjI7CiAgICAgICBfSUZfQklUU19FUSgyNCkgcmV0dXJuIDB4ODAwQjg3 OwogICAgICAgX0lGX0JJVFNfRVEoMjUpIHJldHVybiAweDEwMDA0RjM7CiAgICAgICBfSUZf QklUU19FUSgyNikgcmV0dXJuIDB4MjAwMDcyRDsKICAgICAgIF9JRl9CSVRTX0VRKDI3KSBy ZXR1cm4gMHg0MDAwNkFFOwogICAgICAgX0lGX0JJVFNfRVEoMjgpIHJldHVybiAweDgwMDA5 RTM7CiAgICAgICBfSUZfQklUU19FUSgyOSkgcmV0dXJuIDB4MTAwMDA1ODM7CiAgICAgICBf SUZfQklUU19FUSgzMCkgcmV0dXJuIDB4MjAwMDBDOTI7CiN1bmRlZiBfSUZfQklUU19FUQoK ICAgICAgIC8qIFVucmVhY2hhYmxlICovCiAgICAgICByZXR1cm4gMDsKfQoKLyoKICogUGxl YXNlIG5vdGUgdGhhdCBMRlNSIGRvZXNuJ3Qgd29yayB3aXRoIGEgc3RhcnQgc3RhdGUgb2Yg MC4KICovCnN0YXRpYyBpbmxpbmUgdTMyIGxmc3IodTMyIHZhbCwgdTMyIHRhcHMpCnsKICAg ICAgIHUzMiBiaXQgPSB2YWwgJiAxOwoKICAgICAgIHZhbCA+Pj0gMTsKICAgICAgIGlmIChi aXQpCiAgICAgICAgICAgICAgIHZhbCBePSB0YXBzOwogICAgICAgcmV0dXJuIHZhbDsKfQoK I2VuZGlmIC8qIF9MRlNSX0hfICovCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAc3FydC10ZXN0L3BlcmYuaAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAADAwMDA2NDQAMDAwMTc1MAAwMDAxNzUwADAwMDAwMDA1MTc1ADEzMTM0MzM1 MTIwADAxMzU0MAAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAB1c3RhciAgAHBldGVyegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcGV0ZXJ6AAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjaWZuZGVmIF9Q RVJGX1BFUkZfSAojZGVmaW5lIF9QRVJGX1BFUkZfSAoKI2luY2x1ZGUgImJhcnJpZXIuaCIK CiNpbmNsdWRlIDxhc20vdW5pc3RkLmg+CgojaWYgZGVmaW5lZChfX3g4Nl82NF9fKQojaWZu ZGVmIF9fTlJfcGVyZl9ldmVudF9vcGVuCiMgZGVmaW5lIF9fTlJfcGVyZl9ldmVudF9vcGVu IDI5OAojZW5kaWYKI2VuZGlmCgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8dW5pc3Rk Lmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zeXNjYWxsLmg+Cgoj aW5jbHVkZSA8bGludXgvcGVyZl9ldmVudC5oPgoKLyoKICogcHJjdGwoUFJfVEFTS19QRVJG X0VWRU5UU19ESVNBQkxFKSB3aWxsIChjaGVhcGx5KSBkaXNhYmxlIGFsbAogKiBjb3VudGVy cyBpbiB0aGUgY3VycmVudCB0YXNrLgogKi8KI2RlZmluZSBQUl9UQVNLX1BFUkZfRVZFTlRT X0RJU0FCTEUgICAzMQojZGVmaW5lIFBSX1RBU0tfUEVSRl9FVkVOVFNfRU5BQkxFICAgIDMy CgpzdGF0aWMgaW5saW5lIGludApzeXNfcGVyZl9ldmVudF9vcGVuKHN0cnVjdCBwZXJmX2V2 ZW50X2F0dHIgKmF0dHIsCgkJICAgICAgcGlkX3QgcGlkLCBpbnQgY3B1LCBpbnQgZ3JvdXBf ZmQsCgkJICAgICAgdW5zaWduZWQgbG9uZyBmbGFncykKewoJaW50IGZkOwoKCWZkID0gc3lz Y2FsbChfX05SX3BlcmZfZXZlbnRfb3BlbiwgYXR0ciwgcGlkLCBjcHUsCgkJICAgICBncm91 cF9mZCwgZmxhZ3MpOwoKCXJldHVybiBmZDsKfQoKc3RhdGljIGlubGluZSB1NjQgcmRwbWMo dW5zaWduZWQgaW50IGNvdW50ZXIpCnsKCXVuc2lnbmVkIGludCBsb3csIGhpZ2g7CgoJYXNt IHZvbGF0aWxlKCJyZHBtYyIgOiAiPWEiIChsb3cpLCAiPWQiIChoaWdoKSA6ICJjIiAoY291 bnRlcikpOwoKCXJldHVybiBsb3cgfCAoKHU2NCloaWdoKSA8PCAzMjsKfQoKc3RhdGljIGlu bGluZSB1NjQgcmR0c2Modm9pZCkKewoJdW5zaWduZWQgaW50IGxvdywgaGlnaDsKCglhc20g dm9sYXRpbGUoInJkdHNjIiA6ICI9YSIgKGxvdyksICI9ZCIgKGhpZ2gpKTsKCglyZXR1cm4g bG93IHwgKCh1NjQpaGlnaCkgPDwgMzI7Cn0KCnN0YXRpYyBpbmxpbmUgdTY0IG1tYXBfcmVh ZF9zZWxmKHZvaWQgKmFkZHIpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X21tYXBfcGFnZSAqcGMg PSBhZGRyOwoJdTMyIHNlcSwgaWR4LCB0aW1lX211bHQgPSAwLCB0aW1lX3NoaWZ0ID0gMCwg d2lkdGggPSAwOwoJdTY0IGNvdW50LCBjeWMgPSAwLCB0aW1lX29mZnNldCA9IDAsIGVuYWJs ZWQsIHJ1bm5pbmcsIGRlbHRhOwoJczY0IHBtYyA9IDA7CgoJZG8gewoJCXNlcSA9IHBjLT5s b2NrOwoJCWJhcnJpZXIoKTsKCgkJZW5hYmxlZCA9IHBjLT50aW1lX2VuYWJsZWQ7CgkJcnVu bmluZyA9IHBjLT50aW1lX3J1bm5pbmc7CgoJCWlmIChwYy0+Y2FwX3VzZXJfdGltZSAmJiBl bmFibGVkICE9IHJ1bm5pbmcpIHsKCQkJY3ljID0gcmR0c2MoKTsKCQkJdGltZV9tdWx0ID0g cGMtPnRpbWVfbXVsdDsKCQkJdGltZV9zaGlmdCA9IHBjLT50aW1lX3NoaWZ0OwoJCQl0aW1l X29mZnNldCA9IHBjLT50aW1lX29mZnNldDsKCQl9CgoJCWlkeCA9IHBjLT5pbmRleDsKCQlj b3VudCA9IHBjLT5vZmZzZXQ7CgkJaWYgKHBjLT5jYXBfdXNlcl9yZHBtYyAmJiBpZHgpIHsK CQkJd2lkdGggPSBwYy0+cG1jX3dpZHRoOwoJCQlwbWMgPSByZHBtYyhpZHggLSAxKTsKCQl9 CgoJCWJhcnJpZXIoKTsKCX0gd2hpbGUgKHBjLT5sb2NrICE9IHNlcSk7CgoJaWYgKGlkeCkg ewoJCXBtYyA8PD0gNjQgLSB3aWR0aDsKCQlwbWMgPj49IDY0IC0gd2lkdGg7IC8qIHNoaWZ0 IHJpZ2h0IHNpZ25lZCAqLwoJCWNvdW50ICs9IHBtYzsKCX0KCglpZiAoZW5hYmxlZCAhPSBy dW5uaW5nKSB7CgkJdTY0IHF1b3QsIHJlbTsKCgkJcXVvdCA9IChjeWMgPj4gdGltZV9zaGlm dCk7CgkJcmVtID0gY3ljICYgKCgxIDw8IHRpbWVfc2hpZnQpIC0gMSk7CgkJZGVsdGEgPSB0 aW1lX29mZnNldCArIHF1b3QgKiB0aW1lX211bHQgKwoJCQkoKHJlbSAqIHRpbWVfbXVsdCkg Pj4gdGltZV9zaGlmdCk7CgoJCWVuYWJsZWQgKz0gZGVsdGE7CgkJaWYgKGlkeCkKCQkJcnVu bmluZyArPSBkZWx0YTsKCgkJcXVvdCA9IGNvdW50IC8gcnVubmluZzsKCQlyZW0gPSBjb3Vu dCAlIHJ1bm5pbmc7CgkJY291bnQgPSBxdW90ICogZW5hYmxlZCArIChyZW0gKiBlbmFibGVk KSAvIHJ1bm5pbmc7Cgl9CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgaW5saW5lIHU2NCBt bWFwX3JlYWRfcGlubmVkKHZvaWQgKmFkZHIpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X21tYXBf cGFnZSAqcGMgPSBhZGRyOwoJdTMyIHNlcSwgaWR4LCB3aWR0aCA9IDA7Cgl1NjQgY291bnQ7 CglzNjQgcG1jID0gMDsKCglkbyB7CgkJc2VxID0gcGMtPmxvY2s7CgkJYmFycmllcigpOwoK CQlpZHggPSBwYy0+aW5kZXg7CgkJY291bnQgPSBwYy0+b2Zmc2V0OwoJCWlmIChwYy0+Y2Fw X3VzZXJfcmRwbWMgJiYgaWR4KSB7CgkJCXdpZHRoID0gcGMtPnBtY193aWR0aDsKCQkJcG1j ID0gcmRwbWMoaWR4IC0gMSk7CgkJfQoKCQliYXJyaWVyKCk7Cgl9IHdoaWxlIChwYy0+bG9j ayAhPSBzZXEpOwoKCWlmIChpZHgpIHsKCQlwbWMgPDw9IDY0IC0gd2lkdGg7CgkJcG1jID4+ PSA2NCAtIHdpZHRoOyAvKiBzaGlmdCByaWdodCBzaWduZWQgKi8KCQljb3VudCArPSBwbWM7 Cgl9CgoJcmV0dXJuIGNvdW50Owp9CiNlbmRpZgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzcXJ0LXRlc3Qvc3FydC5j AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDY0NAAwMDAxNzUwADAwMDE3NTAA MDAwMDAwMDc1MTEAMTMxMzQzNjM0MzQAMDEzNTc1ACAwAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyICAAcGV0ZXJ6AAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAABwZXRlcnoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAACNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVk ZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojaW5jbHVkZSA8c3RkbGliLmg+ CgojaW5jbHVkZSAicGVyZi5oIgojaW5jbHVkZSAic3RhdC5oIgojaW5jbHVkZSAibGZzci5o IgoKdm9sYXRpbGUgdW5zaWduZWQgbG9uZyBhY2MgPSAwOwoKI2lmbmRlZiBMRlNSX0JJVFMK I2RlZmluZSBMRlNSX0JJVFMgMTYKI2VuZGlmCgp2b2lkIF9fYXR0cmlidXRlX18oKG5vaW5s aW5lKSkgd2lwZV9idGIodm9pZCkKCnsKCXUzMiB2YWwgPSAxOwoJaW50IGk7CgoJZm9yIChp PTA7IGk8MTw8TEZTUl9CSVRTOyBpKyspIHsKCQlpZiAodmFsICYgMSkKCQkJYWNjKys7CgkJ ZWxzZQoJCQlhY2MtLTsKCQl2YWwgPSBsZnNyKHZhbCwgbGZzcl90YXBzKExGU1JfQklUUykp OwoKCQlpZiAofnZhbCAmIDEpCgkJCWFjYy0tOwoJCWVsc2UKCQkJYWNjKys7CgkJdmFsID0g bGZzcih2YWwsIGxmc3JfdGFwcyhMRlNSX0JJVFMpKTsKCX0KfQoKI2RlZmluZSBCSVRTX1BF Ul9MT05HCShzaXplb2YobG9uZykgKiA4KQoKI2lmbmRlZiBMT09QUwojZGVmaW5lIExPT1BT IDEwMDAwMDAKI2VuZGlmCgojaWZkZWYgU09GVEZMUwoKc3RhdGljIF9fYWx3YXlzX2lubGlu ZSB1bnNpZ25lZCBsb25nIF9fZmxzKHVuc2lnbmVkIGxvbmcgd29yZCkKewoJaW50IG51bSA9 IEJJVFNfUEVSX0xPTkcgLSAxOwoKCWlmICghKHdvcmQgJiAofjB1bCA8PCAzMikpKSB7CgkJ bnVtIC09IDMyOwoJCXdvcmQgPDw9IDMyOwoJfQoJaWYgKCEod29yZCAmICh+MHVsIDw8IChC SVRTX1BFUl9MT05HLTE2KSkpKSB7CgkJbnVtIC09IDE2OwoJCXdvcmQgPDw9IDE2OwoJfQoJ aWYgKCEod29yZCAmICh+MHVsIDw8IChCSVRTX1BFUl9MT05HLTgpKSkpIHsKCQludW0gLT0g ODsKCQl3b3JkIDw8PSA4OwoJfQoJaWYgKCEod29yZCAmICh+MHVsIDw8IChCSVRTX1BFUl9M T05HLTQpKSkpIHsKCQludW0gLT0gNDsKCQl3b3JkIDw8PSA0OwoJfQoJaWYgKCEod29yZCAm ICh+MHVsIDw8IChCSVRTX1BFUl9MT05HLTIpKSkpIHsKCQludW0gLT0gMjsKCQl3b3JkIDw8 PSAyOwoJfQoJaWYgKCEod29yZCAmICh+MHVsIDw8IChCSVRTX1BFUl9MT05HLTEpKSkpCgkJ bnVtIC09IDE7CgoJcmV0dXJuIG51bTsKfQoKI2Vsc2UKCnN0YXRpYyBfX2Fsd2F5c19pbmxp bmUgdW5zaWduZWQgbG9uZyBfX2Zscyh1bnNpZ25lZCBsb25nIHdvcmQpCnsKI2lmIExaQ05U Cglhc20oInJlcDsgYnNyICUxLCUwIgoJCTogIj1yIiAod29yZCkKCQk6ICJybSIgKHdvcmQp KTsKCXJldHVybiBCSVRTX1BFUl9MT05HIC0gMSAtIHdvcmQ7CiNlbHNlCglhc20oImJzciAl MSwlMCIKCQk6ICI9ciIgKHdvcmQpCgkJOiAicm0iICh3b3JkKSk7CglyZXR1cm4gd29yZDsK I2VuZGlmCn0KCiNlbmRpZgoKCiNpZmRlZiBORVcKCnVuc2lnbmVkIGxvbmcgX19hdHRyaWJ1 dGVfXygobm9pbmxpbmUpKSBpbnRfc3FydCh1bnNpZ25lZCBsb25nIHgpCnsKCXVuc2lnbmVk IGxvbmcgYiwgbSwgeSA9IDA7CgoJaWYgKHggPD0gMSkKCQlyZXR1cm4geDsKCiNpZmRlZiBG TFMKCW0gPSAxVUwgPDwgKF9fZmxzKHgpICYgfjFVTCk7CiNlbHNlCgltID0gMVVMIDw8IChC SVRTX1BFUl9MT05HIC0gMik7CiNlbmRpZgoKI2lmZGVmIEFOU0hVTAoJd2hpbGUgKG0gPiB4 KQoJCW0gPj49IDI7CiNlbmRpZgoKCXdoaWxlIChtICE9IDApIHsKCQliID0geSArIG07CgkJ eSA+Pj0gMTsKCgkJaWYgKHggPj0gYikgewoJCQl4IC09IGI7CgkJCXkgKz0gbTsKCQl9CgkJ bSA+Pj0gMjsKCX0KCglyZXR1cm4geTsKfQoKI2VsaWYgTElOVVMKCgp1bnNpZ25lZCBsb25n IF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkgaW50X3NxcnQodW5zaWduZWQgbG9uZyB4KQp7 Cgl1bnNpZ25lZCBsb25nIG0sIHk7CgoJaWYgKHggPD0gMSkKCQlyZXR1cm4geDsKCgltID0g NjQ7CglkbyB7CgkJdW5zaWduZWQgbG9uZyBuZXdfbSA9IG0gPDwgMjsKCQlpZiAoIW5ld19t KQoJCQlicmVhazsKCQltID0gbmV3X207Cgl9IHdoaWxlIChtIDwgeCk7CgoJeSA9IDA7Cglk byB7CgkJdW5zaWduZWQgbG9uZyBiID0geSArIG07CgkJYiA9IHkgKyBtOwoJCXkgPj49IDE7 CgoJCWlmICh4ID49IGIpIHsKCQkJeCAtPSBiOwoJCQl5ICs9IG07CgkJfQoJCW0gPj49IDI7 Cgl9IHdoaWxlIChtKTsKCglyZXR1cm4geTsKfQoKI2Vsc2UKCnVuc2lnbmVkIGxvbmcgX19h dHRyaWJ1dGVfXygobm9pbmxpbmUpKSBpbnRfc3FydCh1bnNpZ25lZCBsb25nIHgpCnsKCXVu c2lnbmVkIGxvbmcgb3AsIHJlcywgb25lOwoKCW9wID0geDsKCXJlcyA9IDA7CgoJb25lID0g MVVMIDw8IChCSVRTX1BFUl9MT05HIC0gMik7Cgl3aGlsZSAob25lID4gb3ApCgkJb25lID4+ PSAyOwoKCXdoaWxlIChvbmUgIT0gMCkgewoJCWlmIChvcCA+PSByZXMgKyBvbmUpIHsKCQkJ b3AgPSBvcCAtIChyZXMgKyBvbmUpOwoJCQlyZXMgPSByZXMgKyAgMiAqIG9uZTsKCQl9CgkJ cmVzIC89IDI7CgkJb25lIC89IDQ7Cgl9CglyZXR1cm4gcmVzOwp9CgojZW5kaWYKCiNpZm5k ZWYgRVZFTlQKI2RlZmluZSBFVkVOVCBQRVJGX0NPVU5UX0hXX0NQVV9DWUNMRVMKI2VuZGlm CgpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfYXR0ciBhdHRyX2V2ZW50ID0gewoJLnR5cGUg PSBQRVJGX1RZUEVfSEFSRFdBUkUsCgkuY29uZmlnID0gRVZFTlQsCgkuZXhjbHVkZV9rZXJu ZWwgPSAxLAoJLnBpbm5lZCA9IDEsCn07CgpzdGF0aWMgdm9pZCAqY3JlYXRlX2V2ZW50KHN0 cnVjdCBwZXJmX2V2ZW50X2F0dHIgKmF0dHIpCnsKCXZvaWQgKmV2ZW50OwoJaW50IGZkID0g c3lzX3BlcmZfZXZlbnRfb3BlbihhdHRyLCAwLCAtMSwgLTEsIDApOwoKCWlmIChmZCA8IDAp IHsKCQlwZXJyb3IoInN5c19wZXJmX2V2ZW50X29wZW4iKTsKCQlleGl0KC0xKTsKCX0KCgll dmVudCA9IG1tYXAoTlVMTCwgc3lzY29uZihfU0NfUEFHRVNJWkUpLCBQUk9UX1JFQUQsIE1B UF9TSEFSRUQsIGZkLCAwKTsKCWlmIChldmVudCA9PSAodm9pZCAqKS0xKSB7CgkJcGVycm9y KCJtbWFwIik7CgkJZXhpdCgtMSk7Cgl9CgoJY2xvc2UoZmQpOwoKCW1tYXBfcmVhZF9waW5u ZWQoZXZlbnQpOwoKCXJldHVybiBldmVudDsKfQoKdm9pZCBtYWluKHZvaWQpCnsKCXZvaWQg KmV2ZW50ID0gY3JlYXRlX2V2ZW50KCZhdHRyX2V2ZW50KTsKCXN0cnVjdCBzdGF0cyBzdGF0 c19ub3A7CglzdHJ1Y3Qgc3RhdHMgc3RhdHNfZXZlbnQ7Cgl1bnNpZ25lZCBsb25nIGk7Cgl1 NjQgdmFsOwoKCWluaXRfc3RhdHMoJnN0YXRzX25vcCk7Cglpbml0X3N0YXRzKCZzdGF0c19l dmVudCk7CgoJZm9yIChpPTA7IGk8TE9PUFM7IGkrKykgewoJCXVuc2lnbmVkIGxvbmcgYTsK CiNpZiAxCgkJdmFsID0gbW1hcF9yZWFkX3Bpbm5lZChldmVudCk7CgkJYmFycmllcigpOwoJ CXVwZGF0ZV9zdGF0cygmc3RhdHNfbm9wLCBtbWFwX3JlYWRfcGlubmVkKGV2ZW50KSAtIHZh bCk7CgoJCXZhbCA9IG1tYXBfcmVhZF9waW5uZWQoZXZlbnQpOwoJCWJhcnJpZXIoKTsKCQlh ID0gaW50X3NxcnQoaSk7CgkJYmFycmllcigpOwoJCXVwZGF0ZV9zdGF0cygmc3RhdHNfZXZl bnQsIG1tYXBfcmVhZF9waW5uZWQoZXZlbnQpIC0gdmFsKTsKI2VuZGlmCgoKI2lmZGVmIFZB TElEQVRFCgkJewoJCQl1bnNpZ25lZCBsb25nIGIgPSBmbG9vcihzcXJ0KGkpKTsKCQkJaWYg KGEgIT0gYikKCQkJCXByaW50ZigiJWxkICVsZCAlbGRcbiIsIGksIGEsIGIpOwoJCX0KI2Vu ZGlmCgojaWZkZWYgV0lQRV9CVEIKCQl3aXBlX2J0YigpOwojZW5kaWYKCX0KCglwcmludGYo ImV2ZW50OiAlZiArLSAlZlxuIiwgYXZnX3N0YXRzKCZzdGF0c19ldmVudCkgLSBhdmdfc3Rh dHMoJnN0YXRzX25vcCksIAoJCQlzdW1fZXJyb3JzKHN0ZGRldl9zdGF0cygmc3RhdHNfbm9w KSwgc3RkZGV2X3N0YXRzKCZzdGF0c19ldmVudCkpKTsKfQoAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AABzcXJ0LXRlc3Qvc3RhdC5oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDY0 NAAwMDAxNzUwADAwMDE3NTAAMDAwMDAwMDI2MDEAMTMxMzQzNTU1NjAAMDEzNTYwACAwAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyICAAcGV0 ZXJ6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwZXRlcnoAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNpZm5kZWYgX1NUQVRfSAojZGVmaW5lIF9T VEFUX0gKCnN0cnVjdCBzdGF0cwp7Cglkb3VibGUgbiwgbWVhbiwgTTI7Cgl1NjQgbWF4LCBt aW47Cn07CgpzdGF0aWMgdm9pZCB1cGRhdGVfc3RhdHMoc3RydWN0IHN0YXRzICpzdGF0cywg dTY0IHZhbCkKewoJZG91YmxlIGRlbHRhOwoKCXN0YXRzLT5uKys7CglkZWx0YSA9IHZhbCAt IHN0YXRzLT5tZWFuOwoJc3RhdHMtPm1lYW4gKz0gZGVsdGEgLyBzdGF0cy0+bjsKCXN0YXRz LT5NMiArPSBkZWx0YSoodmFsIC0gc3RhdHMtPm1lYW4pOwoKCWlmICh2YWwgPiBzdGF0cy0+ bWF4KQoJCXN0YXRzLT5tYXggPSB2YWw7CgoJaWYgKHZhbCA8IHN0YXRzLT5taW4pCgkJc3Rh dHMtPm1pbiA9IHZhbDsKfQoKc3RhdGljIGRvdWJsZSBhdmdfc3RhdHMoc3RydWN0IHN0YXRz ICpzdGF0cykKewoJcmV0dXJuIHN0YXRzLT5tZWFuOwp9CgovKgogKiBodHRwOi8vZW4ud2lr aXBlZGlhLm9yZy93aWtpL0FsZ29yaXRobXNfZm9yX2NhbGN1bGF0aW5nX3ZhcmlhbmNlCiAq CiAqICAgICAgIChcU3VtIG5faV4yKSAtICgoXFN1bSBuX2kpXjIpL24KICogc14yID0gLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgICAgICAgICAgICAgICAgIG4gLSAx CiAqCiAqIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RkZGV2CiAqCiAqIFRoZSBz dGQgZGV2IG9mIHRoZSBtZWFuIGlzIHJlbGF0ZWQgdG8gdGhlIHN0ZCBkZXYgYnk6CiAqCiAq ICAgICAgICAgICAgIHMKICogc19tZWFuID0gLS0tLS0tLQogKiAgICAgICAgICBzcXJ0KG4p CiAqCiAqLwpzdGF0aWMgZG91YmxlIHN0ZGRldl9zdGF0cyhzdHJ1Y3Qgc3RhdHMgKnN0YXRz KQp7Cglkb3VibGUgdmFyaWFuY2UsIHZhcmlhbmNlX21lYW47CgoJaWYgKHN0YXRzLT5uIDwg MikKCQlyZXR1cm4gMC4wOwoKCXZhcmlhbmNlID0gc3RhdHMtPk0yIC8gKHN0YXRzLT5uIC0g MSk7Cgl2YXJpYW5jZV9tZWFuID0gdmFyaWFuY2UgLyBzdGF0cy0+bjsKCglyZXR1cm4gc3Fy dCh2YXJpYW5jZV9tZWFuKTsKfQoKc3RhdGljIGRvdWJsZSBzdW1fZXJyb3JzKGRvdWJsZSB4 LCBkb3VibGUgeSkKewoJcmV0dXJuIHNxcnQoeCp4ICsgeSp5KTsKfQoKc3RhdGljIGRvdWJs ZSByZWxfc3RkZGV2X3N0YXRzKGRvdWJsZSBzdGRkZXYsIGRvdWJsZSBhdmcpCnsKCWRvdWJs ZSBwY3QgPSAwLjA7CgoJaWYgKGF2ZykKCQlwY3QgPSAxMDAuMCAqIHN0ZGRldi9hdmc7CgoJ cmV0dXJuIHBjdDsKfQoKc3RhdGljIGlubGluZSB2b2lkIGluaXRfc3RhdHMoc3RydWN0IHN0 YXRzICpzdGF0cykKewoJc3RhdHMtPm4gICAgPSAwLjA7CglzdGF0cy0+bWVhbiA9IDAuMDsK CXN0YXRzLT5NMiAgID0gMC4wOwoJc3RhdHMtPm1pbiAgPSAodTY0KSAtMTsKCXN0YXRzLT5t YXggID0gMDsKfQoKI2VuZGlmIC8qIF9TVEFUX0ggKi8KAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNx cnQtdGVzdC90ZXN0LnNoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwNzU1ADAw MDE3NTAAMDAwMTc1MAAwMDAwMDAwMDUxMgAxMzEzNDM1NDA0MQAwMTM3NDIAIDAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdXN0YXIgIABwZXRlcnoA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHBldGVyegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIyEvYmluL2Jhc2gKCmZvciBFVkVOVCBpbiAwIDQg NSA7IGRvCglmb3IgUEFSQU1TIGluICItRExJTlVTPTEiICItRE5FVz0xIC1EQU5TSFVMPTEi ICItRE5FVz0xIC1EQU5TSFVMPTEgLURGTFM9MSIgIi1ETkVXPTEgLURBTlNIVUw9MSAtREZM Uz0xIC1EU09GVEZMUz0xIiA7IGRvCgkJZm9yIEJUQiBpbiAiIiAiLURXSVBFX0JUQj0xIiA7 IGRvCgkJCWVjaG8gRVZFTlQ9JEVWRU5UICRQQVJBTVMgJEJUQgoJCQlnY2MgLW8gc3FydCBz cXJ0LmMgLWxtIC1PMiAtRExPT1BTPTEwMDAwMCAtREVWRU5UPSRFVkVOVCAkUEFSQU1TICRC VEIgOyAuL3NxcnQKCQlkb25lCglkb25lCmRvbmUKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA= --23eu56dji7datv7c--