<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>126474</bug_id>
          
          <creation_ts>2014-01-03 17:02:57 -0800</creation_ts>
          <short_desc>CStack Branch: ARM64 needs push/pop pair macro assembler instructions</short_desc>
          <delta_ts>2014-01-04 23:25:41 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Michael Saboff">msaboff</reporter>
          <assigned_to name="Michael Saboff">msaboff</assigned_to>
          <cc>barraclough</cc>
    
    <cc>benjamin</cc>
    
    <cc>fpizlo</cc>
    
    <cc>ggaren</cc>
    
    <cc>mark.lam</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>964332</commentid>
    <comment_count>0</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2014-01-03 17:02:57 -0800</bug_when>
    <thetext>On the ARM64 processor, register pushes and pops to/from the stack need to be done with in register pairs using the stp (store pair) and ldp (load pair) instructions.  These are needed for saving and restoring the frame pointer register and link register in function prologues and epilogues.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>964333</commentid>
    <comment_count>1</comment_count>
      <attachid>220355</attachid>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2014-01-03 17:10:42 -0800</bug_when>
    <thetext>Created attachment 220355
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>964398</commentid>
    <comment_count>2</comment_count>
      <attachid>220355</attachid>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2014-01-04 07:02:28 -0800</bug_when>
    <thetext>Comment on attachment 220355
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=220355&amp;action=review

&gt; Source/JavaScriptCore/ChangeLog:14
&gt; +        Verified that we corectly generate the new instructions and that they disassemble

typo: “corectly” ==&gt; “correctly”.

&gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:872
&gt; +    enum MemPairOpSize {
&gt; +        MemPairOp_32,
&gt; +        MemPairOp_LoadSigned_64,
&gt; +        MemPairOp_V64 = 1,
&gt; +        MemPairOp_64,
&gt; +        MemPairOp_V128 = 2
&gt; +    };

I don’t have access to the instruction encoding spec right now, and so I’m uncertain about this.  Can you please confirm if MemPairOp_64 is indeed supposed to have the value 2?  I could be wrong, but it seems strange to me that the instruction encoding (as used in loadStoreRegisterPairPostIndex() and loadStoreRegisterPairPreIndex()) would have MemPairOp_64 as 2 while MemPairOp_LoadSigned_64 and MemPairOp_V64 are 1.

If MemPairOp_64 is supposed to have the value 1 as I suspect, then I suggest expressing the above as:

    // MemPairOpSize values are computed as (log2(number of bits / 8) - 2)).
    enum MemPairOpSize {
        MemPairOp_32 = 0,
        MemPairOp_LoadSigned_64 = 1,
        MemPairOp_V64 = 1,
        MemPairOp_64 = 1,
        MemPairOp_V128 = 2
    };

Spelling out their values explicitly makes it clearer that you intended these enums to have the values of (log2(number of bits / 8) - 2) ... at least clearer than before.  I also add the comment indicating that relationship (log2(number of bits / 8) - 2) since the enum is defined here, but the relationship isn’t clear unless we happened to read the implementation of memPairOffsetShift() below.

If I’m wrong and MemPairOp_64 is supposed to be 2, then I suggest expressing the enum list as follows:

    enum MemPairOpSize {
        MemPairOp_32 = 0,
        MemPairOp_LoadSigned_64 = 1,
        MemPairOp_64 = 2,

        MemPairOp_V64 = 1,
        MemPairOp_V128 = 2
    };

I broke out the V ops from the non-V ops based on &quot;ASSERT(V || (size != MemPairOp_LoadSigned_64) || (opc == MemOp_LOAD))” which I read in loadStoreRegisterPairPostIndex().  IMHO, I think this would better show the relationship between how these enums  increment in value.

&gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:887
&gt; +    static unsigned memPairOffsetShift(bool V, MemPairOpSize size)

I presume by “V”, you mean “isVectorMempairOp”.  Can you use a more descriptive name like that if the one I suggested is not appropriate?  Or maybe add the &quot;“V” means Vector” comment that you use for loadStoreRegisterPairPostIndex() below.

&gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:892
&gt; +        // return the log2 of the size in bytes, e.g. 64 bit size returns 3
&gt; +        if (V)
&gt; +            return size + 2;
&gt; +        return (size &gt;&gt; 1) + 2;

If MemPairOp_64 is supposed to be 1 instead of 2 (see comment above regarding the MemPairOpSize enum list), then this should reduce to &quot;return size + 2;”.  Otherwise, please disregard this comment.

&gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:3488
&gt; +    ALWAYS_INLINE static int loadStoreRegisterPairPreIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
&gt; +    {
&gt; +        ASSERT(size &lt; 3);
&gt; +        ASSERT(opc == (opc &amp; 1)); // Only load or store, load signed 64 is handled via size.
&gt; +        ASSERT(V || (size != MemPairOp_LoadSigned_64) || (opc == MemOp_LOAD)); // There isn&apos;t an integer store signed.
&gt; +        unsigned immedShiftAmount = memPairOffsetShift(V, size);
&gt; +        int imm7 = immediate &gt;&gt; immedShiftAmount;
&gt; +        ASSERT((imm7 &lt;&lt; immedShiftAmount) == immediate &amp;&amp; isInt7(imm7));
&gt; +        return (0x29800000 | size &lt;&lt; 30 | V &lt;&lt; 26 | opc &lt;&lt; 22 | (imm7 &amp; 0x7f) &lt;&lt; 15 | rt2 &lt;&lt; 10 | xOrSp(rn) &lt;&lt; 5 | rt);
&gt; +    }

This appears to be identical to loadStoreRegisterPairPostIndex() except for a one bit difference in the instruction opcode.  I suggest refactoring these 2 functions to be expressed as follows to minimize the amount of cut and paste:

