From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2041.outbound.protection.outlook.com [40.107.7.41]) by sourceware.org (Postfix) with ESMTPS id 21C49385842D for ; Thu, 9 Feb 2023 13:26:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 21C49385842D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=28ZNbbAOKGPOO0ySn8T3TGy+35XnKO46MpIS6ZRUDi8=; b=BELp1Ld4IvrHEso3LB7GYhqAmMNeUKspVoU/PrxMHLlBiYENmTOKiZM4z7gDsZI9ERk1LxMrOz5sS1ovly7gir4VyDHe7TJBZjKHwp7d/OrbVYCEvP0eTs+eFCGX8Oi8mSm4F2GMeDDU+XJwzgTNBIvxCxhbG8odWSk5y4kN9Wc= Received: from AS9PR06CA0614.eurprd06.prod.outlook.com (2603:10a6:20b:46e::11) by DU0PR08MB7487.eurprd08.prod.outlook.com (2603:10a6:10:357::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6086.18; Thu, 9 Feb 2023 13:26:39 +0000 Received: from AM7EUR03FT016.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:46e:cafe::b6) by AS9PR06CA0614.outlook.office365.com (2603:10a6:20b:46e::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6086.17 via Frontend Transport; Thu, 9 Feb 2023 13:26:39 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM7EUR03FT016.mail.protection.outlook.com (100.127.140.106) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6086.19 via Frontend Transport; Thu, 9 Feb 2023 13:26:39 +0000 Received: ("Tessian outbound 43b0faad5a68:v132"); Thu, 09 Feb 2023 13:26:39 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 325939c64fd54030 X-CR-MTA-TID: 64aa7808 Received: from b7dee9d281f2.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id B801190B-FE94-4077-AB95-78E404CECCC5.1; Thu, 09 Feb 2023 13:26:30 +0000 Received: from EUR04-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id b7dee9d281f2.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 09 Feb 2023 13:26:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PWdGYVTowWJ6DCI7X1R5vLLPQfJu+3F1l57tf8EWLwOMHPKIKhibE4KhpSOoLcnL45F5jO1Rz0/VdjdYPFDhymZdfV+efvCNnbZt67XLsJHVRVHhlaHFL1BcE08y3kd3Tvxs5hVEEScCif3G9zXsWa+0jZiLzfmNZpdb6HrOZKOF7CK4IRC4Berf+Hsq2hBPIkDlEhDqYlbdnoI6MkN+guTdPD3FfjOlam7Ro9oOWXDSn6H7biBROQN5MxWssfbrC8PfGjiOacpJ1/P71zDUgaBYbUpvdxJkHQs6A9/28oSW4gpmRjIJZph3xwzH1Q7jvpWYEcpJV4Mr/sj2GiLzGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=28ZNbbAOKGPOO0ySn8T3TGy+35XnKO46MpIS6ZRUDi8=; b=NpW/LLIoseGdDhrPBy+DINFMPvjJpF3aB/HAGAXKQ2Pn79SV+QDqRrfxr7ZCwZEQ+GLD/Zg+6wtVLBAjgQJ/RfT5Y/5bzqSYhus1x824cPiow2kdYzXJKrz2HdZuGyqG/8S4mQWwjVT0VtRCurux4RPZPrC79HVbcocSzB33yj/C6HgUiR2mkS3zBoDB9YHsmCjjGY78TY5X7Vm+iF0S24V1/4eMkLual9cFW++gyU9yLVxPBx4pJQf3opb+ZjJXChU+Tkyzj5LYt6V2BCb+47kBDo255oxNvLrtpQLCGDlsefK4p1lNffRhIQOizZS2xNyX/k7qQJWa1sVrABq7gg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=28ZNbbAOKGPOO0ySn8T3TGy+35XnKO46MpIS6ZRUDi8=; b=BELp1Ld4IvrHEso3LB7GYhqAmMNeUKspVoU/PrxMHLlBiYENmTOKiZM4z7gDsZI9ERk1LxMrOz5sS1ovly7gir4VyDHe7TJBZjKHwp7d/OrbVYCEvP0eTs+eFCGX8Oi8mSm4F2GMeDDU+XJwzgTNBIvxCxhbG8odWSk5y4kN9Wc= Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from DB9PR08MB6507.eurprd08.prod.outlook.com (2603:10a6:10:25a::6) by AM8PR08MB6371.eurprd08.prod.outlook.com (2603:10a6:20b:363::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6086.17; Thu, 9 Feb 2023 13:26:26 +0000 Received: from DB9PR08MB6507.eurprd08.prod.outlook.com ([fe80::bbbe:1a51:c692:c654]) by DB9PR08MB6507.eurprd08.prod.outlook.com ([fe80::bbbe:1a51:c692:c654%4]) with mapi id 15.20.6086.017; Thu, 9 Feb 2023 13:26:26 +0000 Content-Type: multipart/mixed; boundary="------------RE6Gven9LsBwQ60Lckeh0C0w" Message-ID: <92133f1e-ff7e-2dfd-7311-41d8d8357b15@arm.com> Date: Thu, 9 Feb 2023 13:26:22 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: [PATCH 2/2 v3][ping] arm: Add support for MVE Tail-Predicated Low Overhead Loops Content-Language: en-US References: To: "gcc-patches@gcc.gnu.org" Cc: Kyrylo Tkachov , "Andre Vieira (lists)" , Richard Earnshaw From: Stamatis Markianos-Wright In-Reply-To: X-Forwarded-Message-Id: X-ClientProxiedBy: LO4P265CA0166.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:312::10) To DB9PR08MB6507.eurprd08.prod.outlook.com (2603:10a6:10:25a::6) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: DB9PR08MB6507:EE_|AM8PR08MB6371:EE_|AM7EUR03FT016:EE_|DU0PR08MB7487:EE_ X-MS-Office365-Filtering-Correlation-Id: 052610a8-6f2e-4ee6-f128-08db0aa146a6 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: QjsT8SetJuYdVqWy8SknfQmbuhesWYUztvQML65lFHlPrtNsqSBoSLfkecxJatEqVPZrUjmg3tKKCJ9oEsyNnSjnROwPw89W1Ghm82BuvWgqWRSaARGHHJ6pr6b+SOxcgp2MA7lpggviHHlVu9P6E0jD8qs49r+ESQd+YU41PhbwvvqYWyI4DPyygVcpSZ2hg9om1jhSJNP8SHo3MpZ7hmh+1L+hi/nmqhe0VtDvoZKaDZtU3fbHB0ajGs5HKAzTMhc6KWV0B++hQW6ox3ZRunzrCII/vZZG9fO8peEHJOKsbLDzmZSqyoTtQF6TxkRPylil4zZgBn4kxNVWpFkOmfJXXi3StpBiGn/hLm6DOAyC/SVbSeK9BdEFrTlwujXdsE8F/1FjsX7iqp2vfH+IaCh2ldA99YYtO0DdMi3jZLbkvcoXH70ZLjZYZS1FSNiHaMOAk9hGYXQExZUrMvlFmX/6NWGABYQW5G5fpsi0PdoxJ5J4MVuOKoFLxtECYb595VRAM+ZWn+jNYtGOqT6AryoxmuwIYEgwbGKPH0acf8BlKd/Om7AB7F9qZGXf5x21Q+kZ0SNKW5nQparCndj720IwA7IyTYLkCg7L2HvW4FfUJ+BCsG8LS5PevwpgE5Gk7CZqOqmYGxyDdvzFTgEyOw/vUvFNf1MRx/D8Zf3bC//S39eIl7Ra4bNpO9uEa8Yho6FE+d9BMF65mIBcAD3t1qtw1SecqzEB3rfm9OAtTQadfdVu9yR7SdxYCBC7ygEB+pvD6F89sTa37qUVgLnsHQpV9AT3andr1+8v45zVzLr8o4GT/2jbNkm2GkLYQz6I X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DB9PR08MB6507.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(4636009)(396003)(376002)(136003)(39860400002)(346002)(366004)(451199018)(235185007)(36756003)(5660300002)(2906002)(30864003)(83380400001)(2616005)(66556008)(38100700002)(316002)(6916009)(8676002)(66476007)(66946007)(8936002)(54906003)(4326008)(6666004)(41300700001)(6512007)(186003)(478600001)(33964004)(26005)(86362001)(53546011)(31696002)(966005)(6486002)(84970400001)(6506007)(31686004)(43740500002)(45980500001)(579004)(559001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8PR08MB6371 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM7EUR03FT016.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 736d535d-1d1a-4d02-4140-08db0aa13e51 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2M5RCP2cEYTruzTRpL8N+tRAWE3BkQRdPZVI7nQYKOtAwG1KK8pu0ejkaShvSL3rRbPPxegy71pkU4hJurYXWMzF2Muzz8pHc6lz703S/eOEQI1ckK8Jy+MQH3zxH6OZarDHqZe6qDxkU/Y2JpgVKHmPsmkE1f0tcScg0/t3Q6vb1oeVNIcsl0S0HDA8u9XQzQkOWCKJ1R6Xk/6b1rv8RRE/5heovnrihquBLwqNsVIPaMHVFVXnmelx5qmGS+/Kto1QgVe/ocvSWBkLvNhViqR6jkJJxMZB/Oxsy28NVOvqHI1eHY4fyXVIhNQvfiwy9XCYrL3ydkOfSO6WiSTGFoI2DTZec9uKSXf5vpRrBrA7Eg+KJg3Sh5fHLjp+bDS66SlExoGr3tg2nuIsMqeLEBorPrGd6i8hakgFC1tAokf8P4INmsw1ZPyEbq0xz3jJVwdGSSv9vLG9dxtWlaKLu3MpX0+sKN+i3exrUNR489duUr3578OdHmRk3G1jjWGPahAXVw9OgeqdPgL18uDL8enx/LK3N+OMv2teoyqcLhrs9ZAMY2aizrgONUq5Pxe3A2Fp6vrebKg8aZhW76gDlHTxrNIKZk0xe0Bm4Bv6iKJ22JN+UTLZ7mmxISBkYcUnKV1CjsSgfBJDKKLMvxN/sMpm0GviZH8e3e+UPF9GgBgDG4xUV9K1scGueKOlENq72CNI7GZ6Xi8WeyeaIz0kL5FUjb+0WfpHtiSvTm5Ee1zcwiATh7Pc+GtWGu6Si/wwJAunofl/PmX96vIq9KX307l8F+BSWPhwCY07B4eUoSeFE/PGcH+UgCXtHL+ump3v X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(13230025)(4636009)(39860400002)(346002)(376002)(396003)(136003)(451199018)(46966006)(36840700001)(40470700004)(30864003)(84970400001)(2906002)(31696002)(86362001)(40460700003)(81166007)(47076005)(26005)(2616005)(8936002)(336012)(5660300002)(235185007)(186003)(82310400005)(36756003)(6486002)(966005)(6666004)(478600001)(53546011)(33964004)(6506007)(31686004)(36860700001)(83380400001)(6512007)(41300700001)(316002)(356005)(4326008)(40480700001)(8676002)(6916009)(82740400003)(70206006)(70586007)(54906003)(43740500002)(579004)(559001);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Feb 2023 13:26:39.3634 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 052610a8-6f2e-4ee6-f128-08db0aa146a6 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM7EUR03FT016.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB7487 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00,BODY_8BITS,DKIM_SIGNED,DKIM_VALID,FORGED_SPF_HELO,GIT_PATCH_0,KAM_DMARC_NONE,KAM_LOTSOFHASH,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE,TXREP,UNPARSEABLE_RELAY 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: --------------RE6Gven9LsBwQ60Lckeh0C0w Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi all, Changes since v2: a) A rebase onto latest trunk and onto Andre's: https://gcc.gnu.org/pipermail/gcc-patches/2023-January/610520.html patch series. b) Added a new function arm_mve_check_df_for_implic_predic that checks the bb insns backwards recursively, to find if  current insn has been affected by implicit predication of an unpredicated insn. c) Used the new function to simplify some of the checking logic on all insns that don't need to get transformed for lol-ification. Also, as I said in the 1/2 email: I recognise that we are now in Stage 4 and, even though these have been on the list since Stage 1, the 2/2 patch does contain mid-end changes, so do let me know if there's a chance to get this into GCC13 or if we should retarget this for GCC14. Thank you, Stam On 11/01/2023 14:25, Stam Markianos-Wright via Gcc-patches wrote: > ----- Respin of the below patch ----- > > In this 2/2 patch, from v1 to v2 I have: > > * Removed the modification the interface of the doloop_end target-insn > (so I no longer need to touch any other target backends) > > > * Added more modes to `arm_get_required_vpr_reg` to make it flexible > between searching: all operands/only input arguments/only outputs. Also > added helpers: > `arm_get_required_vpr_reg_ret_val` > `arm_get_required_vpr_reg_param` > > * Added support for the use of other VPR predicate values within > a dlstp/letp loop, as long as they don't originate from the vctp-generated > VPR value. Also changed `arm_mve_get_loop_unique_vctp` to the simpler > `arm_mve_get_loop_vctp` since now we can support other VCTP insns > within the loop. > > * Added support for loops of the form: >      int num_of_iters = (num_of_elem + num_of_lanes - 1) / num_of_lanes >      for (i = 0; i < num_of_iters; i++) >        { >          p = vctp (num_of_elem) >          n -= num_of_lanes; >        } >    to be tranformed into dlstp/letp loops. > > * Changed the VCTP look-ahead for SIGN_EXTEND and SUBREG insns to > use df def/use chains instead of `next_nonnote_nondebug_insn_bb`. > > * Added support for using unpredicated (but predicable) insns > within the dlstp/letp loop. These need to meet some specific conditions, > because they _will_ become implicitly tail predicated by the dlstp/letp > transformation. > > * Added a df chain check to any other instructions to make sure that they > don't USE the VCTP-generated VPR value. > > * Added testing of all these various edge cases. > > > Original email with updated Changelog at the end: > > > > Hi all, > > This is the 2/2 patch that contains the functional changes needed > for MVE Tail Predicated Low Overhead Loops.  See my previous email > for a general introduction of MVE LOLs. > > This support is added through the already existing loop-doloop > mechanisms that are used for non-MVE dls/le looping. > > Changes are: > > 1) Relax the loop-doloop mechanism in the mid-end to allow for >    decrement numbers other that -1 and for `count` to be an >    rtx containing the number of elements to be processed, rather >    than an expression for calculating the number of iterations. > 2) Add a `allow_elementwise_doloop` target hook. This allows the >    target backend to manipulate the iteration count as it needs: >    in our case to change it from a pre-calculation of the number >    of iterations to the number of elements to be processed. > 3) The doloop_end target-insn now had an additional parameter: >    the `count` (note: this is before it gets modified to just be >    the number of elements), so that the decrement value is >    extracted from that parameter. > > And many things in the backend to implement the above optimisation: > > 4)  Appropriate changes to the define_expand of doloop_end and new >     patterns for dlstp and letp. > 5) `arm_attempt_dlstp_transform`: (called from the define_expand of >     doloop_end) this function checks for the loop's suitability for >     dlstp/letp transformation and then implements it, if possible. > 6) `arm_mve_get_loop_unique_vctp`: A function that loops through >     the loop contents and returns the vctp VPR-genereting operation >     within the loop, if it is unique and there is exclusively one >     vctp within the loop. > 7) A couple of utility functions: `arm_mve_get_vctp_lanes` to map >    from vctp unspecs to number of lanes, and `arm_get_required_vpr_reg` >    to check an insn to see if it requires the VPR or not. > > No regressions on arm-none-eabi with various targets and on > aarch64-none-elf. Thoughts on getting this into trunk? > > Thank you, > Stam Markianos-Wright > > gcc/ChangeLog: > >         * config/arm/arm-protos.h (arm_attempt_dlstp_transform): New. >         * config/arm/arm.cc (TARGET_ALLOW_ELEMENTWISE_DOLOOP): New. >         (arm_mve_get_vctp_lanes): New. >         (arm_get_required_vpr_reg): New. >         (arm_get_required_vpr_reg_ret_val): New. >         (arm_get_required_vpr_reg_param): New. >         (arm_mve_check_df_for_implic_predic): New. >         (arm_mve_get_loop_vctp): New. >         (arm_attempt_dlstp_transform): New. >         (arm_allow_elementwise_doloop): New. >         * config/arm/iterators.md (DLSTP): New. >         (mode1): Add DLSTP mappings. >         * config/arm/mve.md (*predicated_doloop_end_internal): New. >         (dlstp_insn): New. >         * config/arm/thumb2.md (doloop_end): Update for MVE LOLs. >         * config/arm/unspecs.md: New unspecs. >         * tm.texi: Document new hook. >         * tm.texi.in: Likewise. >         * loop-doloop.cc (doloop_condition_get): Relax conditions. >         (doloop_optimize): Add support for elementwise LoLs. >         * target.def (allow_elementwise_doloop): New hook. >         * targhooks.cc (default_allow_elementwise_doloop): New. >         * targhooks.h (default_allow_elementwise_doloop): New. > > gcc/testsuite/ChangeLog: > >         * gcc.target/arm/lob.h: Update framework. >         * gcc.target/arm/lob1.c: Likewise. >         * gcc.target/arm/lob6.c: Likewise. >         * gcc.target/arm/dlstp-int16x8.c: New test. >         * gcc.target/arm/dlstp-int32x4.c: New test. >         * gcc.target/arm/dlstp-int64x2.c: New test. >         * gcc.target/arm/dlstp-int8x16.c: New test. >         * gcc.target/arm/dlstp-invalid-asm.c: New test. >         * gcc.target/arm/dlstp-compile-asm.c: Add testcases. Inline copy of v3 patch: diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index aea472bfbb9deaa8e925756963c7c5cc6fdc0d09..10ffc713f7744252655e9d78510df5cef98c2355 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -65,7 +65,7 @@ extern void arm_decompose_di_binop (rtx, rtx, rtx *, rtx *, rtx *, rtx *);  extern bool arm_q_bit_access (void);  extern bool arm_ge_bits_access (void);  extern bool arm_target_insn_ok_for_lob (rtx); - +extern rtx arm_attempt_dlstp_transform (rtx);  #ifdef RTX_CODE  enum reg_class  arm_mode_base_reg_class (machine_mode); diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 1d285051fa6d8e6c05813801eb678e58da25714d..d4ac04e095f01f42c1c4611074c3499a01242716 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -472,6 +472,9 @@ static const struct attribute_spec arm_attribute_table[] =  #undef TARGET_SCHED_REORDER  #define TARGET_SCHED_REORDER arm_sched_reorder +#undef TARGET_ALLOW_ELEMENTWISE_DOLOOP_P +#define TARGET_ALLOW_ELEMENTWISE_DOLOOP_P arm_allow_elementwise_doloop_p +  #undef TARGET_REGISTER_MOVE_COST  #define TARGET_REGISTER_MOVE_COST arm_register_move_cost @@ -33067,7 +33070,7 @@ arm_block_set_vect (rtx dstbase,      return arm_block_set_unaligned_vect (dstbase, length, value, align);  } -/* Expand string store operation.  Firstly we try to do that by using +/* Expand string store operation.  First we try to do that by using     vectorization instructions, then try with ARM unaligned access and     double-word store if profitable.  OPERANDS[0] is the destination,     OPERANDS[1] is the number of bytes, operands[2] is the value to @@ -34395,8 +34398,563 @@ arm_target_insn_ok_for_lob (rtx insn)    return single_succ_p (bb)      && single_pred_p (bb) -    && single_succ_edge (bb)->dest == single_pred_edge (bb)->src -    && contains_no_active_insn_p (bb); +    && single_succ_edge (bb)->dest == single_pred_edge (bb)->src; +} + +static int +arm_mve_get_vctp_lanes (rtx x) +{ +  if (GET_CODE (x) == SET && GET_CODE (XEXP (x, 1)) == UNSPEC +      && XINT (XEXP (x, 1), 1) == VCTP) +    { +      switch (GET_MODE (XEXP (x, 1))) +    { +      case V16BImode: +        return 16; +      case V8BImode: +        return 8; +      case V4BImode: +        return 4; +      case V2QImode: +        return 2; +      default: +        break; +    } +    } +  return 0; +} + +/* Check if an insn requires the use of the VPR_REG, if it does, return the +   sub-rtx of the VPR_REG.  The `type` argument controls whether +   this function should: +   * For type == 0, check all operands, including the OUT operands, +     and return the first occurance of the VPR_REG. +   * For type == 1, only check the input operands. +   * For type == 2, only check the output operands. +   (INOUT operands are considered both as input and output operands) +*/ +static rtx +arm_get_required_vpr_reg (rtx_insn *insn, unsigned int type = 0) +{ +  gcc_assert (type < 3); +  if (!NONJUMP_INSN_P (insn)) +    return NULL_RTX; + +  bool requires_vpr; +  extract_constrain_insn (insn); +  int n_operands = recog_data.n_operands; +  if (recog_data.n_alternatives == 0) +    return NULL_RTX; + +  /* Fill in recog_op_alt with information about the constraints of +     this insn.  */ +  preprocess_constraints (insn); + +  for (int op = 0; op < n_operands; op++) +    { +      requires_vpr = true; +      if (type == 1 && (recog_data.operand_type[op] == OP_OUT +            || recog_data.operand_type[op] == OP_INOUT)) +    continue; +      else if (type == 2 && (recog_data.operand_type[op] == OP_IN +                 || recog_data.operand_type[op] == OP_INOUT)) +    continue; + +      /* Iterate through alternatives of operand "op" in recog_op_alt and +     identify if the operand is required to be the VPR.  */ +      for (int alt = 0; alt < recog_data.n_alternatives; alt++) +    { +      const operand_alternative *op_alt +          = &recog_op_alt[alt * n_operands]; +      /* Fetch the reg_class for each entry and check it against the +       * VPR_REG reg_class.  */ +      if (alternative_class (op_alt, op) != VPR_REG) +        requires_vpr = false; +    } +      /* If all alternatives of the insn require the VPR reg for this operand, +     it means that either this is VPR-generating instruction, like a vctp, +     vcmp, etc., or it is a VPT-predicated insruction.  Return the subrtx +     of the VPR reg operand.  */ +      if (requires_vpr) +    return recog_data.operand[op]; +    } +  return NULL_RTX; +} + +static rtx +ALWAYS_INLINE ATTRIBUTE_UNUSED +arm_get_required_vpr_reg_ret_val (rtx_insn *insn) +{ +  return arm_get_required_vpr_reg (insn, 2); +} + +static rtx +ALWAYS_INLINE +arm_get_required_vpr_reg_param (rtx_insn *insn) +{ +  return arm_get_required_vpr_reg (insn, 1); +} + +/* Scan the basic block of a loop body for a vctp instruction. If there is +   at least vctp instruction, return the first rtx_insn *.  */ + +static rtx_insn * +arm_mve_get_loop_vctp (basic_block bb) +{ +  rtx_insn *insn = BB_HEAD (bb); + +  /* Now scan through all the instruction patterns and +     pick out any MVE instructions.  */ +  FOR_BB_INSNS (bb, insn) +    if (INSN_P (insn)) +      if (arm_mve_get_vctp_lanes (PATTERN (insn)) != 0) +    return insn; +  return NULL; +} + +/* Recursively scan through the DF chain backwards within the basic block and +   determine if any of the USEs of the original insn (or the USEs of the insns +   where thy were DEF-ed, etc., recursively) were affected by implicit VPT +   predication of an MVE_VPT_UNPREDICATED_INSN_P in a dlstp/letp loop.  */ + +static bool +arm_mve_check_df_for_implic_predic (rtx_insn *insn, rtx_insn* loop_vctp, +                    rtx vctp_vpr_generated) +{ +  rtx insn_vpr_reg_operand = NULL_RTX; + +  /* Exit the recursion with a "true" when we find an unpredicated insn, or with +     a false if we find the dlstp/letp loop vctp or a correctly dlstp/letp +     predicated insn.  */ +  if (MVE_VPT_UNPREDICATED_INSN_P (insn) && insn != loop_vctp) +    return true; +  else if (insn == loop_vctp +       || ((insn_vpr_reg_operand = arm_get_required_vpr_reg_param (insn)) +           && rtx_equal_p (vctp_vpr_generated, insn_vpr_reg_operand))) +    return false; + +  /* For each USE in the instruction we are called for, we will loop backwards +     up the BB to try and find if it was DEF-ed within the dlstp/letp loop. +     If we do find such a DEF, then recurse on it's INSN.  The intention here +     is find if any of the inputs to the current instruction were affected by +     implicit predication by being MVE_VPT_UNPREDICATED_INSN_Ps in a dlstp/letp +     loop.  */ +  df_ref insn_uses = NULL; +  FOR_EACH_INSN_USE (insn_uses, insn) +  { +    /* Starting from the current insn, scan backwards through the insn chain +       until BB_HEAD: "for each insn in the BB prior to the current one".  */ +    rtx_insn *prev_insn = NULL; +    for (prev_insn = insn; +     prev_insn && prev_insn != PREV_INSN (BB_HEAD (BLOCK_FOR_INSN (insn))); +     prev_insn = PREV_INSN (prev_insn)) +      { +    /* Look at all the DEFs of that previous insn: if one of them is on +       the same REG as our current insn, then recurse in order to check +       that insn's USEs.  If any of these insns return true as +       MVE_VPT_UNPREDICATED_INSN_Ps, then the whole chain is affected +       by the change in behaviour from being placed in dlstp/letp loop.  */ +    df_ref prev_insn_defs = NULL; +    FOR_EACH_INSN_DEF (prev_insn_defs, prev_insn) +    { +      if (DF_REF_REGNO (insn_uses) == DF_REF_REGNO (prev_insn_defs) +          && insn != prev_insn +          && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_insn) +          && arm_mve_check_df_for_implic_predic (prev_insn, +                             loop_vctp, +                             vctp_vpr_generated)) +        return true; +    } +      } +  } +  return false; +} + +/* Attempt to transform the loop contents of loop basic block from VPT +   predicated insns into unpredicated insns for a dlstp/letp loop.  */ + +rtx +arm_attempt_dlstp_transform (rtx label) +{ +  int decrementnum; +  basic_block body = BLOCK_FOR_INSN (label)->prev_bb; + +  /* Ensure that the bb is within a loop that has all required metadata.  */ +  if (!body->loop_father || !body->loop_father->header +      || !body->loop_father->simple_loop_desc) +    return GEN_INT (1); +  basic_block pre_loop_bb1 = loop_preheader_edge (body->loop_father)->src; +  basic_block pre_loop_bb2 = pre_loop_bb1->prev_bb; +  rtx count = simple_loop_desc (body->loop_father)->niter_expr; +  rtx shift_expr = NULL_RTX; +  rtx initial_compare = NULL_RTX; + +  /* Doloop can only be done "elementwise" with predicated dlstp/letp if it +     contains a VCTP on the number of elements processed by the loop. +     Find the VCTP predicate generation inside the loop body BB. */ +  rtx_insn *vctp_insn = arm_mve_get_loop_vctp (body); +  if (!vctp_insn) +    return GEN_INT (1); + +  /* Additionally, the iteration counter must only get decremented by the +     number of MVE lanes (as per the data type). +     There are only two types of loops that can be turned into dlstp/letp loops: +     A) Loops of the form: +     while (num_of_elem > 0) +       { +         p = vctp (num_of_elem) +         n -= num_of_lanes; +       } +     B) Loops of the form: +     int num_of_iters = (num_of_elem + num_of_lanes - 1) / num_of_lanes +     for (i = 0; i < num_of_iters; i++) +       { +         p = vctp (num_of_elem) +         n -= num_of_lanes; +       } + +     These can be verified through the "count" variable in the middle-end +     (a.k.a. get_simple_loop_desc (loop)->desc->niter_expr).  This is the +     expression used to calculate the number of iterations that the loop would +     execute for a standard dls/le loop. + +     For dlstp/letp we only support cases where this is a power of 2, so from +     "count" we want to extract something like: +    ( [l/a] shiftrt: (x) (const_int y)) +     For loops of form A), "count" is already a shiftrt expression. +     For loops of form B), "count" gets given as: +    (plus: (not (i)) (num_of_iters)) +     with setup happening in a previous basic block.  Here we need to verify: +       * That i is _always_ initialized to (const_int 0) +       * That num_of_iters is a shiftrt expression. +  */ +  if (GET_CODE (count) == LSHIFTRT +      || GET_CODE (count) == ASHIFTRT) +    { +      shift_expr = count; +      /* In this situation where we are looping on a decreasing number of +     elements, a dlstp/letp loop can only work if the looping ends when the +     element counter reaches zero and not some other value (e.g. n > 0 +     works, not n > 1), or we can incorrectly end up running one additional +     iteration.  To by-pass any hoisting that the compiler may have done +     with the first arg to `count`, we can instead look at the bb before +     the loop preheader: this should end with a cmp+jump pair, where the +     cmp needs to be: (const_int 0).  */ +      if (!pre_loop_bb2 || !BB_END (pre_loop_bb2) +      || !prev_nonnote_nondebug_insn_bb (BB_END (pre_loop_bb2)) +      || !INSN_P (prev_nonnote_nondebug_insn_bb (BB_END (pre_loop_bb2)))) +    return GEN_INT (1); +      else +    initial_compare +        = PATTERN (prev_nonnote_nondebug_insn_bb (BB_END (pre_loop_bb2))); + +      if (!(initial_compare && GET_CODE (initial_compare) == SET +        && cc_register (XEXP (initial_compare, 0), VOIDmode) +        && GET_CODE (XEXP (initial_compare, 1)) == COMPARE +        && CONST_INT_P (XEXP (XEXP (initial_compare, 1), 1)) +        && INTVAL (XEXP (XEXP (initial_compare, 1), 1)) == 0)) +    return GEN_INT (1); +    } +  else if (GET_CODE (count) == PLUS) +    { +      if (!(GET_CODE (XEXP (count, 0)) == NOT +        && REG_P (XEXP (XEXP (count, 0), 0)) && REG_P (XEXP (count, 1)))) +    return GEN_INT (1); +      else +    { +      /* Verify the first argument to the plus.  */ +      rtx loop_counter = XEXP (XEXP (count, 0), 0); +      df_ref loop_counter_init_def = NULL; +      loop_counter_init_def +          = df_bb_regno_last_def_find (pre_loop_bb1, REGNO (loop_counter)); +      rtx loop_counter_init +          = PATTERN (DF_REF_INSN (loop_counter_init_def)); +      if (!(loop_counter_init_def && GET_CODE (loop_counter_init) == SET +        && CONST_INT_P (XEXP (loop_counter_init, 1)) +        && INTVAL (XEXP (loop_counter_init, 1)) == 0)) +        return GEN_INT (1); + +      /* Verify the second argument to the plus.  */ +      rtx count_max = XEXP (count, 1); +      df_ref counter_max_def = NULL; +      counter_max_def = DF_REG_DEF_CHAIN (REGNO (count_max)); +      if (counter_max_def +          && (GET_CODE (XEXP (single_set (DF_REF_INSN (counter_max_def)), +                  1)) +              == LSHIFTRT +          || GET_CODE ( +             XEXP (single_set (DF_REF_INSN (counter_max_def)), 1)) +             == ASHIFTRT)) +        { +          shift_expr +          = XEXP (single_set (DF_REF_INSN (counter_max_def)), 1); +        } +      else +        return GEN_INT (1); +    } +    } +  else +    return GEN_INT (1); + +  /* Check the validity of the shift: the second operand needs to be a +     constant.  */ +  if (!CONSTANT_P (XEXP (shift_expr, 1))) +    return GEN_INT (1); +  /* Extract the loop decrement from the [A/L]SHIFTR 2nd operand of count.  */ +  decrementnum = (1 << (INTVAL (XEXP (shift_expr, 1)))); +  /* Ensure it matches the number of lanes of the vctp instruction.  */ +  if (decrementnum != arm_mve_get_vctp_lanes (PATTERN (vctp_insn))) +    return GEN_INT (1); + +  rtx_insn *insn = 0; +  rtx_insn *cur_insn = 0; +  rtx_insn *seq; +  rtx vctp_vpr_generated = NULL_RTX; + +  /* Scan through the insns in the loop bb and emit the transformed bb +     insns to a sequence.  */ +  start_sequence (); +  FOR_BB_INSNS (body, insn) +    { +      rtx insn_vpr_reg_operand = NULL_RTX; +      if (GET_CODE (insn) == CODE_LABEL || NOTE_INSN_BASIC_BLOCK_P (insn)) +    continue; +      else if (NOTE_P (insn)) +    emit_note ((enum insn_note) NOTE_KIND (insn)); +      else if (DEBUG_INSN_P (insn)) +    emit_debug_insn (PATTERN (insn)); +      else if (!INSN_P (insn)) +    { +      end_sequence (); +      return GEN_INT (1); +    } +      /* When we find the vctp instruction: This may be followed by +      a zero-extend insn to SImode.  If it is, then save the +      zero-extended REG into vctp_vpr_generated.  If there is no +      zero-extend, then store the raw output of the vctp. +      For any VPT-predicated instructions we need to ensure that +      the VPR they use is the same as the one given here and +      they often consume the output of a subreg of the SImode +      zero-extended VPR-reg.  As a result, comparing against the +      output of the zero-extend is more likely to succeed. +      This code also guarantees to us that the vctp comes before +      any instructions that use the VPR within the loop, for the +      dlstp/letp transform to succeed.  */ +      else if (insn == vctp_insn) +    { +      rtx_insn *next_use1 = NULL; +      df_ref use; +      for (use = DF_REG_USE_CHAIN ( +           DF_REF_REGNO (DF_INSN_INFO_DEFS (DF_INSN_INFO_GET (insn)))); +           use; use = DF_REF_NEXT_REG (use)) +        if (!next_use1 && NONDEBUG_INSN_P (DF_REF_INSN (use))) +          next_use1 = DF_REF_INSN (use); + +      if (GET_CODE (SET_SRC (single_set (next_use1))) == ZERO_EXTEND) +        { +          rtx_insn *next_use2 = NULL; +          for (use = DF_REG_USE_CHAIN (DF_REF_REGNO ( +               DF_INSN_INFO_DEFS (DF_INSN_INFO_GET (next_use1)))); +           use; use = DF_REF_NEXT_REG (use)) +        if (!next_use2 && NONDEBUG_INSN_P (DF_REF_INSN (use))) +          next_use2 = DF_REF_INSN (use); + +          if (GET_CODE (SET_SRC (single_set (next_use2))) == SUBREG) +        vctp_vpr_generated = XEXP (PATTERN (next_use2), 0); +        } + +      if (!vctp_vpr_generated) +        { +          end_sequence (); +          return GEN_INT (1); +        } +        /* Also emit a USE of the source register of the vctp. +         This holds the number of elements being processed +         by the loop.  This later gets stored into `count` +         for the middle-end to initialise the loop counter.  */ +      emit_use (XVECEXP (XEXP (PATTERN (insn), 1), 0, 0)); +      continue; +    } +       /* If the insn pattern requires the use of the VPR value from the +      vctp as an input parameter.  */ +      else if ((insn_vpr_reg_operand = arm_get_required_vpr_reg_param (insn)) +           && rtx_equal_p (vctp_vpr_generated, insn_vpr_reg_operand)) +    { +      gcc_assert (MVE_VPT_PREDICATED_INSN_P (insn)); +      int new_icode = get_attr_mve_unpredicated_insn (insn); +      extract_insn (insn); +      rtx arr[8]; +      int j = 0; + +      /* When transforming a VPT-predicated instruction +         into its unpredicated equivalent we need to drop +         the VPR operand and we may need to also drop a +         merge "vuninit" input operand, depending on the +         instruction pattern.  Here ensure that we have at +         most a two-operand difference between the two +         instrunctions.  */ +      int n_operands_diff +          = recog_data.n_operands - insn_data[new_icode].n_operands; +      gcc_assert (n_operands_diff > 0 && n_operands_diff <= 2); + +      /* Then, loop through the operands of the predicated +         instruction, and retain the ones that map to the +         unpredicated instruction.  */ +      for (int i = 0; i < recog_data.n_operands; i++) +        { +          /* Ignore the VPR and, if needed, the vuninit +         operand.  */ +          if (insn_vpr_reg_operand == recog_data.operand[i] +          || (n_operands_diff == 2 +              && !strcmp (recog_data.constraints[i], "0"))) +        continue; +          else +        { +          arr[j] = recog_data.operand[i]; +          j++; +        } +        } + +      /* Finally, emit the upredicated instruction.  */ +      switch (j) +        { +          case 1: +        emit_insn (GEN_FCN (new_icode) (arr[0])); +        break; +          case 2: +        emit_insn (GEN_FCN (new_icode) (arr[0], arr[1])); +        break; +          case 3: +        emit_insn (GEN_FCN (new_icode) (arr[0], arr[1], arr[2])); +        break; +          case 4: +        emit_insn (GEN_FCN (new_icode) (arr[0], arr[1], arr[2], +                        arr[3])); +        break; +          case 5: +        emit_insn (GEN_FCN (new_icode) (arr[0], arr[1], arr[2], arr[3], +                        arr[4])); +        break; +          case 6: +        emit_insn (GEN_FCN (new_icode) (arr[0], arr[1], arr[2], arr[3], +                        arr[4], arr[5])); +        break; +          case 7: +        emit_insn (GEN_FCN (new_icode) (arr[0], arr[1], arr[2], arr[3], +                        arr[4], arr[5], arr[6])); +        break; +          default: +        gcc_unreachable (); +        } +    } +      /* If the insn isn't VPT predicated on vctp_vpr_generated, we need to +     make sure that it is still valid within the dlstp/letp loop.  */ +      else +    { +      /* None of registers USE-d by the instruction need can be the VPR +         vctp_vpr_generated.  This blocks the optimisation if there any +         instructions that use the optimised-out VPR value in any way +         other than as a VPT block predicate.  */ +      df_ref insn_uses = NULL; +      FOR_EACH_INSN_USE (insn_uses, insn) +      { +        if (rtx_equal_p (vctp_vpr_generated, DF_REF_REG (insn_uses))) +          { +        end_sequence (); +        return GEN_INT (1); +          } +      } +      /* If within the loop we have an MVE vector instruction that is +         unpredicated, the dlstp/letp looping will add implicit +         predication to it.  This will result in a change in behaviour +         of the instruction, so we need to find out if any instructions +         that feed into the current instruction were implicitly +         predicated.  */ +      if (arm_mve_check_df_for_implic_predic (insn, vctp_insn, +                          vctp_vpr_generated)) +        { +          if (mve_memory_operand (SET_DEST (single_set (insn)), +                      GET_MODE (SET_DEST (single_set (insn))))) +        { +          end_sequence (); +          return GEN_INT (1); +        } + +         /* Next, if we have identified that the current DEF will be +        modified by such implicit predication, scan through all the +        insns that USE it and bail out if any one is outside the +        current basic block.  */ +          df_ref insn_def = NULL; +          insn_def = DF_INSN_INFO_DEFS (DF_INSN_INFO_GET (insn)); +          if (insn_def) +        { +          for (df_ref use = DF_REG_USE_CHAIN (DF_REF_REGNO (insn_def)); +               use; use = DF_REF_NEXT_REG (use)) +            { +              rtx_insn *next_use_insn = DF_REF_INSN (use); +              if (NONDEBUG_INSN_P (next_use_insn)) +            { +              rtx next_insn_set_dest +                  = SET_DEST (single_set (next_use_insn)); +              if (BLOCK_FOR_INSN (insn) +                  != BLOCK_FOR_INSN (next_use_insn)) +              { +                end_sequence (); +                return GEN_INT (1); +              } +            } +            } +        } +        } +      emit_insn (PATTERN (insn)); +    } +    } +  seq = get_insns (); +  end_sequence (); + +  /* Re-write the entire BB contents with the transformed +     sequence.  */ +  FOR_BB_INSNS_SAFE (body, insn, cur_insn) +    if (!(GET_CODE (insn) == CODE_LABEL || NOTE_INSN_BASIC_BLOCK_P (insn))) +      delete_insn (insn); +  for (insn = seq; NEXT_INSN (insn); insn = NEXT_INSN (insn)) +    if (NOTE_P (insn)) +      emit_note_after ((enum insn_note)NOTE_KIND (insn), BB_END (body)); +    else if (DEBUG_INSN_P (insn)) +      emit_debug_insn_after (PATTERN (insn), BB_END (body)); +    else +      emit_insn_after (PATTERN (insn), BB_END (body)); + +  emit_jump_insn_after (PATTERN (insn), BB_END (body)); +  return GEN_INT (decrementnum); +} + +/* Target hook to the number of elements to be processed by a dlstp/letp loop +   into `count` to intialise the counter register.  The number of elements was +   previously extracted from the vctp insn and placed into a USE rtx. +   We only check that the doloop_end pattern successfully decrements by a +   number other than -1 for a valid dlstp/letp loop.  No other checking is +   needed as that was done previously.  */ + +rtx +arm_allow_elementwise_doloop_p (rtx count, rtx label, rtx doloop) +{ +  if (doloop +      && INTVAL (XEXP (SET_SRC (XVECEXP (PATTERN (doloop), 0, 1)), 1)) != -1) +    { +      basic_block body = BLOCK_FOR_INSN (label)->prev_bb; +      rtx_insn* insn; +      FOR_BB_INSNS (body, insn) +    { +      if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE) +        { +          rtx num_elem_reg = copy_rtx (XEXP (PATTERN (insn), 0)); +          delete_insn (insn); +          return num_elem_reg; +        } +    } +    } +  return count;  }  #if CHECKING_P diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 39895ad62aa3afd55d3cbc92c55b45bc56710bcb..95024fe01612c0dfcd3a7dc97d3f1eda1fccc063 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -1464,6 +1464,10 @@                 (VADCIQ_M_S "s") (SQRSHRL_64 "64") (SQRSHRL_48 "48")                 (UQRSHLL_64 "64") (UQRSHLL_48 "48") (VSHLCQ_M_S "s")                 (VSHLCQ_M_U "u")]) + +(define_int_attr mode1 [(DLSTP8 "8") (DLSTP16 "16") (DLSTP32 "32") +            (DLSTP64 "64")]) +  ;; Both kinds of return insn.  (define_code_iterator RETURNS [return simple_return])  (define_code_attr return_str [(return "") (simple_return "simple_")]) @@ -1769,6 +1773,8 @@  (define_int_iterator UQRSHLLQ [UQRSHLL_64 UQRSHLL_48])  (define_int_iterator SQRSHRLQ [SQRSHRL_64 SQRSHRL_48])  (define_int_iterator VSHLCQ_M [VSHLCQ_M_S VSHLCQ_M_U]) +(define_int_iterator DLSTP [DLSTP8 DLSTP16 DLSTP32 +                   DLSTP64])  ;; Define iterators for VCMLA operations  (define_int_iterator VCMLA_OP [UNSPEC_VCMLA diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 854b8ab935f82ad0eb99e6af9852ce8154cf9d9d..8dd3567759e5d794b1039c114ccb13765a131304 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -11100,3 +11100,38 @@      }    DONE;  }) + +;; Originally expanded by 'predicated_doloop_end'. +(define_insn "*predicated_doloop_end_internal" +  [(set (pc) +    (if_then_else +       (ge (plus:SI (reg:SI LR_REGNUM) +            (match_operand:SI 0 "const_int_operand" "")) +        (const_int 0)) +     (label_ref (match_operand 1 "" "")) +     (pc))) +   (set (reg:SI LR_REGNUM) +    (plus:SI (reg:SI LR_REGNUM) (match_dup 0))) +   (clobber (reg:CC CC_REGNUM))] +  "TARGET_32BIT && TARGET_HAVE_LOB && TARGET_HAVE_MVE && TARGET_THUMB2" +  { +    if (get_attr_length (insn) == 4) +      return "letp\t%|lr, %l1"; +    else +      return "subs\t%|lr, #%0;bgt\t%l1"; +  } +  [(set (attr "length") +    (if_then_else +       (ltu (minus (pc) (match_dup 1)) (const_int 1024)) +        (const_int 4) +        (const_int 6))) +   (set_attr "type" "branch")]) + +(define_insn "dlstp_insn" +  [ +    (set (reg:SI LR_REGNUM) +     (unspec:SI [(match_operand:SI 0 "s_register_operand" "r")] +      DLSTP)) +  ] +  "TARGET_32BIT && TARGET_HAVE_LOB && TARGET_HAVE_MVE && TARGET_THUMB2" +  "dlstp.\t%|lr, %0") \ No newline at end of file diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index e1e013befa7a67ddbf517bf22797bdaeeb96b94f..3beb4d4b48cd47c8e946fba53c49975ff8271ac1 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -1613,7 +1613,7 @@     (use (match_operand 1 "" ""))]     ; label    "TARGET_32BIT"    " - { +{     /* Currently SMS relies on the do-loop pattern to recognize loops        where (1) the control part consists of all insns defining and/or        using a certain 'count' register and (2) the loop count can be @@ -1623,41 +1623,67 @@        Also used to implement the low over head loops feature, which is part of        the Armv8.1-M Mainline Low Overhead Branch (LOB) extension.  */ -   if (optimize > 0 && (flag_modulo_sched || TARGET_HAVE_LOB)) -   { -     rtx s0; -     rtx bcomp; -     rtx loc_ref; -     rtx cc_reg; -     rtx insn; -     rtx cmp; - -     if (GET_MODE (operands[0]) != SImode) -       FAIL; - -     s0 = operands [0]; - -     /* Low over head loop instructions require the first operand to be LR.  */ -     if (TARGET_HAVE_LOB && arm_target_insn_ok_for_lob (operands [1])) -       s0 = gen_rtx_REG (SImode, LR_REGNUM); - -     if (TARGET_THUMB2) -       insn = emit_insn (gen_thumb2_addsi3_compare0 (s0, s0, GEN_INT (-1))); -     else -       insn = emit_insn (gen_addsi3_compare0 (s0, s0, GEN_INT (-1))); - -     cmp = XVECEXP (PATTERN (insn), 0, 0); -     cc_reg = SET_DEST (cmp); -     bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx); -     loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]); -     emit_jump_insn (gen_rtx_SET (pc_rtx, -                                  gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, -                                                        loc_ref, pc_rtx))); -     DONE; -   } - else -   FAIL; - }") +  if (optimize > 0 && (flag_modulo_sched || TARGET_HAVE_LOB)) +    { +      rtx s0; +      rtx bcomp; +      rtx loc_ref; +      rtx cc_reg; +      rtx insn; +      rtx cmp; +      rtx decrement_num; + +      if (GET_MODE (operands[0]) != SImode) +    FAIL; + +      s0 = operands[0]; + +       if (TARGET_HAVE_LOB && arm_target_insn_ok_for_lob (operands[1])) +    { +      s0 = gen_rtx_REG (SImode, LR_REGNUM); + +      /* If we have a compatibe MVE target, try and analyse the loop +         contents to determine if we can use predicated dlstp/letp +         looping.  */ +      if (TARGET_HAVE_MVE && TARGET_THUMB2 +          && (decrement_num = arm_attempt_dlstp_transform (operands[1])) +          && (INTVAL (decrement_num) != 1)) +        { +          insn = emit_insn +              (gen_thumb2_addsi3_compare0 +              (s0, s0, GEN_INT ((-1) * (INTVAL (decrement_num))))); +          cmp = XVECEXP (PATTERN (insn), 0, 0); +          cc_reg = SET_DEST (cmp); +          bcomp = gen_rtx_GE (VOIDmode, cc_reg, const0_rtx); +          loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[1]); +          emit_jump_insn (gen_rtx_SET (pc_rtx, +                       gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, +                                 loc_ref, pc_rtx))); +          DONE; +        } + +      /* Otherwise, try standard decrement-by-one dls/le looping.  */ +      if (TARGET_THUMB2) +        insn = emit_insn (gen_thumb2_addsi3_compare0 (s0, s0, +                              GEN_INT (-1))); +      else +        insn = emit_insn (gen_addsi3_compare0 (s0, s0, GEN_INT (-1))); + +      cmp = XVECEXP (PATTERN (insn), 0, 0); +      cc_reg = SET_DEST (cmp); +      bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx); +      loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[1]); +      emit_jump_insn (gen_rtx_SET (pc_rtx, +                       gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, +                                 loc_ref, pc_rtx))); +      DONE; +    } +      else +    FAIL; +    } +  else +    FAIL; +}")  (define_insn "*clear_apsr"    [(unspec_volatile:SI [(const_int 0)] VUNSPEC_CLRM_APSR) @@ -1755,7 +1781,37 @@    {      if (REGNO (operands[0]) == LR_REGNUM)        { -    emit_insn (gen_dls_insn (operands[0])); +    /* Pick out the number by which we are decrementing the loop counter +       in every iteration.  If it's > 1, then use dlstp.  */ +    int const_int_dec_num +         = abs (INTVAL (XEXP (XEXP (XVECEXP (PATTERN (operands[1]), 0, 1), +                  1), +                1))); +    switch (const_int_dec_num) +      { +        case 16: +          emit_insn (gen_dlstp8_insn (operands[0])); +          break; + +        case 8: +          emit_insn (gen_dlstp16_insn (operands[0])); +          break; + +        case 4: +          emit_insn (gen_dlstp32_insn (operands[0])); +          break; + +        case 2: +          emit_insn (gen_dlstp64_insn (operands[0])); +          break; + +        case 1: +          emit_insn (gen_dls_insn (operands[0])); +          break; + +        default: +          gcc_unreachable (); +      }      DONE;        }      else diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 84384ee798de363b874c41a16dc5daae34eccb94..e533c60215a49fe0aabfa8b5fb6d988faf3c4f51 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -581,6 +581,10 @@    VADDLVQ_U    VCTP    VCTP_M +  DLSTP8 +  DLSTP16 +  DLSTP32 +  DLSTP64    VPNOT    VCREATEQ_F    VCVTQ_N_TO_F_S diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c6c891972d1e58cd163b259ba96a599d62326865..4e3fcb1a845ed176386be41b3ace9f067fef9361 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11796,6 +11796,14 @@ loops, and will help ivopts to make some decisions.  The default version of this hook returns false.  @end deftypefn +@deftypefn {Target Hook} rtx TARGET_ALLOW_ELEMENTWISE_DOLOOP_P (rtx @var{count}, rtx @var{label}, rtx @var{doloop}) +This target hook allows the target to support loop-doloop optimisations +where the value that gets put into the loop counter register is not a +pre-calculation of the number of iteration of the loop.  For instance, +the value used can be the number of elements that the loop will process. +The default version of this hook returns the same rtx it was given. +@end deftypefn +  @deftypevr {Target Hook} bool TARGET_HAVE_COUNT_REG_DECR_P  Return true if the target supports hardware count register for decrement  and branch. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 613b2534149415f442163d599503efaf423b673b..f3e74dfd553c2b5a5857668f6835e762ce2c2616 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7732,6 +7732,8 @@ to by @var{ce_info}.  @hook TARGET_PREDICT_DOLOOP_P +@hook TARGET_ALLOW_ELEMENTWISE_DOLOOP_P +  @hook TARGET_HAVE_COUNT_REG_DECR_P  @hook TARGET_DOLOOP_COST_FOR_GENERIC diff --git a/gcc/loop-doloop.cc b/gcc/loop-doloop.cc index 4feb0a25ab9331b7124df900f73c9fc6fb3eb10b..38024e223439cac1ca00c0fe2af87d7628c8a815 100644 --- a/gcc/loop-doloop.cc +++ b/gcc/loop-doloop.cc @@ -85,29 +85,29 @@ doloop_condition_get (rtx_insn *doloop_pat)       forms:       1)  (parallel [(set (pc) (if_then_else (condition) -                              (label_ref (label)) -                            (pc))) -                 (set (reg) (plus (reg) (const_int -1))) -                 (additional clobbers and uses)]) +                        (label_ref (label)) +                        (pc))) +             (set (reg) (plus (reg) (const_int -n))) +             (additional clobbers and uses)])       The branch must be the first entry of the parallel (also required       by jump.cc), and the second entry of the parallel must be a set of       the loop counter register.  Some targets (IA-64) wrap the set of       the loop counter in an if_then_else too. -     2)  (set (reg) (plus (reg) (const_int -1)) -         (set (pc) (if_then_else (reg != 0) -                             (label_ref (label)) -                     (pc))). +     2)  (set (reg) (plus (reg) (const_int -n)) +     (set (pc) (if_then_else (reg != 0) +                 (label_ref (label)) +                 (pc))).       Some targets (ARM) do the comparison before the branch, as in the       following form: -     3) (parallel [(set (cc) (compare ((plus (reg) (const_int -1), 0))) -                   (set (reg) (plus (reg) (const_int -1)))]) -        (set (pc) (if_then_else (cc == NE) -                                (label_ref (label)) -                                (pc))) */ +     3) (parallel [(set (cc) (compare ((plus (reg) (const_int -n), 0))) +           (set (reg) (plus (reg) (const_int -n)))]) +    (set (pc) (if_then_else (cc == NE) +                (label_ref (label)) +                (pc))) */    pattern = PATTERN (doloop_pat); @@ -143,7 +143,7 @@ doloop_condition_get (rtx_insn *doloop_pat)            || GET_CODE (cmp_arg1) != PLUS)          return 0;        reg_orig = XEXP (cmp_arg1, 0); -      if (XEXP (cmp_arg1, 1) != GEN_INT (-1) +      if (!CONST_INT_P (XEXP (cmp_arg1, 1))            || !REG_P (reg_orig))          return 0;        cc_reg = SET_DEST (cmp_orig); @@ -156,7 +156,8 @@ doloop_condition_get (rtx_insn *doloop_pat)      {        /* We expect the condition to be of the form (reg != 0)  */        cond = XEXP (SET_SRC (cmp), 0); -      if (GET_CODE (cond) != NE || XEXP (cond, 1) != const0_rtx) +      if ((GET_CODE (cond) != NE && GET_CODE (cond) != GE) +          || XEXP (cond, 1) != const0_rtx)          return 0;      }      } @@ -173,14 +174,14 @@ doloop_condition_get (rtx_insn *doloop_pat)    if (! REG_P (reg))      return 0; -  /* Check if something = (plus (reg) (const_int -1)). +  /* Check if something = (plus (reg) (const_int -n)).       On IA-64, this decrement is wrapped in an if_then_else.  */    inc_src = SET_SRC (inc);    if (GET_CODE (inc_src) == IF_THEN_ELSE)      inc_src = XEXP (inc_src, 1);    if (GET_CODE (inc_src) != PLUS        || XEXP (inc_src, 0) != reg -      || XEXP (inc_src, 1) != constm1_rtx) +      || !CONST_INT_P (XEXP (inc_src, 1)))      return 0;    /* Check for (set (pc) (if_then_else (condition) @@ -211,42 +212,49 @@ doloop_condition_get (rtx_insn *doloop_pat)        || (GET_CODE (XEXP (condition, 0)) == PLUS        && XEXP (XEXP (condition, 0), 0) == reg))     { -     if (GET_CODE (pattern) != PARALLEL)       /*  For the second form we expect: -         (set (reg) (plus (reg) (const_int -1)) -         (set (pc) (if_then_else (reg != 0) -                                 (label_ref (label)) -                                 (pc))). +     (set (reg) (plus (reg) (const_int -n)) +     (set (pc) (if_then_else (reg != 0) +                 (label_ref (label)) +                 (pc))). -         is equivalent to the following: +     If n == 1, that is equivalent to the following: -         (parallel [(set (pc) (if_then_else (reg != 1) -                                            (label_ref (label)) -                                            (pc))) -                     (set (reg) (plus (reg) (const_int -1))) -                     (additional clobbers and uses)]) +     (parallel [(set (pc) (if_then_else (reg != 1) +                        (label_ref (label)) +                        (pc))) +             (set (reg) (plus (reg) (const_int -1))) +             (additional clobbers and uses)]) -        For the third form we expect: +    For the third form we expect: -        (parallel [(set (cc) (compare ((plus (reg) (const_int -1)), 0)) -                   (set (reg) (plus (reg) (const_int -1)))]) -        (set (pc) (if_then_else (cc == NE) -                                (label_ref (label)) -                                (pc))) +    (parallel [(set (cc) (compare ((plus (reg) (const_int -n)), 0)) +           (set (reg) (plus (reg) (const_int -n)))]) +    (set (pc) (if_then_else (cc == NE) +                (label_ref (label)) +                (pc))) -        which is equivalent to the following: +    Which also for n == 1 is equivalent to the following: -        (parallel [(set (cc) (compare (reg,  1)) -                   (set (reg) (plus (reg) (const_int -1))) -                   (set (pc) (if_then_else (NE == cc) -                                           (label_ref (label)) -                                           (pc))))]) +    (parallel [(set (cc) (compare (reg,  1)) +           (set (reg) (plus (reg) (const_int -1))) +           (set (pc) (if_then_else (NE == cc) +                       (label_ref (label)) +                       (pc))))]) -        So we return the second form instead for the two cases. +    So we return the second form instead for the two cases. +    For the "elementwise" form where the decrement number isn't -1, +    the final value may be exceeded, so use GE instead of NE.       */ -        condition = gen_rtx_fmt_ee (NE, VOIDmode, inc_src, const1_rtx); +     if (GET_CODE (pattern) != PARALLEL) +       { +    if (INTVAL (XEXP (inc_src, 1)) != -1) +      condition = gen_rtx_fmt_ee (GE, VOIDmode, inc_src, const0_rtx); +    else +      condition = gen_rtx_fmt_ee (NE, VOIDmode, inc_src, const1_rtx);; +       }      return condition;     } @@ -685,17 +693,6 @@ doloop_optimize (class loop *loop)        return false;      } -  max_cost -    = COSTS_N_INSNS (param_max_iterations_computation_cost); -  if (set_src_cost (desc->niter_expr, mode, optimize_loop_for_speed_p (loop)) -      > max_cost) -    { -      if (dump_file) -    fprintf (dump_file, -         "Doloop: number of iterations too costly to compute.\n"); -      return false; -    } -    if (desc->const_iter)      iterations = widest_int::from (rtx_mode_t (desc->niter_expr, mode),                     UNSIGNED); @@ -722,6 +719,23 @@ doloop_optimize (class loop *loop)    doloop_reg = gen_reg_rtx (mode);    rtx_insn *doloop_seq = targetm.gen_doloop_end (doloop_reg, start_label); +  /* Not all targets need to pre-calculate the number of the iterations of +     the loop, they instead work by storing the number of elements in the +     counter_reg and decrementing that.  Call the appropriate target hook to +     change the value of count.  */ +  count = targetm.allow_elementwise_doloop_p (count, start_label, doloop_seq); + +  max_cost +    = COSTS_N_INSNS (param_max_iterations_computation_cost); +  if (set_src_cost (count, mode, optimize_loop_for_speed_p (loop)) +      > max_cost) +    { +      if (dump_file) +    fprintf (dump_file, +         "Doloop: number of iterations too costly to compute.\n"); +      return false; +    } +    word_mode_size = GET_MODE_PRECISION (word_mode);    word_mode_max = (HOST_WIDE_INT_1U << (word_mode_size - 1) << 1) - 1;    if (! doloop_seq diff --git a/gcc/target.def b/gcc/target.def index db8af0cbe81624513f114fc9bbd8be61d855f409..e799cd97de50b814b0428c0f2960912a6091d330 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4411,6 +4411,16 @@ The default version of this hook returns false.",   bool, (class loop *loop),   default_predict_doloop_p) +DEFHOOK +(allow_elementwise_doloop_p, + "This target hook allows the target to support loop-doloop optimisations\n\ +where the value that gets put into the loop counter register is not a\n\ +pre-calculation of the number of iteration of the loop.  For instance,\n\ +the value used can be the number of elements that the loop will process.\n\ +The default version of this hook returns the same rtx it was given.", + rtx, (rtx count, rtx label, rtx doloop), + default_allow_elementwise_doloop_p) +  DEFHOOKPOD  (have_count_reg_decr_p,   "Return true if the target supports hardware count register for decrement\n\ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index a1df260f5483dc84f18d8f12c5202484a32d5bb7..e94ac1fe09dd48bd24210a8c8982f7a59e4cbc63 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -88,6 +88,7 @@ extern bool default_fixed_point_supported_p (void);  extern bool default_has_ifunc_p (void);  extern bool default_predict_doloop_p (class loop *); +extern rtx default_allow_elementwise_doloop_p (rtx, rtx, rtx);  extern machine_mode default_preferred_doloop_mode (machine_mode);  extern const char * default_invalid_within_doloop (const rtx_insn *); diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index fe0116521feaf32187e7bc113bf93b1805852c79..de4eea9ec0302a6bc4e5274893925aecf2444676 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -661,6 +661,12 @@ default_predict_doloop_p (class loop *loop ATTRIBUTE_UNUSED)    return false;  } +rtx +default_allow_elementwise_doloop_p (rtx count, rtx, rtx) +{ +  return count; +} +  /* By default, just use the input MODE itself.  */  machine_mode diff --git a/gcc/testsuite/gcc.target/arm/dlstp-compile-asm.c b/gcc/testsuite/gcc.target/arm/dlstp-compile-asm.c index acf0836050c19b983feeaf97c3e52e1318bb194d..e036b0386260a547a3a2e42d8f34f0913793e593 100644 --- a/gcc/testsuite/gcc.target/arm/dlstp-compile-asm.c +++ b/gcc/testsuite/gcc.target/arm/dlstp-compile-asm.c @@ -140,10 +140,196 @@ TEST_COMPILE_IN_DLSTP_INTBITS_SIGNED_UNSIGNED_TERNARY_M_N (vbrsrq, _m)  TEST_COMPILE_IN_DLSTP_INTBITS_SIGNED_UNSIGNED_TERNARY_M_N (vshlq, _m)  TEST_COMPILE_IN_DLSTP_INTBITS_SIGNED_UNSIGNED_TERNARY_M_N (vshrq, _m) +/* Now test some more configurations.  */ + +/* Test a for loop format of decrementing to zero */ +int32_t a[] = {0, 1, 2, 3, 4, 5, 6, 7}; +void test1 (int32_t *b, int num_elems) +{ +    for (int i = num_elems; i >= 0; i-= 4) +    { +        mve_pred16_t p = vctp32q (i); +        int32x4_t va = vldrwq_z_s32 (&(a[i]), p); +        vstrwq_p_s32 (b + i, va, p); +    } +} + +/* Iteration counter counting up to num_iter.  */ +void test2 (uint8_t *a, uint8_t *b, uint8_t *c, int n) +{ +    int num_iter = (n + 15)/16; +    for (int i = 0; i < num_iter; i++) +    { +        mve_pred16_t p = vctp8q (n); +        uint8x16_t va = vldrbq_z_u8 (a, p); +        uint8x16_t vb = vldrbq_z_u8 (b, p); +        uint8x16_t vc = vaddq_x_u8 (va, vb, p); +        vstrbq_p_u8 (c, vc, p); +        n-=16; +    } +} + +/* Using an unpredicated arithmetic instruction within the loop. */ +void test3 (uint8_t *a, uint8_t *b, uint8_t *c,  uint8_t *d, int n) +{ +    while (n > 0) +    { +        mve_pred16_t p = vctp8q (n); +        uint8x16_t va = vldrbq_z_u8 (a, p); +        uint8x16_t vb = vldrbq_u8 (b); +        uint8x16_t vc = vaddq_u8 (va, vb); +        uint8x16_t vd = vaddq_x_u8 (va, vb, p); +        vstrbq_p_u8 (c, vc, p); +        vstrbq_p_u8 (d, vd, p); +        n-=16; +    } +} + +/* Using a different VPR value for one instruction in the loop. */ +void test4 (int32_t *a, int32_t *b, int32_t *c, int n, mve_pred16_t p1) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Generating and using a constant VPR value in the loop, with a vctp.  */ +void test5 (int32_t *a, int32_t *b, int32_t *c, int n, int g) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      mve_pred16_t p1 = vctp32q (g); +      int32x4_t vb = vldrwq_z_s32 (b, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Generating and using a different VPR value in the loop, with a vctp.  */ +void test6 (int32_t *a, int32_t *b, int32_t *c, int n, int g) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      mve_pred16_t p1 = vctp32q (g); +      int32x4_t vb = vldrwq_z_s32 (b, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +      g++; +    } +} + +/* Generating and using a different VPR value in the loop, with a vctp_m.  */ +void test7 (int32_t *a, int32_t *b, int32_t *c, int n, mve_pred16_t p1) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      mve_pred16_t p2 = vctp32q_m (n, p1); +      int32x4_t vb = vldrwq_z_s32 (b, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p2); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Generating and using a different VPR value in the loop, with a vctp_m that is tied to the base vctp VPR.  */ +void test8 (int32_t *a, int32_t *b, int32_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      mve_pred16_t p1 = vctp32q_m (n, p); +      int32x4_t vb = vldrwq_z_s32 (b, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p1); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Generating and using a different VPR value in the loop, with a vcmp.  */ +void test9 (int32_t *a, int32_t *b, int32_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      mve_pred16_t p1 = vcmpeqq_s32 (va, vb); +      int32x4_t vc = vaddq_x_s32 (va, vb, p1); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Generating and using a different VPR value in the loop, with a vcmp_m.  */ +void test10 (int32_t *a, int32_t *b, int32_t *c, int n, mve_pred16_t p1) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      mve_pred16_t p2 = vcmpeqq_m_s32 (va, vb, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p2); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Generating and using a different VPR value in the loop, with a vcmp_m that is tied to the base vctp VPR.  */ +void test11 (int32_t *a, int32_t *b, int32_t *c, int n, mve_pred16_t p1) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      mve_pred16_t p2 = vcmpeqq_m_s32 (va, vb, p1); +      int32x4_t vc = vaddq_x_s32 (va, vb, p2); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} +  /* The final number of DLSTPs currently is calculated by the number of -  `TEST_COMPILE_IN_DLSTP_INTBITS_SIGNED_UNSIGNED_TERNARY.*` macros * 6.  */ -/* { dg-final { scan-assembler-times {\tdlstp} 144 } } */ -/* { dg-final { scan-assembler-times {\tletp} 144 } } */ -/* { dg-final { scan-assembler-not "\tvctp\t" } } */ -/* { dg-final { scan-assembler-not "\tvpst\t" } } */ -/* { dg-final { scan-assembler-not "p0" } } */ +  `TEST_COMPILE_IN_DLSTP_INTBITS_SIGNED_UNSIGNED_TERNARY.*` macros * 6 + 11.  */ +/* { dg-final { scan-assembler-times {\tdlstp} 155 } } */ +/* { dg-final { scan-assembler-times {\tletp} 155 } } */ diff --git a/gcc/testsuite/gcc.target/arm/dlstp-int16x8.c b/gcc/testsuite/gcc.target/arm/dlstp-int16x8.c new file mode 100644 index 0000000000000000000000000000000000000000..b1c03b618e0dcc7d4268f2f004663b6e332a402a --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/dlstp-int16x8.c @@ -0,0 +1,68 @@ +/* { dg-do run { target { arm*-*-* } } } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main+fp.dp+mve.fp -mfloat-abi=hard -mfpu=auto -O3 --save-temps" } */ + +#include +#include +#include +#include "lob.h" + +void  __attribute__ ((noinline)) test (int16_t *a, int16_t *b, int16_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp16q (n); +      int16x8_t va = vldrhq_z_s16 (a, p); +      int16x8_t vb = vldrhq_z_s16 (b, p); +      int16x8_t vc = vaddq_x_s16 (va, vb, p); +      vstrhq_p_s16 (c, vc, p); +      c+=8; +      a+=8; +      b+=8; +      n-=8; +    } +} + +int main () +{ +  int i; +  int16_t temp1[N]; +  int16_t temp2[N]; +  int16_t temp3[N]; +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 0); +  check_plus16 (temp1, temp2, temp3, 0); + +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 1); +  check_plus16 (temp1, temp2, temp3, 1); + +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 7); +  check_plus16 (temp1, temp2, temp3, 7); + +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 8); +  check_plus16 (temp1, temp2, temp3, 8); + +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 9); +  check_plus16 (temp1, temp2, temp3, 9); + +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 16); +  check_plus16 (temp1, temp2, temp3, 16); + +  reset_data16 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 17); +  check_plus16 (temp1, temp2, temp3, 17); + +  reset_data16 (temp1, temp2, temp3, N); +} + +/* { dg-final { scan-assembler-times {\tdlstp.16} 1 } } */ +/* { dg-final { scan-assembler-times {\tletp} 1 } } */ +/* { dg-final { scan-assembler-not "\tvctp" } } */ +/* { dg-final { scan-assembler-not "\tvpst" } } */ +/* { dg-final { scan-assembler-not "p0" } } */ diff --git a/gcc/testsuite/gcc.target/arm/dlstp-int32x4.c b/gcc/testsuite/gcc.target/arm/dlstp-int32x4.c new file mode 100644 index 0000000000000000000000000000000000000000..4a3eb0577be0631ab4e07f6f75c2c802b535c88c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/dlstp-int32x4.c @@ -0,0 +1,68 @@ +/* { dg-do run { target { arm*-*-* } } } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main+fp.dp+mve.fp -mfloat-abi=hard -mfpu=auto -O3 --save-temps" } */ + +#include +#include +#include +#include "lob.h" + +void  __attribute__ ((noinline)) test (int32_t *a, int32_t *b, int32_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c+=4; +      a+=4; +      b+=4; +      n-=4; +    } +} + +int main () +{ +  int i; +  int32_t temp1[N]; +  int32_t temp2[N]; +  int32_t temp3[N]; +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 0); +  check_plus32 (temp1, temp2, temp3, 0); + +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 1); +  check_plus32 (temp1, temp2, temp3, 1); + +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 3); +  check_plus32 (temp1, temp2, temp3, 3); + +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 4); +  check_plus32 (temp1, temp2, temp3, 4); + +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 5); +  check_plus32 (temp1, temp2, temp3, 5); + +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 8); +  check_plus32 (temp1, temp2, temp3, 8); + +  reset_data32 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 9); +  check_plus32 (temp1, temp2, temp3, 9); + +  reset_data32 (temp1, temp2, temp3, N); +} + +/* { dg-final { scan-assembler-times {\tdlstp.32} 1 } } */ +/* { dg-final { scan-assembler-times {\tletp} 1 } } */ +/* { dg-final { scan-assembler-not "\tvctp" } } */ +/* { dg-final { scan-assembler-not "\tvpst" } } */ +/* { dg-final { scan-assembler-not "p0" } } */ diff --git a/gcc/testsuite/gcc.target/arm/dlstp-int64x2.c b/gcc/testsuite/gcc.target/arm/dlstp-int64x2.c new file mode 100644 index 0000000000000000000000000000000000000000..f05ff834363e2a47a9faddb6b8b09b60eb94a3c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/dlstp-int64x2.c @@ -0,0 +1,68 @@ +/* { dg-do run { target { arm*-*-* } } } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main+fp.dp+mve.fp -mfloat-abi=hard -mfpu=auto -O3 --save-temps" } */ + +#include +#include +#include +#include "lob.h" + +void  __attribute__ ((noinline)) test (int64_t *a, int64_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp64q (n); +      int64x2_t va = vldrdq_gather_offset_z_s64 (a, vcreateq_u64 (8, 0), p); +      vstrdq_scatter_offset_p_s64 (c, vcreateq_u64 (8, 0), va, p); +      c+=2; +      a+=2; +      n-=2; +    } +} + +int main () +{ +  int i; +  int64_t temp1[N]; +  int64_t temp3[N]; +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 0); +  check_memcpy64 (temp1, temp3, 0); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 1); +  check_memcpy64 (temp1, temp3, 1); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 2); +  check_memcpy64 (temp1, temp3, 2); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 3); +  check_memcpy64 (temp1, temp3, 3); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 4); +  check_memcpy64 (temp1, temp3, 4); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 5); +  check_memcpy64 (temp1, temp3, 5); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 6); +  check_memcpy64 (temp1, temp3, 6); + +  reset_data64  (temp1, temp3, N); +  test (temp1, temp3, 7); +  check_memcpy64 (temp1, temp3, 7); + +  reset_data64  (temp1, temp3, N); +} + +/* { dg-final { scan-assembler-times {\tdlstp.64} 1 } } */ +/* { dg-final { scan-assembler-times {\tletp} 1 } } */ +/* { dg-final { scan-assembler-not "\tvctp" } } */ +/* { dg-final { scan-assembler-not "\tvpst" } } */ +/* { dg-final { scan-assembler-not "p0" } } */ diff --git a/gcc/testsuite/gcc.target/arm/dlstp-int8x16.c b/gcc/testsuite/gcc.target/arm/dlstp-int8x16.c new file mode 100644 index 0000000000000000000000000000000000000000..f281ba7848d1ba3321124e996eb5bea44977c2ab --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/dlstp-int8x16.c @@ -0,0 +1,68 @@ +/* { dg-do run { target { arm*-*-* } } } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main+fp.dp+mve.fp -mfloat-abi=hard -mfpu=auto -O3 --save-temps" } */ + +#include +#include +#include +#include "lob.h" + +void  __attribute__ ((noinline)) test (int8_t *a, int8_t *b, int8_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp8q (n); +      int8x16_t va = vldrbq_z_s8 (a, p); +      int8x16_t vb = vldrbq_z_s8 (b, p); +      int8x16_t vc = vaddq_x_s8 (va, vb, p); +      vstrbq_p_s8 (c, vc, p); +      c+=16; +      a+=16; +      b+=16; +      n-=16; +    } +} + +int main () +{ +  int i; +  int8_t temp1[N]; +  int8_t temp2[N]; +  int8_t temp3[N]; +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 0); +  check_plus8 (temp1, temp2, temp3, 0); + +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 1); +  check_plus8 (temp1, temp2, temp3, 1); + +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 15); +  check_plus8 (temp1, temp2, temp3, 15); + +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 16); +  check_plus8 (temp1, temp2, temp3, 16); + +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 17); +  check_plus8 (temp1, temp2, temp3, 17); + +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 32); +  check_plus8 (temp1, temp2, temp3, 32); + +  reset_data8 (temp1, temp2, temp3, N); +  test (temp1, temp2, temp3, 33); +  check_plus8 (temp1, temp2, temp3, 33); + +  reset_data8 (temp1, temp2, temp3, N); +} + +/* { dg-final { scan-assembler-times {\tdlstp.8} 1 } } */ +/* { dg-final { scan-assembler-times {\tletp} 1 } } */ +/* { dg-final { scan-assembler-not "\tvctp" } } */ +/* { dg-final { scan-assembler-not "\tvpst" } } */ +/* { dg-final { scan-assembler-not "p0" } } */ diff --git a/gcc/testsuite/gcc.target/arm/dlstp-invalid-asm.c b/gcc/testsuite/gcc.target/arm/dlstp-invalid-asm.c new file mode 100644 index 0000000000000000000000000000000000000000..b250625ce426400ad6be1edcb77e854cc6b79dc9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/dlstp-invalid-asm.c @@ -0,0 +1,210 @@ + +/* { dg-do compile { target { arm*-*-* } } } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main+fp.dp+mve.fp -mfloat-abi=hard -mfpu=auto -O3 --save-temps" } */ + +#include + +/* Terminating on a non-zero number of elements.  */ +void test1 (uint8_t *a, uint8_t *b, uint8_t *c, int n) +{ +    while (n > 1) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_x_u8 (va, vb, p); +       vstrbq_p_u8 (c, vc, p); +       n -= 16; +    } +} + +/* Similar, terminating on a non-zero number of elements, but in a for loop +   format.  */ +int32_t a[] = {0, 1, 2, 3, 4, 5, 6, 7}; +void test2 (int32_t *b, int num_elems) +{ +    for (int i = num_elems; i >= 2; i-= 4) +    { +       mve_pred16_t p = vctp32q (i); +       int32x4_t va = vldrwq_z_s32 (&(a[i]), p); +       vstrwq_p_s32 (b + i, va, p); +    } +} + +/* Iteration counter counting up to num_iter, with a non-zero starting num.  */ +void test3 (uint8_t *a, uint8_t *b, uint8_t *c, int n) +{ +    int num_iter = (n + 15)/16; +    for (int i = 1; i < num_iter; i++) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_x_u8 (va, vb, p); +       vstrbq_p_u8 (c, vc, p); +       n -= 16; +    } +} + +/* Iteration counter counting up to num_iter, with a larger increment  */ +void test4 (uint8_t *a, uint8_t *b, uint8_t *c, int n) +{ +    int num_iter = (n + 15)/16; +    for (int i = 0; i < num_iter; i+=2) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_x_u8 (va, vb, p); +       vstrbq_p_u8 (c, vc, p); +       n -= 16; +    } +} + +/* Using an unpredicated store instruction within the loop.  */ +void test5 (uint8_t *a, uint8_t *b, uint8_t *c,  uint8_t *d, int n) +{ +    while (n > 0) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_u8 (va, vb); +       uint8x16_t vd = vaddq_x_u8 (va, vb, p); +       vstrbq_u8 (d, vd); +       n -= 16; +    } +} + +/* Using an unpredicated vcmp to generate a new predicate value in the +   loop and then using it in a store insn.  */ +void test14 (int32_t *a, int32_t *b, int32x4_t vc, int32_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      mve_pred16_t p1 = vcmpeqq_s32 (va, vc); +      vstrwq_p_s32 (c, vc, p1); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Using an unpredicated store outside the loop.  */ +void test6 (uint8_t *a, uint8_t *b, uint8_t *c, int n, uint8x16_t vx) +{ +    while (n > 0) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_m_u8 (vx, va, vb, p); +       vx = vaddq_u8 (vx, vc); +       a += 16; +       b += 16; +       n -= 16; +    } +    vstrbq_u8 (c, vx); +} + +/* Using an unpredicated op with a scalar output, where the result is valid +   outside the bb.  */ +uint8_t test7 (uint8_t *a, uint8_t *b, uint8_t *c, int n, uint8x16_t vx) +{ +    uint8_t sum = 0; +    while (n > 0) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_m_u8 (vx, va, vb, p); +       sum += vaddvq_u8 (vc); +       a += 16; +       b += 16; +       n -= 16; +    } +    return sum; +} + +/* Using an unpredicated op with a scalar output, then a scalar op, +   where the result is valid outside the bb.  */ +uint8_t test8 (uint8_t *a, uint8_t *b, uint8_t *c, int n, uint8x16_t vx, int g) +{ +    uint8_t sum = 0; +    while (n > 0) +    { +       mve_pred16_t p = vctp8q (n); +       uint8x16_t va = vldrbq_z_u8 (a, p); +       uint8x16_t vb = vldrbq_z_u8 (b, p); +       uint8x16_t vc = vaddq_m_u8 (vx, va, vb, p); +       sum += vaddvq_u8 (vc); +       sum += g; +       a += 16; +       b += 16; +       n -= 16; +    } +    return sum; +} + +/* Using a VPR that gets modified within the loop.  */ +void test9 (int32_t *a, int32_t *b, int32_t *c, int n) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q (n); +      int32x4_t va = vldrwq_z_s32 (a, p); +      p++; +      int32x4_t vb = vldrwq_z_s32 (b, p); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Using a VPR that gets re-generated within the loop.  */ +void test10 (int32_t *a, int32_t *b, int32_t *c, int n) +{ +  mve_pred16_t p = vctp32q (n); +  while (n > 0) +    { +      int32x4_t va = vldrwq_z_s32 (a, p); +      p = vctp32q (n); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* Using vctp32q_m instead of vctp32q.  */ +void test11 (int32_t *a, int32_t *b, int32_t *c, int n, mve_pred16_t p0) +{ +  while (n > 0) +    { +      mve_pred16_t p = vctp32q_m (n, p0); +      int32x4_t va = vldrwq_z_s32 (a, p); +      int32x4_t vb = vldrwq_z_s32 (b, p); +      int32x4_t vc = vaddq_x_s32 (va, vb, p); +      vstrwq_p_s32 (c, vc, p); +      c += 4; +      a += 4; +      b += 4; +      n -= 4; +    } +} + +/* { dg-final { scan-assembler-not "\tdlstp" } } */ +/* { dg-final { scan-assembler-not "\tletp" } } */ diff --git a/gcc/testsuite/gcc.target/arm/lob.h b/gcc/testsuite/gcc.target/arm/lob.h index feaae7cc89959b3147368980120700bbc3e85ecb..3941fe7a8b620e62a5f742722be1ba2d031f5a8d 100644 --- a/gcc/testsuite/gcc.target/arm/lob.h +++ b/gcc/testsuite/gcc.target/arm/lob.h @@ -1,15 +1,131 @@  #include - +#include  /* Common code for lob tests.  */  #define NO_LOB asm volatile ("@ clobber lr" : : : "lr" ) -#define N 10000 +#define N 100 + +static void +reset_data (int *a, int *b, int *c, int x) +{ +  memset (a, -1, x * sizeof (*a)); +  memset (b, -1, x * sizeof (*b)); +  memset (c, 0, x * sizeof (*c)); +} + +static void +reset_data8 (int8_t *a, int8_t *b, int8_t *c, int x) +{ +  memset (a, -1, x * sizeof (*a)); +  memset (b, -1, x * sizeof (*b)); +  memset (c, 0, x * sizeof (*c)); +} + +static void +reset_data16 (int16_t *a, int16_t *b, int16_t *c, int x) +{ +  memset (a, -1, x * sizeof (*a)); +  memset (b, -1, x * sizeof (*b)); +  memset (c, 0, x * sizeof (*c)); +} + +static void +reset_data32 (int32_t *a, int32_t *b, int32_t *c, int x) +{ +  memset (a, -1, x * sizeof (*a)); +  memset (b, -1, x * sizeof (*b)); +  memset (c, 0, x * sizeof (*c)); +} + +static void +reset_data64 (int64_t *a, int64_t *c, int x) +{ +  memset (a, -1, x * sizeof (*a)); +  memset (c, 0, x * sizeof (*c)); +} + +static void +check_plus (int *a, int *b, int *c, int x) +{ +  for (int i = 0; i < N; i++) +    { +      NO_LOB; +      if (i < x) +    { +      if (c[i] != (a[i] + b[i])) abort (); +    } +      else +    { +      if (c[i] != 0) abort (); +    } +    } +} + +static void +check_plus8 (int8_t *a, int8_t *b, int8_t *c, int x) +{ +  for (int i = 0; i < N; i++) +    { +      NO_LOB; +      if (i < x) +    { +      if (c[i] != (a[i] + b[i])) abort (); +    } +      else +    { +      if (c[i] != 0) abort (); +    } +    } +} + +static void +check_plus16 (int16_t *a, int16_t *b, int16_t *c, int x) +{ +  for (int i = 0; i < N; i++) +    { +      NO_LOB; +      if (i < x) +    { +      if (c[i] != (a[i] + b[i])) abort (); +    } +      else +    { +      if (c[i] != 0) abort (); +    } +    } +} + +static void +check_plus32 (int32_t *a, int32_t *b, int32_t *c, int x) +{ +  for (int i = 0; i < N; i++) +    { +      NO_LOB; +      if (i < x) +    { +      if (c[i] != (a[i] + b[i])) abort (); +    } +      else +    { +      if (c[i] != 0) abort (); +    } +    } +}  static void -reset_data (int *a, int *b, int *c) +check_memcpy64 (int64_t *a, int64_t *c, int x)  { -  memset (a, -1, N * sizeof (*a)); -  memset (b, -1, N * sizeof (*b)); -  memset (c, -1, N * sizeof (*c)); +  for (int i = 0; i < N; i++) +    { +      NO_LOB; +      if (i < x) +    { +      if (c[i] != a[i]) abort (); +    } +      else +    { +      if (c[i] != 0) abort (); +    } +    }  } diff --git a/gcc/testsuite/gcc.target/arm/lob1.c b/gcc/testsuite/gcc.target/arm/lob1.c index ba5c82cd55c582c96a18ad417a3041e43d843613..c8ce653a5c39fb1ffcf82a6e584d9a0467a130c0 100644 --- a/gcc/testsuite/gcc.target/arm/lob1.c +++ b/gcc/testsuite/gcc.target/arm/lob1.c @@ -54,29 +54,18 @@ loop3 (int *a, int *b, int *c)      } while (i < N);  } -void -check (int *a, int *b, int *c) -{ -  for (int i = 0; i < N; i++) -    { -      NO_LOB; -      if (c[i] != a[i] + b[i]) -    abort (); -    } -} -  int  main (void)  { -  reset_data (a, b, c); +  reset_data (a, b, c, N);    loop1 (a, b ,c); -  check (a, b ,c); -  reset_data (a, b, c); +  check_plus (a, b, c, N); +  reset_data (a, b, c, N);    loop2 (a, b ,c); -  check (a, b ,c); -  reset_data (a, b, c); +  check_plus (a, b, c, N); +  reset_data (a, b, c, N);    loop3 (a, b ,c); -  check (a, b ,c); +  check_plus (a, b, c, N);    return 0;  } diff --git a/gcc/testsuite/gcc.target/arm/lob6.c b/gcc/testsuite/gcc.target/arm/lob6.c index 17b6124295e8ae9e1cb57e41fa43a954b3390eec..4fe116e2c2be3748d1bb6da7bb9092db8f962abc 100644 --- a/gcc/testsuite/gcc.target/arm/lob6.c +++ b/gcc/testsuite/gcc.target/arm/lob6.c @@ -79,14 +79,14 @@ check (void)  int  main (void)  { -  reset_data (a1, b1, c1); -  reset_data (a2, b2, c2); +  reset_data (a1, b1, c1, N); +  reset_data (a2, b2, c2, N);    loop1 (a1, b1, c1);    ref1 (a2, b2, c2);    check (); -  reset_data (a1, b1, c1); -  reset_data (a2, b2, c2); +  reset_data (a1, b1, c1, N); +  reset_data (a2, b2, c2, N);    loop2 (a1, b1, c1);    ref2 (a2, b2, c2);    check (); --------------RE6Gven9LsBwQ60Lckeh0C0w Content-Type: text/x-patch; charset=UTF-8; name="rb16111.patch" Content-Disposition: attachment; filename="rb16111.patch" Content-Transfer-Encoding: base64 ZGlmZiAtLWdpdCBhL2djYy9jb25maWcvYXJtL2FybS1wcm90b3MuaCBiL2djYy9jb25maWcvYXJt L2FybS1wcm90b3MuaAppbmRleCBhZWE0NzJiZmJiOWRlYWE4ZTkyNTc1Njk2M2M3YzVjYzZmZGMw ZDA5Li4xMGZmYzcxM2Y3NzQ0MjUyNjU1ZTlkNzg1MTBkZjVjZWY5OGMyMzU1IDEwMDY0NAotLS0g YS9nY2MvY29uZmlnL2FybS9hcm0tcHJvdG9zLmgKKysrIGIvZ2NjL2NvbmZpZy9hcm0vYXJtLXBy b3Rvcy5oCkBAIC02NSw3ICs2NSw3IEBAIGV4dGVybiB2b2lkIGFybV9kZWNvbXBvc2VfZGlfYmlu b3AgKHJ0eCwgcnR4LCBydHggKiwgcnR4ICosIHJ0eCAqLCBydHggKik7CiBleHRlcm4gYm9vbCBh cm1fcV9iaXRfYWNjZXNzICh2b2lkKTsKIGV4dGVybiBib29sIGFybV9nZV9iaXRzX2FjY2VzcyAo dm9pZCk7CiBleHRlcm4gYm9vbCBhcm1fdGFyZ2V0X2luc25fb2tfZm9yX2xvYiAocnR4KTsKLQor ZXh0ZXJuIHJ0eCBhcm1fYXR0ZW1wdF9kbHN0cF90cmFuc2Zvcm0gKHJ0eCk7CiAjaWZkZWYgUlRY X0NPREUKIGVudW0gcmVnX2NsYXNzCiBhcm1fbW9kZV9iYXNlX3JlZ19jbGFzcyAobWFjaGluZV9t b2RlKTsKZGlmZiAtLWdpdCBhL2djYy9jb25maWcvYXJtL2FybS5jYyBiL2djYy9jb25maWcvYXJt L2FybS5jYwppbmRleCAxZDI4NTA1MWZhNmQ4ZTZjMDU4MTM4MDFlYjY3OGU1OGRhMjU3MTRkLi5k NGFjMDRlMDk1ZjAxZjQyYzFjNDYxMTA3NGMzNDk5YTAxMjQyNzE2IDEwMDY0NAotLS0gYS9nY2Mv Y29uZmlnL2FybS9hcm0uY2MKKysrIGIvZ2NjL2NvbmZpZy9hcm0vYXJtLmNjCkBAIC00NzIsNiAr NDcyLDkgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfc3BlYyBhcm1fYXR0cmlidXRl X3RhYmxlW10gPQogI3VuZGVmIFRBUkdFVF9TQ0hFRF9SRU9SREVSCiAjZGVmaW5lIFRBUkdFVF9T Q0hFRF9SRU9SREVSIGFybV9zY2hlZF9yZW9yZGVyCiAKKyN1bmRlZiBUQVJHRVRfQUxMT1dfRUxF TUVOVFdJU0VfRE9MT09QX1AKKyNkZWZpbmUgVEFSR0VUX0FMTE9XX0VMRU1FTlRXSVNFX0RPTE9P UF9QIGFybV9hbGxvd19lbGVtZW50d2lzZV9kb2xvb3BfcAorCiAjdW5kZWYgVEFSR0VUX1JFR0lT VEVSX01PVkVfQ09TVAogI2RlZmluZSBUQVJHRVRfUkVHSVNURVJfTU9WRV9DT1NUIGFybV9yZWdp c3Rlcl9tb3ZlX2Nvc3QKIApAQCAtMzMwNjcsNyArMzMwNzAsNyBAQCBhcm1fYmxvY2tfc2V0X3Zl Y3QgKHJ0eCBkc3RiYXNlLAogICAgIHJldHVybiBhcm1fYmxvY2tfc2V0X3VuYWxpZ25lZF92ZWN0 IChkc3RiYXNlLCBsZW5ndGgsIHZhbHVlLCBhbGlnbik7CiB9CiAKLS8qIEV4cGFuZCBzdHJpbmcg c3RvcmUgb3BlcmF0aW9uLiAgRmlyc3RseSB3ZSB0cnkgdG8gZG8gdGhhdCBieSB1c2luZworLyog RXhwYW5kIHN0cmluZyBzdG9yZSBvcGVyYXRpb24uICBGaXJzdCB3ZSB0cnkgdG8gZG8gdGhhdCBi eSB1c2luZwogICAgdmVjdG9yaXphdGlvbiBpbnN0cnVjdGlvbnMsIHRoZW4gdHJ5IHdpdGggQVJN IHVuYWxpZ25lZCBhY2Nlc3MgYW5kCiAgICBkb3VibGUtd29yZCBzdG9yZSBpZiBwcm9maXRhYmxl LiAgT1BFUkFORFNbMF0gaXMgdGhlIGRlc3RpbmF0aW9uLAogICAgT1BFUkFORFNbMV0gaXMgdGhl IG51bWJlciBvZiBieXRlcywgb3BlcmFuZHNbMl0gaXMgdGhlIHZhbHVlIHRvCkBAIC0zNDM5NSw4 ICszNDM5OCw1NjMgQEAgYXJtX3RhcmdldF9pbnNuX29rX2Zvcl9sb2IgKHJ0eCBpbnNuKQogCiAg IHJldHVybiBzaW5nbGVfc3VjY19wIChiYikKICAgICAmJiBzaW5nbGVfcHJlZF9wIChiYikKLSAg ICAmJiBzaW5nbGVfc3VjY19lZGdlIChiYiktPmRlc3QgPT0gc2luZ2xlX3ByZWRfZWRnZSAoYmIp LT5zcmMKLSAgICAmJiBjb250YWluc19ub19hY3RpdmVfaW5zbl9wIChiYik7CisgICAgJiYgc2lu Z2xlX3N1Y2NfZWRnZSAoYmIpLT5kZXN0ID09IHNpbmdsZV9wcmVkX2VkZ2UgKGJiKS0+c3JjOwor fQorCitzdGF0aWMgaW50Cithcm1fbXZlX2dldF92Y3RwX2xhbmVzIChydHggeCkKK3sKKyAgaWYg KEdFVF9DT0RFICh4KSA9PSBTRVQgJiYgR0VUX0NPREUgKFhFWFAgKHgsIDEpKSA9PSBVTlNQRUMK KyAgICAgICYmIFhJTlQgKFhFWFAgKHgsIDEpLCAxKSA9PSBWQ1RQKQorICAgIHsKKyAgICAgIHN3 aXRjaCAoR0VUX01PREUgKFhFWFAgKHgsIDEpKSkKKwl7CisJICBjYXNlIFYxNkJJbW9kZToKKwkg ICAgcmV0dXJuIDE2OworCSAgY2FzZSBWOEJJbW9kZToKKwkgICAgcmV0dXJuIDg7CisJICBjYXNl IFY0Qkltb2RlOgorCSAgICByZXR1cm4gNDsKKwkgIGNhc2UgVjJRSW1vZGU6CisJICAgIHJldHVy biAyOworCSAgZGVmYXVsdDoKKwkgICAgYnJlYWs7CisJfQorICAgIH0KKyAgcmV0dXJuIDA7Cit9 CisKKy8qIENoZWNrIGlmIGFuIGluc24gcmVxdWlyZXMgdGhlIHVzZSBvZiB0aGUgVlBSX1JFRywg aWYgaXQgZG9lcywgcmV0dXJuIHRoZQorICAgc3ViLXJ0eCBvZiB0aGUgVlBSX1JFRy4gIFRoZSBg dHlwZWAgYXJndW1lbnQgY29udHJvbHMgd2hldGhlcgorICAgdGhpcyBmdW5jdGlvbiBzaG91bGQ6 CisgICAqIEZvciB0eXBlID09IDAsIGNoZWNrIGFsbCBvcGVyYW5kcywgaW5jbHVkaW5nIHRoZSBP VVQgb3BlcmFuZHMsCisgICAgIGFuZCByZXR1cm4gdGhlIGZpcnN0IG9jY3VyYW5jZSBvZiB0aGUg VlBSX1JFRy4KKyAgICogRm9yIHR5cGUgPT0gMSwgb25seSBjaGVjayB0aGUgaW5wdXQgb3BlcmFu ZHMuCisgICAqIEZvciB0eXBlID09IDIsIG9ubHkgY2hlY2sgdGhlIG91dHB1dCBvcGVyYW5kcy4K KyAgIChJTk9VVCBvcGVyYW5kcyBhcmUgY29uc2lkZXJlZCBib3RoIGFzIGlucHV0IGFuZCBvdXRw dXQgb3BlcmFuZHMpCisqLworc3RhdGljIHJ0eAorYXJtX2dldF9yZXF1aXJlZF92cHJfcmVnIChy dHhfaW5zbiAqaW5zbiwgdW5zaWduZWQgaW50IHR5cGUgPSAwKQoreworICBnY2NfYXNzZXJ0ICh0 eXBlIDwgMyk7CisgIGlmICghTk9OSlVNUF9JTlNOX1AgKGluc24pKQorICAgIHJldHVybiBOVUxM X1JUWDsKKworICBib29sIHJlcXVpcmVzX3ZwcjsKKyAgZXh0cmFjdF9jb25zdHJhaW5faW5zbiAo aW5zbik7CisgIGludCBuX29wZXJhbmRzID0gcmVjb2dfZGF0YS5uX29wZXJhbmRzOworICBpZiAo cmVjb2dfZGF0YS5uX2FsdGVybmF0aXZlcyA9PSAwKQorICAgIHJldHVybiBOVUxMX1JUWDsKKwor ICAvKiBGaWxsIGluIHJlY29nX29wX2FsdCB3aXRoIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb25z dHJhaW50cyBvZgorICAgICB0aGlzIGluc24uICAqLworICBwcmVwcm9jZXNzX2NvbnN0cmFpbnRz IChpbnNuKTsKKworICBmb3IgKGludCBvcCA9IDA7IG9wIDwgbl9vcGVyYW5kczsgb3ArKykKKyAg ICB7CisgICAgICByZXF1aXJlc192cHIgPSB0cnVlOworICAgICAgaWYgKHR5cGUgPT0gMSAmJiAo cmVjb2dfZGF0YS5vcGVyYW5kX3R5cGVbb3BdID09IE9QX09VVAorCQkJfHwgcmVjb2dfZGF0YS5v cGVyYW5kX3R5cGVbb3BdID09IE9QX0lOT1VUKSkKKwljb250aW51ZTsKKyAgICAgIGVsc2UgaWYg KHR5cGUgPT0gMiAmJiAocmVjb2dfZGF0YS5vcGVyYW5kX3R5cGVbb3BdID09IE9QX0lOCisJCQkg ICAgIHx8IHJlY29nX2RhdGEub3BlcmFuZF90eXBlW29wXSA9PSBPUF9JTk9VVCkpCisJY29udGlu dWU7CisKKyAgICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCBhbHRlcm5hdGl2ZXMgb2Ygb3BlcmFuZCAi b3AiIGluIHJlY29nX29wX2FsdCBhbmQKKwkgaWRlbnRpZnkgaWYgdGhlIG9wZXJhbmQgaXMgcmVx dWlyZWQgdG8gYmUgdGhlIFZQUi4gICovCisgICAgICBmb3IgKGludCBhbHQgPSAwOyBhbHQgPCBy ZWNvZ19kYXRhLm5fYWx0ZXJuYXRpdmVzOyBhbHQrKykKKwl7CisJICBjb25zdCBvcGVyYW5kX2Fs dGVybmF0aXZlICpvcF9hbHQKKwkgICAgICA9ICZyZWNvZ19vcF9hbHRbYWx0ICogbl9vcGVyYW5k c107CisJICAvKiBGZXRjaCB0aGUgcmVnX2NsYXNzIGZvciBlYWNoIGVudHJ5IGFuZCBjaGVjayBp dCBhZ2FpbnN0IHRoZQorCSAgICogVlBSX1JFRyByZWdfY2xhc3MuICAqLworCSAgaWYgKGFsdGVy bmF0aXZlX2NsYXNzIChvcF9hbHQsIG9wKSAhPSBWUFJfUkVHKQorCSAgICByZXF1aXJlc192cHIg PSBmYWxzZTsKKwl9CisgICAgICAvKiBJZiBhbGwgYWx0ZXJuYXRpdmVzIG9mIHRoZSBpbnNuIHJl cXVpcmUgdGhlIFZQUiByZWcgZm9yIHRoaXMgb3BlcmFuZCwKKwkgaXQgbWVhbnMgdGhhdCBlaXRo ZXIgdGhpcyBpcyBWUFItZ2VuZXJhdGluZyBpbnN0cnVjdGlvbiwgbGlrZSBhIHZjdHAsCisJIHZj bXAsIGV0Yy4sIG9yIGl0IGlzIGEgVlBULXByZWRpY2F0ZWQgaW5zcnVjdGlvbi4gIFJldHVybiB0 aGUgc3VicnR4CisJIG9mIHRoZSBWUFIgcmVnIG9wZXJhbmQuICAqLworICAgICAgaWYgKHJlcXVp cmVzX3ZwcikKKwlyZXR1cm4gcmVjb2dfZGF0YS5vcGVyYW5kW29wXTsKKyAgICB9CisgIHJldHVy biBOVUxMX1JUWDsKK30KKworc3RhdGljIHJ0eAorQUxXQVlTX0lOTElORSBBVFRSSUJVVEVfVU5V U0VECithcm1fZ2V0X3JlcXVpcmVkX3Zwcl9yZWdfcmV0X3ZhbCAocnR4X2luc24gKmluc24pCit7 CisgIHJldHVybiBhcm1fZ2V0X3JlcXVpcmVkX3Zwcl9yZWcgKGluc24sIDIpOworfQorCitzdGF0 aWMgcnR4CitBTFdBWVNfSU5MSU5FCithcm1fZ2V0X3JlcXVpcmVkX3Zwcl9yZWdfcGFyYW0gKHJ0 eF9pbnNuICppbnNuKQoreworICByZXR1cm4gYXJtX2dldF9yZXF1aXJlZF92cHJfcmVnIChpbnNu LCAxKTsKK30KKworLyogU2NhbiB0aGUgYmFzaWMgYmxvY2sgb2YgYSBsb29wIGJvZHkgZm9yIGEg dmN0cCBpbnN0cnVjdGlvbi4gIElmIHRoZXJlIGlzCisgICBhdCBsZWFzdCB2Y3RwIGluc3RydWN0 aW9uLCByZXR1cm4gdGhlIGZpcnN0IHJ0eF9pbnNuICouICAqLworCitzdGF0aWMgcnR4X2luc24g KgorYXJtX212ZV9nZXRfbG9vcF92Y3RwIChiYXNpY19ibG9jayBiYikKK3sKKyAgcnR4X2luc24g Kmluc24gPSBCQl9IRUFEIChiYik7CisKKyAgLyogTm93IHNjYW4gdGhyb3VnaCBhbGwgdGhlIGlu c3RydWN0aW9uIHBhdHRlcm5zIGFuZAorICAgICBwaWNrIG91dCBhbnkgTVZFIGluc3RydWN0aW9u cy4gICovCisgIEZPUl9CQl9JTlNOUyAoYmIsIGluc24pCisgICAgaWYgKElOU05fUCAoaW5zbikp CisgICAgICBpZiAoYXJtX212ZV9nZXRfdmN0cF9sYW5lcyAoUEFUVEVSTiAoaW5zbikpICE9IDAp CisJcmV0dXJuIGluc247CisgIHJldHVybiBOVUxMOworfQorCisvKiBSZWN1cnNpdmVseSBzY2Fu IHRocm91Z2ggdGhlIERGIGNoYWluIGJhY2t3YXJkcyB3aXRoaW4gdGhlIGJhc2ljIGJsb2NrIGFu ZAorICAgZGV0ZXJtaW5lIGlmIGFueSBvZiB0aGUgVVNFcyBvZiB0aGUgb3JpZ2luYWwgaW5zbiAo b3IgdGhlIFVTRXMgb2YgdGhlIGluc25zCisgICB3aGVyZSB0aHkgd2VyZSBERUYtZWQsIGV0Yy4s IHJlY3Vyc2l2ZWx5KSB3ZXJlIGFmZmVjdGVkIGJ5IGltcGxpY2l0IFZQVAorICAgcHJlZGljYXRp b24gb2YgYW4gTVZFX1ZQVF9VTlBSRURJQ0FURURfSU5TTl9QIGluIGEgZGxzdHAvbGV0cCBsb29w LiAgKi8KKworc3RhdGljIGJvb2wKK2FybV9tdmVfY2hlY2tfZGZfZm9yX2ltcGxpY19wcmVkaWMg KHJ0eF9pbnNuICppbnNuLCBydHhfaW5zbiogbG9vcF92Y3RwLAorCQkJCSAgICBydHggdmN0cF92 cHJfZ2VuZXJhdGVkKQoreworICBydHggaW5zbl92cHJfcmVnX29wZXJhbmQgPSBOVUxMX1JUWDsK KworICAvKiBFeGl0IHRoZSByZWN1cnNpb24gd2l0aCBhICJ0cnVlIiB3aGVuIHdlIGZpbmQgYW4g dW5wcmVkaWNhdGVkIGluc24sIG9yIHdpdGgKKyAgICAgYSBmYWxzZSBpZiB3ZSBmaW5kIHRoZSBk bHN0cC9sZXRwIGxvb3AgdmN0cCBvciBhIGNvcnJlY3RseSBkbHN0cC9sZXRwCisgICAgIHByZWRp Y2F0ZWQgaW5zbi4gICovCisgIGlmIChNVkVfVlBUX1VOUFJFRElDQVRFRF9JTlNOX1AgKGluc24p ICYmIGluc24gIT0gbG9vcF92Y3RwKQorICAgIHJldHVybiB0cnVlOworICBlbHNlIGlmIChpbnNu ID09IGxvb3BfdmN0cAorCSAgIHx8ICgoaW5zbl92cHJfcmVnX29wZXJhbmQgPSBhcm1fZ2V0X3Jl cXVpcmVkX3Zwcl9yZWdfcGFyYW0gKGluc24pKQorCSAgICAgICAmJiBydHhfZXF1YWxfcCAodmN0 cF92cHJfZ2VuZXJhdGVkLCBpbnNuX3Zwcl9yZWdfb3BlcmFuZCkpKQorICAgIHJldHVybiBmYWxz ZTsKKworICAvKiBGb3IgZWFjaCBVU0UgaW4gdGhlIGluc3RydWN0aW9uIHdlIGFyZSBjYWxsZWQg Zm9yLCB3ZSB3aWxsIGxvb3AgYmFja3dhcmRzCisgICAgIHVwIHRoZSBCQiB0byB0cnkgYW5kIGZp bmQgaWYgaXQgd2FzIERFRi1lZCB3aXRoaW4gdGhlIGRsc3RwL2xldHAgbG9vcC4KKyAgICAgSWYg d2UgZG8gZmluZCBzdWNoIGEgREVGLCB0aGVuIHJlY3Vyc2Ugb24gaXQncyBJTlNOLiAgVGhlIGlu dGVudGlvbiBoZXJlCisgICAgIGlzIGZpbmQgaWYgYW55IG9mIHRoZSBpbnB1dHMgdG8gdGhlIGN1 cnJlbnQgaW5zdHJ1Y3Rpb24gd2VyZSBhZmZlY3RlZCBieQorICAgICBpbXBsaWNpdCBwcmVkaWNh dGlvbiBieSBiZWluZyBNVkVfVlBUX1VOUFJFRElDQVRFRF9JTlNOX1BzIGluIGEgZGxzdHAvbGV0 cAorICAgICBsb29wLiAgKi8KKyAgZGZfcmVmIGluc25fdXNlcyA9IE5VTEw7CisgIEZPUl9FQUNI X0lOU05fVVNFIChpbnNuX3VzZXMsIGluc24pCisgIHsKKyAgICAvKiBTdGFydGluZyBmcm9tIHRo ZSBjdXJyZW50IGluc24sIHNjYW4gYmFja3dhcmRzIHRocm91Z2ggdGhlIGluc24gY2hhaW4KKyAg ICAgICB1bnRpbCBCQl9IRUFEOiAiZm9yIGVhY2ggaW5zbiBpbiB0aGUgQkIgcHJpb3IgdG8gdGhl IGN1cnJlbnQgb25lIi4gICovCisgICAgcnR4X2luc24gKnByZXZfaW5zbiA9IE5VTEw7CisgICAg Zm9yIChwcmV2X2luc24gPSBpbnNuOworCSBwcmV2X2luc24gJiYgcHJldl9pbnNuICE9IFBSRVZf SU5TTiAoQkJfSEVBRCAoQkxPQ0tfRk9SX0lOU04gKGluc24pKSk7CisJIHByZXZfaW5zbiA9IFBS RVZfSU5TTiAocHJldl9pbnNuKSkKKyAgICAgIHsKKwkvKiBMb29rIGF0IGFsbCB0aGUgREVGcyBv ZiB0aGF0IHByZXZpb3VzIGluc246IGlmIG9uZSBvZiB0aGVtIGlzIG9uCisJICAgdGhlIHNhbWUg UkVHIGFzIG91ciBjdXJyZW50IGluc24sIHRoZW4gcmVjdXJzZSBpbiBvcmRlciB0byBjaGVjawor CSAgIHRoYXQgaW5zbidzIFVTRXMuICBJZiBhbnkgb2YgdGhlc2UgaW5zbnMgcmV0dXJuIHRydWUg YXMKKwkgICBNVkVfVlBUX1VOUFJFRElDQVRFRF9JTlNOX1BzLCB0aGVuIHRoZSB3aG9sZSBjaGFp biBpcyBhZmZlY3RlZAorCSAgIGJ5IHRoZSBjaGFuZ2UgaW4gYmVoYXZpb3VyIGZyb20gYmVpbmcg cGxhY2VkIGluIGRsc3RwL2xldHAgbG9vcC4gICovCisJZGZfcmVmIHByZXZfaW5zbl9kZWZzID0g TlVMTDsKKwlGT1JfRUFDSF9JTlNOX0RFRiAocHJldl9pbnNuX2RlZnMsIHByZXZfaW5zbikKKwl7 CisJICBpZiAoREZfUkVGX1JFR05PIChpbnNuX3VzZXMpID09IERGX1JFRl9SRUdOTyAocHJldl9p bnNuX2RlZnMpCisJICAgICAgJiYgaW5zbiAhPSBwcmV2X2luc24KKwkgICAgICAmJiBCTE9DS19G T1JfSU5TTiAoaW5zbikgPT0gQkxPQ0tfRk9SX0lOU04gKHByZXZfaW5zbikKKwkgICAgICAmJiBh cm1fbXZlX2NoZWNrX2RmX2Zvcl9pbXBsaWNfcHJlZGljIChwcmV2X2luc24sCisJCQkJCQkgICAg IGxvb3BfdmN0cCwKKwkJCQkJCSAgICAgdmN0cF92cHJfZ2VuZXJhdGVkKSkKKwkgICAgcmV0dXJu IHRydWU7CisJfQorICAgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworLyogQXR0ZW1w dCB0byB0cmFuc2Zvcm0gdGhlIGxvb3AgY29udGVudHMgb2YgbG9vcCBiYXNpYyBibG9jayBmcm9t IFZQVAorICAgcHJlZGljYXRlZCBpbnNucyBpbnRvIHVucHJlZGljYXRlZCBpbnNucyBmb3IgYSBk bHN0cC9sZXRwIGxvb3AuICAqLworCitydHgKK2FybV9hdHRlbXB0X2Rsc3RwX3RyYW5zZm9ybSAo cnR4IGxhYmVsKQoreworICBpbnQgZGVjcmVtZW50bnVtOworICBiYXNpY19ibG9jayBib2R5ID0g QkxPQ0tfRk9SX0lOU04gKGxhYmVsKS0+cHJldl9iYjsKKworICAvKiBFbnN1cmUgdGhhdCB0aGUg YmIgaXMgd2l0aGluIGEgbG9vcCB0aGF0IGhhcyBhbGwgcmVxdWlyZWQgbWV0YWRhdGEuICAqLwor ICBpZiAoIWJvZHktPmxvb3BfZmF0aGVyIHx8ICFib2R5LT5sb29wX2ZhdGhlci0+aGVhZGVyCisg ICAgICB8fCAhYm9keS0+bG9vcF9mYXRoZXItPnNpbXBsZV9sb29wX2Rlc2MpCisgICAgcmV0dXJu IEdFTl9JTlQgKDEpOworICBiYXNpY19ibG9jayBwcmVfbG9vcF9iYjEgPSBsb29wX3ByZWhlYWRl cl9lZGdlIChib2R5LT5sb29wX2ZhdGhlciktPnNyYzsKKyAgYmFzaWNfYmxvY2sgcHJlX2xvb3Bf YmIyID0gcHJlX2xvb3BfYmIxLT5wcmV2X2JiOworICBydHggY291bnQgPSBzaW1wbGVfbG9vcF9k ZXNjIChib2R5LT5sb29wX2ZhdGhlciktPm5pdGVyX2V4cHI7CisgIHJ0eCBzaGlmdF9leHByID0g TlVMTF9SVFg7CisgIHJ0eCBpbml0aWFsX2NvbXBhcmUgPSBOVUxMX1JUWDsKKworICAvKiBEb2xv b3AgY2FuIG9ubHkgYmUgZG9uZSAiZWxlbWVudHdpc2UiIHdpdGggcHJlZGljYXRlZCBkbHN0cC9s ZXRwIGlmIGl0CisgICAgIGNvbnRhaW5zIGEgVkNUUCBvbiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRz IHByb2Nlc3NlZCBieSB0aGUgbG9vcC4KKyAgICAgRmluZCB0aGUgVkNUUCBwcmVkaWNhdGUgZ2Vu ZXJhdGlvbiBpbnNpZGUgdGhlIGxvb3AgYm9keSBCQi4gICovCisgIHJ0eF9pbnNuICp2Y3RwX2lu c24gPSBhcm1fbXZlX2dldF9sb29wX3ZjdHAgKGJvZHkpOworICBpZiAoIXZjdHBfaW5zbikKKyAg ICByZXR1cm4gR0VOX0lOVCAoMSk7CisKKyAgLyogQWRkaXRpb25hbGx5LCB0aGUgaXRlcmF0aW9u IGNvdW50ZXIgbXVzdCBvbmx5IGdldCBkZWNyZW1lbnRlZCBieSB0aGUKKyAgICAgbnVtYmVyIG9m IE1WRSBsYW5lcyAoYXMgcGVyIHRoZSBkYXRhIHR5cGUpLgorICAgICBUaGVyZSBhcmUgb25seSB0 d28gdHlwZXMgb2YgbG9vcHMgdGhhdCBjYW4gYmUgdHVybmVkIGludG8gZGxzdHAvbGV0cCBsb29w czoKKyAgICAgQSkgTG9vcHMgb2YgdGhlIGZvcm06CisJIHdoaWxlIChudW1fb2ZfZWxlbSA+IDAp CisJICAgeworCSAgICAgcCA9IHZjdHA8c2l6ZT4gKG51bV9vZl9lbGVtKQorCSAgICAgbiAtPSBu dW1fb2ZfbGFuZXM7CisJICAgfQorICAgICBCKSBMb29wcyBvZiB0aGUgZm9ybToKKwkgaW50IG51 bV9vZl9pdGVycyA9IChudW1fb2ZfZWxlbSArIG51bV9vZl9sYW5lcyAtIDEpIC8gbnVtX29mX2xh bmVzCisJIGZvciAoaSA9IDA7IGkgPCBudW1fb2ZfaXRlcnM7IGkrKykKKwkgICB7CisJICAgICBw ID0gdmN0cDxzaXplPiAobnVtX29mX2VsZW0pCisJICAgICBuIC09IG51bV9vZl9sYW5lczsKKwkg ICB9CisKKyAgICAgVGhlc2UgY2FuIGJlIHZlcmlmaWVkIHRocm91Z2ggdGhlICJjb3VudCIgdmFy aWFibGUgaW4gdGhlIG1pZGRsZS1lbmQKKyAgICAgKGEuay5hLiBnZXRfc2ltcGxlX2xvb3BfZGVz YyAobG9vcCktPmRlc2MtPm5pdGVyX2V4cHIpLiAgVGhpcyBpcyB0aGUKKyAgICAgZXhwcmVzc2lv biB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdGhhdCB0aGUgbG9v cCB3b3VsZAorICAgICBleGVjdXRlIGZvciBhIHN0YW5kYXJkIGRscy9sZSBsb29wLgorCisgICAg IEZvciBkbHN0cC9sZXRwIHdlIG9ubHkgc3VwcG9ydCBjYXNlcyB3aGVyZSB0aGlzIGlzIGEgcG93 ZXIgb2YgMiwgc28gZnJvbQorICAgICAiY291bnQiIHdlIHdhbnQgdG8gZXh0cmFjdCBzb21ldGhp bmcgbGlrZToKKwkoIFtsL2FdIHNoaWZ0cnQ6ICh4KSAoY29uc3RfaW50IHkpKQorICAgICBGb3Ig bG9vcHMgb2YgZm9ybSBBKSwgImNvdW50IiBpcyBhbHJlYWR5IGEgc2hpZnRydCBleHByZXNzaW9u LgorICAgICBGb3IgbG9vcHMgb2YgZm9ybSBCKSwgImNvdW50IiBnZXRzIGdpdmVuIGFzOgorCShw bHVzOiAobm90IChpKSkgKG51bV9vZl9pdGVycykpCisgICAgIHdpdGggc2V0dXAgaGFwcGVuaW5n IGluIGEgcHJldmlvdXMgYmFzaWMgYmxvY2suICBIZXJlIHdlIG5lZWQgdG8gdmVyaWZ5OgorICAg ICAgICogVGhhdCBpIGlzIF9hbHdheXNfIGluaXRpYWxpemVkIHRvIChjb25zdF9pbnQgMCkKKyAg ICAgICAqIFRoYXQgbnVtX29mX2l0ZXJzIGlzIGEgc2hpZnRydCBleHByZXNzaW9uLgorICAqLwor ICBpZiAoR0VUX0NPREUgKGNvdW50KSA9PSBMU0hJRlRSVAorICAgICAgfHwgR0VUX0NPREUgKGNv dW50KSA9PSBBU0hJRlRSVCkKKyAgICB7CisgICAgICBzaGlmdF9leHByID0gY291bnQ7CisgICAg ICAvKiBJbiB0aGlzIHNpdHVhdGlvbiB3aGVyZSB3ZSBhcmUgbG9vcGluZyBvbiBhIGRlY3JlYXNp bmcgbnVtYmVyIG9mCisJIGVsZW1lbnRzLCBhIGRsc3RwL2xldHAgbG9vcCBjYW4gb25seSB3b3Jr IGlmIHRoZSBsb29waW5nIGVuZHMgd2hlbiB0aGUKKwkgZWxlbWVudCBjb3VudGVyIHJlYWNoZXMg emVybyBhbmQgbm90IHNvbWUgb3RoZXIgdmFsdWUgKGUuZy4gbiA+IDAKKwkgd29ya3MsIG5vdCBu ID4gMSksIG9yIHdlIGNhbiBpbmNvcnJlY3RseSBlbmQgdXAgcnVubmluZyBvbmUgYWRkaXRpb25h bAorCSBpdGVyYXRpb24uICBUbyBieS1wYXNzIGFueSBob2lzdGluZyB0aGF0IHRoZSBjb21waWxl ciBtYXkgaGF2ZSBkb25lCisJIHdpdGggdGhlIGZpcnN0IGFyZyB0byBgY291bnRgLCB3ZSBjYW4g aW5zdGVhZCBsb29rIGF0IHRoZSBiYiBiZWZvcmUKKwkgdGhlIGxvb3AgcHJlaGVhZGVyOiB0aGlz IHNob3VsZCBlbmQgd2l0aCBhIGNtcCtqdW1wIHBhaXIsIHdoZXJlIHRoZQorCSBjbXAgbmVlZHMg dG8gYmU6IChjb25zdF9pbnQgMCkuICAqLworICAgICAgaWYgKCFwcmVfbG9vcF9iYjIgfHwgIUJC X0VORCAocHJlX2xvb3BfYmIyKQorCSAgfHwgIXByZXZfbm9ubm90ZV9ub25kZWJ1Z19pbnNuX2Ji IChCQl9FTkQgKHByZV9sb29wX2JiMikpCisJICB8fCAhSU5TTl9QIChwcmV2X25vbm5vdGVfbm9u ZGVidWdfaW5zbl9iYiAoQkJfRU5EIChwcmVfbG9vcF9iYjIpKSkpCisJcmV0dXJuIEdFTl9JTlQg KDEpOworICAgICAgZWxzZQorCWluaXRpYWxfY29tcGFyZQorCSAgICA9IFBBVFRFUk4gKHByZXZf bm9ubm90ZV9ub25kZWJ1Z19pbnNuX2JiIChCQl9FTkQgKHByZV9sb29wX2JiMikpKTsKKworICAg ICAgaWYgKCEoaW5pdGlhbF9jb21wYXJlICYmIEdFVF9DT0RFIChpbml0aWFsX2NvbXBhcmUpID09 IFNFVAorCSAgICAmJiBjY19yZWdpc3RlciAoWEVYUCAoaW5pdGlhbF9jb21wYXJlLCAwKSwgVk9J RG1vZGUpCisJICAgICYmIEdFVF9DT0RFIChYRVhQIChpbml0aWFsX2NvbXBhcmUsIDEpKSA9PSBD T01QQVJFCisJICAgICYmIENPTlNUX0lOVF9QIChYRVhQIChYRVhQIChpbml0aWFsX2NvbXBhcmUs IDEpLCAxKSkKKwkgICAgJiYgSU5UVkFMIChYRVhQIChYRVhQIChpbml0aWFsX2NvbXBhcmUsIDEp LCAxKSkgPT0gMCkpCisJcmV0dXJuIEdFTl9JTlQgKDEpOworICAgIH0KKyAgZWxzZSBpZiAoR0VU X0NPREUgKGNvdW50KSA9PSBQTFVTKQorICAgIHsKKyAgICAgIGlmICghKEdFVF9DT0RFIChYRVhQ IChjb3VudCwgMCkpID09IE5PVAorCSAgICAmJiBSRUdfUCAoWEVYUCAoWEVYUCAoY291bnQsIDAp LCAwKSkgJiYgUkVHX1AgKFhFWFAgKGNvdW50LCAxKSkpKQorCXJldHVybiBHRU5fSU5UICgxKTsK KyAgICAgIGVsc2UKKwl7CisJICAvKiBWZXJpZnkgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZSBw bHVzLiAgKi8KKwkgIHJ0eCBsb29wX2NvdW50ZXIgPSBYRVhQIChYRVhQIChjb3VudCwgMCksIDAp OworCSAgZGZfcmVmIGxvb3BfY291bnRlcl9pbml0X2RlZiA9IE5VTEw7CisJICBsb29wX2NvdW50 ZXJfaW5pdF9kZWYKKwkgICAgICA9IGRmX2JiX3JlZ25vX2xhc3RfZGVmX2ZpbmQgKHByZV9sb29w X2JiMSwgUkVHTk8gKGxvb3BfY291bnRlcikpOworCSAgcnR4IGxvb3BfY291bnRlcl9pbml0CisJ ICAgICAgPSBQQVRURVJOIChERl9SRUZfSU5TTiAobG9vcF9jb3VudGVyX2luaXRfZGVmKSk7CisJ ICBpZiAoIShsb29wX2NvdW50ZXJfaW5pdF9kZWYgJiYgR0VUX0NPREUgKGxvb3BfY291bnRlcl9p bml0KSA9PSBTRVQKKwkJJiYgQ09OU1RfSU5UX1AgKFhFWFAgKGxvb3BfY291bnRlcl9pbml0LCAx KSkKKwkJJiYgSU5UVkFMIChYRVhQIChsb29wX2NvdW50ZXJfaW5pdCwgMSkpID09IDApKQorCSAg ICByZXR1cm4gR0VOX0lOVCAoMSk7CisKKwkgIC8qIFZlcmlmeSB0aGUgc2Vjb25kIGFyZ3VtZW50 IHRvIHRoZSBwbHVzLiAgKi8KKwkgIHJ0eCBjb3VudF9tYXggPSBYRVhQIChjb3VudCwgMSk7CisJ ICBkZl9yZWYgY291bnRlcl9tYXhfZGVmID0gTlVMTDsKKwkgIGNvdW50ZXJfbWF4X2RlZiA9IERG X1JFR19ERUZfQ0hBSU4gKFJFR05PIChjb3VudF9tYXgpKTsKKwkgIGlmIChjb3VudGVyX21heF9k ZWYKKwkgICAgICAmJiAoR0VUX0NPREUgKFhFWFAgKHNpbmdsZV9zZXQgKERGX1JFRl9JTlNOIChj b3VudGVyX21heF9kZWYpKSwKKwkJCQkgIDEpKQorCQkgICAgICA9PSBMU0hJRlRSVAorCQkgIHx8 IEdFVF9DT0RFICgKKwkJCSBYRVhQIChzaW5nbGVfc2V0IChERl9SRUZfSU5TTiAoY291bnRlcl9t YXhfZGVmKSksIDEpKQorCQkJID09IEFTSElGVFJUKSkKKwkgICAgeworCSAgICAgIHNoaWZ0X2V4 cHIKKwkJICA9IFhFWFAgKHNpbmdsZV9zZXQgKERGX1JFRl9JTlNOIChjb3VudGVyX21heF9kZWYp KSwgMSk7CisJICAgIH0KKwkgIGVsc2UKKwkgICAgcmV0dXJuIEdFTl9JTlQgKDEpOworCX0KKyAg ICB9CisgIGVsc2UKKyAgICByZXR1cm4gR0VOX0lOVCAoMSk7CisKKyAgLyogQ2hlY2sgdGhlIHZh bGlkaXR5IG9mIHRoZSBzaGlmdDogdGhlIHNlY29uZCBvcGVyYW5kIG5lZWRzIHRvIGJlIGEKKyAg ICAgY29uc3RhbnQuICAqLworICBpZiAoIUNPTlNUQU5UX1AgKFhFWFAgKHNoaWZ0X2V4cHIsIDEp KSkKKyAgICByZXR1cm4gR0VOX0lOVCAoMSk7CisgIC8qIEV4dHJhY3QgdGhlIGxvb3AgZGVjcmVt ZW50IGZyb20gdGhlIFtBL0xdU0hJRlRSIDJuZCBvcGVyYW5kIG9mIGNvdW50LiAgKi8KKyAgZGVj cmVtZW50bnVtID0gKDEgPDwgKElOVFZBTCAoWEVYUCAoc2hpZnRfZXhwciwgMSkpKSk7CisgIC8q IEVuc3VyZSBpdCBtYXRjaGVzIHRoZSBudW1iZXIgb2YgbGFuZXMgb2YgdGhlIHZjdHAgaW5zdHJ1 Y3Rpb24uICAqLworICBpZiAoZGVjcmVtZW50bnVtICE9IGFybV9tdmVfZ2V0X3ZjdHBfbGFuZXMg KFBBVFRFUk4gKHZjdHBfaW5zbikpKQorICAgIHJldHVybiBHRU5fSU5UICgxKTsKKworICBydHhf aW5zbiAqaW5zbiA9IDA7CisgIHJ0eF9pbnNuICpjdXJfaW5zbiA9IDA7CisgIHJ0eF9pbnNuICpz ZXE7CisgIHJ0eCB2Y3RwX3Zwcl9nZW5lcmF0ZWQgPSBOVUxMX1JUWDsKKworICAvKiBTY2FuIHRo cm91Z2ggdGhlIGluc25zIGluIHRoZSBsb29wIGJiIGFuZCBlbWl0IHRoZSB0cmFuc2Zvcm1lZCBi YgorICAgICBpbnNucyB0byBhIHNlcXVlbmNlLiAgKi8KKyAgc3RhcnRfc2VxdWVuY2UgKCk7Cisg IEZPUl9CQl9JTlNOUyAoYm9keSwgaW5zbikKKyAgICB7CisgICAgICBydHggaW5zbl92cHJfcmVn X29wZXJhbmQgPSBOVUxMX1JUWDsKKyAgICAgIGlmIChHRVRfQ09ERSAoaW5zbikgPT0gQ09ERV9M QUJFTCB8fCBOT1RFX0lOU05fQkFTSUNfQkxPQ0tfUCAoaW5zbikpCisJY29udGludWU7CisgICAg ICBlbHNlIGlmIChOT1RFX1AgKGluc24pKQorCWVtaXRfbm90ZSAoKGVudW0gaW5zbl9ub3RlKSBO T1RFX0tJTkQgKGluc24pKTsKKyAgICAgIGVsc2UgaWYgKERFQlVHX0lOU05fUCAoaW5zbikpCisJ ZW1pdF9kZWJ1Z19pbnNuIChQQVRURVJOIChpbnNuKSk7CisgICAgICBlbHNlIGlmICghSU5TTl9Q IChpbnNuKSkKKwl7CisJICBlbmRfc2VxdWVuY2UgKCk7CisJICByZXR1cm4gR0VOX0lOVCAoMSk7 CisJfQorICAgICAgLyogV2hlbiB3ZSBmaW5kIHRoZSB2Y3RwIGluc3RydWN0aW9uOiBUaGlzIG1h eSBiZSBmb2xsb3dlZCBieQorICAgICAgYSB6ZXJvLWV4dGVuZCBpbnNuIHRvIFNJbW9kZS4gIElm IGl0IGlzLCB0aGVuIHNhdmUgdGhlCisgICAgICB6ZXJvLWV4dGVuZGVkIFJFRyBpbnRvIHZjdHBf dnByX2dlbmVyYXRlZC4gIElmIHRoZXJlIGlzIG5vCisgICAgICB6ZXJvLWV4dGVuZCwgdGhlbiBz dG9yZSB0aGUgcmF3IG91dHB1dCBvZiB0aGUgdmN0cC4KKyAgICAgIEZvciBhbnkgVlBULXByZWRp Y2F0ZWQgaW5zdHJ1Y3Rpb25zIHdlIG5lZWQgdG8gZW5zdXJlIHRoYXQKKyAgICAgIHRoZSBWUFIg dGhleSB1c2UgaXMgdGhlIHNhbWUgYXMgdGhlIG9uZSBnaXZlbiBoZXJlIGFuZAorICAgICAgdGhl eSBvZnRlbiBjb25zdW1lIHRoZSBvdXRwdXQgb2YgYSBzdWJyZWcgb2YgdGhlIFNJbW9kZQorICAg ICAgemVyby1leHRlbmRlZCBWUFItcmVnLiAgQXMgYSByZXN1bHQsIGNvbXBhcmluZyBhZ2FpbnN0 IHRoZQorICAgICAgb3V0cHV0IG9mIHRoZSB6ZXJvLWV4dGVuZCBpcyBtb3JlIGxpa2VseSB0byBz dWNjZWVkLgorICAgICAgVGhpcyBjb2RlIGFsc28gZ3VhcmFudGVlcyB0byB1cyB0aGF0IHRoZSB2 Y3RwIGNvbWVzIGJlZm9yZQorICAgICAgYW55IGluc3RydWN0aW9ucyB0aGF0IHVzZSB0aGUgVlBS IHdpdGhpbiB0aGUgbG9vcCwgZm9yIHRoZQorICAgICAgZGxzdHAvbGV0cCB0cmFuc2Zvcm0gdG8g c3VjY2VlZC4gICovCisgICAgICBlbHNlIGlmIChpbnNuID09IHZjdHBfaW5zbikKKwl7CisJICBy dHhfaW5zbiAqbmV4dF91c2UxID0gTlVMTDsKKwkgIGRmX3JlZiB1c2U7CisJICBmb3IgKHVzZSA9 IERGX1JFR19VU0VfQ0hBSU4gKAorCQkgICBERl9SRUZfUkVHTk8gKERGX0lOU05fSU5GT19ERUZT IChERl9JTlNOX0lORk9fR0VUIChpbnNuKSkpKTsKKwkgICAgICAgdXNlOyB1c2UgPSBERl9SRUZf TkVYVF9SRUcgKHVzZSkpCisJICAgIGlmICghbmV4dF91c2UxICYmIE5PTkRFQlVHX0lOU05fUCAo REZfUkVGX0lOU04gKHVzZSkpKQorCSAgICAgIG5leHRfdXNlMSA9IERGX1JFRl9JTlNOICh1c2Up OworCisJICBpZiAoR0VUX0NPREUgKFNFVF9TUkMgKHNpbmdsZV9zZXQgKG5leHRfdXNlMSkpKSA9 PSBaRVJPX0VYVEVORCkKKwkgICAgeworCSAgICAgIHJ0eF9pbnNuICpuZXh0X3VzZTIgPSBOVUxM OworCSAgICAgIGZvciAodXNlID0gREZfUkVHX1VTRV9DSEFJTiAoREZfUkVGX1JFR05PICgKKwkJ ICAgICAgIERGX0lOU05fSU5GT19ERUZTIChERl9JTlNOX0lORk9fR0VUIChuZXh0X3VzZTEpKSkp OworCQkgICB1c2U7IHVzZSA9IERGX1JFRl9ORVhUX1JFRyAodXNlKSkKKwkJaWYgKCFuZXh0X3Vz ZTIgJiYgTk9OREVCVUdfSU5TTl9QIChERl9SRUZfSU5TTiAodXNlKSkpCisJCSAgbmV4dF91c2Uy ID0gREZfUkVGX0lOU04gKHVzZSk7CisKKwkgICAgICBpZiAoR0VUX0NPREUgKFNFVF9TUkMgKHNp bmdsZV9zZXQgKG5leHRfdXNlMikpKSA9PSBTVUJSRUcpCisJCXZjdHBfdnByX2dlbmVyYXRlZCA9 IFhFWFAgKFBBVFRFUk4gKG5leHRfdXNlMiksIDApOworCSAgICB9CisKKwkgIGlmICghdmN0cF92 cHJfZ2VuZXJhdGVkKQorCSAgICB7CisJICAgICAgZW5kX3NlcXVlbmNlICgpOworCSAgICAgIHJl dHVybiBHRU5fSU5UICgxKTsKKwkgICAgfQorCSAgICAvKiBBbHNvIGVtaXQgYSBVU0Ugb2YgdGhl IHNvdXJjZSByZWdpc3RlciBvZiB0aGUgdmN0cC4KKwkgICAgIFRoaXMgaG9sZHMgdGhlIG51bWJl ciBvZiBlbGVtZW50cyBiZWluZyBwcm9jZXNzZWQKKwkgICAgIGJ5IHRoZSBsb29wLiAgVGhpcyBs YXRlciBnZXRzIHN0b3JlZCBpbnRvIGBjb3VudGAKKwkgICAgIGZvciB0aGUgbWlkZGxlLWVuZCB0 byBpbml0aWFsaXNlIHRoZSBsb29wIGNvdW50ZXIuICAqLworCSAgZW1pdF91c2UgKFhWRUNFWFAg KFhFWFAgKFBBVFRFUk4gKGluc24pLCAxKSwgMCwgMCkpOworCSAgY29udGludWU7CisJfQorICAg ICAgIC8qIElmIHRoZSBpbnNuIHBhdHRlcm4gcmVxdWlyZXMgdGhlIHVzZSBvZiB0aGUgVlBSIHZh bHVlIGZyb20gdGhlCisJICB2Y3RwIGFzIGFuIGlucHV0IHBhcmFtZXRlci4gICovCisgICAgICBl bHNlIGlmICgoaW5zbl92cHJfcmVnX29wZXJhbmQgPSBhcm1fZ2V0X3JlcXVpcmVkX3Zwcl9yZWdf cGFyYW0gKGluc24pKQorCSAgICAgICAmJiBydHhfZXF1YWxfcCAodmN0cF92cHJfZ2VuZXJhdGVk LCBpbnNuX3Zwcl9yZWdfb3BlcmFuZCkpCisJeworCSAgZ2NjX2Fzc2VydCAoTVZFX1ZQVF9QUkVE SUNBVEVEX0lOU05fUCAoaW5zbikpOworCSAgaW50IG5ld19pY29kZSA9IGdldF9hdHRyX212ZV91 bnByZWRpY2F0ZWRfaW5zbiAoaW5zbik7CisJICBleHRyYWN0X2luc24gKGluc24pOworCSAgcnR4 IGFycls4XTsKKwkgIGludCBqID0gMDsKKworCSAgLyogV2hlbiB0cmFuc2Zvcm1pbmcgYSBWUFQt cHJlZGljYXRlZCBpbnN0cnVjdGlvbgorCSAgICAgaW50byBpdHMgdW5wcmVkaWNhdGVkIGVxdWl2 YWxlbnQgd2UgbmVlZCB0byBkcm9wCisJICAgICB0aGUgVlBSIG9wZXJhbmQgYW5kIHdlIG1heSBu ZWVkIHRvIGFsc28gZHJvcCBhCisJICAgICBtZXJnZSAidnVuaW5pdCIgaW5wdXQgb3BlcmFuZCwg ZGVwZW5kaW5nIG9uIHRoZQorCSAgICAgaW5zdHJ1Y3Rpb24gcGF0dGVybi4gIEhlcmUgZW5zdXJl IHRoYXQgd2UgaGF2ZSBhdAorCSAgICAgbW9zdCBhIHR3by1vcGVyYW5kIGRpZmZlcmVuY2UgYmV0 d2VlbiB0aGUgdHdvCisJICAgICBpbnN0cnVuY3Rpb25zLiAgKi8KKwkgIGludCBuX29wZXJhbmRz X2RpZmYKKwkgICAgICA9IHJlY29nX2RhdGEubl9vcGVyYW5kcyAtIGluc25fZGF0YVtuZXdfaWNv ZGVdLm5fb3BlcmFuZHM7CisJICBnY2NfYXNzZXJ0IChuX29wZXJhbmRzX2RpZmYgPiAwICYmIG5f b3BlcmFuZHNfZGlmZiA8PSAyKTsKKworCSAgLyogVGhlbiwgbG9vcCB0aHJvdWdoIHRoZSBvcGVy YW5kcyBvZiB0aGUgcHJlZGljYXRlZAorCSAgICAgaW5zdHJ1Y3Rpb24sIGFuZCByZXRhaW4gdGhl IG9uZXMgdGhhdCBtYXAgdG8gdGhlCisJICAgICB1bnByZWRpY2F0ZWQgaW5zdHJ1Y3Rpb24uICAq LworCSAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvZ19kYXRhLm5fb3BlcmFuZHM7IGkrKykKKwkg ICAgeworCSAgICAgIC8qIElnbm9yZSB0aGUgVlBSIGFuZCwgaWYgbmVlZGVkLCB0aGUgdnVuaW5p dAorCQkgb3BlcmFuZC4gICovCisJICAgICAgaWYgKGluc25fdnByX3JlZ19vcGVyYW5kID09IHJl Y29nX2RhdGEub3BlcmFuZFtpXQorCQkgIHx8IChuX29wZXJhbmRzX2RpZmYgPT0gMgorCQkgICAg ICAmJiAhc3RyY21wIChyZWNvZ19kYXRhLmNvbnN0cmFpbnRzW2ldLCAiMCIpKSkKKwkJY29udGlu dWU7CisJICAgICAgZWxzZQorCQl7CisJCSAgYXJyW2pdID0gcmVjb2dfZGF0YS5vcGVyYW5kW2ld OworCQkgIGorKzsKKwkJfQorCSAgICB9CisKKwkgIC8qIEZpbmFsbHksIGVtaXQgdGhlIHVwcmVk aWNhdGVkIGluc3RydWN0aW9uLiAgKi8KKwkgIHN3aXRjaCAoaikKKwkgICAgeworCSAgICAgIGNh c2UgMToKKwkJZW1pdF9pbnNuIChHRU5fRkNOIChuZXdfaWNvZGUpIChhcnJbMF0pKTsKKwkJYnJl YWs7CisJICAgICAgY2FzZSAyOgorCQllbWl0X2luc24gKEdFTl9GQ04gKG5ld19pY29kZSkgKGFy clswXSwgYXJyWzFdKSk7CisJCWJyZWFrOworCSAgICAgIGNhc2UgMzoKKwkJZW1pdF9pbnNuIChH RU5fRkNOIChuZXdfaWNvZGUpIChhcnJbMF0sIGFyclsxXSwgYXJyWzJdKSk7CisJCWJyZWFrOwor CSAgICAgIGNhc2UgNDoKKwkJZW1pdF9pbnNuIChHRU5fRkNOIChuZXdfaWNvZGUpIChhcnJbMF0s IGFyclsxXSwgYXJyWzJdLAorCQkJCQkJYXJyWzNdKSk7CisJCWJyZWFrOworCSAgICAgIGNhc2Ug NToKKwkJZW1pdF9pbnNuIChHRU5fRkNOIChuZXdfaWNvZGUpIChhcnJbMF0sIGFyclsxXSwgYXJy WzJdLCBhcnJbM10sCisJCQkJCQlhcnJbNF0pKTsKKwkJYnJlYWs7CisJICAgICAgY2FzZSA2Ogor CQllbWl0X2luc24gKEdFTl9GQ04gKG5ld19pY29kZSkgKGFyclswXSwgYXJyWzFdLCBhcnJbMl0s IGFyclszXSwKKwkJCQkJCWFycls0XSwgYXJyWzVdKSk7CisJCWJyZWFrOworCSAgICAgIGNhc2Ug NzoKKwkJZW1pdF9pbnNuIChHRU5fRkNOIChuZXdfaWNvZGUpIChhcnJbMF0sIGFyclsxXSwgYXJy WzJdLCBhcnJbM10sCisJCQkJCQlhcnJbNF0sIGFycls1XSwgYXJyWzZdKSk7CisJCWJyZWFrOwor CSAgICAgIGRlZmF1bHQ6CisJCWdjY191bnJlYWNoYWJsZSAoKTsKKwkgICAgfQorCX0KKyAgICAg IC8qIElmIHRoZSBpbnNuIGlzbid0IFZQVCBwcmVkaWNhdGVkIG9uIHZjdHBfdnByX2dlbmVyYXRl ZCwgd2UgbmVlZCB0bworCSBtYWtlIHN1cmUgdGhhdCBpdCBpcyBzdGlsbCB2YWxpZCB3aXRoaW4g dGhlIGRsc3RwL2xldHAgbG9vcC4gICovCisgICAgICBlbHNlCisJeworCSAgLyogTm9uZSBvZiBy ZWdpc3RlcnMgVVNFLWQgYnkgdGhlIGluc3RydWN0aW9uIG5lZWQgY2FuIGJlIHRoZSBWUFIKKwkg ICAgIHZjdHBfdnByX2dlbmVyYXRlZC4gIFRoaXMgYmxvY2tzIHRoZSBvcHRpbWlzYXRpb24gaWYg dGhlcmUgYW55CisJICAgICBpbnN0cnVjdGlvbnMgdGhhdCB1c2UgdGhlIG9wdGltaXNlZC1vdXQg VlBSIHZhbHVlIGluIGFueSB3YXkKKwkgICAgIG90aGVyIHRoYW4gYXMgYSBWUFQgYmxvY2sgcHJl ZGljYXRlLiAgKi8KKwkgIGRmX3JlZiBpbnNuX3VzZXMgPSBOVUxMOworCSAgRk9SX0VBQ0hfSU5T Tl9VU0UgKGluc25fdXNlcywgaW5zbikKKwkgIHsKKwkgICAgaWYgKHJ0eF9lcXVhbF9wICh2Y3Rw X3Zwcl9nZW5lcmF0ZWQsIERGX1JFRl9SRUcgKGluc25fdXNlcykpKQorCSAgICAgIHsKKwkJZW5k X3NlcXVlbmNlICgpOworCQlyZXR1cm4gR0VOX0lOVCAoMSk7CisJICAgICAgfQorCSAgfQorCSAg LyogSWYgd2l0aGluIHRoZSBsb29wIHdlIGhhdmUgYW4gTVZFIHZlY3RvciBpbnN0cnVjdGlvbiB0 aGF0IGlzCisJICAgICB1bnByZWRpY2F0ZWQsIHRoZSBkbHN0cC9sZXRwIGxvb3Bpbmcgd2lsbCBh ZGQgaW1wbGljaXQKKwkgICAgIHByZWRpY2F0aW9uIHRvIGl0LiAgVGhpcyB3aWxsIHJlc3VsdCBp biBhIGNoYW5nZSBpbiBiZWhhdmlvdXIKKwkgICAgIG9mIHRoZSBpbnN0cnVjdGlvbiwgc28gd2Ug bmVlZCB0byBmaW5kIG91dCBpZiBhbnkgaW5zdHJ1Y3Rpb25zCisJICAgICB0aGF0IGZlZWQgaW50 byB0aGUgY3VycmVudCBpbnN0cnVjdGlvbiB3ZXJlIGltcGxpY2l0bHkKKwkgICAgIHByZWRpY2F0 ZWQuICAqLworCSAgaWYgKGFybV9tdmVfY2hlY2tfZGZfZm9yX2ltcGxpY19wcmVkaWMgKGluc24s IHZjdHBfaW5zbiwKKwkJCQkJCSAgdmN0cF92cHJfZ2VuZXJhdGVkKSkKKwkgICAgeworCSAgICAg IGlmIChtdmVfbWVtb3J5X29wZXJhbmQgKFNFVF9ERVNUIChzaW5nbGVfc2V0IChpbnNuKSksCisJ CQkJICAgICAgR0VUX01PREUgKFNFVF9ERVNUIChzaW5nbGVfc2V0IChpbnNuKSkpKSkKKwkJewor CQkgIGVuZF9zZXF1ZW5jZSAoKTsKKwkJICByZXR1cm4gR0VOX0lOVCAoMSk7CisJCX0KKworCSAg ICAgLyogTmV4dCwgaWYgd2UgaGF2ZSBpZGVudGlmaWVkIHRoYXQgdGhlIGN1cnJlbnQgREVGIHdp bGwgYmUKKwkJbW9kaWZpZWQgYnkgc3VjaCBpbXBsaWNpdCBwcmVkaWNhdGlvbiwgc2NhbiB0aHJv dWdoIGFsbCB0aGUKKwkJaW5zbnMgdGhhdCBVU0UgaXQgYW5kIGJhaWwgb3V0IGlmIGFueSBvbmUg aXMgb3V0c2lkZSB0aGUKKwkJY3VycmVudCBiYXNpYyBibG9jay4gICovCisJICAgICAgZGZfcmVm IGluc25fZGVmID0gTlVMTDsKKwkgICAgICBpbnNuX2RlZiA9IERGX0lOU05fSU5GT19ERUZTIChE Rl9JTlNOX0lORk9fR0VUIChpbnNuKSk7CisJICAgICAgaWYgKGluc25fZGVmKQorCQl7CisJCSAg Zm9yIChkZl9yZWYgdXNlID0gREZfUkVHX1VTRV9DSEFJTiAoREZfUkVGX1JFR05PIChpbnNuX2Rl ZikpOworCQkgICAgICAgdXNlOyB1c2UgPSBERl9SRUZfTkVYVF9SRUcgKHVzZSkpCisJCSAgICB7 CisJCSAgICAgIHJ0eF9pbnNuICpuZXh0X3VzZV9pbnNuID0gREZfUkVGX0lOU04gKHVzZSk7CisJ CSAgICAgIGlmIChOT05ERUJVR19JTlNOX1AgKG5leHRfdXNlX2luc24pKQorCQkJeworCQkJICBy dHggbmV4dF9pbnNuX3NldF9kZXN0CisJCQkgICAgICA9IFNFVF9ERVNUIChzaW5nbGVfc2V0IChu ZXh0X3VzZV9pbnNuKSk7CisJCQkgIGlmIChCTE9DS19GT1JfSU5TTiAoaW5zbikKKwkJCSAgICAg ICE9IEJMT0NLX0ZPUl9JTlNOIChuZXh0X3VzZV9pbnNuKSkKKwkJCSAgeworCQkJICAgIGVuZF9z ZXF1ZW5jZSAoKTsKKwkJCSAgICByZXR1cm4gR0VOX0lOVCAoMSk7CisJCQkgIH0KKwkJCX0KKwkJ ICAgIH0KKwkJfQorCSAgICB9CisJICBlbWl0X2luc24gKFBBVFRFUk4gKGluc24pKTsKKwl9Cisg ICAgfQorICBzZXEgPSBnZXRfaW5zbnMgKCk7CisgIGVuZF9zZXF1ZW5jZSAoKTsKKworICAvKiBS ZS13cml0ZSB0aGUgZW50aXJlIEJCIGNvbnRlbnRzIHdpdGggdGhlIHRyYW5zZm9ybWVkCisgICAg IHNlcXVlbmNlLiAgKi8KKyAgRk9SX0JCX0lOU05TX1NBRkUgKGJvZHksIGluc24sIGN1cl9pbnNu KQorICAgIGlmICghKEdFVF9DT0RFIChpbnNuKSA9PSBDT0RFX0xBQkVMIHx8IE5PVEVfSU5TTl9C QVNJQ19CTE9DS19QIChpbnNuKSkpCisgICAgICBkZWxldGVfaW5zbiAoaW5zbik7CisgIGZvciAo aW5zbiA9IHNlcTsgTkVYVF9JTlNOIChpbnNuKTsgaW5zbiA9IE5FWFRfSU5TTiAoaW5zbikpCisg ICAgaWYgKE5PVEVfUCAoaW5zbikpCisgICAgICBlbWl0X25vdGVfYWZ0ZXIgKChlbnVtIGluc25f bm90ZSlOT1RFX0tJTkQgKGluc24pLCBCQl9FTkQgKGJvZHkpKTsKKyAgICBlbHNlIGlmIChERUJV R19JTlNOX1AgKGluc24pKQorICAgICAgZW1pdF9kZWJ1Z19pbnNuX2FmdGVyIChQQVRURVJOIChp bnNuKSwgQkJfRU5EIChib2R5KSk7CisgICAgZWxzZQorICAgICAgZW1pdF9pbnNuX2FmdGVyIChQ QVRURVJOIChpbnNuKSwgQkJfRU5EIChib2R5KSk7CisKKyAgZW1pdF9qdW1wX2luc25fYWZ0ZXIg KFBBVFRFUk4gKGluc24pLCBCQl9FTkQgKGJvZHkpKTsKKyAgcmV0dXJuIEdFTl9JTlQgKGRlY3Jl bWVudG51bSk7Cit9CisKKy8qIFRhcmdldCBob29rIHRvIHRoZSBudW1iZXIgb2YgZWxlbWVudHMg dG8gYmUgcHJvY2Vzc2VkIGJ5IGEgZGxzdHAvbGV0cCBsb29wCisgICBpbnRvIGBjb3VudGAgdG8g aW50aWFsaXNlIHRoZSBjb3VudGVyIHJlZ2lzdGVyLiAgVGhlIG51bWJlciBvZiBlbGVtZW50cyB3 YXMKKyAgIHByZXZpb3VzbHkgZXh0cmFjdGVkIGZyb20gdGhlIHZjdHAgaW5zbiBhbmQgcGxhY2Vk IGludG8gYSBVU0UgcnR4LgorICAgV2Ugb25seSBjaGVjayB0aGF0IHRoZSBkb2xvb3BfZW5kIHBh dHRlcm4gc3VjY2Vzc2Z1bGx5IGRlY3JlbWVudHMgYnkgYQorICAgbnVtYmVyIG90aGVyIHRoYW4g LTEgZm9yIGEgdmFsaWQgZGxzdHAvbGV0cCBsb29wLiAgTm8gb3RoZXIgY2hlY2tpbmcgaXMKKyAg IG5lZWRlZCBhcyB0aGF0IHdhcyBkb25lIHByZXZpb3VzbHkuICAqLworCitydHgKK2FybV9hbGxv d19lbGVtZW50d2lzZV9kb2xvb3BfcCAocnR4IGNvdW50LCBydHggbGFiZWwsIHJ0eCBkb2xvb3Ap Cit7CisgIGlmIChkb2xvb3AKKyAgICAgICYmIElOVFZBTCAoWEVYUCAoU0VUX1NSQyAoWFZFQ0VY UCAoUEFUVEVSTiAoZG9sb29wKSwgMCwgMSkpLCAxKSkgIT0gLTEpCisgICAgeworICAgICAgYmFz aWNfYmxvY2sgYm9keSA9IEJMT0NLX0ZPUl9JTlNOIChsYWJlbCktPnByZXZfYmI7CisgICAgICBy dHhfaW5zbiogaW5zbjsKKyAgICAgIEZPUl9CQl9JTlNOUyAoYm9keSwgaW5zbikKKwl7CisJICBp ZiAoSU5TTl9QIChpbnNuKSAmJiBHRVRfQ09ERSAoUEFUVEVSTiAoaW5zbikpID09IFVTRSkKKwkg ICAgeworCSAgICAgIHJ0eCBudW1fZWxlbV9yZWcgPSBjb3B5X3J0eCAoWEVYUCAoUEFUVEVSTiAo aW5zbiksIDApKTsKKwkgICAgICBkZWxldGVfaW5zbiAoaW5zbik7CisJICAgICAgcmV0dXJuIG51 bV9lbGVtX3JlZzsKKwkgICAgfQorCX0KKyAgICB9CisgIHJldHVybiBjb3VudDsKIH0KIAogI2lm IENIRUNLSU5HX1AKZGlmZiAtLWdpdCBhL2djYy9jb25maWcvYXJtL2l0ZXJhdG9ycy5tZCBiL2dj Yy9jb25maWcvYXJtL2l0ZXJhdG9ycy5tZAppbmRleCAzOTg5NWFkNjJhYTNhZmQ1NWQzY2JjOTJj NTViNDViYzU2NzEwYmNiLi45NTAyNGZlMDE2MTJjMGRmY2QzYTdkYzk3ZDNmMWVkYTFmY2NjMDYz IDEwMDY0NAotLS0gYS9nY2MvY29uZmlnL2FybS9pdGVyYXRvcnMubWQKKysrIGIvZ2NjL2NvbmZp Zy9hcm0vaXRlcmF0b3JzLm1kCkBAIC0xNDY0LDYgKzE0NjQsMTAgQEAKIAkJICAgICAgIChWQURD SVFfTV9TICJzIikgKFNRUlNIUkxfNjQgIjY0IikgKFNRUlNIUkxfNDggIjQ4IikKIAkJICAgICAg IChVUVJTSExMXzY0ICI2NCIpIChVUVJTSExMXzQ4ICI0OCIpIChWU0hMQ1FfTV9TICJzIikKIAkJ ICAgICAgIChWU0hMQ1FfTV9VICJ1IildKQorCisoZGVmaW5lX2ludF9hdHRyIG1vZGUxIFsoRExT VFA4ICI4IikgKERMU1RQMTYgIjE2IikgKERMU1RQMzIgIjMyIikKKwkJCShETFNUUDY0ICI2NCIp XSkKKwogOzsgQm90aCBraW5kcyBvZiByZXR1cm4gaW5zbi4KIChkZWZpbmVfY29kZV9pdGVyYXRv ciBSRVRVUk5TIFtyZXR1cm4gc2ltcGxlX3JldHVybl0pCiAoZGVmaW5lX2NvZGVfYXR0ciByZXR1 cm5fc3RyIFsocmV0dXJuICIiKSAoc2ltcGxlX3JldHVybiAic2ltcGxlXyIpXSkKQEAgLTE3Njks NiArMTc3Myw4IEBACiAoZGVmaW5lX2ludF9pdGVyYXRvciBVUVJTSExMUSBbVVFSU0hMTF82NCBV UVJTSExMXzQ4XSkKIChkZWZpbmVfaW50X2l0ZXJhdG9yIFNRUlNIUkxRIFtTUVJTSFJMXzY0IFNR UlNIUkxfNDhdKQogKGRlZmluZV9pbnRfaXRlcmF0b3IgVlNITENRX00gW1ZTSExDUV9NX1MgVlNI TENRX01fVV0pCisoZGVmaW5lX2ludF9pdGVyYXRvciBETFNUUCBbRExTVFA4IERMU1RQMTYgRExT VFAzMgorCQkJCSAgIERMU1RQNjRdKQogCiA7OyBEZWZpbmUgaXRlcmF0b3JzIGZvciBWQ01MQSBv cGVyYXRpb25zCiAoZGVmaW5lX2ludF9pdGVyYXRvciBWQ01MQV9PUCBbVU5TUEVDX1ZDTUxBCmRp ZmYgLS1naXQgYS9nY2MvY29uZmlnL2FybS9tdmUubWQgYi9nY2MvY29uZmlnL2FybS9tdmUubWQK aW5kZXggODU0YjhhYjkzNWY4MmFkMGViOTllNmFmOTg1MmNlODE1NGNmOWQ5ZC4uOGRkMzU2Nzc1 OWU1ZDc5NGIxMDM5YzExNGNjYjEzNzY1YTEzMTMwNCAxMDA2NDQKLS0tIGEvZ2NjL2NvbmZpZy9h cm0vbXZlLm1kCisrKyBiL2djYy9jb25maWcvYXJtL212ZS5tZApAQCAtMTExMDAsMyArMTExMDAs MzggQEAKICAgICB9CiAgIERPTkU7CiB9KQorCis7OyBPcmlnaW5hbGx5IGV4cGFuZGVkIGJ5ICdw cmVkaWNhdGVkX2RvbG9vcF9lbmQnLgorKGRlZmluZV9pbnNuICIqcHJlZGljYXRlZF9kb2xvb3Bf ZW5kX2ludGVybmFsIgorICBbKHNldCAocGMpCisJKGlmX3RoZW5fZWxzZQorCSAgIChnZSAocGx1 czpTSSAocmVnOlNJIExSX1JFR05VTSkKKwkJCShtYXRjaF9vcGVyYW5kOlNJIDAgImNvbnN0X2lu dF9vcGVyYW5kIiAiIikpCisJCShjb25zdF9pbnQgMCkpCisJIChsYWJlbF9yZWYgKG1hdGNoX29w ZXJhbmQgMSAiIiAiIikpCisJIChwYykpKQorICAgKHNldCAocmVnOlNJIExSX1JFR05VTSkKKwko cGx1czpTSSAocmVnOlNJIExSX1JFR05VTSkgKG1hdGNoX2R1cCAwKSkpCisgICAoY2xvYmJlciAo cmVnOkNDIENDX1JFR05VTSkpXQorICAiVEFSR0VUXzMyQklUICYmIFRBUkdFVF9IQVZFX0xPQiAm JiBUQVJHRVRfSEFWRV9NVkUgJiYgVEFSR0VUX1RIVU1CMiIKKyAgeworICAgIGlmIChnZXRfYXR0 cl9sZW5ndGggKGluc24pID09IDQpCisgICAgICByZXR1cm4gImxldHBcdCV8bHIsICVsMSI7Cisg ICAgZWxzZQorICAgICAgcmV0dXJuICJzdWJzXHQlfGxyLCAjJTA7Ymd0XHQlbDEiOworICB9Cisg IFsoc2V0IChhdHRyICJsZW5ndGgiKQorCShpZl90aGVuX2Vsc2UKKwkgICAobHR1IChtaW51cyAo cGMpIChtYXRjaF9kdXAgMSkpIChjb25zdF9pbnQgMTAyNCkpCisJICAgIChjb25zdF9pbnQgNCkK KwkgICAgKGNvbnN0X2ludCA2KSkpCisgICAoc2V0X2F0dHIgInR5cGUiICJicmFuY2giKV0pCisK KyhkZWZpbmVfaW5zbiAiZGxzdHA8bW9kZTE+X2luc24iCisgIFsKKyAgICAoc2V0IChyZWc6U0kg TFJfUkVHTlVNKQorCSAodW5zcGVjOlNJIFsobWF0Y2hfb3BlcmFuZDpTSSAwICJzX3JlZ2lzdGVy X29wZXJhbmQiICJyIildCisJICBETFNUUCkpCisgIF0KKyAgIlRBUkdFVF8zMkJJVCAmJiBUQVJH RVRfSEFWRV9MT0IgJiYgVEFSR0VUX0hBVkVfTVZFICYmIFRBUkdFVF9USFVNQjIiCisgICJkbHN0 cC48bW9kZTE+XHQlfGxyLCAlMCIpClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0t Z2l0IGEvZ2NjL2NvbmZpZy9hcm0vdGh1bWIyLm1kIGIvZ2NjL2NvbmZpZy9hcm0vdGh1bWIyLm1k CmluZGV4IGUxZTAxM2JlZmE3YTY3ZGRiZjUxN2JmMjI3OTdiZGFlZWI5NmI5NGYuLjNiZWI0ZDRi NDhjZDQ3YzhlOTQ2ZmJhNTNjNDk5NzVmZjgyNzFhYzEgMTAwNjQ0Ci0tLSBhL2djYy9jb25maWcv YXJtL3RodW1iMi5tZAorKysgYi9nY2MvY29uZmlnL2FybS90aHVtYjIubWQKQEAgLTE2MTMsNyAr MTYxMyw3IEBACiAgICAodXNlIChtYXRjaF9vcGVyYW5kIDEgIiIgIiIpKV0gICAgIDsgbGFiZWwK ICAgIlRBUkdFVF8zMkJJVCIKICAgIgotIHsKK3sKICAgIC8qIEN1cnJlbnRseSBTTVMgcmVsaWVz IG9uIHRoZSBkby1sb29wIHBhdHRlcm4gdG8gcmVjb2duaXplIGxvb3BzCiAgICAgICB3aGVyZSAo MSkgdGhlIGNvbnRyb2wgcGFydCBjb25zaXN0cyBvZiBhbGwgaW5zbnMgZGVmaW5pbmcgYW5kL29y CiAgICAgICB1c2luZyBhIGNlcnRhaW4gJ2NvdW50JyByZWdpc3RlciBhbmQgKDIpIHRoZSBsb29w IGNvdW50IGNhbiBiZQpAQCAtMTYyMyw0MSArMTYyMyw2NyBAQAogCiAgICAgICBBbHNvIHVzZWQg dG8gaW1wbGVtZW50IHRoZSBsb3cgb3ZlciBoZWFkIGxvb3BzIGZlYXR1cmUsIHdoaWNoIGlzIHBh cnQgb2YKICAgICAgIHRoZSBBcm12OC4xLU0gTWFpbmxpbmUgTG93IE92ZXJoZWFkIEJyYW5jaCAo TE9CKSBleHRlbnNpb24uICAqLwotICAgaWYgKG9wdGltaXplID4gMCAmJiAoZmxhZ19tb2R1bG9f c2NoZWQgfHwgVEFSR0VUX0hBVkVfTE9CKSkKLSAgIHsKLSAgICAgcnR4IHMwOwotICAgICBydHgg YmNvbXA7Ci0gICAgIHJ0eCBsb2NfcmVmOwotICAgICBydHggY2NfcmVnOwotICAgICBydHggaW5z bjsKLSAgICAgcnR4IGNtcDsKLQotICAgICBpZiAoR0VUX01PREUgKG9wZXJhbmRzWzBdKSAhPSBT SW1vZGUpCi0gICAgICAgRkFJTDsKLQotICAgICBzMCA9IG9wZXJhbmRzIFswXTsKLQotICAgICAv KiBMb3cgb3ZlciBoZWFkIGxvb3AgaW5zdHJ1Y3Rpb25zIHJlcXVpcmUgdGhlIGZpcnN0IG9wZXJh bmQgdG8gYmUgTFIuICAqLwotICAgICBpZiAoVEFSR0VUX0hBVkVfTE9CICYmIGFybV90YXJnZXRf aW5zbl9va19mb3JfbG9iIChvcGVyYW5kcyBbMV0pKQotICAgICAgIHMwID0gZ2VuX3J0eF9SRUcg KFNJbW9kZSwgTFJfUkVHTlVNKTsKLQotICAgICBpZiAoVEFSR0VUX1RIVU1CMikKLSAgICAgICBp bnNuID0gZW1pdF9pbnNuIChnZW5fdGh1bWIyX2FkZHNpM19jb21wYXJlMCAoczAsIHMwLCBHRU5f SU5UICgtMSkpKTsKLSAgICAgZWxzZQotICAgICAgIGluc24gPSBlbWl0X2luc24gKGdlbl9hZGRz aTNfY29tcGFyZTAgKHMwLCBzMCwgR0VOX0lOVCAoLTEpKSk7Ci0KLSAgICAgY21wID0gWFZFQ0VY UCAoUEFUVEVSTiAoaW5zbiksIDAsIDApOwotICAgICBjY19yZWcgPSBTRVRfREVTVCAoY21wKTsK LSAgICAgYmNvbXAgPSBnZW5fcnR4X05FIChWT0lEbW9kZSwgY2NfcmVnLCBjb25zdDBfcnR4KTsK LSAgICAgbG9jX3JlZiA9IGdlbl9ydHhfTEFCRUxfUkVGIChWT0lEbW9kZSwgb3BlcmFuZHMgWzFd KTsKLSAgICAgZW1pdF9qdW1wX2luc24gKGdlbl9ydHhfU0VUIChwY19ydHgsCi0gICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgZ2VuX3J0eF9JRl9USEVOX0VMU0UgKFZPSURtb2RlLCBi Y29tcCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgbG9jX3JlZiwgcGNfcnR4KSkpOwotICAgICBET05FOwotICAgfQotIGVsc2UKLSAgIEZB SUw7Ci0gfSIpCisgIGlmIChvcHRpbWl6ZSA+IDAgJiYgKGZsYWdfbW9kdWxvX3NjaGVkIHx8IFRB UkdFVF9IQVZFX0xPQikpCisgICAgeworICAgICAgcnR4IHMwOworICAgICAgcnR4IGJjb21wOwor ICAgICAgcnR4IGxvY19yZWY7CisgICAgICBydHggY2NfcmVnOworICAgICAgcnR4IGluc247Cisg ICAgICBydHggY21wOworICAgICAgcnR4IGRlY3JlbWVudF9udW07CisKKyAgICAgIGlmIChHRVRf TU9ERSAob3BlcmFuZHNbMF0pICE9IFNJbW9kZSkKKwlGQUlMOworCisgICAgICBzMCA9IG9wZXJh bmRzWzBdOworCisgICAgICAgaWYgKFRBUkdFVF9IQVZFX0xPQiAmJiBhcm1fdGFyZ2V0X2luc25f b2tfZm9yX2xvYiAob3BlcmFuZHNbMV0pKQorCXsKKwkgIHMwID0gZ2VuX3J0eF9SRUcgKFNJbW9k ZSwgTFJfUkVHTlVNKTsKKworCSAgLyogSWYgd2UgaGF2ZSBhIGNvbXBhdGliZSBNVkUgdGFyZ2V0 LCB0cnkgYW5kIGFuYWx5c2UgdGhlIGxvb3AKKwkgICAgIGNvbnRlbnRzIHRvIGRldGVybWluZSBp ZiB3ZSBjYW4gdXNlIHByZWRpY2F0ZWQgZGxzdHAvbGV0cAorCSAgICAgbG9vcGluZy4gICovCisJ ICBpZiAoVEFSR0VUX0hBVkVfTVZFICYmIFRBUkdFVF9USFVNQjIKKwkgICAgICAmJiAoZGVjcmVt ZW50X251bSA9IGFybV9hdHRlbXB0X2Rsc3RwX3RyYW5zZm9ybSAob3BlcmFuZHNbMV0pKQorCSAg ICAgICYmIChJTlRWQUwgKGRlY3JlbWVudF9udW0pICE9IDEpKQorCSAgICB7CisJICAgICAgaW5z biA9IGVtaXRfaW5zbgorCQkgICAgICAoZ2VuX3RodW1iMl9hZGRzaTNfY29tcGFyZTAKKwkJCSAg KHMwLCBzMCwgR0VOX0lOVCAoKC0xKSAqIChJTlRWQUwgKGRlY3JlbWVudF9udW0pKSkpKTsKKwkg ICAgICBjbXAgPSBYVkVDRVhQIChQQVRURVJOIChpbnNuKSwgMCwgMCk7CisJICAgICAgY2NfcmVn ID0gU0VUX0RFU1QgKGNtcCk7CisJICAgICAgYmNvbXAgPSBnZW5fcnR4X0dFIChWT0lEbW9kZSwg Y2NfcmVnLCBjb25zdDBfcnR4KTsKKwkgICAgICBsb2NfcmVmID0gZ2VuX3J0eF9MQUJFTF9SRUYg KFZPSURtb2RlLCBvcGVyYW5kc1sxXSk7CisJICAgICAgZW1pdF9qdW1wX2luc24gKGdlbl9ydHhf U0VUIChwY19ydHgsCisJCQkJICAgICAgIGdlbl9ydHhfSUZfVEhFTl9FTFNFIChWT0lEbW9kZSwg YmNvbXAsCisJCQkJCQkJICAgICBsb2NfcmVmLCBwY19ydHgpKSk7CisJICAgICAgRE9ORTsKKwkg ICAgfQorCisJICAvKiBPdGhlcndpc2UsIHRyeSBzdGFuZGFyZCBkZWNyZW1lbnQtYnktb25lIGRs cy9sZSBsb29waW5nLiAgKi8KKwkgIGlmIChUQVJHRVRfVEhVTUIyKQorCSAgICBpbnNuID0gZW1p dF9pbnNuIChnZW5fdGh1bWIyX2FkZHNpM19jb21wYXJlMCAoczAsIHMwLAorCQkJCQkJCSAgR0VO X0lOVCAoLTEpKSk7CisJICBlbHNlCisJICAgIGluc24gPSBlbWl0X2luc24gKGdlbl9hZGRzaTNf Y29tcGFyZTAgKHMwLCBzMCwgR0VOX0lOVCAoLTEpKSk7CisKKwkgIGNtcCA9IFhWRUNFWFAgKFBB VFRFUk4gKGluc24pLCAwLCAwKTsKKwkgIGNjX3JlZyA9IFNFVF9ERVNUIChjbXApOworCSAgYmNv bXAgPSBnZW5fcnR4X05FIChWT0lEbW9kZSwgY2NfcmVnLCBjb25zdDBfcnR4KTsKKwkgIGxvY19y ZWYgPSBnZW5fcnR4X0xBQkVMX1JFRiAoVk9JRG1vZGUsIG9wZXJhbmRzWzFdKTsKKwkgIGVtaXRf anVtcF9pbnNuIChnZW5fcnR4X1NFVCAocGNfcnR4LAorCQkJCSAgICAgICBnZW5fcnR4X0lGX1RI RU5fRUxTRSAoVk9JRG1vZGUsIGJjb21wLAorCQkJCQkJCSAgICAgbG9jX3JlZiwgcGNfcnR4KSkp OworCSAgRE9ORTsKKwl9CisgICAgICBlbHNlCisJRkFJTDsKKyAgICB9CisgIGVsc2UKKyAgICBG QUlMOworfSIpCiAKIChkZWZpbmVfaW5zbiAiKmNsZWFyX2Fwc3IiCiAgIFsodW5zcGVjX3ZvbGF0 aWxlOlNJIFsoY29uc3RfaW50IDApXSBWVU5TUEVDX0NMUk1fQVBTUikKQEAgLTE3NTUsNyArMTc4 MSwzNyBAQAogICB7CiAgICAgaWYgKFJFR05PIChvcGVyYW5kc1swXSkgPT0gTFJfUkVHTlVNKQog ICAgICAgewotCWVtaXRfaW5zbiAoZ2VuX2Rsc19pbnNuIChvcGVyYW5kc1swXSkpOworCS8qIFBp Y2sgb3V0IHRoZSBudW1iZXIgYnkgd2hpY2ggd2UgYXJlIGRlY3JlbWVudGluZyB0aGUgbG9vcCBj b3VudGVyCisJICAgaW4gZXZlcnkgaXRlcmF0aW9uLiAgSWYgaXQncyA+IDEsIHRoZW4gdXNlIGRs c3RwLiAgKi8KKwlpbnQgY29uc3RfaW50X2RlY19udW0KKwkgICAgID0gYWJzIChJTlRWQUwgKFhF WFAgKFhFWFAgKFhWRUNFWFAgKFBBVFRFUk4gKG9wZXJhbmRzWzFdKSwgMCwgMSksCisJCQkJICAx KSwKKwkJCSAgICAxKSkpOworCXN3aXRjaCAoY29uc3RfaW50X2RlY19udW0pCisJICB7CisJICAg IGNhc2UgMTY6CisJICAgICAgZW1pdF9pbnNuIChnZW5fZGxzdHA4X2luc24gKG9wZXJhbmRzWzBd KSk7CisJICAgICAgYnJlYWs7CisKKwkgICAgY2FzZSA4OgorCSAgICAgIGVtaXRfaW5zbiAoZ2Vu X2Rsc3RwMTZfaW5zbiAob3BlcmFuZHNbMF0pKTsKKwkgICAgICBicmVhazsKKworCSAgICBjYXNl IDQ6CisJICAgICAgZW1pdF9pbnNuIChnZW5fZGxzdHAzMl9pbnNuIChvcGVyYW5kc1swXSkpOwor CSAgICAgIGJyZWFrOworCisJICAgIGNhc2UgMjoKKwkgICAgICBlbWl0X2luc24gKGdlbl9kbHN0 cDY0X2luc24gKG9wZXJhbmRzWzBdKSk7CisJICAgICAgYnJlYWs7CisKKwkgICAgY2FzZSAxOgor CSAgICAgIGVtaXRfaW5zbiAoZ2VuX2Rsc19pbnNuIChvcGVyYW5kc1swXSkpOworCSAgICAgIGJy ZWFrOworCisJICAgIGRlZmF1bHQ6CisJICAgICAgZ2NjX3VucmVhY2hhYmxlICgpOworCSAgfQog CURPTkU7CiAgICAgICB9CiAgICAgZWxzZQpkaWZmIC0tZ2l0IGEvZ2NjL2NvbmZpZy9hcm0vdW5z cGVjcy5tZCBiL2djYy9jb25maWcvYXJtL3Vuc3BlY3MubWQKaW5kZXggODQzODRlZTc5OGRlMzYz Yjg3NGM0MWExNmRjNWRhYWUzNGVjY2I5NC4uZTUzM2M2MDIxNWE0OWZlMGFhYmZhOGI1ZmI2ZDk4 OGZhZjNjNGY1MSAxMDA2NDQKLS0tIGEvZ2NjL2NvbmZpZy9hcm0vdW5zcGVjcy5tZAorKysgYi9n Y2MvY29uZmlnL2FybS91bnNwZWNzLm1kCkBAIC01ODEsNiArNTgxLDEwIEBACiAgIFZBRERMVlFf VQogICBWQ1RQCiAgIFZDVFBfTQorICBETFNUUDgKKyAgRExTVFAxNgorICBETFNUUDMyCisgIERM U1RQNjQKICAgVlBOT1QKICAgVkNSRUFURVFfRgogICBWQ1ZUUV9OX1RPX0ZfUwpkaWZmIC0tZ2l0 IGEvZ2NjL2RvYy90bS50ZXhpIGIvZ2NjL2RvYy90bS50ZXhpCmluZGV4IGM2Yzg5MTk3MmQxZTU4 Y2QxNjNiMjU5YmE5NmE1OTlkNjIzMjY4NjUuLjRlM2ZjYjFhODQ1ZWQxNzYzODZiZTQxYjNhY2U5 ZjA2N2ZlZjkzNjEgMTAwNjQ0Ci0tLSBhL2djYy9kb2MvdG0udGV4aQorKysgYi9nY2MvZG9jL3Rt LnRleGkKQEAgLTExNzk2LDYgKzExNzk2LDE0IEBAIGxvb3BzLCBhbmQgd2lsbCBoZWxwIGl2b3B0 cyB0byBtYWtlIHNvbWUgZGVjaXNpb25zLgogVGhlIGRlZmF1bHQgdmVyc2lvbiBvZiB0aGlzIGhv b2sgcmV0dXJucyBmYWxzZS4KIEBlbmQgZGVmdHlwZWZuCiAKK0BkZWZ0eXBlZm4ge1RhcmdldCBI b29rfSBydHggVEFSR0VUX0FMTE9XX0VMRU1FTlRXSVNFX0RPTE9PUF9QIChydHggQHZhcntjb3Vu dH0sIHJ0eCBAdmFye2xhYmVsfSwgcnR4IEB2YXJ7ZG9sb29wfSkKK1RoaXMgdGFyZ2V0IGhvb2sg YWxsb3dzIHRoZSB0YXJnZXQgdG8gc3VwcG9ydCBsb29wLWRvbG9vcCBvcHRpbWlzYXRpb25zCit3 aGVyZSB0aGUgdmFsdWUgdGhhdCBnZXRzIHB1dCBpbnRvIHRoZSBsb29wIGNvdW50ZXIgcmVnaXN0 ZXIgaXMgbm90IGEKK3ByZS1jYWxjdWxhdGlvbiBvZiB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbiBv ZiB0aGUgbG9vcC4gIEZvciBpbnN0YW5jZSwKK3RoZSB2YWx1ZSB1c2VkIGNhbiBiZSB0aGUgbnVt YmVyIG9mIGVsZW1lbnRzIHRoYXQgdGhlIGxvb3Agd2lsbCBwcm9jZXNzLgorVGhlIGRlZmF1bHQg dmVyc2lvbiBvZiB0aGlzIGhvb2sgcmV0dXJucyB0aGUgc2FtZSBydHggaXQgd2FzIGdpdmVuLgor QGVuZCBkZWZ0eXBlZm4KKwogQGRlZnR5cGV2ciB7VGFyZ2V0IEhvb2t9IGJvb2wgVEFSR0VUX0hB VkVfQ09VTlRfUkVHX0RFQ1JfUAogUmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldCBzdXBwb3J0cyBo YXJkd2FyZSBjb3VudCByZWdpc3RlciBmb3IgZGVjcmVtZW50CiBhbmQgYnJhbmNoLgpkaWZmIC0t Z2l0IGEvZ2NjL2RvYy90bS50ZXhpLmluIGIvZ2NjL2RvYy90bS50ZXhpLmluCmluZGV4IDYxM2Iy NTM0MTQ5NDE1ZjQ0MjE2M2Q1OTk1MDNlZmFmNDIzYjY3M2IuLmYzZTc0ZGZkNTUzYzJiNWE1ODU3 NjY4ZjY4MzVlNzYyY2UyYzI2MTYgMTAwNjQ0Ci0tLSBhL2djYy9kb2MvdG0udGV4aS5pbgorKysg Yi9nY2MvZG9jL3RtLnRleGkuaW4KQEAgLTc3MzIsNiArNzczMiw4IEBAIHRvIGJ5IEB2YXJ7Y2Vf aW5mb30uCiAKIEBob29rIFRBUkdFVF9QUkVESUNUX0RPTE9PUF9QCiAKK0Bob29rIFRBUkdFVF9B TExPV19FTEVNRU5UV0lTRV9ET0xPT1BfUAorCiBAaG9vayBUQVJHRVRfSEFWRV9DT1VOVF9SRUdf REVDUl9QCiAKIEBob29rIFRBUkdFVF9ET0xPT1BfQ09TVF9GT1JfR0VORVJJQwpkaWZmIC0tZ2l0 IGEvZ2NjL2xvb3AtZG9sb29wLmNjIGIvZ2NjL2xvb3AtZG9sb29wLmNjCmluZGV4IDRmZWIwYTI1 YWI5MzMxYjcxMjRkZjkwMGY3M2M5ZmM2ZmIzZWIxMGIuLjM4MDI0ZTIyMzQzOWNhYzFjYTAwYzBm ZTJhZjg3ZDc2MjhjOGE4MTUgMTAwNjQ0Ci0tLSBhL2djYy9sb29wLWRvbG9vcC5jYworKysgYi9n Y2MvbG9vcC1kb2xvb3AuY2MKQEAgLTg1LDI5ICs4NSwyOSBAQCBkb2xvb3BfY29uZGl0aW9uX2dl dCAocnR4X2luc24gKmRvbG9vcF9wYXQpCiAgICAgIGZvcm1zOgogCiAgICAgIDEpICAocGFyYWxs ZWwgWyhzZXQgKHBjKSAoaWZfdGhlbl9lbHNlIChjb25kaXRpb24pCi0JICAJCQkgICAgICAgICAg ICAobGFiZWxfcmVmIChsYWJlbCkpCi0JCQkJICAgICAgICAgICAgKHBjKSkpCi0JICAgICAgICAg ICAgIChzZXQgKHJlZykgKHBsdXMgKHJlZykgKGNvbnN0X2ludCAtMSkpKQotCSAgICAgICAgICAg ICAoYWRkaXRpb25hbCBjbG9iYmVycyBhbmQgdXNlcyldKQorCQkJCQkgICAgKGxhYmVsX3JlZiAo bGFiZWwpKQorCQkJCQkgICAgKHBjKSkpCisJCSAgICAgKHNldCAocmVnKSAocGx1cyAocmVnKSAo Y29uc3RfaW50IC1uKSkpCisJCSAgICAgKGFkZGl0aW9uYWwgY2xvYmJlcnMgYW5kIHVzZXMpXSkK IAogICAgICBUaGUgYnJhbmNoIG11c3QgYmUgdGhlIGZpcnN0IGVudHJ5IG9mIHRoZSBwYXJhbGxl bCAoYWxzbyByZXF1aXJlZAogICAgICBieSBqdW1wLmNjKSwgYW5kIHRoZSBzZWNvbmQgZW50cnkg b2YgdGhlIHBhcmFsbGVsIG11c3QgYmUgYSBzZXQgb2YKICAgICAgdGhlIGxvb3AgY291bnRlciBy ZWdpc3Rlci4gIFNvbWUgdGFyZ2V0cyAoSUEtNjQpIHdyYXAgdGhlIHNldCBvZgogICAgICB0aGUg bG9vcCBjb3VudGVyIGluIGFuIGlmX3RoZW5fZWxzZSB0b28uCiAKLSAgICAgMikgIChzZXQgKHJl ZykgKHBsdXMgKHJlZykgKGNvbnN0X2ludCAtMSkpCi0gICAgICAgICAoc2V0IChwYykgKGlmX3Ro ZW5fZWxzZSAocmVnICE9IDApCi0JICAgICAgICAgICAgICAgICAgICAgICAgIChsYWJlbF9yZWYg KGxhYmVsKSkKLQkJCSAgICAgICAgIChwYykpKS4gIAorICAgICAyKSAgKHNldCAocmVnKSAocGx1 cyAocmVnKSAoY29uc3RfaW50IC1uKSkKKwkgKHNldCAocGMpIChpZl90aGVuX2Vsc2UgKHJlZyAh PSAwKQorCQkJCSAobGFiZWxfcmVmIChsYWJlbCkpCisJCQkJIChwYykpKS4KIAogICAgICBTb21l IHRhcmdldHMgKEFSTSkgZG8gdGhlIGNvbXBhcmlzb24gYmVmb3JlIHRoZSBicmFuY2gsIGFzIGlu IHRoZQogICAgICBmb2xsb3dpbmcgZm9ybToKIAotICAgICAzKSAocGFyYWxsZWwgWyhzZXQgKGNj KSAoY29tcGFyZSAoKHBsdXMgKHJlZykgKGNvbnN0X2ludCAtMSksIDApKSkKLSAgICAgICAgICAg ICAgICAgICAoc2V0IChyZWcpIChwbHVzIChyZWcpIChjb25zdF9pbnQgLTEpKSldKQotICAgICAg ICAoc2V0IChwYykgKGlmX3RoZW5fZWxzZSAoY2MgPT0gTkUpCi0gICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIChsYWJlbF9yZWYgKGxhYmVsKSkKLSAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgKHBjKSkpICovCisgICAgIDMpIChwYXJhbGxlbCBbKHNldCAoY2MpIChjb21wYXJl ICgocGx1cyAocmVnKSAoY29uc3RfaW50IC1uKSwgMCkpKQorCQkgICAoc2V0IChyZWcpIChwbHVz IChyZWcpIChjb25zdF9pbnQgLW4pKSldKQorCShzZXQgKHBjKSAoaWZfdGhlbl9lbHNlIChjYyA9 PSBORSkKKwkJCQkobGFiZWxfcmVmIChsYWJlbCkpCisJCQkJKHBjKSkpICovCiAKICAgcGF0dGVy biA9IFBBVFRFUk4gKGRvbG9vcF9wYXQpOwogCkBAIC0xNDMsNyArMTQzLDcgQEAgZG9sb29wX2Nv bmRpdGlvbl9nZXQgKHJ0eF9pbnNuICpkb2xvb3BfcGF0KQogCSAgICAgIHx8IEdFVF9DT0RFIChj bXBfYXJnMSkgIT0gUExVUykKIAkgICAgcmV0dXJuIDA7CiAJICByZWdfb3JpZyA9IFhFWFAgKGNt cF9hcmcxLCAwKTsKLQkgIGlmIChYRVhQIChjbXBfYXJnMSwgMSkgIT0gR0VOX0lOVCAoLTEpIAor CSAgaWYgKCFDT05TVF9JTlRfUCAoWEVYUCAoY21wX2FyZzEsIDEpKQogCSAgICAgIHx8ICFSRUdf UCAocmVnX29yaWcpKQogCSAgICByZXR1cm4gMDsKIAkgIGNjX3JlZyA9IFNFVF9ERVNUIChjbXBf b3JpZyk7CkBAIC0xNTYsNyArMTU2LDggQEAgZG9sb29wX2NvbmRpdGlvbl9nZXQgKHJ0eF9pbnNu ICpkb2xvb3BfcGF0KQogCXsKIAkgIC8qIFdlIGV4cGVjdCB0aGUgY29uZGl0aW9uIHRvIGJlIG9m IHRoZSBmb3JtIChyZWcgIT0gMCkgICovCiAJICBjb25kID0gWEVYUCAoU0VUX1NSQyAoY21wKSwg MCk7Ci0JICBpZiAoR0VUX0NPREUgKGNvbmQpICE9IE5FIHx8IFhFWFAgKGNvbmQsIDEpICE9IGNv bnN0MF9ydHgpCisJICBpZiAoKEdFVF9DT0RFIChjb25kKSAhPSBORSAmJiBHRVRfQ09ERSAoY29u ZCkgIT0gR0UpCisJICAgICAgfHwgWEVYUCAoY29uZCwgMSkgIT0gY29uc3QwX3J0eCkKIAkgICAg cmV0dXJuIDA7CiAJfQogICAgIH0KQEAgLTE3MywxNCArMTc0LDE0IEBAIGRvbG9vcF9jb25kaXRp b25fZ2V0IChydHhfaW5zbiAqZG9sb29wX3BhdCkKICAgaWYgKCEgUkVHX1AgKHJlZykpCiAgICAg cmV0dXJuIDA7CiAKLSAgLyogQ2hlY2sgaWYgc29tZXRoaW5nID0gKHBsdXMgKHJlZykgKGNvbnN0 X2ludCAtMSkpLgorICAvKiBDaGVjayBpZiBzb21ldGhpbmcgPSAocGx1cyAocmVnKSAoY29uc3Rf aW50IC1uKSkuCiAgICAgIE9uIElBLTY0LCB0aGlzIGRlY3JlbWVudCBpcyB3cmFwcGVkIGluIGFu IGlmX3RoZW5fZWxzZS4gICovCiAgIGluY19zcmMgPSBTRVRfU1JDIChpbmMpOwogICBpZiAoR0VU X0NPREUgKGluY19zcmMpID09IElGX1RIRU5fRUxTRSkKICAgICBpbmNfc3JjID0gWEVYUCAoaW5j X3NyYywgMSk7CiAgIGlmIChHRVRfQ09ERSAoaW5jX3NyYykgIT0gUExVUwogICAgICAgfHwgWEVY UCAoaW5jX3NyYywgMCkgIT0gcmVnCi0gICAgICB8fCBYRVhQIChpbmNfc3JjLCAxKSAhPSBjb25z dG0xX3J0eCkKKyAgICAgIHx8ICFDT05TVF9JTlRfUCAoWEVYUCAoaW5jX3NyYywgMSkpKQogICAg IHJldHVybiAwOwogCiAgIC8qIENoZWNrIGZvciAoc2V0IChwYykgKGlmX3RoZW5fZWxzZSAoY29u ZGl0aW9uKQpAQCAtMjExLDQyICsyMTIsNDkgQEAgZG9sb29wX2NvbmRpdGlvbl9nZXQgKHJ0eF9p bnNuICpkb2xvb3BfcGF0KQogICAgICAgfHwgKEdFVF9DT0RFIChYRVhQIChjb25kaXRpb24sIDAp KSA9PSBQTFVTCiAJICAmJiBYRVhQIChYRVhQIChjb25kaXRpb24sIDApLCAwKSA9PSByZWcpKQog ICAgewotICAgICBpZiAoR0VUX0NPREUgKHBhdHRlcm4pICE9IFBBUkFMTEVMKQogICAgICAvKiAg Rm9yIHRoZSBzZWNvbmQgZm9ybSB3ZSBleHBlY3Q6CiAKLSAgICAgICAgIChzZXQgKHJlZykgKHBs dXMgKHJlZykgKGNvbnN0X2ludCAtMSkpCi0gICAgICAgICAoc2V0IChwYykgKGlmX3RoZW5fZWxz ZSAocmVnICE9IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFiZWxfcmVm IChsYWJlbCkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGMpKSkuCisJIChz ZXQgKHJlZykgKHBsdXMgKHJlZykgKGNvbnN0X2ludCAtbikpCisJIChzZXQgKHBjKSAoaWZfdGhl bl9lbHNlIChyZWcgIT0gMCkKKwkJCQkgKGxhYmVsX3JlZiAobGFiZWwpKQorCQkJCSAocGMpKSku CiAKLSAgICAgICAgIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGZvbGxvd2luZzoKKwkgSWYgbiA9PSAx LCB0aGF0IGlzIGVxdWl2YWxlbnQgdG8gdGhlIGZvbGxvd2luZzoKIAotICAgICAgICAgKHBhcmFs bGVsIFsoc2V0IChwYykgKGlmX3RoZW5fZWxzZSAocmVnICE9IDEpCi0gICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYWJlbF9yZWYgKGxhYmVsKSkKLSAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBjKSkpCi0gICAgICAgICAgICAg ICAgICAgICAoc2V0IChyZWcpIChwbHVzIChyZWcpIChjb25zdF9pbnQgLTEpKSkKLSAgICAgICAg ICAgICAgICAgICAgIChhZGRpdGlvbmFsIGNsb2JiZXJzIGFuZCB1c2VzKV0pCisJIChwYXJhbGxl bCBbKHNldCAocGMpIChpZl90aGVuX2Vsc2UgKHJlZyAhPSAxKQorCQkJCQkgICAgKGxhYmVsX3Jl ZiAobGFiZWwpKQorCQkJCQkgICAgKHBjKSkpCisJCSAgICAgKHNldCAocmVnKSAocGx1cyAocmVn KSAoY29uc3RfaW50IC0xKSkpCisJCSAgICAgKGFkZGl0aW9uYWwgY2xvYmJlcnMgYW5kIHVzZXMp XSkKIAotICAgICAgICBGb3IgdGhlIHRoaXJkIGZvcm0gd2UgZXhwZWN0OgorCUZvciB0aGUgdGhp cmQgZm9ybSB3ZSBleHBlY3Q6CiAKLSAgICAgICAgKHBhcmFsbGVsIFsoc2V0IChjYykgKGNvbXBh cmUgKChwbHVzIChyZWcpIChjb25zdF9pbnQgLTEpKSwgMCkpCi0gICAgICAgICAgICAgICAgICAg KHNldCAocmVnKSAocGx1cyAocmVnKSAoY29uc3RfaW50IC0xKSkpXSkKLSAgICAgICAgKHNldCAo cGMpIChpZl90aGVuX2Vsc2UgKGNjID09IE5FKQotICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAobGFiZWxfcmVmIChsYWJlbCkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IChwYykpKSAKKwkocGFyYWxsZWwgWyhzZXQgKGNjKSAoY29tcGFyZSAoKHBsdXMgKHJlZykgKGNv bnN0X2ludCAtbikpLCAwKSkKKwkJICAgKHNldCAocmVnKSAocGx1cyAocmVnKSAoY29uc3RfaW50 IC1uKSkpXSkKKwkoc2V0IChwYykgKGlmX3RoZW5fZWxzZSAoY2MgPT0gTkUpCisJCQkJKGxhYmVs X3JlZiAobGFiZWwpKQorCQkJCShwYykpKQogCi0gICAgICAgIHdoaWNoIGlzIGVxdWl2YWxlbnQg dG8gdGhlIGZvbGxvd2luZzoKKwlXaGljaCBhbHNvIGZvciBuID09IDEgaXMgZXF1aXZhbGVudCB0 byB0aGUgZm9sbG93aW5nOgogCi0gICAgICAgIChwYXJhbGxlbCBbKHNldCAoY2MpIChjb21wYXJl IChyZWcsICAxKSkKLSAgICAgICAgICAgICAgICAgICAoc2V0IChyZWcpIChwbHVzIChyZWcpIChj b25zdF9pbnQgLTEpKSkKLSAgICAgICAgICAgICAgICAgICAoc2V0IChwYykgKGlmX3RoZW5fZWxz ZSAoTkUgPT0gY2MpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg KGxhYmVsX3JlZiAobGFiZWwpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIChwYykpKSldKQorCShwYXJhbGxlbCBbKHNldCAoY2MpIChjb21wYXJlIChyZWcsICAx KSkKKwkJICAgKHNldCAocmVnKSAocGx1cyAocmVnKSAoY29uc3RfaW50IC0xKSkpCisJCSAgIChz ZXQgKHBjKSAoaWZfdGhlbl9lbHNlIChORSA9PSBjYykKKwkJCQkJICAgKGxhYmVsX3JlZiAobGFi ZWwpKQorCQkJCQkgICAocGMpKSkpXSkKIAotICAgICAgICBTbyB3ZSByZXR1cm4gdGhlIHNlY29u ZCBmb3JtIGluc3RlYWQgZm9yIHRoZSB0d28gY2FzZXMuCisJU28gd2UgcmV0dXJuIHRoZSBzZWNv bmQgZm9ybSBpbnN0ZWFkIGZvciB0aGUgdHdvIGNhc2VzLgogCisJRm9yIHRoZSAiZWxlbWVudHdp c2UiIGZvcm0gd2hlcmUgdGhlIGRlY3JlbWVudCBudW1iZXIgaXNuJ3QgLTEsCisJdGhlIGZpbmFs IHZhbHVlIG1heSBiZSBleGNlZWRlZCwgc28gdXNlIEdFIGluc3RlYWQgb2YgTkUuCiAgICAgICov Ci0gICAgICAgIGNvbmRpdGlvbiA9IGdlbl9ydHhfZm10X2VlIChORSwgVk9JRG1vZGUsIGluY19z cmMsIGNvbnN0MV9ydHgpOworICAgICBpZiAoR0VUX0NPREUgKHBhdHRlcm4pICE9IFBBUkFMTEVM KQorICAgICAgIHsKKwlpZiAoSU5UVkFMIChYRVhQIChpbmNfc3JjLCAxKSkgIT0gLTEpCisJICBj b25kaXRpb24gPSBnZW5fcnR4X2ZtdF9lZSAoR0UsIFZPSURtb2RlLCBpbmNfc3JjLCBjb25zdDBf cnR4KTsKKwllbHNlCisJICBjb25kaXRpb24gPSBnZW5fcnR4X2ZtdF9lZSAoTkUsIFZPSURtb2Rl LCBpbmNfc3JjLCBjb25zdDFfcnR4KTs7CisgICAgICAgfQogCiAgICAgcmV0dXJuIGNvbmRpdGlv bjsKICAgIH0KQEAgLTY4NSwxNyArNjkzLDYgQEAgZG9sb29wX29wdGltaXplIChjbGFzcyBsb29w ICpsb29wKQogICAgICAgcmV0dXJuIGZhbHNlOwogICAgIH0KIAotICBtYXhfY29zdAotICAgID0g Q09TVFNfTl9JTlNOUyAocGFyYW1fbWF4X2l0ZXJhdGlvbnNfY29tcHV0YXRpb25fY29zdCk7Ci0g IGlmIChzZXRfc3JjX2Nvc3QgKGRlc2MtPm5pdGVyX2V4cHIsIG1vZGUsIG9wdGltaXplX2xvb3Bf Zm9yX3NwZWVkX3AgKGxvb3ApKQotICAgICAgPiBtYXhfY29zdCkKLSAgICB7Ci0gICAgICBpZiAo ZHVtcF9maWxlKQotCWZwcmludGYgKGR1bXBfZmlsZSwKLQkJICJEb2xvb3A6IG51bWJlciBvZiBp dGVyYXRpb25zIHRvbyBjb3N0bHkgdG8gY29tcHV0ZS5cbiIpOwotICAgICAgcmV0dXJuIGZhbHNl OwotICAgIH0KLQogICBpZiAoZGVzYy0+Y29uc3RfaXRlcikKICAgICBpdGVyYXRpb25zID0gd2lk ZXN0X2ludDo6ZnJvbSAocnR4X21vZGVfdCAoZGVzYy0+bml0ZXJfZXhwciwgbW9kZSksCiAJCQkJ ICAgVU5TSUdORUQpOwpAQCAtNzIyLDYgKzcxOSwyMyBAQCBkb2xvb3Bfb3B0aW1pemUgKGNsYXNz IGxvb3AgKmxvb3ApCiAgIGRvbG9vcF9yZWcgPSBnZW5fcmVnX3J0eCAobW9kZSk7CiAgIHJ0eF9p bnNuICpkb2xvb3Bfc2VxID0gdGFyZ2V0bS5nZW5fZG9sb29wX2VuZCAoZG9sb29wX3JlZywgc3Rh cnRfbGFiZWwpOwogCisgIC8qIE5vdCBhbGwgdGFyZ2V0cyBuZWVkIHRvIHByZS1jYWxjdWxhdGUg dGhlIG51bWJlciBvZiB0aGUgaXRlcmF0aW9ucyBvZgorICAgICB0aGUgbG9vcCwgdGhleSBpbnN0 ZWFkIHdvcmsgYnkgc3RvcmluZyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZQorICAgICBj b3VudGVyX3JlZyBhbmQgZGVjcmVtZW50aW5nIHRoYXQuICBDYWxsIHRoZSBhcHByb3ByaWF0ZSB0 YXJnZXQgaG9vayB0bworICAgICBjaGFuZ2UgdGhlIHZhbHVlIG9mIGNvdW50LiAgKi8KKyAgY291 bnQgPSB0YXJnZXRtLmFsbG93X2VsZW1lbnR3aXNlX2RvbG9vcF9wIChjb3VudCwgc3RhcnRfbGFi ZWwsIGRvbG9vcF9zZXEpOworCisgIG1heF9jb3N0CisgICAgPSBDT1NUU19OX0lOU05TIChwYXJh bV9tYXhfaXRlcmF0aW9uc19jb21wdXRhdGlvbl9jb3N0KTsKKyAgaWYgKHNldF9zcmNfY29zdCAo Y291bnQsIG1vZGUsIG9wdGltaXplX2xvb3BfZm9yX3NwZWVkX3AgKGxvb3ApKQorICAgICAgPiBt YXhfY29zdCkKKyAgICB7CisgICAgICBpZiAoZHVtcF9maWxlKQorCWZwcmludGYgKGR1bXBfZmls ZSwKKwkJICJEb2xvb3A6IG51bWJlciBvZiBpdGVyYXRpb25zIHRvbyBjb3N0bHkgdG8gY29tcHV0 ZS5cbiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKwogICB3b3JkX21vZGVfc2l6ZSA9 IEdFVF9NT0RFX1BSRUNJU0lPTiAod29yZF9tb2RlKTsKICAgd29yZF9tb2RlX21heCA9IChIT1NU X1dJREVfSU5UXzFVIDw8ICh3b3JkX21vZGVfc2l6ZSAtIDEpIDw8IDEpIC0gMTsKICAgaWYgKCEg ZG9sb29wX3NlcQpkaWZmIC0tZ2l0IGEvZ2NjL3RhcmdldC5kZWYgYi9nY2MvdGFyZ2V0LmRlZgpp bmRleCBkYjhhZjBjYmU4MTYyNDUxM2YxMTRmYzliYmQ4YmU2MWQ4NTVmNDA5Li5lNzk5Y2Q5N2Rl NTBiODE0YjA0MjhjMGYyOTYwOTEyYTYwOTFkMzMwIDEwMDY0NAotLS0gYS9nY2MvdGFyZ2V0LmRl ZgorKysgYi9nY2MvdGFyZ2V0LmRlZgpAQCAtNDQxMSw2ICs0NDExLDE2IEBAIFRoZSBkZWZhdWx0 IHZlcnNpb24gb2YgdGhpcyBob29rIHJldHVybnMgZmFsc2UuIiwKICBib29sLCAoY2xhc3MgbG9v cCAqbG9vcCksCiAgZGVmYXVsdF9wcmVkaWN0X2RvbG9vcF9wKQogCitERUZIT09LCisoYWxsb3df ZWxlbWVudHdpc2VfZG9sb29wX3AsCisgIlRoaXMgdGFyZ2V0IGhvb2sgYWxsb3dzIHRoZSB0YXJn ZXQgdG8gc3VwcG9ydCBsb29wLWRvbG9vcCBvcHRpbWlzYXRpb25zXG5cCit3aGVyZSB0aGUgdmFs dWUgdGhhdCBnZXRzIHB1dCBpbnRvIHRoZSBsb29wIGNvdW50ZXIgcmVnaXN0ZXIgaXMgbm90IGFc blwKK3ByZS1jYWxjdWxhdGlvbiBvZiB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbiBvZiB0aGUgbG9v cC4gIEZvciBpbnN0YW5jZSxcblwKK3RoZSB2YWx1ZSB1c2VkIGNhbiBiZSB0aGUgbnVtYmVyIG9m IGVsZW1lbnRzIHRoYXQgdGhlIGxvb3Agd2lsbCBwcm9jZXNzLlxuXAorVGhlIGRlZmF1bHQgdmVy c2lvbiBvZiB0aGlzIGhvb2sgcmV0dXJucyB0aGUgc2FtZSBydHggaXQgd2FzIGdpdmVuLiIsCisg cnR4LCAocnR4IGNvdW50LCBydHggbGFiZWwsIHJ0eCBkb2xvb3ApLAorIGRlZmF1bHRfYWxsb3df ZWxlbWVudHdpc2VfZG9sb29wX3ApCisKIERFRkhPT0tQT0QKIChoYXZlX2NvdW50X3JlZ19kZWNy X3AsCiAgIlJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgc3VwcG9ydHMgaGFyZHdhcmUgY291bnQg cmVnaXN0ZXIgZm9yIGRlY3JlbWVudFxuXApkaWZmIC0tZ2l0IGEvZ2NjL3Rhcmdob29rcy5oIGIv Z2NjL3Rhcmdob29rcy5oCmluZGV4IGExZGYyNjBmNTQ4M2RjODRmMThkOGYxMmM1MjAyNDg0YTMy ZDViYjcuLmU5NGFjMWZlMDlkZDQ4YmQyNDIxMGE4Yzg5ODJmN2E1OWU0Y2JjNjMgMTAwNjQ0Ci0t LSBhL2djYy90YXJnaG9va3MuaAorKysgYi9nY2MvdGFyZ2hvb2tzLmgKQEAgLTg4LDYgKzg4LDcg QEAgZXh0ZXJuIGJvb2wgZGVmYXVsdF9maXhlZF9wb2ludF9zdXBwb3J0ZWRfcCAodm9pZCk7CiBl eHRlcm4gYm9vbCBkZWZhdWx0X2hhc19pZnVuY19wICh2b2lkKTsKIAogZXh0ZXJuIGJvb2wgZGVm YXVsdF9wcmVkaWN0X2RvbG9vcF9wIChjbGFzcyBsb29wICopOworZXh0ZXJuIHJ0eCBkZWZhdWx0 X2FsbG93X2VsZW1lbnR3aXNlX2RvbG9vcF9wIChydHgsIHJ0eCwgcnR4KTsKIGV4dGVybiBtYWNo aW5lX21vZGUgZGVmYXVsdF9wcmVmZXJyZWRfZG9sb29wX21vZGUgKG1hY2hpbmVfbW9kZSk7CiBl eHRlcm4gY29uc3QgY2hhciAqIGRlZmF1bHRfaW52YWxpZF93aXRoaW5fZG9sb29wIChjb25zdCBy dHhfaW5zbiAqKTsKIApkaWZmIC0tZ2l0IGEvZ2NjL3Rhcmdob29rcy5jYyBiL2djYy90YXJnaG9v a3MuY2MKaW5kZXggZmUwMTE2NTIxZmVhZjMyMTg3ZTdiYzExM2JmOTNiMTgwNTg1MmM3OS4uZGU0 ZWVhOWVjMDMwMmE2YmM0ZTUyNzQ4OTM5MjVhZWNmMjQ0NDY3NiAxMDA2NDQKLS0tIGEvZ2NjL3Rh cmdob29rcy5jYworKysgYi9nY2MvdGFyZ2hvb2tzLmNjCkBAIC02NjEsNiArNjYxLDEyIEBAIGRl ZmF1bHRfcHJlZGljdF9kb2xvb3BfcCAoY2xhc3MgbG9vcCAqbG9vcCBBVFRSSUJVVEVfVU5VU0VE KQogICByZXR1cm4gZmFsc2U7CiB9CiAKK3J0eAorZGVmYXVsdF9hbGxvd19lbGVtZW50d2lzZV9k b2xvb3BfcCAocnR4IGNvdW50LCBydHgsIHJ0eCkKK3sKKyAgcmV0dXJuIGNvdW50OworfQorCiAv KiBCeSBkZWZhdWx0LCBqdXN0IHVzZSB0aGUgaW5wdXQgTU9ERSBpdHNlbGYuICAqLwogCiBtYWNo aW5lX21vZGUKZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxzdHAt Y29tcGlsZS1hc20uYyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxzdHAtY29tcGls ZS1hc20uYwppbmRleCBhY2YwODM2MDUwYzE5Yjk4M2ZlZWFmOTdjM2U1MmUxMzE4YmIxOTRkLi5l MDM2YjAzODYyNjBhNTQ3YTNhMmU0MmQ4ZjM0ZjA5MTM3OTNlNTkzIDEwMDY0NAotLS0gYS9nY2Mv dGVzdHN1aXRlL2djYy50YXJnZXQvYXJtL2Rsc3RwLWNvbXBpbGUtYXNtLmMKKysrIGIvZ2NjL3Rl c3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9kbHN0cC1jb21waWxlLWFzbS5jCkBAIC0xNDAsMTAgKzE0 MCwxOTYgQEAgVEVTVF9DT01QSUxFX0lOX0RMU1RQX0lOVEJJVFNfU0lHTkVEX1VOU0lHTkVEX1RF Uk5BUllfTV9OICh2YnJzcnEsIF9tKQogVEVTVF9DT01QSUxFX0lOX0RMU1RQX0lOVEJJVFNfU0lH TkVEX1VOU0lHTkVEX1RFUk5BUllfTV9OICh2c2hscSwgX20pCiBURVNUX0NPTVBJTEVfSU5fRExT VFBfSU5UQklUU19TSUdORURfVU5TSUdORURfVEVSTkFSWV9NX04gKHZzaHJxLCBfbSkKIAorLyog Tm93IHRlc3Qgc29tZSBtb3JlIGNvbmZpZ3VyYXRpb25zLiAgKi8KKworLyogVGVzdCBhIGZvciBs b29wIGZvcm1hdCBvZiBkZWNyZW1lbnRpbmcgdG8gemVybyAqLworaW50MzJfdCBhW10gPSB7MCwg MSwgMiwgMywgNCwgNSwgNiwgN307Cit2b2lkIHRlc3QxIChpbnQzMl90ICpiLCBpbnQgbnVtX2Vs ZW1zKQoreworICAgIGZvciAoaW50IGkgPSBudW1fZWxlbXM7IGkgPj0gMDsgaS09IDQpCisgICAg eworICAgICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHAzMnEgKGkpOworICAgICAgICBpbnQzMng0 X3QgdmEgPSB2bGRyd3Ffel9zMzIgKCYoYVtpXSksIHApOworICAgICAgICB2c3Ryd3FfcF9zMzIg KGIgKyBpLCB2YSwgcCk7CisgICAgfQorfQorCisvKiBJdGVyYXRpb24gY291bnRlciBjb3VudGlu ZyB1cCB0byBudW1faXRlci4gICovCit2b2lkIHRlc3QyICh1aW50OF90ICphLCB1aW50OF90ICpi LCB1aW50OF90ICpjLCBpbnQgbikKK3sKKyAgICBpbnQgbnVtX2l0ZXIgPSAobiArIDE1KS8xNjsK KyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bV9pdGVyOyBpKyspCisgICAgeworICAgICAgICBt dmVfcHJlZDE2X3QgcCA9IHZjdHA4cSAobik7CisgICAgICAgIHVpbnQ4eDE2X3QgdmEgPSB2bGRy YnFfel91OCAoYSwgcCk7CisgICAgICAgIHVpbnQ4eDE2X3QgdmIgPSB2bGRyYnFfel91OCAoYiwg cCk7CisgICAgICAgIHVpbnQ4eDE2X3QgdmMgPSB2YWRkcV94X3U4ICh2YSwgdmIsIHApOworICAg ICAgICB2c3RyYnFfcF91OCAoYywgdmMsIHApOworICAgICAgICBuLT0xNjsKKyAgICB9Cit9CisK Ky8qIFVzaW5nIGFuIHVucHJlZGljYXRlZCBhcml0aG1ldGljIGluc3RydWN0aW9uIHdpdGhpbiB0 aGUgbG9vcC4gICovCit2b2lkIHRlc3QzICh1aW50OF90ICphLCB1aW50OF90ICpiLCB1aW50OF90 ICpjLCAgdWludDhfdCAqZCwgaW50IG4pCit7CisgICAgd2hpbGUgKG4gPiAwKQorICAgIHsKKyAg ICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwOHEgKG4pOworICAgICAgICB1aW50OHgxNl90IHZh ID0gdmxkcmJxX3pfdTggKGEsIHApOworICAgICAgICB1aW50OHgxNl90IHZiID0gdmxkcmJxX3U4 IChiKTsKKyAgICAgICAgdWludDh4MTZfdCB2YyA9IHZhZGRxX3U4ICh2YSwgdmIpOworICAgICAg ICB1aW50OHgxNl90IHZkID0gdmFkZHFfeF91OCAodmEsIHZiLCBwKTsKKyAgICAgICAgdnN0cmJx X3BfdTggKGMsIHZjLCBwKTsKKyAgICAgICAgdnN0cmJxX3BfdTggKGQsIHZkLCBwKTsKKyAgICAg ICAgbi09MTY7CisgICAgfQorfQorCisvKiBVc2luZyBhIGRpZmZlcmVudCBWUFIgdmFsdWUgZm9y IG9uZSBpbnN0cnVjdGlvbiBpbiB0aGUgbG9vcC4gICovCit2b2lkIHRlc3Q0IChpbnQzMl90ICph LCBpbnQzMl90ICpiLCBpbnQzMl90ICpjLCBpbnQgbiwgbXZlX3ByZWQxNl90IHAxKQoreworICB3 aGlsZSAobiA+IDApCisgICAgeworICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwMzJxIChuKTsK KyAgICAgIGludDMyeDRfdCB2YSA9IHZsZHJ3cV96X3MzMiAoYSwgcCk7CisgICAgICBpbnQzMng0 X3QgdmIgPSB2bGRyd3Ffel9zMzIgKGIsIHAxKTsKKyAgICAgIGludDMyeDRfdCB2YyA9IHZhZGRx X3hfczMyICh2YSwgdmIsIHApOworICAgICAgdnN0cndxX3BfczMyIChjLCB2YywgcCk7CisgICAg ICBjICs9IDQ7CisgICAgICBhICs9IDQ7CisgICAgICBiICs9IDQ7CisgICAgICBuIC09IDQ7Cisg ICAgfQorfQorCisvKiBHZW5lcmF0aW5nIGFuZCB1c2luZyBhIGNvbnN0YW50IFZQUiB2YWx1ZSBp biB0aGUgbG9vcCwgd2l0aCBhIHZjdHAuICAqLwordm9pZCB0ZXN0NSAoaW50MzJfdCAqYSwgaW50 MzJfdCAqYiwgaW50MzJfdCAqYywgaW50IG4sIGludCBnKQoreworICB3aGlsZSAobiA+IDApCisg ICAgeworICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwMzJxIChuKTsKKyAgICAgIGludDMyeDRf dCB2YSA9IHZsZHJ3cV96X3MzMiAoYSwgcCk7CisgICAgICBtdmVfcHJlZDE2X3QgcDEgPSB2Y3Rw MzJxIChnKTsKKyAgICAgIGludDMyeDRfdCB2YiA9IHZsZHJ3cV96X3MzMiAoYiwgcDEpOworICAg ICAgaW50MzJ4NF90IHZjID0gdmFkZHFfeF9zMzIgKHZhLCB2YiwgcCk7CisgICAgICB2c3Ryd3Ff cF9zMzIgKGMsIHZjLCBwKTsKKyAgICAgIGMgKz0gNDsKKyAgICAgIGEgKz0gNDsKKyAgICAgIGIg Kz0gNDsKKyAgICAgIG4gLT0gNDsKKyAgICB9Cit9CisKKy8qIEdlbmVyYXRpbmcgYW5kIHVzaW5n IGEgZGlmZmVyZW50IFZQUiB2YWx1ZSBpbiB0aGUgbG9vcCwgd2l0aCBhIHZjdHAuICAqLwordm9p ZCB0ZXN0NiAoaW50MzJfdCAqYSwgaW50MzJfdCAqYiwgaW50MzJfdCAqYywgaW50IG4sIGludCBn KQoreworICB3aGlsZSAobiA+IDApCisgICAgeworICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3Rw MzJxIChuKTsKKyAgICAgIGludDMyeDRfdCB2YSA9IHZsZHJ3cV96X3MzMiAoYSwgcCk7CisgICAg ICBtdmVfcHJlZDE2X3QgcDEgPSB2Y3RwMzJxIChnKTsKKyAgICAgIGludDMyeDRfdCB2YiA9IHZs ZHJ3cV96X3MzMiAoYiwgcDEpOworICAgICAgaW50MzJ4NF90IHZjID0gdmFkZHFfeF9zMzIgKHZh LCB2YiwgcCk7CisgICAgICB2c3Ryd3FfcF9zMzIgKGMsIHZjLCBwKTsKKyAgICAgIGMgKz0gNDsK KyAgICAgIGEgKz0gNDsKKyAgICAgIGIgKz0gNDsKKyAgICAgIG4gLT0gNDsKKyAgICAgIGcrKzsK KyAgICB9Cit9CisKKy8qIEdlbmVyYXRpbmcgYW5kIHVzaW5nIGEgZGlmZmVyZW50IFZQUiB2YWx1 ZSBpbiB0aGUgbG9vcCwgd2l0aCBhIHZjdHBfbS4gICovCit2b2lkIHRlc3Q3IChpbnQzMl90ICph LCBpbnQzMl90ICpiLCBpbnQzMl90ICpjLCBpbnQgbiwgbXZlX3ByZWQxNl90IHAxKQoreworICB3 aGlsZSAobiA+IDApCisgICAgeworICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwMzJxIChuKTsK KyAgICAgIGludDMyeDRfdCB2YSA9IHZsZHJ3cV96X3MzMiAoYSwgcCk7CisgICAgICBtdmVfcHJl ZDE2X3QgcDIgPSB2Y3RwMzJxX20gKG4sIHAxKTsKKyAgICAgIGludDMyeDRfdCB2YiA9IHZsZHJ3 cV96X3MzMiAoYiwgcDEpOworICAgICAgaW50MzJ4NF90IHZjID0gdmFkZHFfeF9zMzIgKHZhLCB2 YiwgcDIpOworICAgICAgdnN0cndxX3BfczMyIChjLCB2YywgcCk7CisgICAgICBjICs9IDQ7Cisg ICAgICBhICs9IDQ7CisgICAgICBiICs9IDQ7CisgICAgICBuIC09IDQ7CisgICAgfQorfQorCisv KiBHZW5lcmF0aW5nIGFuZCB1c2luZyBhIGRpZmZlcmVudCBWUFIgdmFsdWUgaW4gdGhlIGxvb3As IHdpdGggYSB2Y3RwX20gdGhhdCBpcyB0aWVkIHRvIHRoZSBiYXNlIHZjdHAgVlBSLiAgKi8KK3Zv aWQgdGVzdDggKGludDMyX3QgKmEsIGludDMyX3QgKmIsIGludDMyX3QgKmMsIGludCBuKQorewor ICB3aGlsZSAobiA+IDApCisgICAgeworICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwMzJxIChu KTsKKyAgICAgIGludDMyeDRfdCB2YSA9IHZsZHJ3cV96X3MzMiAoYSwgcCk7CisgICAgICBtdmVf cHJlZDE2X3QgcDEgPSB2Y3RwMzJxX20gKG4sIHApOworICAgICAgaW50MzJ4NF90IHZiID0gdmxk cndxX3pfczMyIChiLCBwMSk7CisgICAgICBpbnQzMng0X3QgdmMgPSB2YWRkcV94X3MzMiAodmEs IHZiLCBwMSk7CisgICAgICB2c3Ryd3FfcF9zMzIgKGMsIHZjLCBwKTsKKyAgICAgIGMgKz0gNDsK KyAgICAgIGEgKz0gNDsKKyAgICAgIGIgKz0gNDsKKyAgICAgIG4gLT0gNDsKKyAgICB9Cit9CisK Ky8qIEdlbmVyYXRpbmcgYW5kIHVzaW5nIGEgZGlmZmVyZW50IFZQUiB2YWx1ZSBpbiB0aGUgbG9v cCwgd2l0aCBhIHZjbXAuICAqLwordm9pZCB0ZXN0OSAoaW50MzJfdCAqYSwgaW50MzJfdCAqYiwg aW50MzJfdCAqYywgaW50IG4pCit7CisgIHdoaWxlIChuID4gMCkKKyAgICB7CisgICAgICBtdmVf cHJlZDE2X3QgcCA9IHZjdHAzMnEgKG4pOworICAgICAgaW50MzJ4NF90IHZhID0gdmxkcndxX3pf czMyIChhLCBwKTsKKyAgICAgIGludDMyeDRfdCB2YiA9IHZsZHJ3cV96X3MzMiAoYiwgcCk7Cisg ICAgICBtdmVfcHJlZDE2X3QgcDEgPSB2Y21wZXFxX3MzMiAodmEsIHZiKTsKKyAgICAgIGludDMy eDRfdCB2YyA9IHZhZGRxX3hfczMyICh2YSwgdmIsIHAxKTsKKyAgICAgIHZzdHJ3cV9wX3MzMiAo YywgdmMsIHApOworICAgICAgYyArPSA0OworICAgICAgYSArPSA0OworICAgICAgYiArPSA0Owor ICAgICAgbiAtPSA0OworICAgIH0KK30KKworLyogR2VuZXJhdGluZyBhbmQgdXNpbmcgYSBkaWZm ZXJlbnQgVlBSIHZhbHVlIGluIHRoZSBsb29wLCB3aXRoIGEgdmNtcF9tLiAgKi8KK3ZvaWQgdGVz dDEwIChpbnQzMl90ICphLCBpbnQzMl90ICpiLCBpbnQzMl90ICpjLCBpbnQgbiwgbXZlX3ByZWQx Nl90IHAxKQoreworICB3aGlsZSAobiA+IDApCisgICAgeworICAgICAgbXZlX3ByZWQxNl90IHAg PSB2Y3RwMzJxIChuKTsKKyAgICAgIGludDMyeDRfdCB2YSA9IHZsZHJ3cV96X3MzMiAoYSwgcCk7 CisgICAgICBpbnQzMng0X3QgdmIgPSB2bGRyd3Ffel9zMzIgKGIsIHApOworICAgICAgbXZlX3By ZWQxNl90IHAyID0gdmNtcGVxcV9tX3MzMiAodmEsIHZiLCBwMSk7CisgICAgICBpbnQzMng0X3Qg dmMgPSB2YWRkcV94X3MzMiAodmEsIHZiLCBwMik7CisgICAgICB2c3Ryd3FfcF9zMzIgKGMsIHZj LCBwKTsKKyAgICAgIGMgKz0gNDsKKyAgICAgIGEgKz0gNDsKKyAgICAgIGIgKz0gNDsKKyAgICAg IG4gLT0gNDsKKyAgICB9Cit9CisKKy8qIEdlbmVyYXRpbmcgYW5kIHVzaW5nIGEgZGlmZmVyZW50 IFZQUiB2YWx1ZSBpbiB0aGUgbG9vcCwgd2l0aCBhIHZjbXBfbSB0aGF0IGlzIHRpZWQgdG8gdGhl IGJhc2UgdmN0cCBWUFIuICAqLwordm9pZCB0ZXN0MTEgKGludDMyX3QgKmEsIGludDMyX3QgKmIs IGludDMyX3QgKmMsIGludCBuLCBtdmVfcHJlZDE2X3QgcDEpCit7CisgIHdoaWxlIChuID4gMCkK KyAgICB7CisgICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHAzMnEgKG4pOworICAgICAgaW50MzJ4 NF90IHZhID0gdmxkcndxX3pfczMyIChhLCBwKTsKKyAgICAgIGludDMyeDRfdCB2YiA9IHZsZHJ3 cV96X3MzMiAoYiwgcCk7CisgICAgICBtdmVfcHJlZDE2X3QgcDIgPSB2Y21wZXFxX21fczMyICh2 YSwgdmIsIHAxKTsKKyAgICAgIGludDMyeDRfdCB2YyA9IHZhZGRxX3hfczMyICh2YSwgdmIsIHAy KTsKKyAgICAgIHZzdHJ3cV9wX3MzMiAoYywgdmMsIHApOworICAgICAgYyArPSA0OworICAgICAg YSArPSA0OworICAgICAgYiArPSA0OworICAgICAgbiAtPSA0OworICAgIH0KK30KKwogLyogVGhl IGZpbmFsIG51bWJlciBvZiBETFNUUHMgY3VycmVudGx5IGlzIGNhbGN1bGF0ZWQgYnkgdGhlIG51 bWJlciBvZgotICBgVEVTVF9DT01QSUxFX0lOX0RMU1RQX0lOVEJJVFNfU0lHTkVEX1VOU0lHTkVE X1RFUk5BUlkuKmAgbWFjcm9zICogNi4gICovCi0vKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3NlbWJs ZXItdGltZXMge1x0ZGxzdHB9IDE0NCB9IH0gKi8KLS8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2Vt Ymxlci10aW1lcyB7XHRsZXRwfSAxNDQgfSB9ICovCi0vKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3Nl bWJsZXItbm90ICJcdHZjdHBcdCIgfSB9ICovCi0vKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3NlbWJs ZXItbm90ICJcdHZwc3RcdCIgfSB9ICovCi0vKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3NlbWJsZXIt bm90ICJwMCIgfSB9ICovCisgIGBURVNUX0NPTVBJTEVfSU5fRExTVFBfSU5UQklUU19TSUdORURf VU5TSUdORURfVEVSTkFSWS4qYCBtYWNyb3MgKiA2ICsgMTEuICAqLworLyogeyBkZy1maW5hbCB7 IHNjYW4tYXNzZW1ibGVyLXRpbWVzIHtcdGRsc3RwfSAxNTUgfSB9ICovCisvKiB7IGRnLWZpbmFs IHsgc2Nhbi1hc3NlbWJsZXItdGltZXMge1x0bGV0cH0gMTU1IH0gfSAqLwpkaWZmIC0tZ2l0IGEv Z2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9kbHN0cC1pbnQxNng4LmMgYi9nY2MvdGVzdHN1 aXRlL2djYy50YXJnZXQvYXJtL2Rsc3RwLWludDE2eDguYwpuZXcgZmlsZSBtb2RlIDEwMDY0NApp bmRleCAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLi5iMWMwM2I2MThl MGRjYzdkNDI2OGYyZjAwNDY2M2I2ZTMzMmE0MDJhCi0tLSAvZGV2L251bGwKKysrIGIvZ2NjL3Rl c3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9kbHN0cC1pbnQxNng4LmMKQEAgLTAsMCArMSw2OCBAQAor LyogeyBkZy1kbyBydW4geyB0YXJnZXQgeyBhcm0qLSotKiB9IH0gfSAqLworLyogeyBkZy1yZXF1 aXJlLWVmZmVjdGl2ZS10YXJnZXQgYXJtX3Y4XzFtX212ZV9vayB9ICovCisvKiB7IGRnLXNraXAt aWYgImF2b2lkIGNvbmZsaWN0aW5nIG11bHRpbGliIG9wdGlvbnMiIHsgKi0qLSogfSB7ICItbWFy bSIgIi1tY3B1PSoiIH0gfSAqLworLyogeyBkZy1vcHRpb25zICItbWFyY2g9YXJtdjguMS1tLm1h aW4rZnAuZHArbXZlLmZwIC1tZmxvYXQtYWJpPWhhcmQgLW1mcHU9YXV0byAtTzMgLS1zYXZlLXRl bXBzIiB9ICovCisKKyNpbmNsdWRlIDxhcm1fbXZlLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNp bmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlICJsb2IuaCIKKwordm9pZCAgX19hdHRyaWJ1dGVf XyAoKG5vaW5saW5lKSkgdGVzdCAoaW50MTZfdCAqYSwgaW50MTZfdCAqYiwgaW50MTZfdCAqYywg aW50IG4pCit7CisgIHdoaWxlIChuID4gMCkKKyAgICB7CisgICAgICBtdmVfcHJlZDE2X3QgcCA9 IHZjdHAxNnEgKG4pOworICAgICAgaW50MTZ4OF90IHZhID0gdmxkcmhxX3pfczE2IChhLCBwKTsK KyAgICAgIGludDE2eDhfdCB2YiA9IHZsZHJocV96X3MxNiAoYiwgcCk7CisgICAgICBpbnQxNng4 X3QgdmMgPSB2YWRkcV94X3MxNiAodmEsIHZiLCBwKTsKKyAgICAgIHZzdHJocV9wX3MxNiAoYywg dmMsIHApOworICAgICAgYys9ODsKKyAgICAgIGErPTg7CisgICAgICBiKz04OworICAgICAgbi09 ODsKKyAgICB9Cit9CisKK2ludCBtYWluICgpCit7CisgIGludCBpOworICBpbnQxNl90IHRlbXAx W05dOworICBpbnQxNl90IHRlbXAyW05dOworICBpbnQxNl90IHRlbXAzW05dOworICByZXNldF9k YXRhMTYgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIE4pOworICB0ZXN0ICh0ZW1wMSwgdGVtcDIsIHRl bXAzLCAwKTsKKyAgY2hlY2tfcGx1czE2ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCAwKTsKKworICBy ZXNldF9kYXRhMTYgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIE4pOworICB0ZXN0ICh0ZW1wMSwgdGVt cDIsIHRlbXAzLCAxKTsKKyAgY2hlY2tfcGx1czE2ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCAxKTsK KworICByZXNldF9kYXRhMTYgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIE4pOworICB0ZXN0ICh0ZW1w MSwgdGVtcDIsIHRlbXAzLCA3KTsKKyAgY2hlY2tfcGx1czE2ICh0ZW1wMSwgdGVtcDIsIHRlbXAz LCA3KTsKKworICByZXNldF9kYXRhMTYgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIE4pOworICB0ZXN0 ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCA4KTsKKyAgY2hlY2tfcGx1czE2ICh0ZW1wMSwgdGVtcDIs IHRlbXAzLCA4KTsKKworICByZXNldF9kYXRhMTYgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIE4pOwor ICB0ZXN0ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCA5KTsKKyAgY2hlY2tfcGx1czE2ICh0ZW1wMSwg dGVtcDIsIHRlbXAzLCA5KTsKKworICByZXNldF9kYXRhMTYgKHRlbXAxLCB0ZW1wMiwgdGVtcDMs IE4pOworICB0ZXN0ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCAxNik7CisgIGNoZWNrX3BsdXMxNiAo dGVtcDEsIHRlbXAyLCB0ZW1wMywgMTYpOworCisgIHJlc2V0X2RhdGExNiAodGVtcDEsIHRlbXAy LCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDE3KTsKKyAgY2hlY2tf cGx1czE2ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCAxNyk7CisKKyAgcmVzZXRfZGF0YTE2ICh0ZW1w MSwgdGVtcDIsIHRlbXAzLCBOKTsKK30KKworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNzZW1ibGVy LXRpbWVzIHtcdGRsc3RwLjE2fSAxIH0gfSAqLworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNzZW1i bGVyLXRpbWVzIHtcdGxldHB9IDEgfSB9ICovCisvKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3NlbWJs ZXItbm90ICJcdHZjdHAiIH0gfSAqLworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNzZW1ibGVyLW5v dCAiXHR2cHN0IiB9IH0gKi8KKy8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2VtYmxlci1ub3QgInAw IiB9IH0gKi8KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxzdHAt aW50MzJ4NC5jIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9kbHN0cC1pbnQzMng0LmMK bmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMC4uNGEzZWIwNTc3YmUwNjMxYWI0ZTA3ZjZmNzVjMmM4MDJiNTM1Yzg4YwotLS0g L2Rldi9udWxsCisrKyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxzdHAtaW50MzJ4 NC5jCkBAIC0wLDAgKzEsNjggQEAKKy8qIHsgZGctZG8gcnVuIHsgdGFyZ2V0IHsgYXJtKi0qLSog fSB9IH0gKi8KKy8qIHsgZGctcmVxdWlyZS1lZmZlY3RpdmUtdGFyZ2V0IGFybV92OF8xbV9tdmVf b2sgfSAqLworLyogeyBkZy1za2lwLWlmICJhdm9pZCBjb25mbGljdGluZyBtdWx0aWxpYiBvcHRp b25zIiB7ICotKi0qIH0geyAiLW1hcm0iICItbWNwdT0qIiB9IH0gKi8KKy8qIHsgZGctb3B0aW9u cyAiLW1hcmNoPWFybXY4LjEtbS5tYWluK2ZwLmRwK212ZS5mcCAtbWZsb2F0LWFiaT1oYXJkIC1t ZnB1PWF1dG8gLU8zIC0tc2F2ZS10ZW1wcyIgfSAqLworCisjaW5jbHVkZSA8YXJtX212ZS5oPgor I2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSAibG9iLmgi CisKK3ZvaWQgIF9fYXR0cmlidXRlX18gKChub2lubGluZSkpIHRlc3QgKGludDMyX3QgKmEsIGlu dDMyX3QgKmIsIGludDMyX3QgKmMsIGludCBuKQoreworICB3aGlsZSAobiA+IDApCisgICAgewor ICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwMzJxIChuKTsKKyAgICAgIGludDMyeDRfdCB2YSA9 IHZsZHJ3cV96X3MzMiAoYSwgcCk7CisgICAgICBpbnQzMng0X3QgdmIgPSB2bGRyd3Ffel9zMzIg KGIsIHApOworICAgICAgaW50MzJ4NF90IHZjID0gdmFkZHFfeF9zMzIgKHZhLCB2YiwgcCk7Cisg ICAgICB2c3Ryd3FfcF9zMzIgKGMsIHZjLCBwKTsKKyAgICAgIGMrPTQ7CisgICAgICBhKz00Owor ICAgICAgYis9NDsKKyAgICAgIG4tPTQ7CisgICAgfQorfQorCitpbnQgbWFpbiAoKQoreworICBp bnQgaTsKKyAgaW50MzJfdCB0ZW1wMVtOXTsKKyAgaW50MzJfdCB0ZW1wMltOXTsKKyAgaW50MzJf dCB0ZW1wM1tOXTsKKyAgcmVzZXRfZGF0YTMyICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCBOKTsKKyAg dGVzdCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgMCk7CisgIGNoZWNrX3BsdXMzMiAodGVtcDEsIHRl bXAyLCB0ZW1wMywgMCk7CisKKyAgcmVzZXRfZGF0YTMyICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCBO KTsKKyAgdGVzdCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgMSk7CisgIGNoZWNrX3BsdXMzMiAodGVt cDEsIHRlbXAyLCB0ZW1wMywgMSk7CisKKyAgcmVzZXRfZGF0YTMyICh0ZW1wMSwgdGVtcDIsIHRl bXAzLCBOKTsKKyAgdGVzdCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgMyk7CisgIGNoZWNrX3BsdXMz MiAodGVtcDEsIHRlbXAyLCB0ZW1wMywgMyk7CisKKyAgcmVzZXRfZGF0YTMyICh0ZW1wMSwgdGVt cDIsIHRlbXAzLCBOKTsKKyAgdGVzdCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgNCk7CisgIGNoZWNr X3BsdXMzMiAodGVtcDEsIHRlbXAyLCB0ZW1wMywgNCk7CisKKyAgcmVzZXRfZGF0YTMyICh0ZW1w MSwgdGVtcDIsIHRlbXAzLCBOKTsKKyAgdGVzdCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgNSk7Cisg IGNoZWNrX3BsdXMzMiAodGVtcDEsIHRlbXAyLCB0ZW1wMywgNSk7CisKKyAgcmVzZXRfZGF0YTMy ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCBOKTsKKyAgdGVzdCAodGVtcDEsIHRlbXAyLCB0ZW1wMywg OCk7CisgIGNoZWNrX3BsdXMzMiAodGVtcDEsIHRlbXAyLCB0ZW1wMywgOCk7CisKKyAgcmVzZXRf ZGF0YTMyICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCBOKTsKKyAgdGVzdCAodGVtcDEsIHRlbXAyLCB0 ZW1wMywgOSk7CisgIGNoZWNrX3BsdXMzMiAodGVtcDEsIHRlbXAyLCB0ZW1wMywgOSk7CisKKyAg cmVzZXRfZGF0YTMyICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCBOKTsKK30KKworLyogeyBkZy1maW5h bCB7IHNjYW4tYXNzZW1ibGVyLXRpbWVzIHtcdGRsc3RwLjMyfSAxIH0gfSAqLworLyogeyBkZy1m aW5hbCB7IHNjYW4tYXNzZW1ibGVyLXRpbWVzIHtcdGxldHB9IDEgfSB9ICovCisvKiB7IGRnLWZp bmFsIHsgc2Nhbi1hc3NlbWJsZXItbm90ICJcdHZjdHAiIH0gfSAqLworLyogeyBkZy1maW5hbCB7 IHNjYW4tYXNzZW1ibGVyLW5vdCAiXHR2cHN0IiB9IH0gKi8KKy8qIHsgZGctZmluYWwgeyBzY2Fu LWFzc2VtYmxlci1ub3QgInAwIiB9IH0gKi8KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2Nj LnRhcmdldC9hcm0vZGxzdHAtaW50NjR4Mi5jIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2Fy bS9kbHN0cC1pbnQ2NHgyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMC4uZjA1ZmY4MzQzNjNlMmE0N2E5ZmFkZGI2Yjhi MDliNjBlYjk0YTNjMgotLS0gL2Rldi9udWxsCisrKyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdl dC9hcm0vZGxzdHAtaW50NjR4Mi5jCkBAIC0wLDAgKzEsNjggQEAKKy8qIHsgZGctZG8gcnVuIHsg dGFyZ2V0IHsgYXJtKi0qLSogfSB9IH0gKi8KKy8qIHsgZGctcmVxdWlyZS1lZmZlY3RpdmUtdGFy Z2V0IGFybV92OF8xbV9tdmVfb2sgfSAqLworLyogeyBkZy1za2lwLWlmICJhdm9pZCBjb25mbGlj dGluZyBtdWx0aWxpYiBvcHRpb25zIiB7ICotKi0qIH0geyAiLW1hcm0iICItbWNwdT0qIiB9IH0g Ki8KKy8qIHsgZGctb3B0aW9ucyAiLW1hcmNoPWFybXY4LjEtbS5tYWluK2ZwLmRwK212ZS5mcCAt bWZsb2F0LWFiaT1oYXJkIC1tZnB1PWF1dG8gLU8zIC0tc2F2ZS10ZW1wcyIgfSAqLworCisjaW5j bHVkZSA8YXJtX212ZS5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+ CisjaW5jbHVkZSAibG9iLmgiCisKK3ZvaWQgIF9fYXR0cmlidXRlX18gKChub2lubGluZSkpIHRl c3QgKGludDY0X3QgKmEsIGludDY0X3QgKmMsIGludCBuKQoreworICB3aGlsZSAobiA+IDApCisg ICAgeworICAgICAgbXZlX3ByZWQxNl90IHAgPSB2Y3RwNjRxIChuKTsKKyAgICAgIGludDY0eDJf dCB2YSA9IHZsZHJkcV9nYXRoZXJfb2Zmc2V0X3pfczY0IChhLCB2Y3JlYXRlcV91NjQgKDgsIDAp LCBwKTsKKyAgICAgIHZzdHJkcV9zY2F0dGVyX29mZnNldF9wX3M2NCAoYywgdmNyZWF0ZXFfdTY0 ICg4LCAwKSwgdmEsIHApOworICAgICAgYys9MjsKKyAgICAgIGErPTI7CisgICAgICBuLT0yOwor ICAgIH0KK30KKworaW50IG1haW4gKCkKK3sKKyAgaW50IGk7CisgIGludDY0X3QgdGVtcDFbTl07 CisgIGludDY0X3QgdGVtcDNbTl07CisgIHJlc2V0X2RhdGE2NCAgKHRlbXAxLCB0ZW1wMywgTik7 CisgIHRlc3QgKHRlbXAxLCB0ZW1wMywgMCk7CisgIGNoZWNrX21lbWNweTY0ICh0ZW1wMSwgdGVt cDMsIDApOworCisgIHJlc2V0X2RhdGE2NCAgKHRlbXAxLCB0ZW1wMywgTik7CisgIHRlc3QgKHRl bXAxLCB0ZW1wMywgMSk7CisgIGNoZWNrX21lbWNweTY0ICh0ZW1wMSwgdGVtcDMsIDEpOworCisg IHJlc2V0X2RhdGE2NCAgKHRlbXAxLCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMywg Mik7CisgIGNoZWNrX21lbWNweTY0ICh0ZW1wMSwgdGVtcDMsIDIpOworCisgIHJlc2V0X2RhdGE2 NCAgKHRlbXAxLCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMywgMyk7CisgIGNoZWNr X21lbWNweTY0ICh0ZW1wMSwgdGVtcDMsIDMpOworCisgIHJlc2V0X2RhdGE2NCAgKHRlbXAxLCB0 ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMywgNCk7CisgIGNoZWNrX21lbWNweTY0ICh0 ZW1wMSwgdGVtcDMsIDQpOworCisgIHJlc2V0X2RhdGE2NCAgKHRlbXAxLCB0ZW1wMywgTik7Cisg IHRlc3QgKHRlbXAxLCB0ZW1wMywgNSk7CisgIGNoZWNrX21lbWNweTY0ICh0ZW1wMSwgdGVtcDMs IDUpOworCisgIHJlc2V0X2RhdGE2NCAgKHRlbXAxLCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAx LCB0ZW1wMywgNik7CisgIGNoZWNrX21lbWNweTY0ICh0ZW1wMSwgdGVtcDMsIDYpOworCisgIHJl c2V0X2RhdGE2NCAgKHRlbXAxLCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMywgNyk7 CisgIGNoZWNrX21lbWNweTY0ICh0ZW1wMSwgdGVtcDMsIDcpOworCisgIHJlc2V0X2RhdGE2NCAg KHRlbXAxLCB0ZW1wMywgTik7Cit9CisKKy8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2VtYmxlci10 aW1lcyB7XHRkbHN0cC42NH0gMSB9IH0gKi8KKy8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2VtYmxl ci10aW1lcyB7XHRsZXRwfSAxIH0gfSAqLworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNzZW1ibGVy LW5vdCAiXHR2Y3RwIiB9IH0gKi8KKy8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2VtYmxlci1ub3Qg Ilx0dnBzdCIgfSB9ICovCisvKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3NlbWJsZXItbm90ICJwMCIg fSB9ICovCmRpZmYgLS1naXQgYS9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYXJtL2Rsc3RwLWlu dDh4MTYuYyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxzdHAtaW50OHgxNi5jCm5l dyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAuLmYyODFiYTc4NDhkMWJhMzMyMTEyNGU5OTZlYjViZWE0NDk3N2MyYWIKLS0tIC9k ZXYvbnVsbAorKysgYi9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYXJtL2Rsc3RwLWludDh4MTYu YwpAQCAtMCwwICsxLDY4IEBACisvKiB7IGRnLWRvIHJ1biB7IHRhcmdldCB7IGFybSotKi0qIH0g fSB9ICovCisvKiB7IGRnLXJlcXVpcmUtZWZmZWN0aXZlLXRhcmdldCBhcm1fdjhfMW1fbXZlX29r IH0gKi8KKy8qIHsgZGctc2tpcC1pZiAiYXZvaWQgY29uZmxpY3RpbmcgbXVsdGlsaWIgb3B0aW9u cyIgeyAqLSotKiB9IHsgIi1tYXJtIiAiLW1jcHU9KiIgfSB9ICovCisvKiB7IGRnLW9wdGlvbnMg Ii1tYXJjaD1hcm12OC4xLW0ubWFpbitmcC5kcCttdmUuZnAgLW1mbG9hdC1hYmk9aGFyZCAtbWZw dT1hdXRvIC1PMyAtLXNhdmUtdGVtcHMiIH0gKi8KKworI2luY2x1ZGUgPGFybV9tdmUuaD4KKyNp bmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgImxvYi5oIgor Cit2b2lkICBfX2F0dHJpYnV0ZV9fICgobm9pbmxpbmUpKSB0ZXN0IChpbnQ4X3QgKmEsIGludDhf dCAqYiwgaW50OF90ICpjLCBpbnQgbikKK3sKKyAgd2hpbGUgKG4gPiAwKQorICAgIHsKKyAgICAg IG12ZV9wcmVkMTZfdCBwID0gdmN0cDhxIChuKTsKKyAgICAgIGludDh4MTZfdCB2YSA9IHZsZHJi cV96X3M4IChhLCBwKTsKKyAgICAgIGludDh4MTZfdCB2YiA9IHZsZHJicV96X3M4IChiLCBwKTsK KyAgICAgIGludDh4MTZfdCB2YyA9IHZhZGRxX3hfczggKHZhLCB2YiwgcCk7CisgICAgICB2c3Ry YnFfcF9zOCAoYywgdmMsIHApOworICAgICAgYys9MTY7CisgICAgICBhKz0xNjsKKyAgICAgIGIr PTE2OworICAgICAgbi09MTY7CisgICAgfQorfQorCitpbnQgbWFpbiAoKQoreworICBpbnQgaTsK KyAgaW50OF90IHRlbXAxW05dOworICBpbnQ4X3QgdGVtcDJbTl07CisgIGludDhfdCB0ZW1wM1tO XTsKKyAgcmVzZXRfZGF0YTggKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIE4pOworICB0ZXN0ICh0ZW1w MSwgdGVtcDIsIHRlbXAzLCAwKTsKKyAgY2hlY2tfcGx1czggKHRlbXAxLCB0ZW1wMiwgdGVtcDMs IDApOworCisgIHJlc2V0X2RhdGE4ICh0ZW1wMSwgdGVtcDIsIHRlbXAzLCBOKTsKKyAgdGVzdCAo dGVtcDEsIHRlbXAyLCB0ZW1wMywgMSk7CisgIGNoZWNrX3BsdXM4ICh0ZW1wMSwgdGVtcDIsIHRl bXAzLCAxKTsKKworICByZXNldF9kYXRhOCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgTik7CisgIHRl c3QgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDE1KTsKKyAgY2hlY2tfcGx1czggKHRlbXAxLCB0ZW1w MiwgdGVtcDMsIDE1KTsKKworICByZXNldF9kYXRhOCAodGVtcDEsIHRlbXAyLCB0ZW1wMywgTik7 CisgIHRlc3QgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDE2KTsKKyAgY2hlY2tfcGx1czggKHRlbXAx LCB0ZW1wMiwgdGVtcDMsIDE2KTsKKworICByZXNldF9kYXRhOCAodGVtcDEsIHRlbXAyLCB0ZW1w MywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDE3KTsKKyAgY2hlY2tfcGx1czgg KHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDE3KTsKKworICByZXNldF9kYXRhOCAodGVtcDEsIHRlbXAy LCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDMyKTsKKyAgY2hlY2tf cGx1czggKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDMyKTsKKworICByZXNldF9kYXRhOCAodGVtcDEs IHRlbXAyLCB0ZW1wMywgTik7CisgIHRlc3QgKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDMzKTsKKyAg Y2hlY2tfcGx1czggKHRlbXAxLCB0ZW1wMiwgdGVtcDMsIDMzKTsKKworICByZXNldF9kYXRhOCAo dGVtcDEsIHRlbXAyLCB0ZW1wMywgTik7Cit9CisKKy8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2Vt Ymxlci10aW1lcyB7XHRkbHN0cC44fSAxIH0gfSAqLworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNz ZW1ibGVyLXRpbWVzIHtcdGxldHB9IDEgfSB9ICovCisvKiB7IGRnLWZpbmFsIHsgc2Nhbi1hc3Nl bWJsZXItbm90ICJcdHZjdHAiIH0gfSAqLworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNzZW1ibGVy LW5vdCAiXHR2cHN0IiB9IH0gKi8KKy8qIHsgZGctZmluYWwgeyBzY2FuLWFzc2VtYmxlci1ub3Qg InAwIiB9IH0gKi8KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxz dHAtaW52YWxpZC1hc20uYyBiL2djYy90ZXN0c3VpdGUvZ2NjLnRhcmdldC9hcm0vZGxzdHAtaW52 YWxpZC1hc20uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwLi5iMjUwNjI1Y2U0MjY0MDBhZDZiZTFlZGNiNzdlODU0Y2M2 Yjc5ZGM5Ci0tLSAvZGV2L251bGwKKysrIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9k bHN0cC1pbnZhbGlkLWFzbS5jCkBAIC0wLDAgKzEsMjEwIEBACisKKy8qIHsgZGctZG8gY29tcGls ZSB7IHRhcmdldCB7IGFybSotKi0qIH0gfSB9ICovCisvKiB7IGRnLXJlcXVpcmUtZWZmZWN0aXZl LXRhcmdldCBhcm1fdjhfMW1fbXZlX29rIH0gKi8KKy8qIHsgZGctc2tpcC1pZiAiYXZvaWQgY29u ZmxpY3RpbmcgbXVsdGlsaWIgb3B0aW9ucyIgeyAqLSotKiB9IHsgIi1tYXJtIiAiLW1jcHU9KiIg fSB9ICovCisvKiB7IGRnLW9wdGlvbnMgIi1tYXJjaD1hcm12OC4xLW0ubWFpbitmcC5kcCttdmUu ZnAgLW1mbG9hdC1hYmk9aGFyZCAtbWZwdT1hdXRvIC1PMyAtLXNhdmUtdGVtcHMiIH0gKi8KKwor I2luY2x1ZGUgPGFybV9tdmUuaD4KKworLyogVGVybWluYXRpbmcgb24gYSBub24temVybyBudW1i ZXIgb2YgZWxlbWVudHMuICAqLwordm9pZCB0ZXN0MSAodWludDhfdCAqYSwgdWludDhfdCAqYiwg dWludDhfdCAqYywgaW50IG4pCit7CisgICAgd2hpbGUgKG4gPiAxKQorICAgIHsKKyAgICAgICBt dmVfcHJlZDE2X3QgcCA9IHZjdHA4cSAobik7CisgICAgICAgdWludDh4MTZfdCB2YSA9IHZsZHJi cV96X3U4IChhLCBwKTsKKyAgICAgICB1aW50OHgxNl90IHZiID0gdmxkcmJxX3pfdTggKGIsIHAp OworICAgICAgIHVpbnQ4eDE2X3QgdmMgPSB2YWRkcV94X3U4ICh2YSwgdmIsIHApOworICAgICAg IHZzdHJicV9wX3U4IChjLCB2YywgcCk7CisgICAgICAgbiAtPSAxNjsKKyAgICB9Cit9CisKKy8q IFNpbWlsYXIsIHRlcm1pbmF0aW5nIG9uIGEgbm9uLXplcm8gbnVtYmVyIG9mIGVsZW1lbnRzLCBi dXQgaW4gYSBmb3IgbG9vcAorICAgZm9ybWF0LiAgKi8KK2ludDMyX3QgYVtdID0gezAsIDEsIDIs IDMsIDQsIDUsIDYsIDd9Owordm9pZCB0ZXN0MiAoaW50MzJfdCAqYiwgaW50IG51bV9lbGVtcykK K3sKKyAgICBmb3IgKGludCBpID0gbnVtX2VsZW1zOyBpID49IDI7IGktPSA0KQorICAgIHsKKyAg ICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHAzMnEgKGkpOworICAgICAgIGludDMyeDRfdCB2YSA9 IHZsZHJ3cV96X3MzMiAoJihhW2ldKSwgcCk7CisgICAgICAgdnN0cndxX3BfczMyIChiICsgaSwg dmEsIHApOworICAgIH0KK30KKworLyogSXRlcmF0aW9uIGNvdW50ZXIgY291bnRpbmcgdXAgdG8g bnVtX2l0ZXIsIHdpdGggYSBub24temVybyBzdGFydGluZyBudW0uICAqLwordm9pZCB0ZXN0MyAo dWludDhfdCAqYSwgdWludDhfdCAqYiwgdWludDhfdCAqYywgaW50IG4pCit7CisgICAgaW50IG51 bV9pdGVyID0gKG4gKyAxNSkvMTY7CisgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBudW1faXRlcjsg aSsrKQorICAgIHsKKyAgICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHA4cSAobik7CisgICAgICAg dWludDh4MTZfdCB2YSA9IHZsZHJicV96X3U4IChhLCBwKTsKKyAgICAgICB1aW50OHgxNl90IHZi ID0gdmxkcmJxX3pfdTggKGIsIHApOworICAgICAgIHVpbnQ4eDE2X3QgdmMgPSB2YWRkcV94X3U4 ICh2YSwgdmIsIHApOworICAgICAgIHZzdHJicV9wX3U4IChjLCB2YywgcCk7CisgICAgICAgbiAt PSAxNjsKKyAgICB9Cit9CisKKy8qIEl0ZXJhdGlvbiBjb3VudGVyIGNvdW50aW5nIHVwIHRvIG51 bV9pdGVyLCB3aXRoIGEgbGFyZ2VyIGluY3JlbWVudCAgKi8KK3ZvaWQgdGVzdDQgKHVpbnQ4X3Qg KmEsIHVpbnQ4X3QgKmIsIHVpbnQ4X3QgKmMsIGludCBuKQoreworICAgIGludCBudW1faXRlciA9 IChuICsgMTUpLzE2OworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtX2l0ZXI7IGkrPTIpCisg ICAgeworICAgICAgIG12ZV9wcmVkMTZfdCBwID0gdmN0cDhxIChuKTsKKyAgICAgICB1aW50OHgx Nl90IHZhID0gdmxkcmJxX3pfdTggKGEsIHApOworICAgICAgIHVpbnQ4eDE2X3QgdmIgPSB2bGRy YnFfel91OCAoYiwgcCk7CisgICAgICAgdWludDh4MTZfdCB2YyA9IHZhZGRxX3hfdTggKHZhLCB2 YiwgcCk7CisgICAgICAgdnN0cmJxX3BfdTggKGMsIHZjLCBwKTsKKyAgICAgICBuIC09IDE2Owor ICAgIH0KK30KKworLyogVXNpbmcgYW4gdW5wcmVkaWNhdGVkIHN0b3JlIGluc3RydWN0aW9uIHdp dGhpbiB0aGUgbG9vcC4gICovCit2b2lkIHRlc3Q1ICh1aW50OF90ICphLCB1aW50OF90ICpiLCB1 aW50OF90ICpjLCAgdWludDhfdCAqZCwgaW50IG4pCit7CisgICAgd2hpbGUgKG4gPiAwKQorICAg IHsKKyAgICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHA4cSAobik7CisgICAgICAgdWludDh4MTZf dCB2YSA9IHZsZHJicV96X3U4IChhLCBwKTsKKyAgICAgICB1aW50OHgxNl90IHZiID0gdmxkcmJx X3pfdTggKGIsIHApOworICAgICAgIHVpbnQ4eDE2X3QgdmMgPSB2YWRkcV91OCAodmEsIHZiKTsK KyAgICAgICB1aW50OHgxNl90IHZkID0gdmFkZHFfeF91OCAodmEsIHZiLCBwKTsKKyAgICAgICB2 c3RyYnFfdTggKGQsIHZkKTsKKyAgICAgICBuIC09IDE2OworICAgIH0KK30KKworLyogVXNpbmcg YW4gdW5wcmVkaWNhdGVkIHZjbXAgdG8gZ2VuZXJhdGUgYSBuZXcgcHJlZGljYXRlIHZhbHVlIGlu IHRoZQorICAgbG9vcCBhbmQgdGhlbiB1c2luZyBpdCBpbiBhIHN0b3JlIGluc24uICAqLwordm9p ZCB0ZXN0MTQgKGludDMyX3QgKmEsIGludDMyX3QgKmIsIGludDMyeDRfdCB2YywgaW50MzJfdCAq YywgaW50IG4pCit7CisgIHdoaWxlIChuID4gMCkKKyAgICB7CisgICAgICBtdmVfcHJlZDE2X3Qg cCA9IHZjdHAzMnEgKG4pOworICAgICAgaW50MzJ4NF90IHZhID0gdmxkcndxX3pfczMyIChhLCBw KTsKKyAgICAgIGludDMyeDRfdCB2YiA9IHZsZHJ3cV96X3MzMiAoYiwgcCk7CisgICAgICBpbnQz Mng0X3QgdmMgPSB2YWRkcV94X3MzMiAodmEsIHZiLCBwKTsKKyAgICAgIG12ZV9wcmVkMTZfdCBw MSA9IHZjbXBlcXFfczMyICh2YSwgdmMpOworICAgICAgdnN0cndxX3BfczMyIChjLCB2YywgcDEp OworICAgICAgYyArPSA0OworICAgICAgYSArPSA0OworICAgICAgYiArPSA0OworICAgICAgbiAt PSA0OworICAgIH0KK30KKworLyogVXNpbmcgYW4gdW5wcmVkaWNhdGVkIHN0b3JlIG91dHNpZGUg dGhlIGxvb3AuICAqLwordm9pZCB0ZXN0NiAodWludDhfdCAqYSwgdWludDhfdCAqYiwgdWludDhf dCAqYywgaW50IG4sIHVpbnQ4eDE2X3QgdngpCit7CisgICAgd2hpbGUgKG4gPiAwKQorICAgIHsK KyAgICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHA4cSAobik7CisgICAgICAgdWludDh4MTZfdCB2 YSA9IHZsZHJicV96X3U4IChhLCBwKTsKKyAgICAgICB1aW50OHgxNl90IHZiID0gdmxkcmJxX3pf dTggKGIsIHApOworICAgICAgIHVpbnQ4eDE2X3QgdmMgPSB2YWRkcV9tX3U4ICh2eCwgdmEsIHZi LCBwKTsKKyAgICAgICB2eCA9IHZhZGRxX3U4ICh2eCwgdmMpOworICAgICAgIGEgKz0gMTY7Cisg ICAgICAgYiArPSAxNjsKKyAgICAgICBuIC09IDE2OworICAgIH0KKyAgICB2c3RyYnFfdTggKGMs IHZ4KTsKK30KKworLyogVXNpbmcgYW4gdW5wcmVkaWNhdGVkIG9wIHdpdGggYSBzY2FsYXIgb3V0 cHV0LCB3aGVyZSB0aGUgcmVzdWx0IGlzIHZhbGlkCisgICBvdXRzaWRlIHRoZSBiYi4gICovCit1 aW50OF90IHRlc3Q3ICh1aW50OF90ICphLCB1aW50OF90ICpiLCB1aW50OF90ICpjLCBpbnQgbiwg dWludDh4MTZfdCB2eCkKK3sKKyAgICB1aW50OF90IHN1bSA9IDA7CisgICAgd2hpbGUgKG4gPiAw KQorICAgIHsKKyAgICAgICBtdmVfcHJlZDE2X3QgcCA9IHZjdHA4cSAobik7CisgICAgICAgdWlu dDh4MTZfdCB2YSA9IHZsZHJicV96X3U4IChhLCBwKTsKKyAgICAgICB1aW50OHgxNl90IHZiID0g dmxkcmJxX3pfdTggKGIsIHApOworICAgICAgIHVpbnQ4eDE2X3QgdmMgPSB2YWRkcV9tX3U4ICh2 eCwgdmEsIHZiLCBwKTsKKyAgICAgICBzdW0gKz0gdmFkZHZxX3U4ICh2Yyk7CisgICAgICAgYSAr PSAxNjsKKyAgICAgICBiICs9IDE2OworICAgICAgIG4gLT0gMTY7CisgICAgfQorICAgIHJldHVy biBzdW07Cit9CisKKy8qIFVzaW5nIGFuIHVucHJlZGljYXRlZCBvcCB3aXRoIGEgc2NhbGFyIG91 dHB1dCwgdGhlbiBhIHNjYWxhciBvcCwKKyAgIHdoZXJlIHRoZSByZXN1bHQgaXMgdmFsaWQgb3V0 c2lkZSB0aGUgYmIuICAqLwordWludDhfdCB0ZXN0OCAodWludDhfdCAqYSwgdWludDhfdCAqYiwg dWludDhfdCAqYywgaW50IG4sIHVpbnQ4eDE2X3QgdngsIGludCBnKQoreworICAgIHVpbnQ4X3Qg c3VtID0gMDsKKyAgICB3aGlsZSAobiA+IDApCisgICAgeworICAgICAgIG12ZV9wcmVkMTZfdCBw ID0gdmN0cDhxIChuKTsKKyAgICAgICB1aW50OHgxNl90IHZhID0gdmxkcmJxX3pfdTggKGEsIHAp OworICAgICAgIHVpbnQ4eDE2X3QgdmIgPSB2bGRyYnFfel91OCAoYiwgcCk7CisgICAgICAgdWlu dDh4MTZfdCB2YyA9IHZhZGRxX21fdTggKHZ4LCB2YSwgdmIsIHApOworICAgICAgIHN1bSArPSB2 YWRkdnFfdTggKHZjKTsKKyAgICAgICBzdW0gKz0gZzsKKyAgICAgICBhICs9IDE2OworICAgICAg IGIgKz0gMTY7CisgICAgICAgbiAtPSAxNjsKKyAgICB9CisgICAgcmV0dXJuIHN1bTsKK30KKwor LyogVXNpbmcgYSBWUFIgdGhhdCBnZXRzIG1vZGlmaWVkIHdpdGhpbiB0aGUgbG9vcC4gICovCit2 b2lkIHRlc3Q5IChpbnQzMl90ICphLCBpbnQzMl90ICpiLCBpbnQzMl90ICpjLCBpbnQgbikKK3sK KyAgd2hpbGUgKG4gPiAwKQorICAgIHsKKyAgICAgIG12ZV9wcmVkMTZfdCBwID0gdmN0cDMycSAo bik7CisgICAgICBpbnQzMng0X3QgdmEgPSB2bGRyd3Ffel9zMzIgKGEsIHApOworICAgICAgcCsr OworICAgICAgaW50MzJ4NF90IHZiID0gdmxkcndxX3pfczMyIChiLCBwKTsKKyAgICAgIGludDMy eDRfdCB2YyA9IHZhZGRxX3hfczMyICh2YSwgdmIsIHApOworICAgICAgdnN0cndxX3BfczMyIChj LCB2YywgcCk7CisgICAgICBjICs9IDQ7CisgICAgICBhICs9IDQ7CisgICAgICBiICs9IDQ7Cisg ICAgICBuIC09IDQ7CisgICAgfQorfQorCisvKiBVc2luZyBhIFZQUiB0aGF0IGdldHMgcmUtZ2Vu ZXJhdGVkIHdpdGhpbiB0aGUgbG9vcC4gICovCit2b2lkIHRlc3QxMCAoaW50MzJfdCAqYSwgaW50 MzJfdCAqYiwgaW50MzJfdCAqYywgaW50IG4pCit7CisgIG12ZV9wcmVkMTZfdCBwID0gdmN0cDMy cSAobik7CisgIHdoaWxlIChuID4gMCkKKyAgICB7CisgICAgICBpbnQzMng0X3QgdmEgPSB2bGRy d3Ffel9zMzIgKGEsIHApOworICAgICAgcCA9IHZjdHAzMnEgKG4pOworICAgICAgaW50MzJ4NF90 IHZiID0gdmxkcndxX3pfczMyIChiLCBwKTsKKyAgICAgIGludDMyeDRfdCB2YyA9IHZhZGRxX3hf czMyICh2YSwgdmIsIHApOworICAgICAgdnN0cndxX3BfczMyIChjLCB2YywgcCk7CisgICAgICBj ICs9IDQ7CisgICAgICBhICs9IDQ7CisgICAgICBiICs9IDQ7CisgICAgICBuIC09IDQ7CisgICAg fQorfQorCisvKiBVc2luZyB2Y3RwMzJxX20gaW5zdGVhZCBvZiB2Y3RwMzJxLiAgKi8KK3ZvaWQg dGVzdDExIChpbnQzMl90ICphLCBpbnQzMl90ICpiLCBpbnQzMl90ICpjLCBpbnQgbiwgbXZlX3By ZWQxNl90IHAwKQoreworICB3aGlsZSAobiA+IDApCisgICAgeworICAgICAgbXZlX3ByZWQxNl90 IHAgPSB2Y3RwMzJxX20gKG4sIHAwKTsKKyAgICAgIGludDMyeDRfdCB2YSA9IHZsZHJ3cV96X3Mz MiAoYSwgcCk7CisgICAgICBpbnQzMng0X3QgdmIgPSB2bGRyd3Ffel9zMzIgKGIsIHApOworICAg ICAgaW50MzJ4NF90IHZjID0gdmFkZHFfeF9zMzIgKHZhLCB2YiwgcCk7CisgICAgICB2c3Ryd3Ff cF9zMzIgKGMsIHZjLCBwKTsKKyAgICAgIGMgKz0gNDsKKyAgICAgIGEgKz0gNDsKKyAgICAgIGIg Kz0gNDsKKyAgICAgIG4gLT0gNDsKKyAgICB9Cit9CisKKy8qIHsgZGctZmluYWwgeyBzY2FuLWFz c2VtYmxlci1ub3QgIlx0ZGxzdHAiIH0gfSAqLworLyogeyBkZy1maW5hbCB7IHNjYW4tYXNzZW1i bGVyLW5vdCAiXHRsZXRwIiB9IH0gKi8KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLnRh cmdldC9hcm0vbG9iLmggYi9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYXJtL2xvYi5oCmluZGV4 IGZlYWFlN2NjODk5NTliMzE0NzM2ODk4MDEyMDcwMGJiYzNlODVlY2IuLjM5NDFmZTdhOGI2MjBl NjJhNWY3NDI3MjJiZTFiYTJkMDMxZjVhOGQgMTAwNjQ0Ci0tLSBhL2djYy90ZXN0c3VpdGUvZ2Nj LnRhcmdldC9hcm0vbG9iLmgKKysrIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9sb2Iu aApAQCAtMSwxNSArMSwxMzEgQEAKICNpbmNsdWRlIDxzdHJpbmcuaD4KLQorI2luY2x1ZGUgPHN0 ZGludC5oPgogLyogQ29tbW9uIGNvZGUgZm9yIGxvYiB0ZXN0cy4gICovCiAKICNkZWZpbmUgTk9f TE9CIGFzbSB2b2xhdGlsZSAoIkAgY2xvYmJlciBsciIgOiA6IDogImxyIiApCiAKLSNkZWZpbmUg TiAxMDAwMAorI2RlZmluZSBOIDEwMAorCitzdGF0aWMgdm9pZAorcmVzZXRfZGF0YSAoaW50ICph LCBpbnQgKmIsIGludCAqYywgaW50IHgpCit7CisgIG1lbXNldCAoYSwgLTEsIHggKiBzaXplb2Yg KCphKSk7CisgIG1lbXNldCAoYiwgLTEsIHggKiBzaXplb2YgKCpiKSk7CisgIG1lbXNldCAoYywg MCwgeCAqIHNpemVvZiAoKmMpKTsKK30KKworc3RhdGljIHZvaWQKK3Jlc2V0X2RhdGE4IChpbnQ4 X3QgKmEsIGludDhfdCAqYiwgaW50OF90ICpjLCBpbnQgeCkKK3sKKyAgbWVtc2V0IChhLCAtMSwg eCAqIHNpemVvZiAoKmEpKTsKKyAgbWVtc2V0IChiLCAtMSwgeCAqIHNpemVvZiAoKmIpKTsKKyAg bWVtc2V0IChjLCAwLCB4ICogc2l6ZW9mICgqYykpOworfQorCitzdGF0aWMgdm9pZAorcmVzZXRf ZGF0YTE2IChpbnQxNl90ICphLCBpbnQxNl90ICpiLCBpbnQxNl90ICpjLCBpbnQgeCkKK3sKKyAg bWVtc2V0IChhLCAtMSwgeCAqIHNpemVvZiAoKmEpKTsKKyAgbWVtc2V0IChiLCAtMSwgeCAqIHNp emVvZiAoKmIpKTsKKyAgbWVtc2V0IChjLCAwLCB4ICogc2l6ZW9mICgqYykpOworfQorCitzdGF0 aWMgdm9pZAorcmVzZXRfZGF0YTMyIChpbnQzMl90ICphLCBpbnQzMl90ICpiLCBpbnQzMl90ICpj LCBpbnQgeCkKK3sKKyAgbWVtc2V0IChhLCAtMSwgeCAqIHNpemVvZiAoKmEpKTsKKyAgbWVtc2V0 IChiLCAtMSwgeCAqIHNpemVvZiAoKmIpKTsKKyAgbWVtc2V0IChjLCAwLCB4ICogc2l6ZW9mICgq YykpOworfQorCitzdGF0aWMgdm9pZAorcmVzZXRfZGF0YTY0IChpbnQ2NF90ICphLCBpbnQ2NF90 ICpjLCBpbnQgeCkKK3sKKyAgbWVtc2V0IChhLCAtMSwgeCAqIHNpemVvZiAoKmEpKTsKKyAgbWVt c2V0IChjLCAwLCB4ICogc2l6ZW9mICgqYykpOworfQorCitzdGF0aWMgdm9pZAorY2hlY2tfcGx1 cyAoaW50ICphLCBpbnQgKmIsIGludCAqYywgaW50IHgpCit7CisgIGZvciAoaW50IGkgPSAwOyBp IDwgTjsgaSsrKQorICAgIHsKKyAgICAgIE5PX0xPQjsKKyAgICAgIGlmIChpIDwgeCkKKwl7CisJ ICBpZiAoY1tpXSAhPSAoYVtpXSArIGJbaV0pKSBhYm9ydCAoKTsKKwl9CisgICAgICBlbHNlCisJ eworCSAgaWYgKGNbaV0gIT0gMCkgYWJvcnQgKCk7CisJfQorICAgIH0KK30KKworc3RhdGljIHZv aWQKK2NoZWNrX3BsdXM4IChpbnQ4X3QgKmEsIGludDhfdCAqYiwgaW50OF90ICpjLCBpbnQgeCkK K3sKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCisgICAgeworICAgICAgTk9fTE9COwor ICAgICAgaWYgKGkgPCB4KQorCXsKKwkgIGlmIChjW2ldICE9IChhW2ldICsgYltpXSkpIGFib3J0 ICgpOworCX0KKyAgICAgIGVsc2UKKwl7CisJICBpZiAoY1tpXSAhPSAwKSBhYm9ydCAoKTsKKwl9 CisgICAgfQorfQorCitzdGF0aWMgdm9pZAorY2hlY2tfcGx1czE2IChpbnQxNl90ICphLCBpbnQx Nl90ICpiLCBpbnQxNl90ICpjLCBpbnQgeCkKK3sKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBp KyspCisgICAgeworICAgICAgTk9fTE9COworICAgICAgaWYgKGkgPCB4KQorCXsKKwkgIGlmIChj W2ldICE9IChhW2ldICsgYltpXSkpIGFib3J0ICgpOworCX0KKyAgICAgIGVsc2UKKwl7CisJICBp ZiAoY1tpXSAhPSAwKSBhYm9ydCAoKTsKKwl9CisgICAgfQorfQorCitzdGF0aWMgdm9pZAorY2hl Y2tfcGx1czMyIChpbnQzMl90ICphLCBpbnQzMl90ICpiLCBpbnQzMl90ICpjLCBpbnQgeCkKK3sK KyAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCisgICAgeworICAgICAgTk9fTE9COworICAg ICAgaWYgKGkgPCB4KQorCXsKKwkgIGlmIChjW2ldICE9IChhW2ldICsgYltpXSkpIGFib3J0ICgp OworCX0KKyAgICAgIGVsc2UKKwl7CisJICBpZiAoY1tpXSAhPSAwKSBhYm9ydCAoKTsKKwl9Cisg ICAgfQorfQogCiBzdGF0aWMgdm9pZAotcmVzZXRfZGF0YSAoaW50ICphLCBpbnQgKmIsIGludCAq YykKK2NoZWNrX21lbWNweTY0IChpbnQ2NF90ICphLCBpbnQ2NF90ICpjLCBpbnQgeCkKIHsKLSAg bWVtc2V0IChhLCAtMSwgTiAqIHNpemVvZiAoKmEpKTsKLSAgbWVtc2V0IChiLCAtMSwgTiAqIHNp emVvZiAoKmIpKTsKLSAgbWVtc2V0IChjLCAtMSwgTiAqIHNpemVvZiAoKmMpKTsKKyAgZm9yIChp bnQgaSA9IDA7IGkgPCBOOyBpKyspCisgICAgeworICAgICAgTk9fTE9COworICAgICAgaWYgKGkg PCB4KQorCXsKKwkgIGlmIChjW2ldICE9IGFbaV0pIGFib3J0ICgpOworCX0KKyAgICAgIGVsc2UK Kwl7CisJICBpZiAoY1tpXSAhPSAwKSBhYm9ydCAoKTsKKwl9CisgICAgfQogfQpkaWZmIC0tZ2l0 IGEvZ2NjL3Rlc3RzdWl0ZS9nY2MudGFyZ2V0L2FybS9sb2IxLmMgYi9nY2MvdGVzdHN1aXRlL2dj Yy50YXJnZXQvYXJtL2xvYjEuYwppbmRleCBiYTVjODJjZDU1YzU4MmM5NmExOGFkNDE3YTMwNDFl NDNkODQzNjEzLi5jOGNlNjUzYTVjMzlmYjFmZmNmODJhNmU1ODRkOWEwNDY3YTEzMGMwIDEwMDY0 NAotLS0gYS9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYXJtL2xvYjEuYworKysgYi9nY2MvdGVz dHN1aXRlL2djYy50YXJnZXQvYXJtL2xvYjEuYwpAQCAtNTQsMjkgKzU0LDE4IEBAIGxvb3AzIChp bnQgKmEsIGludCAqYiwgaW50ICpjKQogICAgIH0gd2hpbGUgKGkgPCBOKTsKIH0KIAotdm9pZAot Y2hlY2sgKGludCAqYSwgaW50ICpiLCBpbnQgKmMpCi17Ci0gIGZvciAoaW50IGkgPSAwOyBpIDwg TjsgaSsrKQotICAgIHsKLSAgICAgIE5PX0xPQjsKLSAgICAgIGlmIChjW2ldICE9IGFbaV0gKyBi W2ldKQotCWFib3J0ICgpOwotICAgIH0KLX0KLQogaW50CiBtYWluICh2b2lkKQogewotICByZXNl dF9kYXRhIChhLCBiLCBjKTsKKyAgcmVzZXRfZGF0YSAoYSwgYiwgYywgTik7CiAgIGxvb3AxIChh LCBiICxjKTsKLSAgY2hlY2sgKGEsIGIgLGMpOwotICByZXNldF9kYXRhIChhLCBiLCBjKTsKKyAg Y2hlY2tfcGx1cyAoYSwgYiwgYywgTik7CisgIHJlc2V0X2RhdGEgKGEsIGIsIGMsIE4pOwogICBs b29wMiAoYSwgYiAsYyk7Ci0gIGNoZWNrIChhLCBiICxjKTsKLSAgcmVzZXRfZGF0YSAoYSwgYiwg Yyk7CisgIGNoZWNrX3BsdXMgKGEsIGIsIGMsIE4pOworICByZXNldF9kYXRhIChhLCBiLCBjLCBO KTsKICAgbG9vcDMgKGEsIGIgLGMpOwotICBjaGVjayAoYSwgYiAsYyk7CisgIGNoZWNrX3BsdXMg KGEsIGIsIGMsIE4pOwogCiAgIHJldHVybiAwOwogfQpkaWZmIC0tZ2l0IGEvZ2NjL3Rlc3RzdWl0 ZS9nY2MudGFyZ2V0L2FybS9sb2I2LmMgYi9nY2MvdGVzdHN1aXRlL2djYy50YXJnZXQvYXJtL2xv YjYuYwppbmRleCAxN2I2MTI0Mjk1ZThhZTllMWNiNTdlNDFmYTQzYTk1NGIzMzkwZWVjLi40ZmUx MTZlMmMyYmUzNzQ4ZDFiYjZkYTdiYjkwOTJkYjhmOTYyYWJjIDEwMDY0NAotLS0gYS9nY2MvdGVz dHN1aXRlL2djYy50YXJnZXQvYXJtL2xvYjYuYworKysgYi9nY2MvdGVzdHN1aXRlL2djYy50YXJn ZXQvYXJtL2xvYjYuYwpAQCAtNzksMTQgKzc5LDE0IEBAIGNoZWNrICh2b2lkKQogaW50CiBtYWlu ICh2b2lkKQogewotICByZXNldF9kYXRhIChhMSwgYjEsIGMxKTsKLSAgcmVzZXRfZGF0YSAoYTIs IGIyLCBjMik7CisgIHJlc2V0X2RhdGEgKGExLCBiMSwgYzEsIE4pOworICByZXNldF9kYXRhIChh MiwgYjIsIGMyLCBOKTsKICAgbG9vcDEgKGExLCBiMSwgYzEpOwogICByZWYxIChhMiwgYjIsIGMy KTsKICAgY2hlY2sgKCk7CiAKLSAgcmVzZXRfZGF0YSAoYTEsIGIxLCBjMSk7Ci0gIHJlc2V0X2Rh dGEgKGEyLCBiMiwgYzIpOworICByZXNldF9kYXRhIChhMSwgYjEsIGMxLCBOKTsKKyAgcmVzZXRf ZGF0YSAoYTIsIGIyLCBjMiwgTik7CiAgIGxvb3AyIChhMSwgYjEsIGMxKTsKICAgcmVmMiAoYTIs IGIyLCBjMik7CiAgIGNoZWNrICgpOwo= --------------RE6Gven9LsBwQ60Lckeh0C0w--