Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Sep 2012 09:13:56 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Stephen Montgomery-Smith <stephen@missouri.edu>
Cc:        freebsd-numerics@FreeBSD.org
Subject:   Re: Complex arg-trig functions
Message-ID:  <20120922081607.F3613@besplex.bde.org>
In-Reply-To: <505CC11A.5030502@missouri.edu>
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>

next in thread | previous in thread | raw e-mail | index | archive | help
  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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120922081607.F3613>