From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by sourceware.org (Postfix) with ESMTPS id 65EE13858C5F for ; Thu, 2 Feb 2023 14:52:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 65EE13858C5F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-wm1-x336.google.com with SMTP id k8-20020a05600c1c8800b003dc57ea0dfeso3933118wms.0 for ; Thu, 02 Feb 2023 06:52:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=lEWXpJP3wg5hABM3wl9hpH1ElRFAgKpjqmy7WAjrE4U=; b=Sdc8TEVd3F5AW+8QRHeiQPmPe+X5hjmmXc88GWGktB/DNuC3tn0ZonYZ18U6imSJin 2+UwhxLIwOAPph/sslJOHKFx72Xnwems192YTZABJGmRf9tbD1ixDDWE5FLVwEwSYGPQ YPC/pBVp0lSrgUr1kTf0LcWQsvRPzHl+Wmya2DGu3/82GiHZy3Hm90omXndJdPH4fj8t Z0ceCLEyEcoEy6AQbMojcwyDHFkJGmkXCBtl8iIiS0lV3YQRY3NBh/CSxJR4ri4xP+Zl wVFcqfn3eHe4SjVaU4L40TNzEGe7pPFRMyfzNWeMw+DedNFRME7ncDRsQrg6Di0GQgIA zYTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=lEWXpJP3wg5hABM3wl9hpH1ElRFAgKpjqmy7WAjrE4U=; b=aCDkCGlDnQrfHlBXHTwI2OddD8zJo4DyMO29mhgwQ05Io0/noMpTPZoNo5bOWPKOrg 7C9RrHRGirUlEjaI3WRau+Z8kEj/Ok8ut7JUuWcSY5siSZpNzRWY/y0orKTa94dQ6+rR KlqyxTE+sMV9awVo0ZSjk2A89Gclpqu0Ihj44DhjjQPIV3DWj2s3PEms55wI/R4eK/Wp DUP8T/0Q9eTkebbzUV6TeANocerDHvdsCqYKy6bNlzaaYqTvxyOk+Ho9mhum0WBihfdu EL+NLF3mHsxmDOqlgjDMB4ZKF/5d4oF4CK2kdd+HYIL9dN+PjO0Gc4yG6NwPRIyo292g DesA== X-Gm-Message-State: AO0yUKUToSd0lXqB3jqpLFwj+YIJpgVv2cAID0B3xDXt9OcQqqgKM/Y2 ZgsNYhywTSY1vzQmlon7kVZCvdKmm8L/l8jD/qx5Gw== X-Google-Smtp-Source: AK7set+7wS5mcZbu2+26cQ7Knvxg+Pbr8+bb7NPmJr503k7tvJU44LaoPIQ/udINv07NnuQBCm5NPxg6Oh0WkdXM8SI= X-Received: by 2002:a05:600c:3d99:b0:3dc:5ba0:5b74 with SMTP id bi25-20020a05600c3d9900b003dc5ba05b74mr232559wmb.36.1675349534721; Thu, 02 Feb 2023 06:52:14 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Prathamesh Kulkarni Date: Thu, 2 Feb 2023 20:21:37 +0530 Message-ID: Subject: Re: [aarch64] Use dup and zip1 for interleaving elements in initializing vector To: Prathamesh Kulkarni , gcc Patches , richard.sandiford@arm.com Content-Type: multipart/mixed; boundary="000000000000e60dd705f3b8b584" X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SCC_5_SHORT_WORD_LINES,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --000000000000e60dd705f3b8b584 Content-Type: text/plain; charset="UTF-8" On Wed, 1 Feb 2023 at 21:56, Richard Sandiford wrote: > > Prathamesh Kulkarni writes: > > On Thu, 12 Jan 2023 at 21:21, Richard Sandiford > > wrote: > >> > >> Prathamesh Kulkarni writes: > >> > On Tue, 6 Dec 2022 at 07:01, Prathamesh Kulkarni > >> > wrote: > >> >> > >> >> On Mon, 5 Dec 2022 at 16:50, Richard Sandiford > >> >> wrote: > >> >> > > >> >> > Richard Sandiford via Gcc-patches writes: > >> >> > > Prathamesh Kulkarni writes: > >> >> > >> Hi, > >> >> > >> For the following test-case: > >> >> > >> > >> >> > >> int16x8_t foo(int16_t x, int16_t y) > >> >> > >> { > >> >> > >> return (int16x8_t) { x, y, x, y, x, y, x, y }; > >> >> > >> } > >> >> > >> > >> >> > >> Code gen at -O3: > >> >> > >> foo: > >> >> > >> dup v0.8h, w0 > >> >> > >> ins v0.h[1], w1 > >> >> > >> ins v0.h[3], w1 > >> >> > >> ins v0.h[5], w1 > >> >> > >> ins v0.h[7], w1 > >> >> > >> ret > >> >> > >> > >> >> > >> For 16 elements, it results in 8 ins instructions which might not be > >> >> > >> optimal perhaps. > >> >> > >> I guess, the above code-gen would be equivalent to the following ? > >> >> > >> dup v0.8h, w0 > >> >> > >> dup v1.8h, w1 > >> >> > >> zip1 v0.8h, v0.8h, v1.8h > >> >> > >> > >> >> > >> I have attached patch to do the same, if number of elements >= 8, > >> >> > >> which should be possibly better compared to current code-gen ? > >> >> > >> Patch passes bootstrap+test on aarch64-linux-gnu. > >> >> > >> Does the patch look OK ? > >> >> > >> > >> >> > >> Thanks, > >> >> > >> Prathamesh > >> >> > >> > >> >> > >> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > >> >> > >> index c91df6f5006..e5dea70e363 100644 > >> >> > >> --- a/gcc/config/aarch64/aarch64.cc > >> >> > >> +++ b/gcc/config/aarch64/aarch64.cc > >> >> > >> @@ -22028,6 +22028,39 @@ aarch64_expand_vector_init (rtx target, rtx vals) > >> >> > >> return; > >> >> > >> } > >> >> > >> > >> >> > >> + /* Check for interleaving case. > >> >> > >> + For eg if initializer is (int16x8_t) {x, y, x, y, x, y, x, y}. > >> >> > >> + Generate following code: > >> >> > >> + dup v0.h, x > >> >> > >> + dup v1.h, y > >> >> > >> + zip1 v0.h, v0.h, v1.h > >> >> > >> + for "large enough" initializer. */ > >> >> > >> + > >> >> > >> + if (n_elts >= 8) > >> >> > >> + { > >> >> > >> + int i; > >> >> > >> + for (i = 2; i < n_elts; i++) > >> >> > >> + if (!rtx_equal_p (XVECEXP (vals, 0, i), XVECEXP (vals, 0, i % 2))) > >> >> > >> + break; > >> >> > >> + > >> >> > >> + if (i == n_elts) > >> >> > >> + { > >> >> > >> + machine_mode mode = GET_MODE (target); > >> >> > >> + rtx dest[2]; > >> >> > >> + > >> >> > >> + for (int i = 0; i < 2; i++) > >> >> > >> + { > >> >> > >> + rtx x = copy_to_mode_reg (GET_MODE_INNER (mode), XVECEXP (vals, 0, i)); > >> >> > > > >> >> > > Formatting nit: long line. > >> >> > > > >> >> > >> + dest[i] = gen_reg_rtx (mode); > >> >> > >> + aarch64_emit_move (dest[i], gen_vec_duplicate (mode, x)); > >> >> > >> + } > >> >> > > > >> >> > > This could probably be written: > >> >> > > > >> >> > > for (int i = 0; i < 2; i++) > >> >> > > { > >> >> > > rtx x = expand_vector_broadcast (mode, XVECEXP (vals, 0, i)); > >> >> > > dest[i] = force_reg (GET_MODE_INNER (mode), x); > >> >> > > >> >> > Oops, I meant "mode" rather than "GET_MODE_INNER (mode)", sorry. > >> >> Thanks, I have pushed the change in > >> >> 769370f3e2e04823c8a621d8ffa756dd83ebf21e after running > >> >> bootstrap+test on aarch64-linux-gnu. > >> > Hi Richard, > >> > I have attached a patch that extends the transform if one half is dup > >> > and other is set of constants. > >> > For eg: > >> > int8x16_t f(int8_t x) > >> > { > >> > return (int8x16_t) { x, 1, x, 2, x, 3, x, 4, x, 5, x, 6, x, 7, x, 8 }; > >> > } > >> > > >> > code-gen trunk: > >> > f: > >> > adrp x1, .LC0 > >> > ldr q0, [x1, #:lo12:.LC0] > >> > ins v0.b[0], w0 > >> > ins v0.b[2], w0 > >> > ins v0.b[4], w0 > >> > ins v0.b[6], w0 > >> > ins v0.b[8], w0 > >> > ins v0.b[10], w0 > >> > ins v0.b[12], w0 > >> > ins v0.b[14], w0 > >> > ret > >> > > >> > code-gen with patch: > >> > f: > >> > dup v0.16b, w0 > >> > adrp x0, .LC0 > >> > ldr q1, [x0, #:lo12:.LC0] > >> > zip1 v0.16b, v0.16b, v1.16b > >> > ret > >> > > >> > Bootstrapped+tested on aarch64-linux-gnu. > >> > Does it look OK ? > >> > >> Looks like a nice improvement. It'll need to wait for GCC 14 now though. > >> > >> However, rather than handle this case specially, I think we should instead > >> take a divide-and-conquer approach: split the initialiser into even and > >> odd elements, find the best way of loading each part, then compare the > >> cost of these sequences + ZIP with the cost of the fallback code (the code > >> later in aarch64_expand_vector_init). > >> > >> For example, doing that would allow: > >> > >> { x, y, 0, y, 0, y, 0, y, 0, y } > >> > >> to be loaded more easily, even though the even elements aren't wholly > >> constant. > > Hi Richard, > > I have attached a prototype patch based on the above approach. > > It subsumes specializing for above {x, y, x, y, x, y, x, y} case by generating > > same sequence, thus I removed that hunk, and improves the following cases: > > > > (a) > > int8x16_t f_s16(int8_t x) > > { > > return (int8x16_t) { x, 1, x, 2, x, 3, x, 4, > > x, 5, x, 6, x, 7, x, 8 }; > > } > > > > code-gen trunk: > > f_s16: > > adrp x1, .LC0 > > ldr q0, [x1, #:lo12:.LC0] > > ins v0.b[0], w0 > > ins v0.b[2], w0 > > ins v0.b[4], w0 > > ins v0.b[6], w0 > > ins v0.b[8], w0 > > ins v0.b[10], w0 > > ins v0.b[12], w0 > > ins v0.b[14], w0 > > ret > > > > code-gen with patch: > > f_s16: > > dup v0.16b, w0 > > adrp x0, .LC0 > > ldr q1, [x0, #:lo12:.LC0] > > zip1 v0.16b, v0.16b, v1.16b > > ret > > > > (b) > > int8x16_t f_s16(int8_t x, int8_t y) > > { > > return (int8x16_t) { x, y, 1, y, 2, y, 3, y, > > 4, y, 5, y, 6, y, 7, y }; > > } > > > > code-gen trunk: > > f_s16: > > adrp x2, .LC0 > > ldr q0, [x2, #:lo12:.LC0] > > ins v0.b[0], w0 > > ins v0.b[1], w1 > > ins v0.b[3], w1 > > ins v0.b[5], w1 > > ins v0.b[7], w1 > > ins v0.b[9], w1 > > ins v0.b[11], w1 > > ins v0.b[13], w1 > > ins v0.b[15], w1 > > ret > > > > code-gen patch: > > f_s16: > > adrp x2, .LC0 > > dup v1.16b, w1 > > ldr q0, [x2, #:lo12:.LC0] > > ins v0.b[0], w0 > > zip1 v0.16b, v0.16b, v1.16b > > ret > > Nice. > > > There are a couple of issues I have come across: > > (1) Choosing element to pad vector. > > For eg, if we are initiailizing a vector say { x, y, 0, y, 1, y, 2, y } > > with mode V8HI. > > We split it into { x, 0, 1, 2 } and { y, y, y, y} > > However since the mode is V8HI, we would need to pad the above split vectors > > with 4 more elements to match up to vector length. > > For {x, 0, 1, 2} using any constant is the obvious choice while for {y, y, y, y} > > using 'y' is the obvious choice thus making them: > > {x, 0, 1, 2, 0, 0, 0, 0} and {y, y, y, y, y, y, y, y} > > These would be then merged using zip1 which would discard the lower half > > of both vectors. > > Currently I encoded the above two heuristics in > > aarch64_expand_vector_init_get_padded_elem: > > (a) If split portion contains a constant, use the constant to pad the vector. > > (b) If split portion only contains variables, then use the most > > frequently repeating variable > > to pad the vector. > > I suppose tho this could be improved ? > > I think we should just build two 64-bit vectors (V4HIs) and use a subreg > to fill the upper elements with undefined values. > > I suppose in principle we would have the same problem when splitting > a 64-bit vector into 2 32-bit vectors, but it's probably better to punt > on that for now. Eventually it would be worth adding full support for > 32-bit Advanced SIMD modes (with necessary restrictions for FP exceptions) > but it's quite a big task. The 128-bit to 64-bit split is the one that > matters most. > > > (2) Setting cost for zip1: > > Currently it returns 4 as cost for following zip1 insn: > > (set (reg:V8HI 102) > > (unspec:V8HI [ > > (reg:V8HI 103) > > (reg:V8HI 108) > > ] UNSPEC_ZIP1)) > > I am not sure if that's correct, or if not, what cost to use in this case > > for zip1 ? > > TBH 4 seems a bit optimistic. It's COSTS_N_INSNS (1), whereas the > generic advsimd_vec_cost::permute_cost is 2 insns. But the costs of > inserts are probably underestimated to the same extent, so hopefully > things work out. > > So it's probably best to accept the costs as they're currently given. > Changing them would need extensive testing. > > However, one of the advantages of the split is that it allows the > subvectors to be built in parallel. When optimising for speed, > it might make sense to take the maximum of the subsequence costs > and add the cost of the zip to that. Hi Richard, Thanks for the suggestions. In the attached patch, it recurses only if nelts == 16 to punt for 64 -> 32 bit split, and uses std::max(even_init, odd_init) + insn_cost (zip1_insn) for computing total cost of the sequence. So, for following case: int8x16_t f_s8(int8_t x) { return (int8x16_t) { x, 1, x, 2, x, 3, x, 4, x, 5, x, 6, x, 7, x, 8 }; } it now generates: f_s16: dup v0.8b, w0 adrp x0, .LC0 ldr d1, [x0, #:lo12:.LC0] zip1 v0.16b, v0.16b, v1.16b ret Which I assume is correct, since zip1 will merge the lower halves of two vectors while leaving the upper halves undefined ? Thanks, Prathamesh > > Thanks, > Richard --000000000000e60dd705f3b8b584 Content-Type: text/plain; charset="US-ASCII"; name="gnu-821-2.txt" Content-Disposition: attachment; filename="gnu-821-2.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_ldn5ppid0 ZGlmZiAtLWdpdCBhL2djYy9jb25maWcvYWFyY2g2NC9hYXJjaDY0LmNjIGIvZ2NjL2NvbmZpZy9h YXJjaDY0L2FhcmNoNjQuY2MKaW5kZXggYWNjMGNmZTVmOTQuLmE1MjdjNDhlOTE2IDEwMDY0NAot LS0gYS9nY2MvY29uZmlnL2FhcmNoNjQvYWFyY2g2NC5jYworKysgYi9nY2MvY29uZmlnL2FhcmNo NjQvYWFyY2g2NC5jYwpAQCAtMjE5NzYsNyArMjE5NzYsNyBAQCBhYXJjaDY0X3NpbWRfbWFrZV9j b25zdGFudCAocnR4IHZhbHMpCiAgICBpbml0aWFsaXNlZCB0byBjb250YWluIFZBTFMuICAqLwog CiB2b2lkCi1hYXJjaDY0X2V4cGFuZF92ZWN0b3JfaW5pdCAocnR4IHRhcmdldCwgcnR4IHZhbHMp CithYXJjaDY0X2V4cGFuZF92ZWN0b3JfaW5pdF9mYWxsYmFjayAocnR4IHRhcmdldCwgcnR4IHZh bHMpCiB7CiAgIG1hY2hpbmVfbW9kZSBtb2RlID0gR0VUX01PREUgKHRhcmdldCk7CiAgIHNjYWxh cl9tb2RlIGlubmVyX21vZGUgPSBHRVRfTU9ERV9JTk5FUiAobW9kZSk7CkBAIC0yMjE4OSw3ICsy MjE4OSw3IEBAIGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0IChydHggdGFyZ2V0LCBydHggdmFs cykKIAkgICAgfQogCSAgWFZFQ0VYUCAoY29weSwgMCwgaSkgPSBzdWJzdDsKIAl9Ci0gICAgICBh YXJjaDY0X2V4cGFuZF92ZWN0b3JfaW5pdCAodGFyZ2V0LCBjb3B5KTsKKyAgICAgIGFhcmNoNjRf ZXhwYW5kX3ZlY3Rvcl9pbml0X2ZhbGxiYWNrICh0YXJnZXQsIGNvcHkpOwogICAgIH0KIAogICAv KiBJbnNlcnQgdGhlIHZhcmlhYmxlIGxhbmVzIGRpcmVjdGx5LiAgKi8KQEAgLTIyMjAzLDYgKzIy MjAzLDg5IEBAIGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0IChydHggdGFyZ2V0LCBydHggdmFs cykKICAgICB9CiB9CiAKK0RFQlVHX0ZVTkNUSU9OCitzdGF0aWMgdm9pZAorYWFyY2g2NF9leHBh bmRfdmVjdG9yX2luaXRfZGVidWdfc2VxIChydHhfaW5zbiAqc2VxLCBjb25zdCBjaGFyICpzKQor eworICBmcHJpbnRmIChzdGRlcnIsICIlczogJXVcbiIsIHMsIHNlcV9jb3N0IChzZXEsICFvcHRp bWl6ZV9zaXplKSk7CisgIGZvciAocnR4X2luc24gKmkgPSBzZXE7IGk7IGkgPSBORVhUX0lOU04g KGkpKQorICAgIHsKKyAgICAgIGRlYnVnX3J0eCAoUEFUVEVSTiAoaSkpOworICAgICAgZnByaW50 ZiAoc3RkZXJyLCAiY29zdDogJWRcbiIsIHBhdHRlcm5fY29zdCAoUEFUVEVSTiAoaSksICFvcHRp bWl6ZV9zaXplKSk7CisgICAgfQorfQorCitzdGF0aWMgcnR4CithYXJjaDY0X2V4cGFuZF92ZWN0 b3JfaW5pdF9zcGxpdF92YWxzIChtYWNoaW5lX21vZGUgbW9kZSwgcnR4IHZhbHMsIGJvb2wgZXZl bl9wKQoreworICBpbnQgbiA9IFhWRUNMRU4gKHZhbHMsIDApOworICBtYWNoaW5lX21vZGUgbmV3 X21vZGUKKyAgICA9IGFhcmNoNjRfc2ltZF9jb250YWluZXJfbW9kZSAoR0VUX01PREVfSU5ORVIg KG1vZGUpLCA2NCk7CisgIHJ0dmVjIHZlYyA9IHJ0dmVjX2FsbG9jIChuIC8gMik7CisgIGZvciAo aW50IGkgPSAwOyBpIDwgbjsgaSsrKQorICAgIFJUVkVDX0VMVCAodmVjLCBpKSA9IChldmVuX3Ap ID8gWFZFQ0VYUCAodmFscywgMCwgMiAqIGkpCisJCQkJICA6IFhWRUNFWFAgKHZhbHMsIDAsIDIg KiBpICsgMSk7CisgIHJldHVybiBnZW5fcnR4X1BBUkFMTEVMIChuZXdfbW9kZSwgdmVjKTsKK30K KworLyoKK1RoZSBmdW5jdGlvbiBkb2VzIHRoZSBmb2xsb3dpbmc6CisoYSkgR2VuZXJhdGVzIGNv ZGUgc2VxdWVuY2UgYnkgc3BsaXR0aW5nIFZBTFMgaW50byBldmVuIGFuZCBvZGQgaGFsdmVzLAor ICAgIGFuZCByZWN1cnNpdmVseSBjYWxsaW5nIGl0c2VsZiB0byBpbml0aWFsaXplIHRoZW0gYW5k IHRoZW4gbWVyZ2UgdXNpbmcKKyAgICB6aXAxLgorKGIpIEdlbmVyYXRlIGNvZGUgc2VxdWVuY2Ug ZGlyZWN0bHkgdXNpbmcgYWFyY2g2NF9leHBhbmRfdmVjdG9yX2luaXRfZmFsbGJhY2suCisoYykg Q29tcGFyZSB0aGUgY29zdCBvZiBjb2RlIHNlcXVlbmNlcyBnZW5lcmF0ZWQgYnkgKGEpIGFuZCAo YiksIGFuZCBjaG9vc2UKKyAgICB0aGUgbW9yZSBlZmZpY2llbnQgb25lLgorKi8KKwordm9pZAor YWFyY2g2NF9leHBhbmRfdmVjdG9yX2luaXQgKHJ0eCB0YXJnZXQsIHJ0eCB2YWxzKQoreworICBt YWNoaW5lX21vZGUgbW9kZSA9IEdFVF9NT0RFICh0YXJnZXQpOworICBpbnQgbl9lbHRzID0gWFZF Q0xFTiAodmFscywgMCk7CisKKyAgaWYgKG5fZWx0cyA8IDE2KQorICAgIHsKKyAgICAgIGFhcmNo NjRfZXhwYW5kX3ZlY3Rvcl9pbml0X2ZhbGxiYWNrICh0YXJnZXQsIHZhbHMpOworICAgICAgcmV0 dXJuOworICAgIH0KKworICBzdGFydF9zZXF1ZW5jZSAoKTsKKyAgcnR4IGRlc3RbMl07CisgIHVu c2lnbmVkIGNvc3RzWzJdOworICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykKKyAgICB7Cisg ICAgICBzdGFydF9zZXF1ZW5jZSAoKTsKKyAgICAgIGRlc3RbaV0gPSBnZW5fcmVnX3J0eCAobW9k ZSk7CisgICAgICBydHggbmV3X3ZhbHMKKwk9IGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0X3Nw bGl0X3ZhbHMgKG1vZGUsIHZhbHMsIChpICUgMikgPT0gMCk7CisgICAgICBydHggdG1wX3JlZyA9 IGdlbl9yZWdfcnR4IChHRVRfTU9ERSAobmV3X3ZhbHMpKTsKKyAgICAgIGFhcmNoNjRfZXhwYW5k X3ZlY3Rvcl9pbml0ICh0bXBfcmVnLCBuZXdfdmFscyk7CisgICAgICBkZXN0W2ldID0gZ2VuX3J0 eF9TVUJSRUcgKG1vZGUsIHRtcF9yZWcsIDApOworICAgICAgcnR4X2luc24gKnJlY19zZXEgPSBn ZXRfaW5zbnMgKCk7CisgICAgICBlbmRfc2VxdWVuY2UgKCk7CisgICAgICBjb3N0c1tpXSA9IHNl cV9jb3N0IChyZWNfc2VxLCAhb3B0aW1pemVfc2l6ZSk7CisgICAgICBlbWl0X2luc24gKHJlY19z ZXEpOworICAgIH0KKworICBydHZlYyB2ID0gZ2VuX3J0dmVjICgyLCBkZXN0WzBdLCBkZXN0WzFd KTsKKyAgcnR4X2luc24gKnppcDFfaW5zbgorICAgID0gZW1pdF9zZXRfaW5zbiAodGFyZ2V0LCBn ZW5fcnR4X1VOU1BFQyAobW9kZSwgdiwgVU5TUEVDX1pJUDEpKTsKKyAgdW5zaWduZWQgc2VxX3Rv dGFsX2Nvc3QKKyAgICA9IHN0ZDo6bWF4IChjb3N0c1swXSwgY29zdHNbMV0pICsgaW5zbl9jb3N0 ICh6aXAxX2luc24sICFvcHRpbWl6ZV9zaXplKTsKKworICBydHhfaW5zbiAqc2VxID0gZ2V0X2lu c25zICgpOworICBlbmRfc2VxdWVuY2UgKCk7CisKKyAgc3RhcnRfc2VxdWVuY2UgKCk7CisgIGFh cmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0X2ZhbGxiYWNrICh0YXJnZXQsIHZhbHMpOworICBydHhf aW5zbiAqZmFsbGJhY2tfc2VxID0gZ2V0X2luc25zICgpOworICBlbmRfc2VxdWVuY2UgKCk7CisK KyAgZW1pdF9pbnNuIChzZXFfdG90YWxfY29zdCA8IHNlcV9jb3N0IChmYWxsYmFja19zZXEsICFv cHRpbWl6ZV9zaXplKQorCSAgICAgPyBzZXEgOiBmYWxsYmFja19zZXEpOworfQorCiAvKiBFbWl0 IFJUTCBjb3JyZXNwb25kaW5nIHRvOgogICAgaW5zciBUQVJHRVQsIEVMRU0uICAqLwogCmRpZmYg LS1naXQgYS9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC9pbnRlcmxlYXZlLWluaXQt MS5jIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMTguYwpzaW1p bGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2Fh cmNoNjQvaW50ZXJsZWF2ZS1pbml0LTEuYwpyZW5hbWUgdG8gZ2NjL3Rlc3RzdWl0ZS9nY2MudGFy Z2V0L2FhcmNoNjQvdmVjLWluaXQtMTguYwpkaWZmIC0tZ2l0IGEvZ2NjL3Rlc3RzdWl0ZS9nY2Mu dGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMTkuYyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9h YXJjaDY0L3ZlYy1pbml0LTE5LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAw MDAuLmUyOGZkY2RhMjlkCi0tLSAvZGV2L251bGwKKysrIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFy Z2V0L2FhcmNoNjQvdmVjLWluaXQtMTkuYwpAQCAtMCwwICsxLDIxIEBACisvKiB7IGRnLWRvIGNv bXBpbGUgfSAqLworLyogeyBkZy1vcHRpb25zICItTzMiIH0gKi8KKy8qIHsgZGctZmluYWwgeyBj aGVjay1mdW5jdGlvbi1ib2RpZXMgIioqIiAiIiAiIiB9IH0gKi8KKworI2luY2x1ZGUgPGFybV9u ZW9uLmg+CisKKy8qCisqKiBmX3M4OgorKioJLi4uCisqKglkdXAJdlswLTldK1wuOGIsIHdbMC05 XSsKKyoqCWFkcnAJeFswLTldKywgXC5MQ1swLTldKworKioJbGRyCWRbMC05XSssIFxbeFswLTld KywgIzpsbzEyOi5MQ1swLTldK1xdCisqKgl6aXAxCXZbMC05XStcLjE2YiwgdlswLTldK1wuMTZi LCB2WzAtOV0rXC4xNmIKKyoqCXJldAorKi8KKworaW50OHgxNl90IGZfczgoaW50OF90IHgpCit7 CisgIHJldHVybiAoaW50OHgxNl90KSB7IHgsIDEsIHgsIDIsIHgsIDMsIHgsIDQsCisgICAgICAg ICAgICAgICAgICAgICAgIHgsIDUsIHgsIDYsIHgsIDcsIHgsIDggfTsKK30KZGlmZiAtLWdpdCBh L2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIwLmMgYi9nY2MvdGVz dHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMtaW5pdC0yMC5jCm5ldyBmaWxlIG1vZGUgMTAw NjQ0CmluZGV4IDAwMDAwMDAwMDAwLi45MzY2Y2EzNDliNgotLS0gL2Rldi9udWxsCisrKyBiL2dj Yy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIwLmMKQEAgLTAsMCArMSwy MiBAQAorLyogeyBkZy1kbyBjb21waWxlIH0gKi8KKy8qIHsgZGctb3B0aW9ucyAiLU8zIiB9ICov CisvKiB7IGRnLWZpbmFsIHsgY2hlY2stZnVuY3Rpb24tYm9kaWVzICIqKiIgIiIgIiIgfSB9ICov CisKKyNpbmNsdWRlIDxhcm1fbmVvbi5oPgorCisvKgorKiogZl9zODoKKyoqCS4uLgorKioJYWRy cAl4WzAtOV0rLCBcLkxDWzAtOV0rCisqKglkdXAJdlswLTldK1wuOGIsIHdbMC05XSsKKyoqCWxk cglkWzAtOV0rLCBcW3hbMC05XSssICM6bG8xMjpcLkxDWzAtOV0rXF0KKyoqCWlucwl2MFwuYlxb MFxdLCB3MAorKioJemlwMQl2WzAtOV0rXC4xNmIsIHZbMC05XStcLjE2YiwgdlswLTldK1wuMTZi CisqKglyZXQKKyovCisKK2ludDh4MTZfdCBmX3M4KGludDhfdCB4LCBpbnQ4X3QgeSkKK3sKKyAg cmV0dXJuIChpbnQ4eDE2X3QpIHsgeCwgeSwgMSwgeSwgMiwgeSwgMywgeSwKKyAgICAgICAgICAg ICAgICAgICAgICAgNCwgeSwgNSwgeSwgNiwgeSwgNywgeSB9OworfQpkaWZmIC0tZ2l0IGEvZ2Nj L3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMjEuYyBiL2djYy90ZXN0c3Vp dGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIxLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQK aW5kZXggMDAwMDAwMDAwMDAuLmUxNjQ1OTQ4NmQ3Ci0tLSAvZGV2L251bGwKKysrIGIvZ2NjL3Rl c3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMjEuYwpAQCAtMCwwICsxLDIyIEBA CisvKiB7IGRnLWRvIGNvbXBpbGUgfSAqLworLyogeyBkZy1vcHRpb25zICItTzMiIH0gKi8KKy8q IHsgZGctZmluYWwgeyBjaGVjay1mdW5jdGlvbi1ib2RpZXMgIioqIiAiIiAiIiB9IH0gKi8KKwor I2luY2x1ZGUgPGFybV9uZW9uLmg+CisKKy8qCisqKiBmX3M4OgorKioJLi4uCisqKglhZHJwCXhb MC05XSssIFwuTENbMC05XSsKKyoqCWxkcglxWzAtOV0rLCBcW3hbMC05XSssICM6bG8xMjpcLkxD WzAtOV0rXF0KKyoqCWlucwl2MFwuYlxbMFxdLCB3MAorKioJaW5zCXYwXC5iXFsxXF0sIHcxCisq KgkuLi4KKyoqCXJldAorKi8KKworaW50OHgxNl90IGZfczgoaW50OF90IHgsIGludDhfdCB5KQor eworICByZXR1cm4gKGludDh4MTZfdCkgeyB4LCB5LCAxLCAyLCAzLCA0LCA1LCA2LAorICAgICAg ICAgICAgICAgICAgICAgICA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQgfTsKK30KZGlmZiAt LWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIyLmMgYi9n Y2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMtaW5pdC0yMi5jCm5ldyBmaWxlIG1v ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwLi5lNTAxNmE0N2EzYgotLS0gL2Rldi9udWxsCisr KyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIyLmMKQEAgLTAs MCArMSwzMCBAQAorLyogeyBkZy1kbyBjb21waWxlIH0gKi8KKy8qIHsgZGctb3B0aW9ucyAiLU8z IiB9ICovCisvKiB7IGRnLWZpbmFsIHsgY2hlY2stZnVuY3Rpb24tYm9kaWVzICIqKiIgIiIgIiIg fSB9ICovCisKKyNpbmNsdWRlIDxhcm1fbmVvbi5oPgorCisvKiBWZXJpZnkgdGhhdCBmYWxsYmFj ayBjb2RlLXNlcXVlbmNlIGlzIGNob3NlbiBvdmVyCisgICByZWN1cnNpdmVseSBnZW5lcmF0ZWQg Y29kZS1zZXF1ZW5jZSBtZXJnZWQgd2l0aCB6aXAxLiAgKi8KKworLyoKKyoqIGZfczE2OgorKioJ Li4uCisqKglzeHRoCXcwLCB3MAorKioJZm1vdglzMCwgdzAKKyoqCWlucwl2MFwuaFxbMVxdLCB3 MQorKioJaW5zCXYwXC5oXFsyXF0sIHcyCisqKglpbnMJdjBcLmhcWzNcXSwgdzMKKyoqCWlucwl2 MFwuaFxbNFxdLCB3NAorKioJaW5zCXYwXC5oXFs1XF0sIHc1CisqKglpbnMJdjBcLmhcWzZcXSwg dzYKKyoqCWlucwl2MFwuaFxbN1xdLCB3NworKioJLi4uCisqKglyZXQKKyovCisKK2ludDE2eDhf dCBmX3MxNiAoaW50MTZfdCB4MCwgaW50MTZfdCB4MSwgaW50MTZfdCB4MiwgaW50MTZfdCB4MywK KyAgICAgICAgICAgICAgICAgaW50MTZfdCB4NCwgaW50MTZfdCB4NSwgaW50MTZfdCB4NiwgaW50 MTZfdCB4NykKK3sKKyAgcmV0dXJuIChpbnQxNng4X3QpIHsgeDAsIHgxLCB4MiwgeDMsIHg0LCB4 NSwgeDYsIHg3IH07Cit9Cg== --000000000000e60dd705f3b8b584--