From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by sourceware.org (Postfix) with ESMTPS id 7B9AE3858C5E for ; Fri, 3 Feb 2023 01:40:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7B9AE3858C5E 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-x330.google.com with SMTP id c4-20020a1c3504000000b003d9e2f72093so5047986wma.1 for ; Thu, 02 Feb 2023 17:40:55 -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=qmtl/ghAtuIuCVo9W4h6uKWFOypN6KwxJy8Vdqplpf4=; b=iKiTqznL89C7rABj7PqGYLVKE+T1x2sdFq2iV0cOksBCPQBknFbW7He7epDER4WFrB Evm1lqgHEQv2nlNta+BQ5c24tVnk+uytio1V6jYQYhwhm5AqZPZqrLlGIeLmxGWDSP5A L3Dr/4xj0eNNmG59+uGAimyeVgWEN/vIDQo3TqzcbDUZwXAoDei1CBJqKq9a+94CoCXb jXL5ROTxFHoBZRtGTWJKsN/xH0+m+MmVnm2UMiYnZS5c4grsBne2zGTzauImHCISdUev rjBrd0vP3XZ1hWzqD2Zi4+YaLhoPQQmkJnLnpHeK7EguxsaYKdkAZIe5F5H+usbzlQY/ 2dLQ== 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=qmtl/ghAtuIuCVo9W4h6uKWFOypN6KwxJy8Vdqplpf4=; b=Qz0jmb+yn2CETkMzDC616G7W5ZFWc3dJn/da46Raa7iDpY8982rdVgjLMM6L0utGTY dW/VyZvHKmFu5bKynkjkmGs190NSUE8RoUtpyyUjHmrCsGeBOojV+L9bsA2LFslrKxqv 49ER0x8WRAes9MlwahmI7SIrXKp5pX2D8iwenChgRsWf/Dd7SrHQ6MuZU+ARZLx8VnYo pNl0Mf9AT50my/LJTD4Lwq3EchhEVBe5p37iIpGp18h3Z+O/R28hnMIsbOc3i1DqxGpX CdSaYPGJEDyQvLCMOa/0bmQ+7K3jVffP68w1R8HxAHJ7NBiVcfTDwsWJi3iNLWFTvYLY bILg== X-Gm-Message-State: AO0yUKXXFpcxTlEPwEBWtzTSau56qIOz/2iE4PgxS8WxYMgmbxakNJ4P KBs8vPlaP4D9Lm/mxwgHAwC4sO+dcF+BJWjr2jAQOQ== X-Google-Smtp-Source: AK7set9rqn5Yna088G3a9e8i74ajfpgNtD5DyJ5VxwsBTm1GSUSV4lstJ5R652wWrCti1x1WeKALRsLfMopcWLj15PE= X-Received: by 2002:a05:600c:2103:b0:3c8:353b:2553 with SMTP id u3-20020a05600c210300b003c8353b2553mr299725wml.18.1675388453895; Thu, 02 Feb 2023 17:40:53 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Prathamesh Kulkarni Date: Fri, 3 Feb 2023 07:10:16 +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="000000000000a7f14705f3c1c588" X-Spam-Status: No, score=-9.0 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: --000000000000a7f14705f3c1c588 Content-Type: text/plain; charset="UTF-8" On Thu, 2 Feb 2023 at 20:50, Richard Sandiford wrote: > > Prathamesh Kulkarni writes: > >> >> > 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, > > It should be based on the size rather than the number of elements. > The example we talked about above involved building V8HIs from two > V4HIs, which is also valid. Right, sorry got mixed up. The attached patch punts if vector_size == 64 by resorting to fallback, which handles V8HI cases. For eg: int16x8_t f(int16_t x) { return (int16x8_t) { x, 1, x, 2, x, 3, x, 4 }; } code-gen with patch: f: dup v0.4h, w0 adrp x0, .LC0 ldr d1, [x0, #:lo12:.LC0] zip1 v0.8h, v0.8h, v1.8h ret Just to clarify, we punt on 64 bit vector size, because there is no 32-bit vector available, to build 2 32-bit vectors for even and odd halves, and then "extend" them with subreg ? It also punts if n_elts < 8, because I am not sure if it's profitable to do recursion+merging for 4 or lesser elements. Does it look OK ? > > > 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 ? > > Yeah, it looks valid, but I would say that zip1 ignores the upper halves > (rather than leaving them undefined). Yes, sorry for mis-phrasing. For the following test: int16x8_t f_s16 (int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) { return (int16x8_t) { x0, x1, x2, x3, x4, x5, x6, x7 }; } it chose to go recursive+zip1 route since we take max (cost (odd_init), cost (even_init)) and add cost of zip1 insn which turns out to be lesser than cost of fallback: f_s16: sxth w0, w0 sxth w1, w1 fmov d0, x0 fmov d1, x1 ins v0.h[1], w2 ins v1.h[1], w3 ins v0.h[2], w4 ins v1.h[2], w5 ins v0.h[3], w6 ins v1.h[3], w7 zip1 v0.8h, v0.8h, v1.8h ret I assume that's OK since it has fewer dependencies compared to fallback code-gen even if it's longer ? With -Os the cost for sequence is taken as cost(odd_init) + cost(even_init) + cost(zip1_insn) which turns out to be same as cost for fallback sequence and it generates the fallback code-sequence: f_s16: sxth w0, w0 fmov s0, w0 ins v0.h[1], w1 ins v0.h[2], w2 ins v0.h[3], w3 ins v0.h[4], w4 ins v0.h[5], w5 ins v0.h[6], w6 ins v0.h[7], w7 ret Thanks, Prathamesh > > Thanks, > Richard --000000000000a7f14705f3c1c588 Content-Type: text/plain; charset="US-ASCII"; name="gnu-821-3.txt" Content-Disposition: attachment; filename="gnu-821-3.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_ldnua58u0 ZGlmZiAtLWdpdCBhL2djYy9jb25maWcvYWFyY2g2NC9hYXJjaDY0LmNjIGIvZ2NjL2NvbmZpZy9h YXJjaDY0L2FhcmNoNjQuY2MKaW5kZXggYWNjMGNmZTVmOTQuLjQzODNlNGUxZDBjIDEwMDY0NAot LS0gYS9nY2MvY29uZmlnL2FhcmNoNjQvYWFyY2g2NC5jYworKysgYi9nY2MvY29uZmlnL2FhcmNo NjQvYWFyY2g2NC5jYwpAQCAtMjE5NzYsNyArMjE5NzYsNyBAQCBhYXJjaDY0X3NpbWRfbWFrZV9j b25zdGFudCAocnR4IHZhbHMpCiAgICBpbml0aWFsaXNlZCB0byBjb250YWluIFZBTFMuICAqLwog CiB2b2lkCi1hYXJjaDY0X2V4cGFuZF92ZWN0b3JfaW5pdCAocnR4IHRhcmdldCwgcnR4IHZhbHMp CithYXJjaDY0X2V4cGFuZF92ZWN0b3JfaW5pdF9mYWxsYmFjayAocnR4IHRhcmdldCwgcnR4IHZh bHMpCiB7CiAgIG1hY2hpbmVfbW9kZSBtb2RlID0gR0VUX01PREUgKHRhcmdldCk7CiAgIHNjYWxh cl9tb2RlIGlubmVyX21vZGUgPSBHRVRfTU9ERV9JTk5FUiAobW9kZSk7CkBAIC0yMjE4OSw3ICsy MjE4OSw3IEBAIGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0IChydHggdGFyZ2V0LCBydHggdmFs cykKIAkgICAgfQogCSAgWFZFQ0VYUCAoY29weSwgMCwgaSkgPSBzdWJzdDsKIAl9Ci0gICAgICBh YXJjaDY0X2V4cGFuZF92ZWN0b3JfaW5pdCAodGFyZ2V0LCBjb3B5KTsKKyAgICAgIGFhcmNoNjRf ZXhwYW5kX3ZlY3Rvcl9pbml0X2ZhbGxiYWNrICh0YXJnZXQsIGNvcHkpOwogICAgIH0KIAogICAv KiBJbnNlcnQgdGhlIHZhcmlhYmxlIGxhbmVzIGRpcmVjdGx5LiAgKi8KQEAgLTIyMjAzLDYgKzIy MjAzLDkxIEBAIGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0IChydHggdGFyZ2V0LCBydHggdmFs cykKICAgICB9CiB9CiAKK0RFQlVHX0ZVTkNUSU9OCitzdGF0aWMgdm9pZAorYWFyY2g2NF9leHBh bmRfdmVjdG9yX2luaXRfZGVidWdfc2VxIChydHhfaW5zbiAqc2VxLCBjb25zdCBjaGFyICpzKQor eworICBmcHJpbnRmIChzdGRlcnIsICIlczogJXVcbiIsIHMsIHNlcV9jb3N0IChzZXEsICFvcHRp bWl6ZV9zaXplKSk7CisgIGZvciAocnR4X2luc24gKmkgPSBzZXE7IGk7IGkgPSBORVhUX0lOU04g KGkpKQorICAgIHsKKyAgICAgIGRlYnVnX3J0eCAoUEFUVEVSTiAoaSkpOworICAgICAgZnByaW50 ZiAoc3RkZXJyLCAiY29zdDogJWRcbiIsIHBhdHRlcm5fY29zdCAoUEFUVEVSTiAoaSksICFvcHRp bWl6ZV9zaXplKSk7CisgICAgfQorfQorCitzdGF0aWMgcnR4CithYXJjaDY0X2V4cGFuZF92ZWN0 b3JfaW5pdF9zcGxpdF92YWxzIChtYWNoaW5lX21vZGUgbW9kZSwgcnR4IHZhbHMsIGJvb2wgZXZl bl9wKQoreworICBpbnQgbiA9IFhWRUNMRU4gKHZhbHMsIDApOworICBtYWNoaW5lX21vZGUgbmV3 X21vZGUKKyAgICA9IGFhcmNoNjRfc2ltZF9jb250YWluZXJfbW9kZSAoR0VUX01PREVfSU5ORVIg KG1vZGUpLCA2NCk7CisgIHJ0dmVjIHZlYyA9IHJ0dmVjX2FsbG9jIChuIC8gMik7CisgIGZvciAo aW50IGkgPSAwOyBpIDwgbjsgaSsrKQorICAgIFJUVkVDX0VMVCAodmVjLCBpKSA9IChldmVuX3Ap ID8gWFZFQ0VYUCAodmFscywgMCwgMiAqIGkpCisJCQkJICA6IFhWRUNFWFAgKHZhbHMsIDAsIDIg KiBpICsgMSk7CisgIHJldHVybiBnZW5fcnR4X1BBUkFMTEVMIChuZXdfbW9kZSwgdmVjKTsKK30K KworLyoKK1RoZSBmdW5jdGlvbiBkb2VzIHRoZSBmb2xsb3dpbmc6CisoYSkgR2VuZXJhdGVzIGNv ZGUgc2VxdWVuY2UgYnkgc3BsaXR0aW5nIFZBTFMgaW50byBldmVuIGFuZCBvZGQgaGFsdmVzLAor ICAgIGFuZCByZWN1cnNpdmVseSBjYWxsaW5nIGl0c2VsZiB0byBpbml0aWFsaXplIHRoZW0gYW5k IHRoZW4gbWVyZ2UgdXNpbmcKKyAgICB6aXAxLgorKGIpIEdlbmVyYXRlIGNvZGUgc2VxdWVuY2Ug ZGlyZWN0bHkgdXNpbmcgYWFyY2g2NF9leHBhbmRfdmVjdG9yX2luaXRfZmFsbGJhY2suCisoYykg Q29tcGFyZSB0aGUgY29zdCBvZiBjb2RlIHNlcXVlbmNlcyBnZW5lcmF0ZWQgYnkgKGEpIGFuZCAo YiksIGFuZCBjaG9vc2UKKyAgICB0aGUgbW9yZSBlZmZpY2llbnQgb25lLgorKi8KKwordm9pZAor YWFyY2g2NF9leHBhbmRfdmVjdG9yX2luaXQgKHJ0eCB0YXJnZXQsIHJ0eCB2YWxzKQoreworICBt YWNoaW5lX21vZGUgbW9kZSA9IEdFVF9NT0RFICh0YXJnZXQpOworICBpbnQgbl9lbHRzID0gWFZF Q0xFTiAodmFscywgMCk7CisKKyAgaWYgKG5fZWx0cyA8IDgKKyAgICAgIHx8IGtub3duX2VxIChH RVRfTU9ERV9CSVRTSVpFIChtb2RlKSwgNjQpKQorICAgIHsKKyAgICAgIGFhcmNoNjRfZXhwYW5k X3ZlY3Rvcl9pbml0X2ZhbGxiYWNrICh0YXJnZXQsIHZhbHMpOworICAgICAgcmV0dXJuOworICAg IH0KKworICBzdGFydF9zZXF1ZW5jZSAoKTsKKyAgcnR4IGRlc3RbMl07CisgIHVuc2lnbmVkIGNv c3RzWzJdOworICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykKKyAgICB7CisgICAgICBzdGFy dF9zZXF1ZW5jZSAoKTsKKyAgICAgIGRlc3RbaV0gPSBnZW5fcmVnX3J0eCAobW9kZSk7CisgICAg ICBydHggbmV3X3ZhbHMKKwk9IGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9pbml0X3NwbGl0X3ZhbHMg KG1vZGUsIHZhbHMsIChpICUgMikgPT0gMCk7CisgICAgICBydHggdG1wX3JlZyA9IGdlbl9yZWdf cnR4IChHRVRfTU9ERSAobmV3X3ZhbHMpKTsKKyAgICAgIGFhcmNoNjRfZXhwYW5kX3ZlY3Rvcl9p bml0ICh0bXBfcmVnLCBuZXdfdmFscyk7CisgICAgICBkZXN0W2ldID0gZ2VuX3J0eF9TVUJSRUcg KG1vZGUsIHRtcF9yZWcsIDApOworICAgICAgcnR4X2luc24gKnJlY19zZXEgPSBnZXRfaW5zbnMg KCk7CisgICAgICBlbmRfc2VxdWVuY2UgKCk7CisgICAgICBjb3N0c1tpXSA9IHNlcV9jb3N0IChy ZWNfc2VxLCAhb3B0aW1pemVfc2l6ZSk7CisgICAgICBlbWl0X2luc24gKHJlY19zZXEpOworICAg IH0KKworICBydHZlYyB2ID0gZ2VuX3J0dmVjICgyLCBkZXN0WzBdLCBkZXN0WzFdKTsKKyAgcnR4 X2luc24gKnppcDFfaW5zbgorICAgID0gZW1pdF9zZXRfaW5zbiAodGFyZ2V0LCBnZW5fcnR4X1VO U1BFQyAobW9kZSwgdiwgVU5TUEVDX1pJUDEpKTsKKyAgdW5zaWduZWQgc2VxX3RvdGFsX2Nvc3QK KyAgICA9ICghb3B0aW1pemVfc2l6ZSkgPyBzdGQ6Om1heCAoY29zdHNbMF0sIGNvc3RzWzFdKSA6 IGNvc3RzWzBdICsgY29zdHNbMV07CisgIHNlcV90b3RhbF9jb3N0ICs9IGluc25fY29zdCAoemlw MV9pbnNuLCAhb3B0aW1pemVfc2l6ZSk7CisKKyAgcnR4X2luc24gKnNlcSA9IGdldF9pbnNucyAo KTsKKyAgZW5kX3NlcXVlbmNlICgpOworCisgIHN0YXJ0X3NlcXVlbmNlICgpOworICBhYXJjaDY0 X2V4cGFuZF92ZWN0b3JfaW5pdF9mYWxsYmFjayAodGFyZ2V0LCB2YWxzKTsKKyAgcnR4X2luc24g KmZhbGxiYWNrX3NlcSA9IGdldF9pbnNucyAoKTsKKyAgdW5zaWduZWQgZmFsbGJhY2tfc2VxX2Nv c3QgPSBzZXFfY29zdCAoZmFsbGJhY2tfc2VxLCAhb3B0aW1pemVfc2l6ZSk7CisgIGVuZF9zZXF1 ZW5jZSAoKTsKKworICBlbWl0X2luc24gKHNlcV90b3RhbF9jb3N0IDwgZmFsbGJhY2tfc2VxX2Nv c3QgPyBzZXEgOiBmYWxsYmFja19zZXEpOworfQorCiAvKiBFbWl0IFJUTCBjb3JyZXNwb25kaW5n IHRvOgogICAgaW5zciBUQVJHRVQsIEVMRU0uICAqLwogCmRpZmYgLS1naXQgYS9nY2MvdGVzdHN1 aXRlL2djYy50YXJnZXQvYWFyY2g2NC9pbnRlcmxlYXZlLWluaXQtMS5jIGIvZ2NjL3Rlc3RzdWl0 ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMTguYwpzaW1pbGFyaXR5IGluZGV4IDgyJQpy ZW5hbWUgZnJvbSBnY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC9pbnRlcmxlYXZlLWlu aXQtMS5jCnJlbmFtZSB0byBnY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMtaW5p dC0xOC5jCmluZGV4IGVlNzc1MDQ4NTg5Li5lODEyZDM5NDZkZSAxMDA2NDQKLS0tIGEvZ2NjL3Rl c3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvaW50ZXJsZWF2ZS1pbml0LTEuYworKysgYi9nY2Mv dGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMtaW5pdC0xOC5jCkBAIC03LDggKzcsOCBA QAogLyoKICoqIGZvbzoKICoqCS4uLgotKioJZHVwCXZbMC05XStcLjhoLCB3WzAtOV0rCi0qKglk dXAJdlswLTldK1wuOGgsIHdbMC05XSsKKyoqCWR1cAl2WzAtOV0rXC40aCwgd1swLTldKworKioJ ZHVwCXZbMC05XStcLjRoLCB3WzAtOV0rCiAqKgl6aXAxCXZbMC05XStcLjhoLCB2WzAtOV0rXC44 aCwgdlswLTldK1wuOGgKICoqCS4uLgogKioJcmV0CkBAIC0yMyw4ICsyMyw4IEBAIGludDE2eDhf dCBmb28oaW50MTZfdCB4LCBpbnQgeSkKIC8qCiAqKiBmb28yOgogKioJLi4uCi0qKglkdXAJdlsw LTldK1wuOGgsIHdbMC05XSsKLSoqCW1vdmkJdlswLTldK1wuOGgsIDB4MQorKioJZHVwCXZbMC05 XStcLjRoLCB3WzAtOV0rCisqKgltb3ZpCXZbMC05XStcLjRoLCAweDEKICoqCXppcDEJdlswLTld K1wuOGgsIHZbMC05XStcLjhoLCB2WzAtOV0rXC44aAogKioJLi4uCiAqKglyZXQKZGlmZiAtLWdp dCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTE5LmMgYi9nY2Mv dGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMtaW5pdC0xOS5jCm5ldyBmaWxlIG1vZGUg MTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwLi5lMjhmZGNkYTI5ZAotLS0gL2Rldi9udWxsCisrKyBi L2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTE5LmMKQEAgLTAsMCAr MSwyMSBAQAorLyogeyBkZy1kbyBjb21waWxlIH0gKi8KKy8qIHsgZGctb3B0aW9ucyAiLU8zIiB9 ICovCisvKiB7IGRnLWZpbmFsIHsgY2hlY2stZnVuY3Rpb24tYm9kaWVzICIqKiIgIiIgIiIgfSB9 ICovCisKKyNpbmNsdWRlIDxhcm1fbmVvbi5oPgorCisvKgorKiogZl9zODoKKyoqCS4uLgorKioJ ZHVwCXZbMC05XStcLjhiLCB3WzAtOV0rCisqKglhZHJwCXhbMC05XSssIFwuTENbMC05XSsKKyoq CWxkcglkWzAtOV0rLCBcW3hbMC05XSssICM6bG8xMjouTENbMC05XStcXQorKioJemlwMQl2WzAt OV0rXC4xNmIsIHZbMC05XStcLjE2YiwgdlswLTldK1wuMTZiCisqKglyZXQKKyovCisKK2ludDh4 MTZfdCBmX3M4KGludDhfdCB4KQoreworICByZXR1cm4gKGludDh4MTZfdCkgeyB4LCAxLCB4LCAy LCB4LCAzLCB4LCA0LAorICAgICAgICAgICAgICAgICAgICAgICB4LCA1LCB4LCA2LCB4LCA3LCB4 LCA4IH07Cit9CmRpZmYgLS1naXQgYS9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92 ZWMtaW5pdC0yMC5jIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQt MjAuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMC4uOTM2NmNhMzQ5YjYK LS0tIC9kZXYvbnVsbAorKysgYi9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMt aW5pdC0yMC5jCkBAIC0wLDAgKzEsMjIgQEAKKy8qIHsgZGctZG8gY29tcGlsZSB9ICovCisvKiB7 IGRnLW9wdGlvbnMgIi1PMyIgfSAqLworLyogeyBkZy1maW5hbCB7IGNoZWNrLWZ1bmN0aW9uLWJv ZGllcyAiKioiICIiICIiIH0gfSAqLworCisjaW5jbHVkZSA8YXJtX25lb24uaD4KKworLyoKKyoq IGZfczg6CisqKgkuLi4KKyoqCWFkcnAJeFswLTldKywgXC5MQ1swLTldKworKioJZHVwCXZbMC05 XStcLjhiLCB3WzAtOV0rCisqKglsZHIJZFswLTldKywgXFt4WzAtOV0rLCAjOmxvMTI6XC5MQ1sw LTldK1xdCisqKglpbnMJdjBcLmJcWzBcXSwgdzAKKyoqCXppcDEJdlswLTldK1wuMTZiLCB2WzAt OV0rXC4xNmIsIHZbMC05XStcLjE2YgorKioJcmV0CisqLworCitpbnQ4eDE2X3QgZl9zOChpbnQ4 X3QgeCwgaW50OF90IHkpCit7CisgIHJldHVybiAoaW50OHgxNl90KSB7IHgsIHksIDEsIHksIDIs IHksIDMsIHksCisgICAgICAgICAgICAgICAgICAgICAgIDQsIHksIDUsIHksIDYsIHksIDcsIHkg fTsKK30KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1p bml0LTIxLmMgYi9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2NC92ZWMtaW5pdC0yMS5j Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwLi5lMTY0NTk0ODZkNwotLS0g L2Rldi9udWxsCisrKyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0 LTIxLmMKQEAgLTAsMCArMSwyMiBAQAorLyogeyBkZy1kbyBjb21waWxlIH0gKi8KKy8qIHsgZGct b3B0aW9ucyAiLU8zIiB9ICovCisvKiB7IGRnLWZpbmFsIHsgY2hlY2stZnVuY3Rpb24tYm9kaWVz ICIqKiIgIiIgIiIgfSB9ICovCisKKyNpbmNsdWRlIDxhcm1fbmVvbi5oPgorCisvKgorKiogZl9z ODoKKyoqCS4uLgorKioJYWRycAl4WzAtOV0rLCBcLkxDWzAtOV0rCisqKglsZHIJcVswLTldKywg XFt4WzAtOV0rLCAjOmxvMTI6XC5MQ1swLTldK1xdCisqKglpbnMJdjBcLmJcWzBcXSwgdzAKKyoq CWlucwl2MFwuYlxbMVxdLCB3MQorKioJLi4uCisqKglyZXQKKyovCisKK2ludDh4MTZfdCBmX3M4 KGludDhfdCB4LCBpbnQ4X3QgeSkKK3sKKyAgcmV0dXJuIChpbnQ4eDE2X3QpIHsgeCwgeSwgMSwg MiwgMywgNCwgNSwgNiwKKyAgICAgICAgICAgICAgICAgICAgICAgNywgOCwgOSwgMTAsIDExLCAx MiwgMTMsIDE0IH07Cit9CmRpZmYgLS1naXQgYS9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFy Y2g2NC92ZWMtaW5pdC0yMi1zaXplLmMgYi9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYWFyY2g2 NC92ZWMtaW5pdC0yMi1zaXplLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAw MDAuLjhmMzU4NTRjMDA4Ci0tLSAvZGV2L251bGwKKysrIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFy Z2V0L2FhcmNoNjQvdmVjLWluaXQtMjItc2l6ZS5jCkBAIC0wLDAgKzEsMjQgQEAKKy8qIHsgZGct ZG8gY29tcGlsZSB9ICovCisvKiB7IGRnLW9wdGlvbnMgIi1PcyIgfSAqLworLyogeyBkZy1maW5h bCB7IGNoZWNrLWZ1bmN0aW9uLWJvZGllcyAiKioiICIiICIiIH0gfSAqLworCisvKiBWZXJpZnkg dGhhdCBmYWxsYmFjayBjb2RlLXNlcXVlbmNlIGlzIGNob3NlbiBvdmVyCisgICByZWN1cnNpdmVs eSBnZW5lcmF0ZWQgY29kZS1zZXF1ZW5jZSBtZXJnZWQgd2l0aCB6aXAxLiAgKi8KKworLyoKKyoq IGZfczE2OgorKioJLi4uCisqKglzeHRoCXcwLCB3MAorKioJZm1vdglzMCwgdzAKKyoqCWlucwl2 MFwuaFxbMVxdLCB3MQorKioJaW5zCXYwXC5oXFsyXF0sIHcyCisqKglpbnMJdjBcLmhcWzNcXSwg dzMKKyoqCWlucwl2MFwuaFxbNFxdLCB3NAorKioJaW5zCXYwXC5oXFs1XF0sIHc1CisqKglpbnMJ djBcLmhcWzZcXSwgdzYKKyoqCWlucwl2MFwuaFxbN1xdLCB3NworKioJLi4uCisqKglyZXQKKyov CisKKyNpbmNsdWRlICJ2ZWMtaW5pdC0yMi5oIgpkaWZmIC0tZ2l0IGEvZ2NjL3Rlc3RzdWl0ZS9n Y2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMjItc3BlZWQuYyBiL2djYy90ZXN0c3VpdGUvZ2Nj LnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIyLXNwZWVkLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQK aW5kZXggMDAwMDAwMDAwMDAuLjE3MmQ1NmZmZGYxCi0tLSAvZGV2L251bGwKKysrIGIvZ2NjL3Rl c3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMjItc3BlZWQuYwpAQCAtMCwwICsx LDI3IEBACisvKiB7IGRnLWRvIGNvbXBpbGUgfSAqLworLyogeyBkZy1vcHRpb25zICItTzMiIH0g Ki8KKy8qIHsgZGctZmluYWwgeyBjaGVjay1mdW5jdGlvbi1ib2RpZXMgIioqIiAiIiAiIiB9IH0g Ki8KKworLyogVmVyaWZ5IHRoYXQgd2UgcmVjdXJzaXZlbHkgZ2VuZXJhdGUgY29kZSBmb3IgZXZl biBhbmQgb2RkIGhhbHZlcworICAgaW5zdGVhZCBvZiBmYWxsYmFjayBjb2RlLiBUaGlzIGlzIHNv IGRlc3BpdGUgdGhlIGxvbmdlciBjb2RlLWdlbgorICAgYmVjYXVzZSBpdCBoYXMgZmV3ZXIgZGVw ZW5kZW5jaWVzIGFuZCB0aHVzIGhhcyBsZXNzZXIgY29zdC4gICovCisKKy8qCisqKiBmX3MxNjoK KyoqCS4uLgorKioJc3h0aAl3MCwgdzAKKyoqCXN4dGgJdzEsIHcxCisqKglmbW92CWQwLCB4MAor KioJZm1vdglkMSwgeDEKKyoqCWlucwl2WzAtOV0rXC5oXFsxXF0sIHcyCisqKglpbnMJdlswLTld K1wuaFxbMVxdLCB3MworKioJaW5zCXZbMC05XStcLmhcWzJcXSwgdzQKKyoqCWlucwl2WzAtOV0r XC5oXFsyXF0sIHc1CisqKglpbnMJdlswLTldK1wuaFxbM1xdLCB3NgorKioJaW5zCXZbMC05XStc LmhcWzNcXSwgdzcKKyoqCXppcDEJdlswLTldK1wuOGgsIHZbMC05XStcLjhoLCB2WzAtOV0rXC44 aAorKioJLi4uCisqKglyZXQKKyovCisKKyNpbmNsdWRlICJ2ZWMtaW5pdC0yMi5oIgpkaWZmIC0t Z2l0IGEvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMjIuaCBiL2dj Yy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hYXJjaDY0L3ZlYy1pbml0LTIyLmgKbmV3IGZpbGUgbW9k ZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAuLjE1Yjg4OWQ0MDk3Ci0tLSAvZGV2L251bGwKKysr IGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FhcmNoNjQvdmVjLWluaXQtMjIuaApAQCAtMCww ICsxLDcgQEAKKyNpbmNsdWRlIDxhcm1fbmVvbi5oPgorCitpbnQxNng4X3QgZl9zMTYgKGludDE2 X3QgeDAsIGludDE2X3QgeDEsIGludDE2X3QgeDIsIGludDE2X3QgeDMsCisgICAgICAgICAgICAg ICAgIGludDE2X3QgeDQsIGludDE2X3QgeDUsIGludDE2X3QgeDYsIGludDE2X3QgeDcpCit7Cisg IHJldHVybiAoaW50MTZ4OF90KSB7IHgwLCB4MSwgeDIsIHgzLCB4NCwgeDUsIHg2LCB4NyB9Owor fQo= --000000000000a7f14705f3c1c588--