From owner-freebsd-numerics@FreeBSD.ORG Fri Sep 21 23:14:08 2012 Return-Path: Delivered-To: freebsd-numerics@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 396BF106566B for ; Fri, 21 Sep 2012 23:14:08 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail28.syd.optusnet.com.au (mail28.syd.optusnet.com.au [211.29.133.169]) by mx1.freebsd.org (Postfix) with ESMTP id 278C38FC08 for ; Fri, 21 Sep 2012 23:14:06 +0000 (UTC) Received: from c122-106-157-84.carlnfd1.nsw.optusnet.com.au (c122-106-157-84.carlnfd1.nsw.optusnet.com.au [122.106.157.84]) by mail28.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id q8LNDuYQ025170 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 22 Sep 2012 09:13:57 +1000 Date: Sat, 22 Sep 2012 09:13:56 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Stephen Montgomery-Smith In-Reply-To: <505CC11A.5030502@missouri.edu> Message-ID: <20120922081607.F3613@besplex.bde.org> References: <5017111E.6060003@missouri.edu> <50538E28.6050400@missouri.edu> <20120915231032.C2669@besplex.bde.org> <50548E15.3010405@missouri.edu> <5054C027.2040008@missouri.edu> <5054C200.7090307@missouri.edu> <20120916041132.D6344@besplex.bde.org> <50553424.2080902@missouri.edu> <20120916134730.Y957@besplex.bde.org> <5055ECA8.2080008@missouri.edu> <20120917022614.R2943@besplex.bde.org> <50562213.9020400@missouri.edu> <20120917060116.G3825@besplex.bde.org> <50563C57.60806@missouri.edu> <20120918012459.V5094@besplex.bde.org> <5057A932.3000603@missouri.edu> <5057F24B.7020605@missouri.edu> <20120918162105.U991@besplex.bde.org> <20120918232850.N2144@besplex.bde.org> <20120919010613.T2493@besplex.bde.org> <505BD9B4.8020801@missouri.edu> <20120921172402.W945@besplex.bde.org> <20120921212525.W1732@besplex.bde.org> <505C7490.90600@missouri.edu> <20120922042112.E3044@besplex.bde.org> <505CBF14.70908@missouri.edu> <505CC11A.5030502@missouri.edu> MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="0-46617504-1348269236=:3613" Cc: freebsd-numerics@FreeBSD.org Subject: Re: Complex arg-trig functions X-BeenThere: freebsd-numerics@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Discussions of high quality implementation of libm functions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Sep 2012 23:14:08 -0000 This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --0-46617504-1348269236=:3613 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed On Fri, 21 Sep 2012, Stephen Montgomery-Smith wrote: > On 09/21/2012 02:25 PM, Stephen Montgomery-Smith wrote: >> On 09/21/2012 02:05 PM, Bruce Evans wrote: >>> On Fri, 21 Sep 2012, Stephen Montgomery-Smith wrote: >> >>> - decide whether my old change to remove unnecessary accuracy for the >>> case where ax == 1, ay < FLT_EPSILON in catanh() is correct (you >>> didn't accept it, and maybe other accuracy changes make it extra >>> accuracy more interesting). >> >> Or maybe I missed it. > > When you send me changes to catrigf.c, I translate it to catrig.c (the double > version), and then convert it back to catrigf.c. So sometimes I miss things. This time I merged everything into catrig.c and even ran the conversion scripts to check this. I keep forgetting to add or remove f suffixes when manually converting. Patches tomorrow. Well, the main new one now, for all 3 files since part of it has lots of magic numbers which are not handled by the conversion scripts. % diff -u2 catrig.c~ catrig.c % --- catrig.c~ 2012-09-21 15:51:00.000000000 +0000 % +++ catrig.c 2012-09-21 21:40:34.521926000 +0000 % @@ -206,6 +217,6 @@ % */ % *B_is_usable = 0; % - *sqrt_A2my2 = scalbn(A, DBL_MANT_DIG); % - *new_y = scalbn(y, DBL_MANT_DIG); % + *sqrt_A2my2 = A * (2 / DBL_EPSILON); % + *new_y= y * (2 / DBL_EPSILON); % return; % } % @@ -244,6 +255,7 @@ % * scaling should avoid any underflow problems. % */ % - *sqrt_A2my2 = scalbn(x, 2*DBL_MANT_DIG) * y / sqrt((y+1)*(y-1)); % - *new_y = scalbn(y, 2*DBL_MANT_DIG); % + *sqrt_A2my2 = x * (4/DBL_EPSILON/DBL_EPSILON) * y / % + sqrt((y+1)*(y-1)); % + *new_y = y * (4/DBL_EPSILON/DBL_EPSILON); % } else /* if (y < 1) */ { % /* It's easy to eliminiate these scalbn()s, since the values are constant. scalbn() is a builtin in gcc-4.2 but not in gcc-3.3, and in 4.2 the builtin just calls the extern function. Here the constant values could be calculated at compile time, but gcc doesn't do this. I think clang does. The conversion script handles this fine. % @@ -501,29 +519,40 @@ % /* % * real_part_reciprocal(x, y) = Re(1/(x+I*y)) = x/(x*x + y*y). % - * Assumes x and y are positive or zero, and one of x and y is larger than % + * Assumes x and y are not NaN, and one of x and y is larger than % * RECIP_EPSILON. We avoid unwarranted underflow. It is important to not use The old version was passed positive x and y, but didn't depend on this. The caller then had to fix up the sign. This version is passed x and y with their original signs. The sign is handled automatically by expressions in the function, and the caller doesn't fix it up. % * the code creal(1/z), because the imaginary part may produce an unwanted % * underflow. % + * This is only called in a context where inexact is always raised before % + * the call, so no effort is made to avoid or force inexact. % */ % inline static double % real_part_reciprocal(double x, double y) % { % + double scale; % + uint32_t hx, hy; % + int32_t ix, iy; % + % /* % * This code is inspired by the C99 document n1124.pdf, Section G.5.1, % * example 2. % */ % - int ex, ey; % - % - if (isinf(x) || isinf(y)) % - return (0); % - if (y == 0) return (1/x); % - if (x == 0) return (x/y/y); % - ex = ilogb(x); % - ey = ilogb(y); % - if (ex - ey >= DBL_MANT_DIG) return (1/x); % - if (ey - ex >= DBL_MANT_DIG) return (x/y/y); % - x = scalbn(x, -ex); % - y = scalbn(y, -ex); % - return scalbn(x/(x*x + y*y), -ex); The conversion to not use scalbn() is fairly direct and routine, but also fairly magic. % + GET_HIGH_WORD(hx, x); % + ix = hx & 0x7ff00000; % + GET_HIGH_WORD(hy, y); % + iy = hy & 0x7ff00000; ilogb() is a builtin to much the same extent as scalbn() IIRC -- mostly it isn't. By working with the raw exponent, we avoid complications from the following design bugs in ilogb(): - ilogb(0) returns FP_ILOGB0, so the above needs special cases for x == 0 and y == 0 - ilogb(+-Inf) returns INT_MAX, so the above needs to handle infs earlier than is optimal. With the raw exponents, you can just subtract them and most things work. Denormals cause problems with this subtraction in some contexts, and ilogb() has to do a lot of work find their exponent, and scalbn has to do a lot of work to shift their mantissa (compared with just adding to the exponent for a normal). Here we handle them fairly subtly without any extra code: when one arg is denormal, the absolute value exceeds RECIP_EPSILON, so there is a large exponent differences, and the special cases for large exponent differences handle this case automatically. The case of y infinite but x finite is handled similarly. % +#define BIAS (DBL_MAX_EXP - 1) % +/* XXX more guard digits are useful iff there is extra precision. */ Without extra precision, a cutoff of with fewer guard digits somehow gives better accuracy than one with more. (The old cutoffs in terms of exponent bits give ~DBL_MANT_DIG/2 active bits and ~DBL_MANT_DIG/2 guard bits.) % +#define CUTOFF (DBL_MANT_DIG / 2 + 1) /* just half or 1 guard digit */ % + if (ix - iy >= CUTOFF << 20 || isinf(x)) % + return (1/x); /* +-Inf -> +-0 is special */ Constants are shifted to avoid shifting the exponent bits in ix and iy back and forth. The special cases for infinities have been reduced to this one here. The sign used to be handled by copysign(0, x) when x is +-Inf. Now the common 1/x return is used. % + if (iy - ix >= CUTOFF << 20) % + return (x/y/y); /* should avoid double div, but hard */ % + if (ix <= (BIAS + DBL_MAX_EXP / 2 - CUTOFF) << 20) % + return (x/(x*x + y*y)); % + scale = 0; % + SET_HIGH_WORD(scale, 0x7ff00000 - ix); /* 2**(1-ilogb(x)) */ % + x *= scale; % + y *= scale; % + return (x/(x*x + y*y) * scale); % } % % @@ -577,13 +606,22 @@ % % if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) % - return (cpack(copysign(real_part_reciprocal(ax, ay), x), copysign(m_pi_2, y))); % + return (cpack(real_part_reciprocal(x, y), copysign(pio2_hi + pio2_lo, y))); Handle the sign in the function. Unrelated details that I couldn't edit out without breaking the patch hunk: % % - if (ax < SQRT_EPSILON && ay < SQRT_EPSILON) % + if (ax < SQRT_3_EPSILON/2 && ay < SQRT_3_EPSILON/2) { % + /* % + * z = 0 was filtered out above. All other cases must raise % + * inexact, but this is the only only that needs to do it % + * explicitly. % + */ % + raise_inexact(); % return (z); % + } It is an optimization to only raise inexact here. The early return for y == 0 && ax <= 1 worked well, but not the early raising of inexact. I also reduce the x == 0 case to atanf() early. That leaves no z == 0 case here, so we raise inexact unconditionally. % % if (ax == 1 && ay < DBL_EPSILON) { % +#if 0 /* this only improves accuracy in an already relative accurate case */ % if (ay > 2*DBL_MIN) % rx = - log(ay/2) / 2; % else % +#endif This was the change that you might have missed. % rx = - (log(ay) - m_ln2) / 2; % } else Everything for the other files is routine except for the magic numbers in real_part_reciprocal related to the packing of the bits. I prefer to leave those as magic. A full macroization of them would have to macroize the accesses GET_HIGH_WORD() etc. % diff -u2 catrigf.c~ catrigf.c % --- catrigf.c~ 2012-09-21 15:51:16.000000000 +0000 % +++ catrigf.c 2012-09-21 21:34:41.140231000 +0000 % @@ -108,6 +109,6 @@ % if (y < FOUR_SQRT_MIN) { % *B_is_usable = 0; % - *sqrt_A2my2 = scalbnf(A, FLT_MANT_DIG); % - *new_y = scalbnf(y, FLT_MANT_DIG); % + *sqrt_A2my2 = A * (2 / FLT_EPSILON); % + *new_y= y * (2 / FLT_EPSILON); % return; % } % @@ -124,6 +125,7 @@ % *sqrt_A2my2 = sqrtf(Amy*(A+y)); % } else if (y > 1) { % - *sqrt_A2my2 = scalbnf(x, 2*FLT_MANT_DIG) * y / sqrtf((y+1)*(y-1)); % - *new_y = scalbnf(y, 2*FLT_MANT_DIG); % + *sqrt_A2my2 = x * (4/FLT_EPSILON/FLT_EPSILON) * y / % + sqrtf((y+1)*(y-1)); % + *new_y = y * (4/FLT_EPSILON/FLT_EPSILON); % } else { % *sqrt_A2my2 = sqrtf((1-y)*(1+y)); % @@ -293,17 +299,24 @@ % real_part_reciprocal(float x, float y) % { % - int ex, ey; % - % - if (isinf(x) || isinf(y)) % - return (0); % - if (y == 0) return (1/x); % - if (x == 0) return (x/y/y); % - ex = ilogbf(x); % - ey = ilogbf(y); % - if (ex - ey >= FLT_MANT_DIG) return (1/x); % - if (ey - ex >= FLT_MANT_DIG) return (x/y/y); % - x = scalbnf(x, -ex); % - y = scalbnf(y, -ex); % - return scalbnf(x/(x*x + y*y), -ex); % + float scale; % + uint32_t hx, hy; % + int32_t ix, iy; % + % + GET_FLOAT_WORD(hx, x); % + ix = hx & 0x7f800000; % + GET_FLOAT_WORD(hy, y); % + iy = hy & 0x7f800000; % +#define BIAS (FLT_MAX_EXP - 1) % +#define CUTOFF (FLT_MANT_DIG / 2 + 1) % + if (ix - iy >= CUTOFF << 23 || isinf(x)) % + return (1/x); % + if (iy - ix >= CUTOFF << 23) % + return (x/y/y); % + if (ix <= (BIAS + FLT_MAX_EXP / 2 - CUTOFF) << 23) % + return (x/(x*x + y*y)); % + SET_FLOAT_WORD(scale, 0x7f800000 - ix); % + x *= scale; % + y *= scale; % + return (x/(x*x + y*y) * scale); % } % % @@ -335,13 +348,17 @@ % % if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) % - return (cpackf(copysignf(real_part_reciprocal(ax, ay), x), copysignf(m_pi_2, y))); % + return (cpackf(real_part_reciprocal(x, y), copysignf(pio2_hi + pio2_lo, y))); % % - if (ax < SQRT_EPSILON && ay < SQRT_EPSILON) % + if (ax < SQRT_3_EPSILON/2 && ay < SQRT_3_EPSILON/2) { % + raise_inexact(); % return (z); % + } % % if (ax == 1 && ay < FLT_EPSILON) { % +#if 0 % if (ay > 2*FLT_MIN) % rx = - logf(ay/2) / 2; % else % +#endif % rx = - (logf(ay) - m_ln2) / 2; % } else % diff -u2 catrigl.c~ catrigl.c % --- catrigl.c~ 2012-09-21 16:22:40.000000000 +0000 % +++ catrigl.c 2012-09-21 21:17:46.962698000 +0000 % @@ -122,6 +124,6 @@ % if (y < FOUR_SQRT_MIN) { % *B_is_usable = 0; % - *sqrt_A2my2 = scalbnl(A, LDBL_MANT_DIG); % - *new_y = scalbnl(y, LDBL_MANT_DIG); % + *sqrt_A2my2 = A * (2 / LDBL_EPSILON); % + *new_y= y * (2 / LDBL_EPSILON); % return; % } % @@ -138,6 +140,7 @@ % *sqrt_A2my2 = sqrtl(Amy*(A+y)); % } else if (y > 1) { % - *sqrt_A2my2 = scalbnl(x, 2*LDBL_MANT_DIG) * y / sqrtl((y+1)*(y-1)); % - *new_y = scalbnl(y, 2*LDBL_MANT_DIG); % + *sqrt_A2my2 = x * (4/LDBL_EPSILON/LDBL_EPSILON) * y / % + sqrtl((y+1)*(y-1)); % + *new_y = y * (4/LDBL_EPSILON/LDBL_EPSILON); % } else { % *sqrt_A2my2 = sqrtl((1-y)*(1+y)); % @@ -307,17 +314,24 @@ % real_part_reciprocal(long double x, long double y) % { % - int ex, ey; % - % - if (isinf(x) || isinf(y)) % - return (0); % - if (y == 0) return (1/x); % - if (x == 0) return (x/y/y); % - ex = ilogbl(x); % - ey = ilogbl(y); % - if (ex - ey >= LDBL_MANT_DIG) return (1/x); % - if (ey - ex >= LDBL_MANT_DIG) return (x/y/y); % - x = scalbnl(x, -ex); % - y = scalbnl(y, -ex); % - return scalbnl(x/(x*x + y*y), -ex); % + long double scale; % + uint16_t hx, hy; % + int16_t ix, iy; % + % + GET_LDBL_EXPSIGN(hx, x); % + ix = hx & 0x7fff; % + GET_LDBL_EXPSIGN(hy, y); % + iy = hy & 0x7fff; % +#define BIAS (LDBL_MAX_EXP - 1) % +#define CUTOFF (LDBL_MANT_DIG / 2 + 1) % + if (ix - iy >= CUTOFF || isinf(x)) % + return (1/x); % + if (iy - ix >= CUTOFF) % + return (x/y/y); % + if (ix <= BIAS + LDBL_MAX_EXP / 2 - CUTOFF) % + return (x/(x*x + y*y)); % + SET_LDBL_EXPSIGN(scale, 0x7fff - ix); % + x *= scale; % + y *= scale; % + return (x/(x*x + y*y) * scale); % } % % @@ -349,13 +363,17 @@ % % if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) % - return (cpackl(copysignl(real_part_reciprocal(ax, ay), x), copysignl(m_pi_2, y))); % + return (cpackl(real_part_reciprocal(x, y), copysignl(pio2_hi + pio2_lo, y))); % % - if (ax < SQRT_EPSILON && ay < SQRT_EPSILON) % + if (ax < SQRT_3_EPSILON/2 && ay < SQRT_3_EPSILON/2) { % + raise_inexact(); % return (z); % + } % % if (ax == 1 && ay < LDBL_EPSILON) { % +#if 0 % if (ay > 2*LDBL_MIN) % rx = - logl(ay/2) / 2; % else % +#endif % rx = - (logl(ay) - m_ln2) / 2; % } else The patch is also attached. Bruce --0-46617504-1348269236=:3613 Content-Type: TEXT/PLAIN; charset=US-ASCII; name="catrig.diff" Content-Transfer-Encoding: BASE64 Content-ID: <20120922091356.U3613@besplex.bde.org> Content-Description: Content-Disposition: attachment; filename="catrig.diff" ZGlmZiAtdTIgY2F0cmlnLmN+IGNhdHJpZy5jDQotLS0gY2F0cmlnLmN+CTIw MTItMDktMjEgMTU6NTE6MDAuMDAwMDAwMDAwICswMDAwDQorKysgY2F0cmln LmMJMjAxMi0wOS0yMSAyMTo0MDozNC41MjE5MjYwMDAgKzAwMDANCkBAIC0z NSw0ICszNSw1IEBADQogI3VuZGVmIGlzbmFuDQogI2RlZmluZSBpc25hbih4 KQkoKHgpICE9ICh4KSkNCisjZGVmaW5lCXJhaXNlX2luZXhhY3QoKQlkbyB7 IHZvbGF0aWxlIGludCBqdW5rID0gMSArIHRpbnk7IH0gd2hpbGUoMCkNCiAj dW5kZWYgc2lnbmJpdA0KICNkZWZpbmUgc2lnbmJpdCh4KQkoX19idWlsdGlu X3NpZ25iaXQoeCkpDQpAQCAtNDYsMTIgKzQ3LDIyIEBADQogbV9lID0JCQky LjcxODI4MTgyODQ1OTA0NTJlMCwJLyogIDB4MTViZjBhOGIxNDU3NjkuMHAt NTEgKi8NCiBtX2xuMiA9CQkJNi45MzE0NzE4MDU1OTk0NTMxZS0xLAkvKiAg MHgxNjJlNDJmZWZhMzllZi4wcC01MyAqLw0KLW1fcGlfMiA9CQkxLjU3MDc5 NjMyNjc5NDg5NjZlMCwJLyogIDB4MTkyMWZiNTQ0NDJkMTguMHAtNTIgKi8N Ci1waW8yX2hpID0JCTEuNTcwNzk2MzI2Nzk0ODk2NTU4MDBlKzAwLAkvKiAw eDNGRjkyMUZCLCAweDU0NDQyRDE4ICovDQotcGlvMl9sbyA9CQk2LjEyMzIz Mzk5NTczNjc2NjAzNTg3ZS0xNywJLyogMHgzQzkxQTYyNiwgMHgzMzE0NUMw NyAqLw0KKy8qDQorICogV2Ugbm8gbG9uZ2VyIHVzZSBNX1BJXzIgb3IgbV9w aV8yLiAgSW4gZmxvYXQgcHJlY2lzaW9uLCByb3VuZGluZyB0bw0KKyAqIG5l YXJlc3Qgb2YgUEkvMiBoYXBwZW5zIHRvIHJvdW5kIHVwLCBidXQgd2Ugd2Fu dCByb3VuZGluZyBkb3duIHNvDQorICogdGhhdCB0aGUgZXhwcmVzc2lvbnMg Zm9yIGFwcHJveGltYXRpbmcgUEkvMiBhbmQgKFBJLzIgLSB6KSB3b3JrIGlu IGFsbA0KKyAqIHJvdW5kaW5nIG1vZGVzLiAgVGhpcyBpcyBub3QgdmVyeSBp bXBvcnRhbnQsIGJ1dCBpdCBpcyBuZWNlc3NhcnkgZm9yDQorICogdGhlIHNh bWUgcXVhbGl0eSBvZiBpbXBsZW1lbnRhdGlvbiB0aGF0IGZkbGlibSBoYWQg aW4gMTk5MiBhbmQgdGhhdA0KKyAqIHJlYWwgZnVuY3Rpb25zIG1vc3RseSBz dGlsbCBoYXZlLiAgVGhpcyBpcyBrbm93biB0byBiZSBicm9rZW4gb25seSBp bg0KKyAqIGxkODAgYWNvc2woKSB2aWEgaW52dHJpZy5jIGFuZCBpbiBzb21l IGludmFsaWQgb3B0aW1pemF0aW9ucyBpbiBjb2RlDQorICogdW5kZXIgZGV2 ZWxvcG1lbnQsIGFuZCBub3cgaW4gYWxsIGZ1bmN0aW9ucyBpbiBjYXRyaWds LmMgdmlhIGludnRyaWcuYy4NCisgKi8NCitwaW8yX2hpID0JCTEuNTcwNzk2 MzI2Nzk0ODk2NmUwLAkvKiAgMHgxOTIxZmI1NDQ0MmQxOC4wcC01MiAqLw0K IFJFQ0lQX0VQU0lMT04gPQkJMS9EQkxfRVBTSUxPTiwNCi1TUVJUX0VQU0lM T04gPQkJMHgxcC0yNywJCS8qIDw9IHNxcnQoREJMX0VQU0lMT04pICovIA0K K1NRUlRfM19FUFNJTE9OID0JMi41ODA5NTY4Mjc5NTE3ODQ5ZS04LAkvKiAg MHgxYmI2N2FlODU4NGNhYS4wcC03OCAqLw0KK1NRUlRfNl9FUFNJTE9OID0J My42NTAwMjQxNDk5ODg4NTcxZS04LAkvKiAgMHgxMzk4OGUxNDA5MjEyZS4w cC03NyAqLw0KIFNRUlRfTUlOID0JCTB4MXAtNTExOwkvKiA+PSBzcXJ0KERC TF9NSU4pICovDQogDQogc3RhdGljIGNvbnN0IHZvbGF0aWxlIGRvdWJsZQ0K K3BpbzJfbG8gPQkJNi4xMjMyMzM5OTU3MzY3NjU5ZS0xNywJLyogIDB4MTFh NjI2MzMxNDVjMDcuMHAtMTA2ICovDQogdGlueSA9CQkJMHgxcC0xMDAwOw0K IA0KQEAgLTIwNiw2ICsyMTcsNiBAQA0KIAkJICovDQogCQkqQl9pc191c2Fi bGUgPSAwOw0KLQkJKnNxcnRfQTJteTIgPSBzY2FsYm4oQSwgREJMX01BTlRf RElHKTsNCi0JCSpuZXdfeSA9IHNjYWxibih5LCBEQkxfTUFOVF9ESUcpOw0K KwkJKnNxcnRfQTJteTIgPSBBICogKDIgLyBEQkxfRVBTSUxPTik7DQorCQkq bmV3X3k9IHkgKiAoMiAvIERCTF9FUFNJTE9OKTsNCiAJCXJldHVybjsNCiAJ fQ0KQEAgLTI0NCw2ICsyNTUsNyBAQA0KIAkJCSAqIHNjYWxpbmcgc2hvdWxk IGF2b2lkIGFueSB1bmRlcmZsb3cgcHJvYmxlbXMuDQogCQkJICovDQotCQkJ KnNxcnRfQTJteTIgPSBzY2FsYm4oeCwgMipEQkxfTUFOVF9ESUcpICogeSAv IHNxcnQoKHkrMSkqKHktMSkpOw0KLQkJCSpuZXdfeSA9IHNjYWxibih5LCAy KkRCTF9NQU5UX0RJRyk7DQorCQkJKnNxcnRfQTJteTIgPSB4ICogKDQvREJM X0VQU0lMT04vREJMX0VQU0lMT04pICogeSAvDQorCQkJICAgIHNxcnQoKHkr MSkqKHktMSkpOw0KKwkJCSpuZXdfeSA9IHkgKiAoNC9EQkxfRVBTSUxPTi9E QkxfRVBTSUxPTik7DQogCQl9IGVsc2UgLyogaWYgKHkgPCAxKSAqLyB7DQog CQkJLyoNCkBAIC0zMDMsOSArMzE1LDEyIEBADQogCX0NCiANCi0JLyogcmFp c2UgaW5leGFjdCBpZiB6ICE9IDAuICovDQotCWlmICgoeCA9PSAwICYmIHkg PT0gMCkgfHwgKGludCkoMSArIHRpbnkpICE9IDEpDQorCS8qIEF2b2lkIHNw dXJpb3VzbHkgcmFpc2luZyBpbmV4YWN0IGZvciB6ID0gMC4gKi8NCisJaWYg KHggPT0gMCAmJiB5ID09IDApDQogCQlyZXR1cm4gKHopOw0KIA0KLQlpZiAo YXggPCBTUVJUX0VQU0lMT04gJiYgYXkgPCBTUVJUX0VQU0lMT04pDQorCS8q IEFsbCByZW1haW5pbmcgY2FzZXMgYXJlIGluZXhhY3QuICovDQorCXJhaXNl X2luZXhhY3QoKTsNCisNCisJaWYgKGF4IDwgU1FSVF82X0VQU0lMT04vNCAm JiBheSA8IFNRUlRfNl9FUFNJTE9OLzQpDQogCQlyZXR1cm4gKHopOw0KIA0K QEAgLTM2NCw1ICszNzksNSBAQA0KIAkJCXJldHVybiAoY3BhY2soeCt4LCAt eSkpOw0KIAkJLyogY2Fjb3MoMCArIEkqTmFOKSA9IFBJLzIgKyBJKk5hTiB3 aXRoIGluZXhhY3QgKi8NCi0JCWlmICh4ID09IDApIHJldHVybiAoY3BhY2so bV9waV8yICsgdGlueSwgeSt5KSk7DQorCQlpZiAoeCA9PSAwKSByZXR1cm4g KGNwYWNrKHBpbzJfaGkgKyBwaW8yX2xvLCB5K3kpKTsNCiAJCS8qDQogCQkg KiBBbGwgb3RoZXIgY2FzZXMgaW52b2x2aW5nIE5hTiByZXR1cm4gTmFOICsg SSpOYU4uDQpAQCAtMzgzLDkgKzM5OCwxMiBAQA0KIAl9DQogDQotCS8qIHJh aXNlIGluZXhhY3QgaWYgeiAhPSAxLiAqLw0KLQlpZiAoKHggPT0gMSAmJiB5 ID09IDApIHx8IChpbnQpKDEgKyB0aW55KSAhPSAxKQ0KKwkvKiBBdm9pZCBz cHVyaW91c2x5IHJhaXNpbmcgaW5leGFjdCBmb3IgeiA9IDEuICovDQorCWlm ICh4ID09IDEgJiYgeSA9PSAwKQ0KIAkJcmV0dXJuIChjcGFjaygwLCAteSkp Ow0KIA0KLQlpZiAoYXggPCBTUVJUX0VQU0lMT04gJiYgYXkgPCBTUVJUX0VQ U0lMT04pDQorCS8qIEFsbCByZW1haW5pbmcgY2FzZXMgYXJlIGluZXhhY3Qu ICovDQorCXJhaXNlX2luZXhhY3QoKTsNCisNCisJaWYgKGF4IDwgU1FSVF82 X0VQU0lMT04vNCAmJiBheSA8IFNRUlRfNl9FUFNJTE9OLzQpDQogCQlyZXR1 cm4gKGNwYWNrKHBpbzJfaGkgLSAoeCAtIHBpbzJfbG8pLCAteSkpOw0KIA0K QEAgLTUwMSwyOSArNTE5LDQwIEBADQogLyoNCiAgKiByZWFsX3BhcnRfcmVj aXByb2NhbCh4LCB5KSA9IFJlKDEvKHgrSSp5KSkgPSB4Lyh4KnggKyB5Knkp Lg0KLSAqIEFzc3VtZXMgeCBhbmQgeSBhcmUgcG9zaXRpdmUgb3IgemVybywg YW5kIG9uZSBvZiB4IGFuZCB5IGlzIGxhcmdlciB0aGFuDQorICogQXNzdW1l cyB4IGFuZCB5IGFyZSBub3QgTmFOLCBhbmQgb25lIG9mIHggYW5kIHkgaXMg bGFyZ2VyIHRoYW4NCiAgKiBSRUNJUF9FUFNJTE9OLiAgV2UgYXZvaWQgdW53 YXJyYW50ZWQgdW5kZXJmbG93LiAgSXQgaXMgaW1wb3J0YW50IHRvIG5vdCB1 c2UNCiAgKiB0aGUgY29kZSBjcmVhbCgxL3opLCBiZWNhdXNlIHRoZSBpbWFn aW5hcnkgcGFydCBtYXkgcHJvZHVjZSBhbiB1bndhbnRlZA0KICAqIHVuZGVy Zmxvdy4NCisgKiBUaGlzIGlzIG9ubHkgY2FsbGVkIGluIGEgY29udGV4dCB3 aGVyZSBpbmV4YWN0IGlzIGFsd2F5cyByYWlzZWQgYmVmb3JlDQorICogdGhl IGNhbGwsIHNvIG5vIGVmZm9ydCBpcyBtYWRlIHRvIGF2b2lkIG9yIGZvcmNl IGluZXhhY3QuDQogICovDQogaW5saW5lIHN0YXRpYyBkb3VibGUNCiByZWFs X3BhcnRfcmVjaXByb2NhbChkb3VibGUgeCwgZG91YmxlIHkpDQogew0KKwlk b3VibGUgc2NhbGU7DQorCXVpbnQzMl90IGh4LCBoeTsNCisJaW50MzJfdCBp eCwgaXk7DQorDQogCS8qDQogCSAqIFRoaXMgY29kZSBpcyBpbnNwaXJlZCBi eSB0aGUgQzk5IGRvY3VtZW50IG4xMTI0LnBkZiwgU2VjdGlvbiBHLjUuMSwN CiAJICogZXhhbXBsZSAyLg0KIAkgKi8NCi0JaW50IGV4LCBleTsNCi0NCi0J aWYgKGlzaW5mKHgpIHx8IGlzaW5mKHkpKQ0KLQkJcmV0dXJuICgwKTsNCi0J aWYgKHkgPT0gMCkgcmV0dXJuICgxL3gpOw0KLQlpZiAoeCA9PSAwKSByZXR1 cm4gKHgveS95KTsNCi0JZXggPSBpbG9nYih4KTsNCi0JZXkgPSBpbG9nYih5 KTsNCi0JaWYgKGV4IC0gZXkgPj0gREJMX01BTlRfRElHKSByZXR1cm4gKDEv eCk7DQotCWlmIChleSAtIGV4ID49IERCTF9NQU5UX0RJRykgcmV0dXJuICh4 L3kveSk7DQotCXggPSBzY2FsYm4oeCwgLWV4KTsNCi0JeSA9IHNjYWxibih5 LCAtZXgpOw0KLQlyZXR1cm4gc2NhbGJuKHgvKHgqeCArIHkqeSksIC1leCk7 DQorCUdFVF9ISUdIX1dPUkQoaHgsIHgpOw0KKwlpeCA9IGh4ICYgMHg3ZmYw MDAwMDsNCisJR0VUX0hJR0hfV09SRChoeSwgeSk7DQorCWl5ID0gaHkgJiAw eDdmZjAwMDAwOw0KKyNkZWZpbmUJQklBUwkoREJMX01BWF9FWFAgLSAxKQ0K Ky8qIFhYWCBtb3JlIGd1YXJkIGRpZ2l0cyBhcmUgdXNlZnVsIGlmZiB0aGVy ZSBpcyBleHRyYSBwcmVjaXNpb24uICovDQorI2RlZmluZQlDVVRPRkYJKERC TF9NQU5UX0RJRyAvIDIgKyAxKQkvKiBqdXN0IGhhbGYgb3IgMSBndWFyZCBk aWdpdCAqLw0KKwlpZiAoaXggLSBpeSA+PSBDVVRPRkYgPDwgMjAgfHwgaXNp bmYoeCkpDQorCQlyZXR1cm4gKDEveCk7CQkvKiArLUluZiAtPiArLTAgaXMg c3BlY2lhbCAqLw0KKwlpZiAoaXkgLSBpeCA+PSBDVVRPRkYgPDwgMjApDQor CQlyZXR1cm4gKHgveS95KTsJCS8qIHNob3VsZCBhdm9pZCBkb3VibGUgZGl2 LCBidXQgaGFyZCAqLw0KKwlpZiAoaXggPD0gKEJJQVMgKyBEQkxfTUFYX0VY UCAvIDIgLSBDVVRPRkYpIDw8IDIwKQ0KKwkJcmV0dXJuICh4Lyh4KnggKyB5 KnkpKTsNCisJc2NhbGUgPSAwOw0KKwlTRVRfSElHSF9XT1JEKHNjYWxlLCAw eDdmZjAwMDAwIC0gaXgpOwkvKiAyKiooMS1pbG9nYih4KSkgKi8NCisJeCAq PSBzY2FsZTsNCisJeSAqPSBzY2FsZTsNCisJcmV0dXJuICh4Lyh4KnggKyB5 KnkpICogc2NhbGUpOw0KIH0NCiANCkBAIC01NTQsNyArNTgzLDcgQEANCiAJ CXJldHVybiAoY3BhY2soYXRhbmgoeCksIHkpKTsgDQogDQotCS8qIHJhaXNl IGluZXhhY3QgaWYgeiAhPSAwLiAqLw0KLQlpZiAoKHggPT0gMCAmJiB5ID09 IDApIHx8IChpbnQpKDEgKyB0aW55KSAhPSAxKQ0KLQkJcmV0dXJuICh6KTsN CisJLyogVG8gZW5zdXJlIHRoZSBzYW1lIGFjY3VyYWN5IGFzIGF0YW4oKSwg YW5kIHRvIGZpbHRlciBvdXQgeiA9IDAuICovDQorCWlmICh4ID09IDApDQor CQlyZXR1cm4gKGNwYWNrKHgsIGF0YW4oeSkpKTsNCiANCiAJaWYgKGlzbmFu KHgpIHx8IGlzbmFuKHkpKSB7DQpAQCAtNTY0LDUgKzU5Myw1IEBADQogCQkv KiBjYXRhbmgoTmFOICsgSSorLUluZikgPSBzaWduKE5hTikwICsgSSorLVBJ LzIgKi8NCiAJCWlmIChpc2luZih5KSkNCi0JCQlyZXR1cm4gKGNwYWNrKGNv cHlzaWduKDAsIHgpLCBjb3B5c2lnbihtX3BpXzIsIHkpKSk7DQorCQkJcmV0 dXJuIChjcGFjayhjb3B5c2lnbigwLCB4KSwgY29weXNpZ24ocGlvMl9oaSAr IHBpbzJfbG8sIHkpKSk7DQogCQkvKiBjYXRhbmgoKy0wICsgSSpOYU4pID0g Ky0wICsgSSpOYU4gKi8NCiAJCWlmICh4ID09IDApDQpAQCAtNTc3LDEzICs2 MDYsMjIgQEANCiANCiAJaWYgKGF4ID4gUkVDSVBfRVBTSUxPTiB8fCBheSA+ IFJFQ0lQX0VQU0lMT04pDQotCQlyZXR1cm4gKGNwYWNrKGNvcHlzaWduKHJl YWxfcGFydF9yZWNpcHJvY2FsKGF4LCBheSksIHgpLCBjb3B5c2lnbihtX3Bp XzIsIHkpKSk7DQorCQlyZXR1cm4gKGNwYWNrKHJlYWxfcGFydF9yZWNpcHJv Y2FsKHgsIHkpLCBjb3B5c2lnbihwaW8yX2hpICsgcGlvMl9sbywgeSkpKTsN CiANCi0JaWYgKGF4IDwgU1FSVF9FUFNJTE9OICYmIGF5IDwgU1FSVF9FUFNJ TE9OKQ0KKwlpZiAoYXggPCBTUVJUXzNfRVBTSUxPTi8yICYmIGF5IDwgU1FS VF8zX0VQU0lMT04vMikgew0KKwkJLyoNCisJCSAqIHogPSAwIHdhcyBmaWx0 ZXJlZCBvdXQgYWJvdmUuICBBbGwgb3RoZXIgY2FzZXMgbXVzdCByYWlzZQ0K KwkJICogaW5leGFjdCwgYnV0IHRoaXMgaXMgdGhlIG9ubHkgb25seSB0aGF0 IG5lZWRzIHRvIGRvIGl0DQorCQkgKiBleHBsaWNpdGx5Lg0KKwkJICovDQor CQlyYWlzZV9pbmV4YWN0KCk7DQogCQlyZXR1cm4gKHopOw0KKwl9DQogDQog CWlmIChheCA9PSAxICYmIGF5IDwgREJMX0VQU0lMT04pIHsNCisjaWYgMCAv KiB0aGlzIG9ubHkgaW1wcm92ZXMgYWNjdXJhY3kgaW4gYW4gYWxyZWFkeSBy ZWxhdGl2ZSBhY2N1cmF0ZSBjYXNlICovDQogCQlpZiAoYXkgPiAyKkRCTF9N SU4pDQogCQkJcnggPSAtIGxvZyhheS8yKSAvIDI7DQogCQllbHNlDQorI2Vu ZGlmDQogCQkJcnggPSAtIChsb2coYXkpIC0gbV9sbjIpIC8gMjsNCiAJfSBl bHNlDQpAQCAtNTkyLDUgKzYzMCw1IEBADQogCWlmIChheCA9PSAxKQ0KIAkJ cnkgPSBhdGFuMigyLCAtYXkpIC8gMjsNCi0JZWxzZSBpZiAoYXkgPCBGT1VS X1NRUlRfTUlOKQ0KKwllbHNlIGlmIChheSA8IERCTF9FUFNJTE9OKQ0KIAkJ cnkgPSBhdGFuMigyKmF5LCAoMS1heCkqKDErYXgpKSAvIDI7DQogCWVsc2UN CmRpZmYgLXUyIGNhdHJpZ2YuY34gY2F0cmlnZi5jDQotLS0gY2F0cmlnZi5j fgkyMDEyLTA5LTIxIDE1OjUxOjE2LjAwMDAwMDAwMCArMDAwMA0KKysrIGNh dHJpZ2YuYwkyMDEyLTA5LTIxIDIxOjM0OjQxLjE0MDIzMTAwMCArMDAwMA0K QEAgLTQ1LDQgKzQ1LDUgQEANCiAjdW5kZWYgaXNuYW4NCiAjZGVmaW5lIGlz bmFuKHgpCSgoeCkgIT0gKHgpKQ0KKyNkZWZpbmUJcmFpc2VfaW5leGFjdCgp CWRvIHsgdm9sYXRpbGUgaW50IGp1bmsgPSAxICsgdGlueTsgfSB3aGlsZSgw KQ0KICN1bmRlZiBzaWduYml0DQogI2RlZmluZSBzaWduYml0KHgpCShfX2J1 aWx0aW5fc2lnbmJpdGYoeCkpDQpAQCAtNTUsMTIgKzU2LDEyIEBADQogbV9l ID0JCQkyLjcxODI4MTgyODVlMCwJCS8qICAweGFkZjg1NC4wcC0yMiAqLw0K IG1fbG4yID0JCQk2LjkzMTQ3MTgwNTZlLTEsCS8qICAweGIxNzIxOC4wcC0y NCAqLw0KLW1fcGlfMiA9CQkxLjU3MDc5NjMyNjhlMCwJCS8qICAweGM5MGZk Yi4wcC0yMyAqLw0KLXBpbzJfaGkgPQkJMS41NzA3OTYyNTEzZSswMCwJLyog MHgzZmM5MGZkYSAqLw0KLXBpbzJfbG8gPQkJNy41NDk3ODk0MTU5ZS0wOCwJ LyogMHgzM2EyMjE2OCAqLw0KK3BpbzJfaGkgPQkJMS41NzA3OTYyNTEzZTAs CQkvKiAgMHhjOTBmZGEuMHAtMjMgKi8NCiBSRUNJUF9FUFNJTE9OID0JCTEv RkxUX0VQU0lMT04sDQotU1FSVF9FUFNJTE9OID0JCTIwNDggKiBGTFRfRVBT SUxPTiwNCitTUVJUXzNfRVBTSUxPTiA9CTUuOTgwMTk5NTY3M2UtNCwJLyog IDB4OWNjNDcxLjBwLTM0ICovDQorU1FSVF82X0VQU0lMT04gPQk4LjQ1NzI3 OTMzMzhlLTQsCS8qICAweGRkYjNkNy4wcC0zNCAqLw0KIFNRUlRfTUlOID0J CTB4MXAtNjM7DQogDQogc3RhdGljIGNvbnN0IHZvbGF0aWxlIGZsb2F0DQor cGlvMl9sbyA9CQk3LjU0OTc4OTk1NDllLTgsCS8qICAweGEyMjE2OS4wcC00 NyAqLw0KIHRpbnkgPQkJCTB4MXAtMTAwOw0KIA0KQEAgLTEwOCw2ICsxMDks NiBAQA0KIAlpZiAoeSA8IEZPVVJfU1FSVF9NSU4pIHsNCiAJCSpCX2lzX3Vz YWJsZSA9IDA7DQotCQkqc3FydF9BMm15MiA9IHNjYWxibmYoQSwgRkxUX01B TlRfRElHKTsNCi0JCSpuZXdfeSA9IHNjYWxibmYoeSwgRkxUX01BTlRfRElH KTsNCisJCSpzcXJ0X0EybXkyID0gQSAqICgyIC8gRkxUX0VQU0lMT04pOw0K KwkJKm5ld195PSB5ICogKDIgLyBGTFRfRVBTSUxPTik7DQogCQlyZXR1cm47 DQogCX0NCkBAIC0xMjQsNiArMTI1LDcgQEANCiAJCQkqc3FydF9BMm15MiA9 IHNxcnRmKEFteSooQSt5KSk7DQogCQl9IGVsc2UgaWYgKHkgPiAxKSB7DQot CQkJKnNxcnRfQTJteTIgPSBzY2FsYm5mKHgsIDIqRkxUX01BTlRfRElHKSAq IHkgLyBzcXJ0ZigoeSsxKSooeS0xKSk7DQotCQkJKm5ld195ID0gc2NhbGJu Zih5LCAyKkZMVF9NQU5UX0RJRyk7DQorCQkJKnNxcnRfQTJteTIgPSB4ICog KDQvRkxUX0VQU0lMT04vRkxUX0VQU0lMT04pICogeSAvDQorCQkJICAgIHNx cnRmKCh5KzEpKih5LTEpKTsNCisJCQkqbmV3X3kgPSB5ICogKDQvRkxUX0VQ U0lMT04vRkxUX0VQU0lMT04pOw0KIAkJfSBlbHNlIHsNCiAJCQkqc3FydF9B Mm15MiA9IHNxcnRmKCgxLXkpKigxK3kpKTsNCkBAIC0xNjEsOCArMTYzLDEw IEBADQogCX0NCiANCi0JaWYgKCh4ID09IDAgJiYgeSA9PSAwKSB8fCAoaW50 KSgxICsgdGlueSkgIT0gMSkNCisJaWYgKHggPT0gMCAmJiB5ID09IDApDQog CQlyZXR1cm4gKHopOw0KIA0KLQlpZiAoYXggPCBTUVJUX0VQU0lMT04gJiYg YXkgPCBTUVJUX0VQU0lMT04pDQorCXJhaXNlX2luZXhhY3QoKTsNCisNCisJ aWYgKGF4IDwgU1FSVF82X0VQU0lMT04vNCAmJiBheSA8IFNRUlRfNl9FUFNJ TE9OLzQpDQogCQlyZXR1cm4gKHopOw0KIA0KQEAgLTIwMiw1ICsyMDYsNSBA QA0KIAkJaWYgKGlzaW5mKHkpKQ0KIAkJCXJldHVybiAoY3BhY2tmKHgreCwg LXkpKTsNCi0JCWlmICh4ID09IDApIHJldHVybiAoY3BhY2tmKG1fcGlfMiAr IHRpbnksIHkreSkpOw0KKwkJaWYgKHggPT0gMCkgcmV0dXJuIChjcGFja2Yo cGlvMl9oaSArIHBpbzJfbG8sIHkreSkpOw0KIAkJcmV0dXJuIChjcGFja2Yo eCswLjBMKyh5KzApLCB4KzAuMEwrKHkrMCkpKTsNCiAJfQ0KQEAgLTIxNSw4 ICsyMTksMTAgQEANCiAJfQ0KIA0KLQlpZiAoKHggPT0gMSAmJiB5ID09IDAp IHx8IChpbnQpKDEgKyB0aW55KSAhPSAxKQ0KKwlpZiAoeCA9PSAxICYmIHkg PT0gMCkNCiAJCXJldHVybiAoY3BhY2tmKDAsIC15KSk7DQogDQotCWlmIChh eCA8IFNRUlRfRVBTSUxPTiAmJiBheSA8IFNRUlRfRVBTSUxPTikNCisJcmFp c2VfaW5leGFjdCgpOw0KKw0KKwlpZiAoYXggPCBTUVJUXzZfRVBTSUxPTi80 ICYmIGF5IDwgU1FSVF82X0VQU0lMT04vNCkNCiAJCXJldHVybiAoY3BhY2tm KHBpbzJfaGkgLSAoeCAtIHBpbzJfbG8pLCAteSkpOw0KIA0KQEAgLTI5Mywx NyArMjk5LDI0IEBADQogcmVhbF9wYXJ0X3JlY2lwcm9jYWwoZmxvYXQgeCwg ZmxvYXQgeSkNCiB7DQotCWludCBleCwgZXk7DQotDQotCWlmIChpc2luZih4 KSB8fCBpc2luZih5KSkNCi0JCXJldHVybiAoMCk7DQotCWlmICh5ID09IDAp IHJldHVybiAoMS94KTsNCi0JaWYgKHggPT0gMCkgcmV0dXJuICh4L3kveSk7 DQotCWV4ID0gaWxvZ2JmKHgpOw0KLQlleSA9IGlsb2diZih5KTsNCi0JaWYg KGV4IC0gZXkgPj0gRkxUX01BTlRfRElHKSByZXR1cm4gKDEveCk7DQotCWlm IChleSAtIGV4ID49IEZMVF9NQU5UX0RJRykgcmV0dXJuICh4L3kveSk7DQot CXggPSBzY2FsYm5mKHgsIC1leCk7DQotCXkgPSBzY2FsYm5mKHksIC1leCk7 DQotCXJldHVybiBzY2FsYm5mKHgvKHgqeCArIHkqeSksIC1leCk7DQorCWZs b2F0IHNjYWxlOw0KKwl1aW50MzJfdCBoeCwgaHk7DQorCWludDMyX3QgaXgs IGl5Ow0KKw0KKwlHRVRfRkxPQVRfV09SRChoeCwgeCk7DQorCWl4ID0gaHgg JiAweDdmODAwMDAwOw0KKwlHRVRfRkxPQVRfV09SRChoeSwgeSk7DQorCWl5 ID0gaHkgJiAweDdmODAwMDAwOw0KKyNkZWZpbmUJQklBUwkoRkxUX01BWF9F WFAgLSAxKQ0KKyNkZWZpbmUJQ1VUT0ZGCShGTFRfTUFOVF9ESUcgLyAyICsg MSkNCisJaWYgKGl4IC0gaXkgPj0gQ1VUT0ZGIDw8IDIzIHx8IGlzaW5mKHgp KQ0KKwkJcmV0dXJuICgxL3gpOw0KKwlpZiAoaXkgLSBpeCA+PSBDVVRPRkYg PDwgMjMpDQorCQlyZXR1cm4gKHgveS95KTsNCisJaWYgKGl4IDw9IChCSUFT ICsgRkxUX01BWF9FWFAgLyAyIC0gQ1VUT0ZGKSA8PCAyMykNCisJCXJldHVy biAoeC8oeCp4ICsgeSp5KSk7DQorCVNFVF9GTE9BVF9XT1JEKHNjYWxlLCAw eDdmODAwMDAwIC0gaXgpOw0KKwl4ICo9IHNjYWxlOw0KKwl5ICo9IHNjYWxl Ow0KKwlyZXR1cm4gKHgvKHgqeCArIHkqeSkgKiBzY2FsZSk7DQogfQ0KIA0K QEAgLTMyMSw2ICszMzQsNiBAQA0KIAkJcmV0dXJuIChjcGFja2YoYXRhbmhm KHgpLCB5KSk7IA0KIA0KLQlpZiAoKHggPT0gMCAmJiB5ID09IDApIHx8IChp bnQpKDEgKyB0aW55KSAhPSAxKQ0KLQkJcmV0dXJuICh6KTsNCisJaWYgKHgg PT0gMCkNCisJCXJldHVybiAoY3BhY2tmKHgsIGF0YW5mKHkpKSk7DQogDQog CWlmIChpc25hbih4KSB8fCBpc25hbih5KSkgew0KQEAgLTMyOCw1ICszNDEs NSBAQA0KIAkJCXJldHVybiAoY3BhY2tmKGNvcHlzaWduZigwLCB4KSwgeSt5 KSk7DQogCQlpZiAoaXNpbmYoeSkpDQotCQkJcmV0dXJuIChjcGFja2YoY29w eXNpZ25mKDAsIHgpLCBjb3B5c2lnbmYobV9waV8yLCB5KSkpOw0KKwkJCXJl dHVybiAoY3BhY2tmKGNvcHlzaWduZigwLCB4KSwgY29weXNpZ25mKHBpbzJf aGkgKyBwaW8yX2xvLCB5KSkpOw0KIAkJaWYgKHggPT0gMCkNCiAJCQlyZXR1 cm4gKGNwYWNrZih4LCB5K3kpKTsNCkBAIC0zMzUsMTMgKzM0OCwxNyBAQA0K IA0KIAlpZiAoYXggPiBSRUNJUF9FUFNJTE9OIHx8IGF5ID4gUkVDSVBfRVBT SUxPTikNCi0JCXJldHVybiAoY3BhY2tmKGNvcHlzaWduZihyZWFsX3BhcnRf cmVjaXByb2NhbChheCwgYXkpLCB4KSwgY29weXNpZ25mKG1fcGlfMiwgeSkp KTsNCisJCXJldHVybiAoY3BhY2tmKHJlYWxfcGFydF9yZWNpcHJvY2FsKHgs IHkpLCBjb3B5c2lnbmYocGlvMl9oaSArIHBpbzJfbG8sIHkpKSk7DQogDQot CWlmIChheCA8IFNRUlRfRVBTSUxPTiAmJiBheSA8IFNRUlRfRVBTSUxPTikN CisJaWYgKGF4IDwgU1FSVF8zX0VQU0lMT04vMiAmJiBheSA8IFNRUlRfM19F UFNJTE9OLzIpIHsNCisJCXJhaXNlX2luZXhhY3QoKTsNCiAJCXJldHVybiAo eik7DQorCX0NCiANCiAJaWYgKGF4ID09IDEgJiYgYXkgPCBGTFRfRVBTSUxP Tikgew0KKyNpZiAwDQogCQlpZiAoYXkgPiAyKkZMVF9NSU4pDQogCQkJcngg PSAtIGxvZ2YoYXkvMikgLyAyOw0KIAkJZWxzZQ0KKyNlbmRpZg0KIAkJCXJ4 ID0gLSAobG9nZihheSkgLSBtX2xuMikgLyAyOw0KIAl9IGVsc2UNCkBAIC0z NTAsNSArMzY3LDUgQEANCiAJaWYgKGF4ID09IDEpDQogCQlyeSA9IGF0YW4y ZigyLCAtYXkpIC8gMjsNCi0JZWxzZSBpZiAoYXkgPCBGT1VSX1NRUlRfTUlO KQ0KKwllbHNlIGlmIChheSA8IEZMVF9FUFNJTE9OKQ0KIAkJcnkgPSBhdGFu MmYoMipheSwgKDEtYXgpKigxK2F4KSkgLyAyOw0KIAllbHNlDQpkaWZmIC11 MiBjYXRyaWdsLmN+IGNhdHJpZ2wuYw0KLS0tIGNhdHJpZ2wuY34JMjAxMi0w OS0yMSAxNjoyMjo0MC4wMDAwMDAwMDAgKzAwMDANCisrKyBjYXRyaWdsLmMJ MjAxMi0wOS0yMSAyMToxNzo0Ni45NjI2OTgwMDAgKzAwMDANCkBAIC0zOCw1 ICszOCw0IEBADQogI2luY2x1ZGUgPGZsb2F0Lmg+DQogDQotI2luY2x1ZGUg ImZwbWF0aC5oIg0KICNpbmNsdWRlICJpbnZ0cmlnLmgiDQogI2luY2x1ZGUg Im1hdGguaCINCkBAIC00Nyw0ICs0Niw1IEBADQogI3VuZGVmIGlzbmFuDQog I2RlZmluZSBpc25hbih4KQkoKHgpICE9ICh4KSkNCisjZGVmaW5lCXJhaXNl X2luZXhhY3QoKQlkbyB7IHZvbGF0aWxlIGludCBqdW5rID0gMSArIHRpbnk7 IH0gd2hpbGUoMCkNCiAjdW5kZWYgc2lnbmJpdA0KICNkZWZpbmUgc2lnbmJp dCh4KQkoX19idWlsdGluX3NpZ25iaXRsKHgpKSANCkBAIC01Niw1ICs1Niw0 IEBADQogUVVBUlRFUl9TUVJUX01BWCA9CTB4MXA4MTg5TCwNCiBSRUNJUF9F UFNJTE9OID0JCTEvTERCTF9FUFNJTE9OLA0KLVNRUlRfRVBTSUxPTiA9CQkx RS0xMEwsDQogU1FSVF9NSU4gPQkJMHgxcC04MTkxTDsNCiANCkBAIC02Miwx NCArNjEsMTcgQEANCiBzdGF0aWMgY29uc3QgdW5pb24gSUVFRWwyYml0cw0K IHVtX2UgPQkJTEQ4MEMoMHhhZGY4NTQ1OGEyYmI0YTliLCAgMSwgMCwgMi43 MTgyODE4Mjg0NTkwNDUyMzUzNmUwTCksDQotdW1fbG4yID0JTEQ4MEMoMHhi MTcyMTdmN2QxY2Y3OWFjLCAtMSwgMCwgNi45MzE0NzE4MDU1OTk0NTMwOTQx N2UtMUwpLA0KLXVtX3BpXzIgPQlMRDgwQygweGM5MGZkYWEyMjE2OGMyMzUs ICAwLCAwLCAxLjU3MDc5NjMyNjc5NDg5NjYxOTIzZTBMKTsNCit1bV9sbjIg PQlMRDgwQygweGIxNzIxN2Y3ZDFjZjc5YWMsIC0xLCAwLCA2LjkzMTQ3MTgw NTU5OTQ1MzA5NDE3ZS0xTCk7DQogI2RlZmluZQkJbV9lCXVtX2UuZQ0KICNk ZWZpbmUJCW1fbG4yCXVtX2xuMi5lDQotI2RlZmluZQkJbV9waV8yCXVtX3Bp XzIuZQ0KK3N0YXRpYyBjb25zdCBsb25nIGRvdWJsZQ0KKy8qIFRoZSBuZXh0 IDIgbGl0ZXJhbHMgZm9yIG5vbi1pMzg2LiAgTWlzcm91bmRpbmcgdGhlbSBv biBpMzg2IGlzIGhhcm1sZXNzLiAqLw0KK1NRUlRfM19FUFNJTE9OID0gNS43 MDMxNjI3MzQzNTc1ODkxNTMxMGUtMTAsCS8qICAweDljYzQ3MGEwNDkwOTcz ZTguMHAtOTQgKi8NCitTUVJUXzZfRVBTSUxPTiA9IDguMDY1NDkwMDg3MzQ5 MzI3NzE2NjRlLTEwOwkvKiAgMHhkZGIzZDc0MmMyNjU1MzllLjBwLTk0ICov DQogI2VsaWYgTERCTF9NQU5UX0RJRyA9PSAxMTMNCiBzdGF0aWMgY29uc3Qg bG9uZyBkb3VibGUNCiBtX2UgPQkJMi43MTgyODE4Mjg0NTkwNDUyMzUzNjAy ODc0NzEzNTI2NjI1MGUwTCwJLyogMHgxNWJmMGE4YjE0NTc2OTUzNTVmYjhh YzQwNGU3YS4wcC0xMTEgKi8NCiBtX2xuMiA9CQk2LjkzMTQ3MTgwNTU5OTQ1 MzA5NDE3MjMyMTIxNDU4MTc2NTY4ZS0xTCwJLyogMHgxNjJlNDJmZWZhMzll ZjM1NzkzYzc2NzMwMDdlNi4wcC0xMTMgKi8NCi1tX3BpXzIgPQkxLjU3MDc5 NjMyNjc5NDg5NjYxOTIzMTMyMTY5MTYzOTc1MTQ0ZTBMOwkvKiAweDE5MjFm YjU0NDQyZDE4NDY5ODk4Y2M1MTcwMWI4LjBwLTExMiAqLw0KK1NRUlRfM19F UFNJTE9OID0gMi40MDM3MDMzNTc5Nzk0NTQ5MDk3NTMzNjcyNzE5OTg3ODEy NGUtMTcsCS8qICAweDFiYjY3YWU4NTg0Y2FhNzNiMjU3NDJkNzA3OGI4LjBw LTE2OCAqLw0KK1NRUlRfNl9FUFNJTE9OID0gMy4zOTkzNDk4ODg3NzYyOTU4 NzIzOTA4MjU4NjIyMzMwMDM5MWUtMTc7CS8qICAweDEzOTg4ZTE0MDkyMTJl N2QwMzIxOTE0MzIxYTU1LjBwLTE2NyAqLw0KICNlbHNlDQogI2Vycm9yICJV bnN1cHBvcnRlZCBsb25nIGRvdWJsZSBmb3JtYXQiDQpAQCAtMTIyLDYgKzEy NCw2IEBADQogCWlmICh5IDwgRk9VUl9TUVJUX01JTikgew0KIAkJKkJfaXNf dXNhYmxlID0gMDsNCi0JCSpzcXJ0X0EybXkyID0gc2NhbGJubChBLCBMREJM X01BTlRfRElHKTsNCi0JCSpuZXdfeSA9IHNjYWxibmwoeSwgTERCTF9NQU5U X0RJRyk7DQorCQkqc3FydF9BMm15MiA9IEEgKiAoMiAvIExEQkxfRVBTSUxP Tik7DQorCQkqbmV3X3k9IHkgKiAoMiAvIExEQkxfRVBTSUxPTik7DQogCQly ZXR1cm47DQogCX0NCkBAIC0xMzgsNiArMTQwLDcgQEANCiAJCQkqc3FydF9B Mm15MiA9IHNxcnRsKEFteSooQSt5KSk7DQogCQl9IGVsc2UgaWYgKHkgPiAx KSB7DQotCQkJKnNxcnRfQTJteTIgPSBzY2FsYm5sKHgsIDIqTERCTF9NQU5U X0RJRykgKiB5IC8gc3FydGwoKHkrMSkqKHktMSkpOw0KLQkJCSpuZXdfeSA9 IHNjYWxibmwoeSwgMipMREJMX01BTlRfRElHKTsNCisJCQkqc3FydF9BMm15 MiA9IHggKiAoNC9MREJMX0VQU0lMT04vTERCTF9FUFNJTE9OKSAqIHkgLw0K KwkJCSAgICBzcXJ0bCgoeSsxKSooeS0xKSk7DQorCQkJKm5ld195ID0geSAq ICg0L0xEQkxfRVBTSUxPTi9MREJMX0VQU0lMT04pOw0KIAkJfSBlbHNlIHsN CiAJCQkqc3FydF9BMm15MiA9IHNxcnRsKCgxLXkpKigxK3kpKTsNCkBAIC0x NzUsOCArMTc4LDEwIEBADQogCX0NCiANCi0JaWYgKCh4ID09IDAgJiYgeSA9 PSAwKSB8fCAoaW50KSgxICsgdGlueSkgIT0gMSkNCisJaWYgKHggPT0gMCAm JiB5ID09IDApDQogCQlyZXR1cm4gKHopOw0KIA0KLQlpZiAoYXggPCBTUVJU X0VQU0lMT04gJiYgYXkgPCBTUVJUX0VQU0lMT04pDQorCXJhaXNlX2luZXhh Y3QoKTsNCisNCisJaWYgKGF4IDwgU1FSVF82X0VQU0lMT04vNCAmJiBheSA8 IFNRUlRfNl9FUFNJTE9OLzQpDQogCQlyZXR1cm4gKHopOw0KIA0KQEAgLTIx Niw1ICsyMjEsNSBAQA0KIAkJaWYgKGlzaW5mKHkpKQ0KIAkJCXJldHVybiAo Y3BhY2tsKHgreCwgLXkpKTsNCi0JCWlmICh4ID09IDApIHJldHVybiAoY3Bh Y2tsKG1fcGlfMiArIHRpbnksIHkreSkpOw0KKwkJaWYgKHggPT0gMCkgcmV0 dXJuIChjcGFja2wocGlvMl9oaSArIHBpbzJfbG8sIHkreSkpOw0KIAkJcmV0 dXJuIChjcGFja2woeCswLjBMKyh5KzApLCB4KzAuMEwrKHkrMCkpKTsNCiAJ fQ0KQEAgLTIyOSw4ICsyMzQsMTAgQEANCiAJfQ0KIA0KLQlpZiAoKHggPT0g MSAmJiB5ID09IDApIHx8IChpbnQpKDEgKyB0aW55KSAhPSAxKQ0KKwlpZiAo eCA9PSAxICYmIHkgPT0gMCkNCiAJCXJldHVybiAoY3BhY2tsKDAsIC15KSk7 DQogDQotCWlmIChheCA8IFNRUlRfRVBTSUxPTiAmJiBheSA8IFNRUlRfRVBT SUxPTikNCisJcmFpc2VfaW5leGFjdCgpOw0KKw0KKwlpZiAoYXggPCBTUVJU XzZfRVBTSUxPTi80ICYmIGF5IDwgU1FSVF82X0VQU0lMT04vNCkNCiAJCXJl dHVybiAoY3BhY2tsKHBpbzJfaGkgLSAoeCAtIHBpbzJfbG8pLCAteSkpOw0K IA0KQEAgLTMwNywxNyArMzE0LDI0IEBADQogcmVhbF9wYXJ0X3JlY2lwcm9j YWwobG9uZyBkb3VibGUgeCwgbG9uZyBkb3VibGUgeSkNCiB7DQotCWludCBl eCwgZXk7DQotDQotCWlmIChpc2luZih4KSB8fCBpc2luZih5KSkNCi0JCXJl dHVybiAoMCk7DQotCWlmICh5ID09IDApIHJldHVybiAoMS94KTsNCi0JaWYg KHggPT0gMCkgcmV0dXJuICh4L3kveSk7DQotCWV4ID0gaWxvZ2JsKHgpOw0K LQlleSA9IGlsb2dibCh5KTsNCi0JaWYgKGV4IC0gZXkgPj0gTERCTF9NQU5U X0RJRykgcmV0dXJuICgxL3gpOw0KLQlpZiAoZXkgLSBleCA+PSBMREJMX01B TlRfRElHKSByZXR1cm4gKHgveS95KTsNCi0JeCA9IHNjYWxibmwoeCwgLWV4 KTsNCi0JeSA9IHNjYWxibmwoeSwgLWV4KTsNCi0JcmV0dXJuIHNjYWxibmwo eC8oeCp4ICsgeSp5KSwgLWV4KTsNCisJbG9uZyBkb3VibGUgc2NhbGU7DQor CXVpbnQxNl90IGh4LCBoeTsNCisJaW50MTZfdCBpeCwgaXk7DQorDQorCUdF VF9MREJMX0VYUFNJR04oaHgsIHgpOw0KKwlpeCA9IGh4ICYgMHg3ZmZmOw0K KwlHRVRfTERCTF9FWFBTSUdOKGh5LCB5KTsNCisJaXkgPSBoeSAmIDB4N2Zm ZjsNCisjZGVmaW5lCUJJQVMJKExEQkxfTUFYX0VYUCAtIDEpDQorI2RlZmlu ZQlDVVRPRkYJKExEQkxfTUFOVF9ESUcgLyAyICsgMSkNCisJaWYgKGl4IC0g aXkgPj0gQ1VUT0ZGIHx8IGlzaW5mKHgpKQ0KKwkJcmV0dXJuICgxL3gpOw0K KwlpZiAoaXkgLSBpeCA+PSBDVVRPRkYpDQorCQlyZXR1cm4gKHgveS95KTsN CisJaWYgKGl4IDw9IEJJQVMgKyBMREJMX01BWF9FWFAgLyAyIC0gQ1VUT0ZG KQ0KKwkJcmV0dXJuICh4Lyh4KnggKyB5KnkpKTsNCisJU0VUX0xEQkxfRVhQ U0lHTihzY2FsZSwgMHg3ZmZmIC0gaXgpOw0KKwl4ICo9IHNjYWxlOw0KKwl5 ICo9IHNjYWxlOw0KKwlyZXR1cm4gKHgvKHgqeCArIHkqeSkgKiBzY2FsZSk7 DQogfQ0KIA0KQEAgLTMzMyw4ICszNDcsOCBAQA0KIA0KIAlpZiAoeSA9PSAw ICYmIGF4IDw9IDEpDQotCQlyZXR1cm4gKGNwYWNrbChhdGFuaGwoeCksIHkp KTsgDQorCQlyZXR1cm4gKGNwYWNrbChhdGFuaCh4KSwgeSkpOyAJLyogWFhY IG5lZWQgYXRhbmhsKCkgKi8NCiANCi0JaWYgKCh4ID09IDAgJiYgeSA9PSAw KSB8fCAoaW50KSgxICsgdGlueSkgIT0gMSkNCi0JCXJldHVybiAoeik7DQor CWlmICh4ID09IDApDQorCQlyZXR1cm4gKGNwYWNrbCh4LCBhdGFubCh5KSkp Ow0KIA0KIAlpZiAoaXNuYW4oeCkgfHwgaXNuYW4oeSkpIHsNCkBAIC0zNDIs NSArMzU2LDUgQEANCiAJCQlyZXR1cm4gKGNwYWNrbChjb3B5c2lnbmwoMCwg eCksIHkreSkpOw0KIAkJaWYgKGlzaW5mKHkpKQ0KLQkJCXJldHVybiAoY3Bh Y2tsKGNvcHlzaWdubCgwLCB4KSwgY29weXNpZ25sKG1fcGlfMiwgeSkpKTsN CisJCQlyZXR1cm4gKGNwYWNrbChjb3B5c2lnbmwoMCwgeCksIGNvcHlzaWdu bChwaW8yX2hpICsgcGlvMl9sbywgeSkpKTsNCiAJCWlmICh4ID09IDApDQog CQkJcmV0dXJuIChjcGFja2woeCwgeSt5KSk7DQpAQCAtMzQ5LDEzICszNjMs MTcgQEANCiANCiAJaWYgKGF4ID4gUkVDSVBfRVBTSUxPTiB8fCBheSA+IFJF Q0lQX0VQU0lMT04pDQotCQlyZXR1cm4gKGNwYWNrbChjb3B5c2lnbmwocmVh bF9wYXJ0X3JlY2lwcm9jYWwoYXgsIGF5KSwgeCksIGNvcHlzaWdubChtX3Bp XzIsIHkpKSk7DQorCQlyZXR1cm4gKGNwYWNrbChyZWFsX3BhcnRfcmVjaXBy b2NhbCh4LCB5KSwgY29weXNpZ25sKHBpbzJfaGkgKyBwaW8yX2xvLCB5KSkp Ow0KIA0KLQlpZiAoYXggPCBTUVJUX0VQU0lMT04gJiYgYXkgPCBTUVJUX0VQ U0lMT04pDQorCWlmIChheCA8IFNRUlRfM19FUFNJTE9OLzIgJiYgYXkgPCBT UVJUXzNfRVBTSUxPTi8yKSB7DQorCQlyYWlzZV9pbmV4YWN0KCk7DQogCQly ZXR1cm4gKHopOw0KKwl9DQogDQogCWlmIChheCA9PSAxICYmIGF5IDwgTERC TF9FUFNJTE9OKSB7DQorI2lmIDANCiAJCWlmIChheSA+IDIqTERCTF9NSU4p DQogCQkJcnggPSAtIGxvZ2woYXkvMikgLyAyOw0KIAkJZWxzZQ0KKyNlbmRp Zg0KIAkJCXJ4ID0gLSAobG9nbChheSkgLSBtX2xuMikgLyAyOw0KIAl9IGVs c2UNCkBAIC0zNjQsNSArMzgyLDUgQEANCiAJaWYgKGF4ID09IDEpDQogCQly eSA9IGF0YW4ybCgyLCAtYXkpIC8gMjsNCi0JZWxzZSBpZiAoYXkgPCBGT1VS X1NRUlRfTUlOKQ0KKwllbHNlIGlmIChheSA8IExEQkxfRVBTSUxPTikNCiAJ CXJ5ID0gYXRhbjJsKDIqYXksICgxLWF4KSooMStheCkpIC8gMjsNCiAJZWxz ZQ0K --0-46617504-1348269236=:3613--