ALWAYS_INLINE static int loadStoreRegisterPair(int opcodeBits, MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
{
    ...
}

ALWAYS_INLINE static int loadStoreRegisterPairPostIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
{
    return loadStoreRegisterPair(0x28800000, size, V, opc, immediate, rn, rt, rt2);
}

ALWAYS_INLINE static int loadStoreRegisterPairPreIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
{
    return loadStoreRegisterPair(0x29800000, size, V, opc, immediate, rn, rt, rt2);
}

&gt; Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp:186
&gt; +    

Please remove these empty spaces.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>964410</commentid>
    <comment_count>3</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2014-01-04 09:39:51 -0800</bug_when>
    <thetext>(In reply to comment #2)
&gt; (From update of attachment 220355 [details])
&gt; View in context: https://bugs.webkit.org/attachment.cgi?id=220355&amp;action=review
&gt; 
&gt; &gt; Source/JavaScriptCore/ChangeLog:14
&gt; &gt; +        Verified that we corectly generate the new instructions and that they disassemble
&gt; 
&gt; typo: “corectly” ==&gt; “correctly”.

I will fix.

&gt; &gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:872
&gt; &gt; +    enum MemPairOpSize {
&gt; &gt; +        MemPairOp_32,
&gt; &gt; +        MemPairOp_LoadSigned_64,
&gt; &gt; +        MemPairOp_V64 = 1,
&gt; &gt; +        MemPairOp_64,
&gt; &gt; +        MemPairOp_V128 = 2
&gt; &gt; +    };
&gt; 
&gt; I don’t have access to the instruction encoding spec right now, and so I’m uncertain about this.  Can you please confirm if MemPairOp_64 is indeed supposed to have the value 2?  I could be wrong, but it seems strange to me that the instruction encoding (as used in loadStoreRegisterPairPostIndex() and loadStoreRegisterPairPreIndex()) would have MemPairOp_64 as 2 while MemPairOp_LoadSigned_64 and MemPairOp_V64 are 1.

It is indeed strange, but mostly true.  The falsehood is that MemPairOp_LoadSigned_64 should really be MemPairOp_LoadSigned_32 as it loads 32 bit values and then sign extends them.  The rest of the names and values match the instruction encodings. Here is a relevant table from the instruction manual (opc is what we call size):
Decode fields	 Instruction Details
opc	V	L
00	0	0	STP — 32-bit
00	0	1	LDP — 32-bit
00	1	0	STP (SIMD&amp;FP) — 32-bit
00	1	1	LDP (SIMD&amp;FP) — 32-bit
01	0	0	UNALLOCATED
01	0	1	LDPSW   &lt;= This is Load Pair Signed
01	1	0	STP (SIMD&amp;FP) — 64-bit
01	1	1	LDP (SIMD&amp;FP) — 64-bit
10	0	0	STP — 64-bit
10	0	1	LDP — 64-bit
10	1	0	STP (SIMD&amp;FP) — 128-bit
10	1	1	LDP (SIMD&amp;FP) — 128-bit
11			UNALLOCATED

&gt; If MemPairOp_64 is supposed to have the value 1 as I suspect, then I suggest expressing the above as:
&gt; 
&gt;     // MemPairOpSize values are computed as (log2(number of bits / 8) - 2)).
&gt;     enum MemPairOpSize {
&gt;         MemPairOp_32 = 0,
&gt;         MemPairOp_LoadSigned_64 = 1,
&gt;         MemPairOp_V64 = 1,
&gt;         MemPairOp_64 = 1,
&gt;         MemPairOp_V128 = 2
&gt;     };
&gt; 
&gt; Spelling out their values explicitly makes it clearer that you intended these enums to have the values of (log2(number of bits / 8) - 2) ... at least clearer than before.  I also add the comment indicating that relationship (log2(number of bits / 8) - 2) since the enum is defined here, but the relationship isn’t clear unless we happened to read the implementation of memPairOffsetShift() below.
&gt; 
&gt; If I’m wrong and MemPairOp_64 is supposed to be 2, then I suggest expressing the enum list as follows:
&gt; 
&gt;     enum MemPairOpSize {
&gt;         MemPairOp_32 = 0,
&gt;         MemPairOp_LoadSigned_64 = 1,
&gt;         MemPairOp_64 = 2,
&gt; 
&gt;         MemPairOp_V64 = 1,
&gt;         MemPairOp_V128 = 2
&gt;     };

I will make these explicit.

&gt; I broke out the V ops from the non-V ops based on &quot;ASSERT(V || (size != MemPairOp_LoadSigned_64) || (opc == MemOp_LOAD))” which I read in loadStoreRegisterPairPostIndex().  IMHO, I think this would better show the relationship between how these enums  increment in value.

This is complicated a little by MemPairOp_32 being the same for scalar and vector registers.

&gt; &gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:887
&gt; &gt; +    static unsigned memPairOffsetShift(bool V, MemPairOpSize size)
&gt; 
&gt; I presume by “V”, you mean “isVectorMempairOp”.  Can you use a more descriptive name like that if the one I suggested is not appropriate?  Or maybe add the &quot;“V” means Vector” comment that you use for loadStoreRegisterPairPostIndex() below.

The variable name V is used throughout for the V bit in the instruction encodings.  It signifies that the instruction is a vector variant.

&gt; &gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:892
&gt; &gt; +        // return the log2 of the size in bytes, e.g. 64 bit size returns 3
&gt; &gt; +        if (V)
&gt; &gt; +            return size + 2;
&gt; &gt; +        return (size &gt;&gt; 1) + 2;
&gt; 
&gt; If MemPairOp_64 is supposed to be 1 instead of 2 (see comment above regarding the MemPairOpSize enum list), then this should reduce to &quot;return size + 2;”.  Otherwise, please disregard this comment.
&gt; 
&gt; &gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:3488
&gt; &gt; +    ALWAYS_INLINE static int loadStoreRegisterPairPreIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
&gt; &gt; +    {
&gt; &gt; +        ASSERT(size &lt; 3);
&gt; &gt; +        ASSERT(opc == (opc &amp; 1)); // Only load or store, load signed 64 is handled via size.
&gt; &gt; +        ASSERT(V || (size != MemPairOp_LoadSigned_64) || (opc == MemOp_LOAD)); // There isn&apos;t an integer store signed.
&gt; &gt; +        unsigned immedShiftAmount = memPairOffsetShift(V, size);
&gt; &gt; +        int imm7 = immediate &gt;&gt; immedShiftAmount;
&gt; &gt; +        ASSERT((imm7 &lt;&lt; immedShiftAmount) == immediate &amp;&amp; isInt7(imm7));
&gt; &gt; +        return (0x29800000 | size &lt;&lt; 30 | V &lt;&lt; 26 | opc &lt;&lt; 22 | (imm7 &amp; 0x7f) &lt;&lt; 15 | rt2 &lt;&lt; 10 | xOrSp(rn) &lt;&lt; 5 | rt);
&gt; &gt; +    }
&gt; 
&gt; This appears to be identical to loadStoreRegisterPairPostIndex() except for a one bit difference in the instruction opcode.  I suggest refactoring these 2 functions to be expressed as follows to minimize the amount of cut and paste:
&gt; 
&gt; ALWAYS_INLINE static int loadStoreRegisterPair(int opcodeBits, MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
&gt; {
&gt;     ...
&gt; }
&gt; 
&gt; ALWAYS_INLINE static int loadStoreRegisterPairPostIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
&gt; {
&gt;     return loadStoreRegisterPair(0x28800000, size, V, opc, immediate, rn, rt, rt2);
&gt; }
&gt; 
&gt; ALWAYS_INLINE static int loadStoreRegisterPairPreIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
&gt; {
&gt;     return loadStoreRegisterPair(0x29800000, size, V, opc, immediate, rn, rt, rt2);
&gt; }

The function names loadStoreRegisterPairPostIndex() and loadStoreRegisterPairPreIndex() follow the convention in the rest of the file where the function name matches one of the instruction group names.  For example there is the group name Load/store register (immediate post-indexed) and the corresponding 
existing function loadStoreRegisterPostIndex().  I followed the same pattern for the two groups Load/store register pair (post-indexed) and Load/store register pair (pre-indexed).

&gt; &gt; Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp:186
&gt; &gt; +    
&gt; 
&gt; Please remove these empty spaces.

I&apos;ll remove them.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>964454</commentid>
    <comment_count>4</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2014-01-04 22:36:14 -0800</bug_when>
    <thetext>(In reply to comment #3)
&gt; (In reply to comment #2)
&gt; &gt; &gt; Source/JavaScriptCore/assembler/ARM64Assembler.h:872
&gt; &gt; &gt; +    enum MemPairOpSize {
&gt; &gt; &gt; +        MemPairOp_32,
&gt; &gt; &gt; +        MemPairOp_LoadSigned_64,
&gt; &gt; &gt; +        MemPairOp_V64 = 1,
&gt; &gt; &gt; +        MemPairOp_64,
&gt; &gt; &gt; +        MemPairOp_V128 = 2
&gt; &gt; &gt; +    };
&gt; &gt; 
&gt; &gt; I don’t have access to the instruction encoding spec right now, and so I’m uncertain about this.  Can you please confirm if MemPairOp_64 is indeed supposed to have the value 2?  I could be wrong, but it seems strange to me that the instruction encoding (as used in loadStoreRegisterPairPostIndex() and loadStoreRegisterPairPreIndex()) would have MemPairOp_64 as 2 while MemPairOp_LoadSigned_64 and MemPairOp_V64 are 1.
&gt; 
&gt; It is indeed strange, but mostly true.  The falsehood is that MemPairOp_LoadSigned_64 should really be MemPairOp_LoadSigned_32 as it loads 32 bit values and then sign extends them.  The rest of the names and values match the instruction encodings. Here is a relevant table from the instruction manual (opc is what we call size):
&gt; Decode fields     Instruction Details
&gt; opc    V    L
&gt; 00    0    0    STP — 32-bit
&gt; 00    0    1    LDP — 32-bit
&gt; 00    1    0    STP (SIMD&amp;FP) — 32-bit
&gt; 00    1    1    LDP (SIMD&amp;FP) — 32-bit
&gt; 01    0    0    UNALLOCATED
&gt; 01    0    1    LDPSW   &lt;= This is Load Pair Signed
&gt; 01    1    0    STP (SIMD&amp;FP) — 64-bit
&gt; 01    1    1    LDP (SIMD&amp;FP) — 64-bit
&gt; 10    0    0    STP — 64-bit
&gt; 10    0    1    LDP — 64-bit
&gt; 10    1    0    STP (SIMD&amp;FP) — 128-bit
&gt; 10    1    1    LDP (SIMD&amp;FP) — 128-bit
&gt; 11            UNALLOCATED

Funky, but it is what it is.

&gt; &gt; If I’m wrong and MemPairOp_64 is supposed to be 2, then I suggest expressing the enum list as follows:
&gt; &gt; 
&gt; &gt;     enum MemPairOpSize {
&gt; &gt;         MemPairOp_32 = 0,
&gt; &gt;         MemPairOp_LoadSigned_64 = 1,
&gt; &gt;         MemPairOp_64 = 2,
&gt; &gt; 
&gt; &gt;         MemPairOp_V64 = 1,
&gt; &gt;         MemPairOp_V128 = 2
&gt; &gt;     };
&gt; 
&gt; I will make these explicit.
&gt; 
&gt; &gt; I broke out the V ops from the non-V ops based on &quot;ASSERT(V || (size != MemPairOp_LoadSigned_64) || (opc == MemOp_LOAD))” which I read in loadStoreRegisterPairPostIndex().  IMHO, I think this would better show the relationship between how these enums  increment in value.
&gt; 
&gt; This is complicated a little by MemPairOp_32 being the same for scalar and vector registers.

In light of the encoding details you provided, I agree that there isn’t an ideal case in terms of grouping.  How about:

    enum MemPairOpSize {
        MemPairOp_32 = 0,
        MemPairOp_LoadSigned_64 = 1,
        MemPairOp_64 = 2,

        MemPairOp_V32 = MemPairOp_32,
        MemPairOp_V64 = 1,
        MemPairOp_V128 = 2
    };

That still provides the Vector vs non-Vector distinction while explicitly spelling out that the V32 variant uses the same encoding as the non-Vector 32 bit variant.

&gt; The function names loadStoreRegisterPairPostIndex() and loadStoreRegisterPairPreIndex() follow the convention in the rest of the file where the function name matches one of the instruction group names.  For example there is the group name Load/store register (immediate post-indexed) and the corresponding 
&gt; existing function loadStoreRegisterPostIndex().  I followed the same pattern for the two groups Load/store register pair (post-indexed) and Load/store register pair (pre-indexed).

Even though there is precedence, I still don’t like the fact that we’re opting for cutting and pasting instead of using a common function.  However, granted that these functions are highly unlikely to be mutated in the future (given that the hardware spec that they are based on is also high unlikely to change), I can live with it if no one else objects.

With that, I’m satisfied enough with this patch.  r=me with agreed changes / fixes applied.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>964463</commentid>
    <comment_count>5</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2014-01-04 23:25:41 -0800</bug_when>
    <thetext>Committed r161318: &lt;http://trac.webkit.org/changeset/161318&gt;</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>220355</attachid>
            <date>2014-01-03 17:10:42 -0800</date>
            <delta_ts>2014-01-04 22:36:26 -0800</delta_ts>
            <desc>Patch</desc>
            <filename>126474.patch</filename>
            <type>text/plain</type>
            <size>14558</size>
            <attacher name="Michael Saboff">msaboff</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9DaGFuZ2VMb2cKPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291
cmNlL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkocmV2aXNpb24gMTYxMjk4KQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDQ3IEBA
CisyMDE0LTAxLTAzICBNaWNoYWVsIFNhYm9mZiAgPG1zYWJvZmZAYXBwbGUuY29tPgorCisgICAg
ICAgIENTdGFjayBCcmFuY2g6IEFSTTY0IG5lZWRzIHB1c2gvcG9wIHBhaXIgbWFjcm8gYXNzZW1i
bGVyIGluc3RydWN0aW9ucworICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1
Zy5jZ2k/aWQ9MTI2NDc0CisKKyAgICAgICAgUmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCisK
KyAgICAgICAgQWRkZWQgdGVtcGxhdGVkIGxkcCgpIGFuZCBzdHAoKSBpbnN0cnVjdGlvbiBnZW5l
cmF0b3JzIHRvIHRoZSBBUk02NCBhc3NlbWJsZXIuCisgICAgICAgIEFkZGVkIHBvcFBhaXIoKSBh
bmQgcHVzaFBhaXIoKSB0byB0aGUgQVJNNjQgbWFjcm8gYXNzZW1ibGVyLiAgQWRkZWQgQVJNNjQK
KyAgICAgICAgdmVyc2lvbiBvZiBlbWl0RnVuY3Rpb25Qcm9sb2d1ZSgpIGFuZCBlbWl0RnVuY3Rp
b25FcGlsb2d1ZSgpIHRvIEFzc2VtYmx5SGVscGVycy5oCisgICAgICAgIHRoYXQgdXNlIHRoZSBw
dXNoUGFpcigpIGFuZCBwb3BQYWlyKCkgbWFjcm8gaW5zdHJ1Y3Rpb25zLiAgQWRkZWQgZGlzYXNz
ZW1ibGVyIHN1cHBvcnQKKyAgICAgICAgZm9yIHRoZSBuZXdseSBhZGRlZCBsb2FkL3N0b3JlIHBh
aXIgaW5zdHJ1Y3Rpb25zLgorCisgICAgICAgIFZlcmlmaWVkIHRoYXQgd2UgY29yZWN0bHkgZ2Vu
ZXJhdGUgdGhlIG5ldyBpbnN0cnVjdGlvbnMgYW5kIHRoYXQgdGhleSBkaXNhc3NlbWJsZQorICAg
ICAgICB0aGUgc2FtZSBhcyB3aGF0IHRoZSBkZWJ1Z2dlciBzaG93cy4KKworICAgICAgICAqIGFz
c2VtYmxlci9BUk02NEFzc2VtYmxlci5oOgorICAgICAgICAoSlNDOjppc0ludDcpOgorICAgICAg
ICAoSlNDOjppc0ludDExKToKKyAgICAgICAgKEpTQzo6UGFpclBvc3RJbmRleDo6UGFpclBvc3RJ
bmRleCk6CisgICAgICAgIChKU0M6OlBhaXJQb3N0SW5kZXg6Om9wZXJhdG9yIGludCk6CisgICAg
ICAgIChKU0M6OlBhaXJQcmVJbmRleDo6UGFpclByZUluZGV4KToKKyAgICAgICAgKEpTQzo6UGFp
clByZUluZGV4OjpvcGVyYXRvciBpbnQpOgorICAgICAgICAoSlNDOjpBUk02NEFzc2VtYmxlcjo6
bWVtUGFpck9mZnNldFNoaWZ0KToKKyAgICAgICAgKEpTQzo6QVJNNjRBc3NlbWJsZXI6OmxkcCk6
CisgICAgICAgIChKU0M6OkFSTTY0QXNzZW1ibGVyOjpzdHApOgorICAgICAgICAoSlNDOjpBUk02
NEFzc2VtYmxlcjo6bG9hZFN0b3JlUmVnaXN0ZXJQYWlyUG9zdEluZGV4KToKKyAgICAgICAgKEpT
Qzo6QVJNNjRBc3NlbWJsZXI6OmxvYWRTdG9yZVJlZ2lzdGVyUGFpclByZUluZGV4KToKKyAgICAg
ICAgKiBhc3NlbWJsZXIvTWFjcm9Bc3NlbWJsZXJBUk02NC5oOgorICAgICAgICAoSlNDOjpNYWNy
b0Fzc2VtYmxlckFSTTY0Ojpwb3BQYWlyKToKKyAgICAgICAgKEpTQzo6TWFjcm9Bc3NlbWJsZXJB
Uk02NDo6cHVzaFBhaXIpOgorICAgICAgICAqIGRpc2Fzc2VtYmxlci9BUk02NC9BNjRET3Bjb2Rl
LmNwcDoKKyAgICAgICAgKEpTQzo6QVJNNjREaXNhc3NlbWJsZXI6OkE2NERPcGNvZGU6OmFwcGVu
ZFJlZ2lzdGVyTmFtZSk6CisgICAgICAgIChKU0M6OkFSTTY0RGlzYXNzZW1ibGVyOjpBNjRET3Bj
b2RlTG9hZFN0b3JlUmVnaXN0ZXJQYWlyOjpvcE5hbWUpOgorICAgICAgICAoSlNDOjpBUk02NERp
c2Fzc2VtYmxlcjo6QTY0RE9wY29kZUxvYWRTdG9yZVJlZ2lzdGVyUGFpcjo6Zm9ybWF0KToKKyAg
ICAgICAgKiBkaXNhc3NlbWJsZXIvQVJNNjQvQTY0RE9wY29kZS5oOgorICAgICAgICAoSlNDOjpB
Uk02NERpc2Fzc2VtYmxlcjo6QTY0RE9wY29kZUxvYWRTdG9yZVJlZ2lzdGVyUGFpcjo6cnQyKToK
KyAgICAgICAgKEpTQzo6QVJNNjREaXNhc3NlbWJsZXI6OkE2NERPcGNvZGVMb2FkU3RvcmVSZWdp
c3RlclBhaXI6OmltbWVkaWF0ZTcpOgorICAgICAgICAoSlNDOjpBUk02NERpc2Fzc2VtYmxlcjo6
QTY0RE9wY29kZUxvYWRTdG9yZVJlZ2lzdGVyUGFpcjo6b2Zmc2V0TW9kZSk6CisgICAgICAgIChK
U0M6OkFSTTY0RGlzYXNzZW1ibGVyOjpBNjRET3Bjb2RlTG9hZFN0b3JlUmVnaXN0ZXJQYWlyOjps
Qml0KToKKyAgICAgICAgKiBqaXQvQXNzZW1ibHlIZWxwZXJzLmg6CisgICAgICAgIChKU0M6OkFz
c2VtYmx5SGVscGVyczo6ZW1pdEZ1bmN0aW9uUHJvbG9ndWUpOgorICAgICAgICAoSlNDOjpBc3Nl
bWJseUhlbHBlcnM6OmVtaXRGdW5jdGlvbkVwaWxvZ3VlKToKKwogMjAxNC0wMS0wMyAgTWljaGFl
bCBTYWJvZmYgIDxtc2Fib2ZmQGFwcGxlLmNvbT4KIAogICAgICAgICBDU3RhY2sgQnJhbmNoOiBN
YWtlIGVtaXRQdXRUb0NhbGxGcmFtZUhlYWRlckJlZm9yZVByb2xvZ3VlIGFuZCBmcmllbmRzIHdv
cmsgZm9yIGFsbCBwbGF0Zm9ybXMKSW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9hc3NlbWJs
ZXIvQVJNNjRBc3NlbWJsZXIuaAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2YVNjcmlwdENvcmUv
YXNzZW1ibGVyL0FSTTY0QXNzZW1ibGVyLmgJKHJldmlzaW9uIDE2MTI5NikKKysrIFNvdXJjZS9K
YXZhU2NyaXB0Q29yZS9hc3NlbWJsZXIvQVJNNjRBc3NlbWJsZXIuaAkod29ya2luZyBjb3B5KQpA
QCAtNDAsMTQgKzQwLDI2IEBACiAjZGVmaW5lIERBVEFTSVpFIERBVEFTSVpFX09GKGRhdGFzaXpl
KQogI2RlZmluZSBNRU1PUFNJWkUgTUVNT1BTSVpFX09GKGRhdGFzaXplKQogI2RlZmluZSBDSEVD
S19GUF9NRU1PUF9EQVRBU0laRSgpIEFTU0VSVChkYXRhc2l6ZSA9PSA4IHx8IGRhdGFzaXplID09
IDE2IHx8IGRhdGFzaXplID09IDMyIHx8IGRhdGFzaXplID09IDY0IHx8IGRhdGFzaXplID09IDEy
OCkKKyNkZWZpbmUgTUVNUEFJUk9QU0laRV9JTlQoZGF0YXNpemUpICgoZGF0YXNpemUgPT0gNjQp
ID8gTWVtUGFpck9wXzY0IDogTWVtUGFpck9wXzMyKQorI2RlZmluZSBNRU1QQUlST1BTSVpFX0ZQ
KGRhdGFzaXplKSAoKGRhdGFzaXplID09IDEyOCkgPyBNZW1QYWlyT3BfVjEyOCA6IChkYXRhc2l6
ZSA9PSA2NCkgPyBNZW1QYWlyT3BfVjY0IDogTWVtUGFpck9wXzMyKQogCiBuYW1lc3BhY2UgSlND
IHsKIAorQUxXQVlTX0lOTElORSBib29sIGlzSW50NyhpbnQzMl90IHZhbHVlKQoreworICAgIHJl
dHVybiB2YWx1ZSA9PSAoKHZhbHVlIDw8IDI1KSA+PiAyNSk7Cit9CisKIEFMV0FZU19JTkxJTkUg
Ym9vbCBpc0ludDkoaW50MzJfdCB2YWx1ZSkKIHsKICAgICByZXR1cm4gdmFsdWUgPT0gKCh2YWx1
ZSA8PCAyMykgPj4gMjMpOwogfQogCitBTFdBWVNfSU5MSU5FIGJvb2wgaXNJbnQxMShpbnQzMl90
IHZhbHVlKQoreworICAgIHJldHVybiB2YWx1ZSA9PSAoKHZhbHVlIDw8IDIxKSA+PiAyMSk7Cit9
CisKIEFMV0FZU19JTkxJTkUgYm9vbCBpc1VJbnQ1KGludDMyX3QgdmFsdWUpCiB7CiAgICAgcmV0
dXJuICEodmFsdWUgJiB+MHgxZik7CkBAIC0xMTksNiArMTMxLDM0IEBAIHByaXZhdGU6CiAgICAg
aW50IG1fdmFsdWU7CiB9OwogCitjbGFzcyBQYWlyUG9zdEluZGV4IHsKK3B1YmxpYzoKKyAgICBl
eHBsaWNpdCBQYWlyUG9zdEluZGV4KGludCB2YWx1ZSkKKyAgICAgICAgOiBtX3ZhbHVlKHZhbHVl
KQorICAgIHsKKyAgICAgICAgQVNTRVJUKGlzSW50MTEodmFsdWUpKTsKKyAgICB9CisKKyAgICBv
cGVyYXRvciBpbnQoKSB7IHJldHVybiBtX3ZhbHVlOyB9CisKK3ByaXZhdGU6CisgICAgaW50IG1f
dmFsdWU7Cit9OworCitjbGFzcyBQYWlyUHJlSW5kZXggeworcHVibGljOgorICAgIGV4cGxpY2l0
IFBhaXJQcmVJbmRleChpbnQgdmFsdWUpCisgICAgICAgIDogbV92YWx1ZSh2YWx1ZSkKKyAgICB7
CisgICAgICAgIEFTU0VSVChpc0ludDExKHZhbHVlKSk7CisgICAgfQorCisgICAgb3BlcmF0b3Ig
aW50KCkgeyByZXR1cm4gbV92YWx1ZTsgfQorCitwcml2YXRlOgorICAgIGludCBtX3ZhbHVlOwor
fTsKKwogY2xhc3MgTG9naWNhbEltbWVkaWF0ZSB7CiBwdWJsaWM6CiAgICAgc3RhdGljIExvZ2lj
YWxJbW1lZGlhdGUgY3JlYXRlMzIodWludDMyX3QgdmFsdWUpCkBAIC04MjMsNiArODYzLDE0IEBA
IHByaXZhdGU6CiAgICAgICAgIE1lbU9wX0xPQURfc2lnbmVkMzIgPSAzIC8vIHNpemUgbWF5IGJl
IDAgb3IgMQogICAgIH07CiAKKyAgICBlbnVtIE1lbVBhaXJPcFNpemUgeworICAgICAgICBNZW1Q
YWlyT3BfMzIsCisgICAgICAgIE1lbVBhaXJPcF9Mb2FkU2lnbmVkXzY0LAorICAgICAgICBNZW1Q
YWlyT3BfVjY0ID0gMSwKKyAgICAgICAgTWVtUGFpck9wXzY0LAorICAgICAgICBNZW1QYWlyT3Bf
VjEyOCA9IDIKKyAgICB9OworCiAgICAgZW51bSBNb3ZlV2lkZU9wIHsKICAgICAgICAgTW92ZVdp
ZGVPcF9OID0gMCwKICAgICAgICAgTW92ZVdpZGVPcF9aID0gMiwKQEAgLTgzNiw2ICs4ODQsMTQg
QEAgcHJpdmF0ZToKICAgICAgICAgTGRyTGl0ZXJhbE9wXzEyOEJJVCA9IDIKICAgICB9OwogCisg
ICAgc3RhdGljIHVuc2lnbmVkIG1lbVBhaXJPZmZzZXRTaGlmdChib29sIFYsIE1lbVBhaXJPcFNp
emUgc2l6ZSkKKyAgICB7CisgICAgICAgIC8vIHJldHVybiB0aGUgbG9nMiBvZiB0aGUgc2l6ZSBp
biBieXRlcywgZS5nLiA2NCBiaXQgc2l6ZSByZXR1cm5zIDMKKyAgICAgICAgaWYgKFYpCisgICAg
ICAgICAgICByZXR1cm4gc2l6ZSArIDI7CisgICAgICAgIHJldHVybiAoc2l6ZSA+PiAxKSArIDI7
CisgICAgfQorCiBwdWJsaWM6CiAgICAgLy8gSW50ZWdlciBJbnN0cnVjdGlvbnM6CiAKQEAgLTEy
MTYsNiArMTI3MiwyMCBAQCBwdWJsaWM6CiAgICAgfQogCiAgICAgdGVtcGxhdGU8aW50IGRhdGFz
aXplPgorICAgIEFMV0FZU19JTkxJTkUgdm9pZCBsZHAoUmVnaXN0ZXJJRCBydCwgUmVnaXN0ZXJJ
RCBydDIsIFJlZ2lzdGVySUQgcm4sIFBhaXJQb3N0SW5kZXggc2ltbSkKKyAgICB7CisgICAgICAg
IENIRUNLX0RBVEFTSVpFKCk7CisgICAgICAgIGluc24obG9hZFN0b3JlUmVnaXN0ZXJQYWlyUG9z
dEluZGV4KE1FTVBBSVJPUFNJWkVfSU5UKGRhdGFzaXplKSwgZmFsc2UsIE1lbU9wX0xPQUQsIHNp
bW0sIHJuLCBydCwgcnQyKSk7CisgICAgfQorCisgICAgdGVtcGxhdGU8aW50IGRhdGFzaXplPgor
ICAgIEFMV0FZU19JTkxJTkUgdm9pZCBsZHAoUmVnaXN0ZXJJRCBydCwgUmVnaXN0ZXJJRCBydDIs
IFJlZ2lzdGVySUQgcm4sIFBhaXJQcmVJbmRleCBzaW1tKQorICAgIHsKKyAgICAgICAgQ0hFQ0tf
REFUQVNJWkUoKTsKKyAgICAgICAgaW5zbihsb2FkU3RvcmVSZWdpc3RlclBhaXJQcmVJbmRleChN
RU1QQUlST1BTSVpFX0lOVChkYXRhc2l6ZSksIGZhbHNlLCBNZW1PcF9MT0FELCBzaW1tLCBybiwg
cnQsIHJ0MikpOworICAgIH0KKworICAgIHRlbXBsYXRlPGludCBkYXRhc2l6ZT4KICAgICBBTFdB
WVNfSU5MSU5FIHZvaWQgbGRyKFJlZ2lzdGVySUQgcnQsIFJlZ2lzdGVySUQgcm4sIFJlZ2lzdGVy
SUQgcm0pCiAgICAgewogICAgICAgICBsZHI8ZGF0YXNpemU+KHJ0LCBybiwgcm0sIFVYVFgsIDAp
OwpAQCAtMTc0OCw2ICsxODE4LDIwIEBAIHB1YmxpYzoKICAgICB9CiAKICAgICB0ZW1wbGF0ZTxp
bnQgZGF0YXNpemU+CisgICAgQUxXQVlTX0lOTElORSB2b2lkIHN0cChSZWdpc3RlcklEIHJ0LCBS
ZWdpc3RlcklEIHJ0MiwgUmVnaXN0ZXJJRCBybiwgUGFpclBvc3RJbmRleCBzaW1tKQorICAgIHsK
KyAgICAgICAgQ0hFQ0tfREFUQVNJWkUoKTsKKyAgICAgICAgaW5zbihsb2FkU3RvcmVSZWdpc3Rl
clBhaXJQb3N0SW5kZXgoTUVNUEFJUk9QU0laRV9JTlQoZGF0YXNpemUpLCBmYWxzZSwgTWVtT3Bf
U1RPUkUsIHNpbW0sIHJuLCBydCwgcnQyKSk7CisgICAgfQorCisgICAgdGVtcGxhdGU8aW50IGRh
dGFzaXplPgorICAgIEFMV0FZU19JTkxJTkUgdm9pZCBzdHAoUmVnaXN0ZXJJRCBydCwgUmVnaXN0
ZXJJRCBydDIsIFJlZ2lzdGVySUQgcm4sIFBhaXJQcmVJbmRleCBzaW1tKQorICAgIHsKKyAgICAg
ICAgQ0hFQ0tfREFUQVNJWkUoKTsKKyAgICAgICAgaW5zbihsb2FkU3RvcmVSZWdpc3RlclBhaXJQ
cmVJbmRleChNRU1QQUlST1BTSVpFX0lOVChkYXRhc2l6ZSksIGZhbHNlLCBNZW1PcF9TVE9SRSwg
c2ltbSwgcm4sIHJ0LCBydDIpKTsKKyAgICB9CisKKyAgICB0ZW1wbGF0ZTxpbnQgZGF0YXNpemU+
CiAgICAgQUxXQVlTX0lOTElORSB2b2lkIHN0cihSZWdpc3RlcklEIHJ0LCBSZWdpc3RlcklEIHJu
LCBSZWdpc3RlcklEIHJtKQogICAgIHsKICAgICAgICAgc3RyPGRhdGFzaXplPihydCwgcm4sIHJt
LCBVWFRYLCAwKTsKQEAgLTMzNjEsNiArMzQ0NSwyMyBAQCBwcml2YXRlOgogICAgIH0KIAogICAg
IC8vICdWJyBtZWFucyB2ZWN0b3IKKyAgICBBTFdBWVNfSU5MSU5FIHN0YXRpYyBpbnQgbG9hZFN0
b3JlUmVnaXN0ZXJQYWlyUG9zdEluZGV4KE1lbVBhaXJPcFNpemUgc2l6ZSwgYm9vbCBWLCBNZW1P
cCBvcGMsIGludCBpbW1lZGlhdGUsIFJlZ2lzdGVySUQgcm4sIEZQUmVnaXN0ZXJJRCBydCwgRlBS
ZWdpc3RlcklEIHJ0MikKKyAgICB7CisgICAgICAgIEFTU0VSVChzaXplIDwgMyk7CisgICAgICAg
IEFTU0VSVChvcGMgPT0gKG9wYyAmIDEpKTsgLy8gT25seSBsb2FkIG9yIHN0b3JlLCBsb2FkIHNp
Z25lZCA2NCBpcyBoYW5kbGVkIHZpYSBzaXplLgorICAgICAgICBBU1NFUlQoViB8fCAoc2l6ZSAh
PSBNZW1QYWlyT3BfTG9hZFNpZ25lZF82NCkgfHwgKG9wYyA9PSBNZW1PcF9MT0FEKSk7IC8vIFRo
ZXJlIGlzbid0IGFuIGludGVnZXIgc3RvcmUgc2lnbmVkLgorICAgICAgICB1bnNpZ25lZCBpbW1l
ZFNoaWZ0QW1vdW50ID0gbWVtUGFpck9mZnNldFNoaWZ0KFYsIHNpemUpOworICAgICAgICBpbnQg
aW1tNyA9IGltbWVkaWF0ZSA+PiBpbW1lZFNoaWZ0QW1vdW50OworICAgICAgICBBU1NFUlQoKGlt
bTcgPDwgaW1tZWRTaGlmdEFtb3VudCkgPT0gaW1tZWRpYXRlICYmIGlzSW50NyhpbW03KSk7Cisg
ICAgICAgIHJldHVybiAoMHgyODgwMDAwMCB8IHNpemUgPDwgMzAgfCBWIDw8IDI2IHwgb3BjIDw8
IDIyIHwgKGltbTcgJiAweDdmKSA8PCAxNSB8IHJ0MiA8PCAxMCB8IHhPclNwKHJuKSA8PCA1IHwg
cnQpOworICAgIH0KKworICAgIEFMV0FZU19JTkxJTkUgc3RhdGljIGludCBsb2FkU3RvcmVSZWdp
c3RlclBhaXJQb3N0SW5kZXgoTWVtUGFpck9wU2l6ZSBzaXplLCBib29sIFYsIE1lbU9wIG9wYywg
aW50IGltbWVkaWF0ZSwgUmVnaXN0ZXJJRCBybiwgUmVnaXN0ZXJJRCBydCwgUmVnaXN0ZXJJRCBy
dDIpCisgICAgeworICAgICAgICByZXR1cm4gbG9hZFN0b3JlUmVnaXN0ZXJQYWlyUG9zdEluZGV4
KHNpemUsIFYsIG9wYywgaW1tZWRpYXRlLCBybiwgeE9yWnJBc0ZQUihydCksIHhPclpyQXNGUFIo
cnQyKSk7CisgICAgfQorCisgICAgLy8gJ1YnIG1lYW5zIHZlY3RvcgogICAgIEFMV0FZU19JTkxJ
TkUgc3RhdGljIGludCBsb2FkU3RvcmVSZWdpc3RlclByZUluZGV4KE1lbU9wU2l6ZSBzaXplLCBi
b29sIFYsIE1lbU9wIG9wYywgaW50IGltbTksIFJlZ2lzdGVySUQgcm4sIEZQUmVnaXN0ZXJJRCBy
dCkKICAgICB7CiAgICAgICAgIEFTU0VSVCghKHNpemUgJiYgViAmJiAob3BjICYgMikpKTsgLy8g
TWF4aW11bSB2ZWN0b3Igc2l6ZSBpcyAxMjggYml0cy4KQEAgLTMzNzUsNiArMzQ3NiwyMyBAQCBw
cml2YXRlOgogICAgIH0KIAogICAgIC8vICdWJyBtZWFucyB2ZWN0b3IKKyAgICBBTFdBWVNfSU5M
SU5FIHN0YXRpYyBpbnQgbG9hZFN0b3JlUmVnaXN0ZXJQYWlyUHJlSW5kZXgoTWVtUGFpck9wU2l6
ZSBzaXplLCBib29sIFYsIE1lbU9wIG9wYywgaW50IGltbWVkaWF0ZSwgUmVnaXN0ZXJJRCBybiwg
RlBSZWdpc3RlcklEIHJ0LCBGUFJlZ2lzdGVySUQgcnQyKQorICAgIHsKKyAgICAgICAgQVNTRVJU
KHNpemUgPCAzKTsKKyAgICAgICAgQVNTRVJUKG9wYyA9PSAob3BjICYgMSkpOyAvLyBPbmx5IGxv
YWQgb3Igc3RvcmUsIGxvYWQgc2lnbmVkIDY0IGlzIGhhbmRsZWQgdmlhIHNpemUuCisgICAgICAg
IEFTU0VSVChWIHx8IChzaXplICE9IE1lbVBhaXJPcF9Mb2FkU2lnbmVkXzY0KSB8fCAob3BjID09
IE1lbU9wX0xPQUQpKTsgLy8gVGhlcmUgaXNuJ3QgYW4gaW50ZWdlciBzdG9yZSBzaWduZWQuCisg
ICAgICAgIHVuc2lnbmVkIGltbWVkU2hpZnRBbW91bnQgPSBtZW1QYWlyT2Zmc2V0U2hpZnQoViwg
c2l6ZSk7CisgICAgICAgIGludCBpbW03ID0gaW1tZWRpYXRlID4+IGltbWVkU2hpZnRBbW91bnQ7
CisgICAgICAgIEFTU0VSVCgoaW1tNyA8PCBpbW1lZFNoaWZ0QW1vdW50KSA9PSBpbW1lZGlhdGUg
JiYgaXNJbnQ3KGltbTcpKTsKKyAgICAgICAgcmV0dXJuICgweDI5ODAwMDAwIHwgc2l6ZSA8PCAz
MCB8IFYgPDwgMjYgfCBvcGMgPDwgMjIgfCAoaW1tNyAmIDB4N2YpIDw8IDE1IHwgcnQyIDw8IDEw
IHwgeE9yU3Aocm4pIDw8IDUgfCBydCk7CisgICAgfQorCisgICAgQUxXQVlTX0lOTElORSBzdGF0
aWMgaW50IGxvYWRTdG9yZVJlZ2lzdGVyUGFpclByZUluZGV4KE1lbVBhaXJPcFNpemUgc2l6ZSwg
Ym9vbCBWLCBNZW1PcCBvcGMsIGludCBpbW1lZGlhdGUsIFJlZ2lzdGVySUQgcm4sIFJlZ2lzdGVy
SUQgcnQsIFJlZ2lzdGVySUQgcnQyKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGxvYWRTdG9yZVJl
Z2lzdGVyUGFpclByZUluZGV4KHNpemUsIFYsIG9wYywgaW1tZWRpYXRlLCBybiwgeE9yWnJBc0ZQ
UihydCksIHhPclpyQXNGUFIocnQyKSk7CisgICAgfQorCisgICAgLy8gJ1YnIG1lYW5zIHZlY3Rv
cgogICAgIC8vICdTJyBtZWFucyBzaGlmdCBybQogICAgIEFMV0FZU19JTkxJTkUgc3RhdGljIGlu
dCBsb2FkU3RvcmVSZWdpc3RlclJlZ2lzdGVyT2Zmc2V0KE1lbU9wU2l6ZSBzaXplLCBib29sIFYs
IE1lbU9wIG9wYywgUmVnaXN0ZXJJRCBybSwgRXh0ZW5kVHlwZSBvcHRpb24sIGJvb2wgUywgUmVn
aXN0ZXJJRCBybiwgRlBSZWdpc3RlcklEIHJ0KQogICAgIHsKSW5kZXg6IFNvdXJjZS9KYXZhU2Ny
aXB0Q29yZS9hc3NlbWJsZXIvTWFjcm9Bc3NlbWJsZXJBUk02NC5oCj09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFNv
dXJjZS9KYXZhU2NyaXB0Q29yZS9hc3NlbWJsZXIvTWFjcm9Bc3NlbWJsZXJBUk02NC5oCShyZXZp
c2lvbiAxNjEyOTYpCisrKyBTb3VyY2UvSmF2YVNjcmlwdENvcmUvYXNzZW1ibGVyL01hY3JvQXNz
ZW1ibGVyQVJNNjQuaAkod29ya2luZyBjb3B5KQpAQCAtMTQyNCw2ICsxNDI0LDE2IEBAIHB1Ymxp
YzoKICAgICAgICAgQ1JBU0goKTsKICAgICB9CiAKKyAgICB2b2lkIHBvcFBhaXIoUmVnaXN0ZXJJ
RCBkZXN0MSwgUmVnaXN0ZXJJRCBkZXN0MikKKyAgICB7CisgICAgICAgIG1fYXNzZW1ibGVyLmxk
cDw2ND4oZGVzdDEsIGRlc3QyLCBBUk02NFJlZ2lzdGVyczo6c3AsIFBhaXJQb3N0SW5kZXgoMTYp
KTsKKyAgICB9CisKKyAgICB2b2lkIHB1c2hQYWlyKFJlZ2lzdGVySUQgc3JjMSwgUmVnaXN0ZXJJ
RCBzcmMyKQorICAgIHsKKyAgICAgICAgbV9hc3NlbWJsZXIuc3RwPDY0PihzcmMxLCBzcmMyLCBB
Uk02NFJlZ2lzdGVyczo6c3AsIFBhaXJQcmVJbmRleCgtMTYpKTsKKyAgICB9CisKICAgICB2b2lk
IHBvcFRvUmVzdG9yZShSZWdpc3RlcklEIGRlc3QpCiAgICAgewogICAgICAgICBtX2Fzc2VtYmxl
ci5sZHI8NjQ+KGRlc3QsIEFSTTY0UmVnaXN0ZXJzOjpzcCwgUG9zdEluZGV4KDE2KSk7CkluZGV4
OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGlzYXNzZW1ibGVyL0FSTTY0L0E2NERPcGNvZGUuY3Bw
Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT0KLS0tIFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9kaXNhc3NlbWJsZXIvQVJNNjQv
QTY0RE9wY29kZS5jcHAJKHJldmlzaW9uIDE2MTI5NikKKysrIFNvdXJjZS9KYXZhU2NyaXB0Q29y
ZS9kaXNhc3NlbWJsZXIvQVJNNjQvQTY0RE9wY29kZS5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTYy
LDYgKzYyLDggQEAgc3RydWN0IE9wY29kZUdyb3VwSW5pdGlhbGl6ZXIgewogeyBncm91cEluZGV4
LCBncm91cENsYXNzOjptYXNrLCBncm91cENsYXNzOjpwYXR0ZXJuLCBncm91cENsYXNzOjpmb3Jt
YXQgfQogCiBzdGF0aWMgT3Bjb2RlR3JvdXBJbml0aWFsaXplciBvcGNvZGVHcm91cExpc3RbXSA9
IHsKKyAgICBPUENPREVfR1JPVVBfRU5UUlkoMHgwOCwgQTY0RE9wY29kZUxvYWRTdG9yZVJlZ2lz
dGVyUGFpciksCisgICAgT1BDT0RFX0dST1VQX0VOVFJZKDB4MDksIEE2NERPcGNvZGVMb2FkU3Rv
cmVSZWdpc3RlclBhaXIpLAogICAgIE9QQ09ERV9HUk9VUF9FTlRSWSgweDBhLCBBNjRET3Bjb2Rl
TG9naWNhbFNoaWZ0ZWRSZWdpc3RlciksCiAgICAgT1BDT0RFX0dST1VQX0VOVFJZKDB4MGIsIEE2
NERPcGNvZGVBZGRTdWJ0cmFjdEV4dGVuZGVkUmVnaXN0ZXIpLAogICAgIE9QQ09ERV9HUk9VUF9F
TlRSWSgweDBiLCBBNjRET3Bjb2RlQWRkU3VidHJhY3RTaGlmdGVkUmVnaXN0ZXIpLApAQCAtMTcy
LDExICsxNzQsMTYgQEAgY29uc3QgY2hhciogQTY0RE9wY29kZTo6Zm9ybWF0KCkKIAogdm9pZCBB
NjRET3Bjb2RlOjphcHBlbmRSZWdpc3Rlck5hbWUodW5zaWduZWQgcmVnaXN0ZXJOdW1iZXIsIGJv
b2wgaXM2NEJpdCkKIHsKKyAgICBpZiAocmVnaXN0ZXJOdW1iZXIgPT0gMjkpIHsKKyAgICAgICAg
YnVmZmVyUHJpbnRmKGlzNjRCaXQgPyAiZnAiIDogIndmcCIpOworICAgICAgICByZXR1cm47Cisg
ICAgfQorCiAgICAgaWYgKHJlZ2lzdGVyTnVtYmVyID09IDMwKSB7CiAgICAgICAgIGJ1ZmZlclBy
aW50ZihpczY0Qml0ID8gImxyIiA6ICJ3bHIiKTsKICAgICAgICAgcmV0dXJuOwogICAgIH0KLQor
ICAgIAogICAgIGJ1ZmZlclByaW50ZigiJWMldSIsIGlzNjRCaXQgPyAneCcgOiAndycsIHJlZ2lz
dGVyTnVtYmVyKTsKIH0KIApAQCAtOTM5LDYgKzk0Niw2MyBAQCBjb25zdCBjaGFyKiBBNjRET3Bj
b2RlTG9hZFN0b3JlUmVnaXN0ZXJPCiAgICAgcmV0dXJuIG1fZm9ybWF0QnVmZmVyOwogfQogCitj
b25zdCBjaGFyKiBBNjRET3Bjb2RlTG9hZFN0b3JlUmVnaXN0ZXJQYWlyOjpvcE5hbWUoKQorewor
ICAgIGlmICghdkJpdCgpICYmIGxCaXQoKSAmJiBzaXplKCkgPT0gMHgxKQorICAgICAgICByZXR1
cm4gImxkcHN3IjsKKyAgICBpZiAobEJpdCgpKQorICAgICAgICByZXR1cm4gImxkcCI7CisgICAg
cmV0dXJuICJzdHAiOworfQorCitjb25zdCBjaGFyKiBBNjRET3Bjb2RlTG9hZFN0b3JlUmVnaXN0
ZXJQYWlyOjpmb3JtYXQoKQoreworICAgIGNvbnN0IGNoYXIqIHRoaXNPcE5hbWUgPSBvcE5hbWUo
KTsKKyAgICAKKyAgICBpZiAoc2l6ZSgpID09IDB4MykKKyAgICAgICAgcmV0dXJuIEE2NERPcGNv
ZGU6OmZvcm1hdCgpOworCisgICAgaWYgKChvZmZzZXRNb2RlKCkgPCAweDEpIHx8IChvZmZzZXRN
b2RlKCkgPiAweDMpKQorICAgICAgICByZXR1cm4gQTY0RE9wY29kZTo6Zm9ybWF0KCk7CisKKyAg
ICBpZiAoKG9mZnNldE1vZGUoKSA9PSAweDEpICYmICF2Qml0KCkgJiYgIWxCaXQoKSkKKyAgICAg
ICAgcmV0dXJuIEE2NERPcGNvZGU6OmZvcm1hdCgpOworCisgICAgYXBwZW5kSW5zdHJ1Y3Rpb25O
YW1lKHRoaXNPcE5hbWUpOworICAgIHVuc2lnbmVkIG9mZnNldFNoaWZ0OworICAgIGlmICh2Qml0
KCkpIHsKKyAgICAgICAgYXBwZW5kRlBSZWdpc3Rlck5hbWUocnQoKSwgc2l6ZSgpKTsKKyAgICAg
ICAgYXBwZW5kU2VwYXJhdG9yKCk7CisgICAgICAgIGFwcGVuZEZQUmVnaXN0ZXJOYW1lKHJ0Migp
LCBzaXplKCkpOworICAgICAgICBvZmZzZXRTaGlmdCA9IHNpemUoKSArIDI7CisgICAgfSBlbHNl
IHsKKyAgICAgICAgYXBwZW5kUmVnaXN0ZXJOYW1lKHJ0KCksIGlzNjRCaXQoKSk7CisgICAgICAg
IGFwcGVuZFNlcGFyYXRvcigpOworICAgICAgICBhcHBlbmRSZWdpc3Rlck5hbWUocnQyKCksIGlz
NjRCaXQoKSk7CisgICAgICAgIG9mZnNldFNoaWZ0ID0gKHNpemUoKSA+PiAxKSArIDI7CisgICAg
fQorCisgICAgYXBwZW5kU2VwYXJhdG9yKCk7CisgICAgYXBwZW5kQ2hhcmFjdGVyKCdbJyk7Cisg
ICAgYXBwZW5kU1BPclJlZ2lzdGVyTmFtZShybigpKTsKKworICAgIGludCBvZmZzZXQgPSBpbW1l
ZGlhdGU3KCkgPDwgb2Zmc2V0U2hpZnQ7CisKKyAgICBpZiAob2Zmc2V0TW9kZSgpID09IDEpIHsK
KyAgICAgICAgYXBwZW5kQ2hhcmFjdGVyKCddJyk7CisgICAgICAgIGFwcGVuZFNlcGFyYXRvcigp
OworICAgICAgICBhcHBlbmRTaWduZWRJbW1lZGlhdGUob2Zmc2V0KTsKKyAgICB9IGVsc2Ugewor
ICAgICAgICBhcHBlbmRTZXBhcmF0b3IoKTsKKyAgICAgICAgYXBwZW5kU2lnbmVkSW1tZWRpYXRl
KG9mZnNldCk7CisgICAgICAgIGFwcGVuZENoYXJhY3RlcignXScpOworICAgICAgICBpZiAob2Zm
c2V0TW9kZSgpID09IDB4MykKKyAgICAgICAgICAgIGFwcGVuZENoYXJhY3RlcignIScpOworICAg
IH0KKworICAgIHJldHVybiBtX2Zvcm1hdEJ1ZmZlcjsKK30KKwogY29uc3QgY2hhciogQTY0RE9w
Y29kZUxvYWRTdG9yZVVuc2lnbmVkSW1tZWRpYXRlOjpmb3JtYXQoKQogewogICAgIGNvbnN0IGNo
YXIqIHRoaXNPcE5hbWUgPSBvcE5hbWUoKTsKSW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9k
aXNhc3NlbWJsZXIvQVJNNjQvQTY0RE9wY29kZS5oCj09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFNvdXJjZS9KYXZh
U2NyaXB0Q29yZS9kaXNhc3NlbWJsZXIvQVJNNjQvQTY0RE9wY29kZS5oCShyZXZpc2lvbiAxNjEy
OTYpCisrKyBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGlzYXNzZW1ibGVyL0FSTTY0L0E2NERPcGNv
ZGUuaAkod29ya2luZyBjb3B5KQpAQCAtNTY1LDYgKzU2NSwyMiBAQCBwdWJsaWM6CiAgICAgaW50
IHNCaXQoKSB7IHJldHVybiAobV9vcGNvZGUgPj4gMTIpICYgMHgxOyB9CiB9OwogCitjbGFzcyBB
NjRET3Bjb2RlTG9hZFN0b3JlUmVnaXN0ZXJQYWlyIDogcHVibGljIEE2NERPcGNvZGVMb2FkU3Rv
cmUgeworcHVibGljOgorICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBtYXNrID0gMHgzYTAwMDAw
MDsKKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgcGF0dGVybiA9IDB4MjgwMDAwMDA7CisKKyAg
ICBERUZJTkVfU1RBVElDX0ZPUk1BVChBNjRET3Bjb2RlTG9hZFN0b3JlUmVnaXN0ZXJQYWlyLCB0
aGlzT2JqKTsKKworICAgIGNvbnN0IGNoYXIqIGZvcm1hdCgpOworICAgIGNvbnN0IGNoYXIqIG9w
TmFtZSgpOworCisgICAgdW5zaWduZWQgcnQyKCkgeyByZXR1cm4gKG1fb3Bjb2RlID4+IDEwKSAm
IDB4MWY7IH0KKyAgICBpbnQgaW1tZWRpYXRlNygpIHsgcmV0dXJuIChzdGF0aWNfY2FzdDxpbnQ+
KChtX29wY29kZSA+PiAxNSkgJiAweDdmKSA8PCAyNSkgPj4gMjU7IH0KKyAgICB1bnNpZ25lZCBv
ZmZzZXRNb2RlKCkgeyByZXR1cm4gKG1fb3Bjb2RlID4+IDIzKSAmIDB4NzsgfQorICAgIGludCBs
Qml0KCkgeyByZXR1cm4gKG1fb3Bjb2RlID4+IDIyKSAmIDB4MTsgfQorfTsKKwogY2xhc3MgQTY0
RE9wY29kZUxvYWRTdG9yZVVuc2lnbmVkSW1tZWRpYXRlIDogcHVibGljIEE2NERPcGNvZGVMb2Fk
U3RvcmUgewogcHVibGljOgogICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBtYXNrID0gMHgzYjAw
MDAwMDsKSW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9qaXQvQXNzZW1ibHlIZWxwZXJzLmgK
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PQotLS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2ppdC9Bc3NlbWJseUhlbHBlcnMu
aAkocmV2aXNpb24gMTYxMjk4KQorKysgU291cmNlL0phdmFTY3JpcHRDb3JlL2ppdC9Bc3NlbWJs
eUhlbHBlcnMuaAkod29ya2luZyBjb3B5KQpAQCAtMTEwLDYgKzExMCwxOCBAQCBwdWJsaWM6CiAg
ICAgICAgIHJldHVybiAyICogc2l6ZW9mKHZvaWQqKTsKICAgICB9CiAKKyAgICB2b2lkIGVtaXRG
dW5jdGlvblByb2xvZ3VlKCkKKyAgICB7CisgICAgICAgIHB1c2hQYWlyKGZyYW1lUG9pbnRlclJl
Z2lzdGVyLCBsaW5rUmVnaXN0ZXIpOworICAgICAgICBtb3ZlKHN0YWNrUG9pbnRlclJlZ2lzdGVy
LCBmcmFtZVBvaW50ZXJSZWdpc3Rlcik7CisgICAgfQorCisgICAgdm9pZCBlbWl0RnVuY3Rpb25F
cGlsb2d1ZSgpCisgICAgeworICAgICAgICBtb3ZlKGZyYW1lUG9pbnRlclJlZ2lzdGVyLCBzdGFj
a1BvaW50ZXJSZWdpc3Rlcik7CisgICAgICAgIHBvcFBhaXIoZnJhbWVQb2ludGVyUmVnaXN0ZXIs
IGxpbmtSZWdpc3Rlcik7CisgICAgfQorCiAgICAgQUxXQVlTX0lOTElORSB2b2lkIHByZXNlcnZl
UmV0dXJuQWRkcmVzc0FmdGVyQ2FsbChSZWdpc3RlcklEIHJlZykKICAgICB7CiAgICAgICAgIG1v
dmUobGlua1JlZ2lzdGVyLCByZWcpOwo=
</data>
<flag name="review"
          id="244054"
          type_id="1"
          status="+"
          setter="mark.lam"
    />
          </attachment>
      

    </bug>

</bugzilla>