<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[279362] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/279362">279362</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2021-06-28 21:05:14 -0700 (Mon, 28 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add a new pattern to instruction selector to use BIC supported by ARM64
https://bugs.webkit.org/show_bug.cgi?id=227202

Patch by Yijia Huang <yijia_huang@apple.com> on 2021-06-28
Reviewed by Filip Pizlo.

This patch includes three modifications:
    1. Add bit clear (BIC), or not (ORN), and extract and insert bitfield at lower end (FBXIL)
       to Air opcode to serve intruciton selector.
    2. Add bitfield clear (BFC) to MacroAssembler.
    4. Do refactoring - rename Air opcodes added in the previous patches.

------------------
### Part A BIC ###
------------------
Given the operation:

bic Rd, Rn, Rm

The BIC (Bit Clear) instruction performs an AND operation on the bits in Rn with the
complements of the corresponding bits in the value of Rm. The instruction selector can
utilize this to lowering certain patterns in B3 IR before further Air optimization.
The equivalent patterns of this instruction are:

Pattern 1:
    d = n & (-m - 1)

Pattern 2:
    d = n & (m ^ -1)

In order to get benefits for complement operation, current instruction selector uses
mvn instruction to lower the pattern value ^ -1. Then, a new strength reduction rule is
introduced:
    Turn this: -value - 1
    Into this: value ^ -1

So, d = n & (m ^ -1) is selected as the canonical form.

Given B3 IR:
Int @0 = ArgumentReg(%x0)
Int @1 = ArgumentReg(%x1)
Int @2 = -1
Int @3 = BitXor(@1, @2)
Int @4 = BitAnd(@0, @3)
Void@5 = Return(@4, Terminal)

Before Adding BIC:
// Old optimized AIR
Not %x1, %x1,      @3
And %x0, %x1, %x0, @4
Ret %x0,           @5

After Adding BIC:
// New optimized AIR
Bic %x0, %x1, %x0, @4
Ret %x0,           @5

------------------
### Part A ORN ###
------------------
Given the operation:

orn Rd, Rn, Rm

Bitwise OR NOT (shifted register) performs a bitwise (inclusive) OR of a register value
Rn and the complement of an optionally-shifted register value Rm, and writes the result
to the destination register Rd.

The equivalent patterns of this instruction are:

Pattern 1:
    d = n | (-m - 1)

Pattern 2:
    d = n | (m ^ -1)

Then, d = n | (m ^ -1) is selected as the canonical form.

Given B3 IR:
Int @0 = ArgumentReg(%x0)
Int @1 = ArgumentReg(%x1)
Int @2 = -1
Int @3 = BitXor(@1, @2)
Int @4 = BitOr(@0, @3)
Void@5 = Return(@4, Terminal)

Before Adding BIC:
// Old optimized AIR
Not %x1, %x1,      @3
Or  %x0, %x1, %x0, @4
Ret %x0,           @5

After Adding BIC:
// New optimized AIR
Orn %x0, %x1, %x0, @4
Ret %x0,           @5

--------------------
### Part A FBXIL ###
--------------------
Given the operation:

bfxil Rd, Rn, lsb, width

Bitfield extract and insert at low end(FBXIL) copies any number of low-order bits
from a source register into the same number of adjacent bits at the low end in
the destination register, leaving other bits unchanged.

The equivalent patterns of this instruction are:

Pattern 1:
mask1 = (1 << width) - 1
mask2 = ~mask1
((n >> lsb) & mask1) | (d & mask2)

Pattern 2:
mask1 = ((1 << width) - 1) << lsb
mask2 = ~(mask1 >> lsb)
((n & mask1) >> lsb) | (d & mask2)

Then, introduce a strength reduction rule for easier recognization.
Turn this: (v & maskShift) >> shiftAmount
Into this: (v >> shiftAmount) & mask

with constraints:
1. maskShift = mask << lsb
2. mask = (1 << width) - 1
3. 0 <= shiftAmount < datasize
4. 0 < width < datasize
5. shiftAmount + width <= datasize

The canonical form to match FBXIL is d = ((n >> lsb) & mask1) | (d & mask2).

Given B3 IR:
Int @0 = ArgumentReg(%x0)
Int @1 = ArgumentReg(%x1)
Int @2 = lsb
Int @3 = mask1
Int @4 = mask2
Int @5 = BitAnd(@1, @3)
Int @6 = BitAnd(@0, @4))
Int @7 = ZShr(@5, @2)
Int @8 = BitOr(@7, @6)
Void@9 = Return(@8, Terminal)

Before Adding BIC:
// Old optimized AIR
And                      mask2, %x0,   %x0,      @6
ExtractUnsignedBitfield    %x1, lsb, width, %x1, @7
Or                         %x0, %x1,   %x0,      @8
Ret                        %x0,                  @9

After Adding BIC:
// New optimized AIR
ExtractInsertBitfieldAtLowEnd %x1, lsb, width, %x0, @8
Ret64                         %x0,                  @9

--------------
### Part B ###
--------------
The Bitfield Clear (BFC), leaving other bits unchanged, is similar to BFI which is an
alias of BFM. Given the operation:

bfc Rd, lsb, width

The equivalent pattern of this instruction is:

mask = ((1 << width) - 1) << lsb
d = d & ~mask

Since mask is a constant and B3 performs constant fold in the optimization phase, this
pattern will directly lower to the BitAnd binary operation. So, no need to match this pattern.

--------------
### Part C ###
--------------
At MacroAssembler level, the emitters are exepected to be expressed in english
(e.g. something like clearBitField for BFC). Do refactoring to rename Air opcode for
UBFX, UBFIZ, BFI, and BIC.

* assembler/ARM64Assembler.h:
(JSC::ARM64Assembler::bfc):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::extractUnsignedBitfield32):
(JSC::MacroAssemblerARM64::extractUnsignedBitfield64):
(JSC::MacroAssemblerARM64::insertUnsignedBitfieldInZero32):
(JSC::MacroAssemblerARM64::insertUnsignedBitfieldInZero64):
(JSC::MacroAssemblerARM64::insertBitField32):
(JSC::MacroAssemblerARM64::insertBitField64):
(JSC::MacroAssemblerARM64::clearBitField32):
(JSC::MacroAssemblerARM64::clearBitField64):
(JSC::MacroAssemblerARM64::clearBitsWithMask32):
(JSC::MacroAssemblerARM64::clearBitsWithMask64):
(JSC::MacroAssemblerARM64::orNot32):
(JSC::MacroAssemblerARM64::orNot64):
(JSC::MacroAssemblerARM64::ubfx32): Deleted.
(JSC::MacroAssemblerARM64::ubfx64): Deleted.
(JSC::MacroAssemblerARM64::ubfiz32): Deleted.
(JSC::MacroAssemblerARM64::ubfiz64): Deleted.
(JSC::MacroAssemblerARM64::bitFieldInsert32): Deleted.
(JSC::MacroAssemblerARM64::bitFieldInsert64): Deleted.
* assembler/testmasm.cpp:
(JSC::testMultiplySignExtend32):
(JSC::testMultiplySubSignExtend32):
(JSC::testExtractUnsignedBitfield32):
(JSC::testExtractUnsignedBitfield64):
(JSC::testInsertUnsignedBitfieldInZero32):
(JSC::testInsertUnsignedBitfieldInZero64):
(JSC::testInsertBitField32):
(JSC::testInsertBitField64):
(JSC::testClearBitField32):
(JSC::testClearBitField64):
(JSC::testClearBitsWithMask32):
(JSC::testClearBitsWithMask64):
(JSC::testOrNot32):
(JSC::testOrNot64):
(JSC::testMul32SignExtend): Deleted.
(JSC::testMulSubSignExtend32): Deleted.
(JSC::testUbfx32): Deleted.
(JSC::testUbfx64): Deleted.
(JSC::testUbfiz32): Deleted.
(JSC::testUbfiz64): Deleted.
(JSC::testBitFieldInsert32): Deleted.
(JSC::testBitFieldInsert64): Deleted.
* b3/B3LowerToAir.cpp:
* b3/B3ReduceStrength.cpp:
* b3/air/AirOpcode.opcodes:
* b3/testb3.h:
* b3/testb3_2.cpp:
(testInsertBitField32):
(testInsertBitField64):
(testBIC32):
(testBIC64):
(testOrNot32):
(testOrNot64):
(addBitTests):
(testBitFieldInsert32): Deleted.
(testBitFieldInsert64): Deleted.
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::cageWithoutUntagging):
(JSC::AssemblyHelpers::cageConditionallyAndUntag):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerARM64Assemblerh">trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblertestmasmcpp">trunk/Source/JavaScriptCore/assembler/testmasm.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp">trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirOpcodeopcodes">trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3h">trunk/Source/JavaScriptCore/b3/testb3.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3_2cpp">trunk/Source/JavaScriptCore/b3/testb3_2.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelperscpp">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/ChangeLog       2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -1,3 +1,248 @@
</span><ins>+2021-06-28  Yijia Huang  <yijia_huang@apple.com>
+
+        Add a new pattern to instruction selector to use BIC supported by ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=227202
+
+        Reviewed by Filip Pizlo.
+
+        This patch includes three modifications:
+            1. Add bit clear (BIC), or not (ORN), and extract and insert bitfield at lower end (FBXIL) 
+               to Air opcode to serve intruciton selector.
+            2. Add bitfield clear (BFC) to MacroAssembler.
+            4. Do refactoring - rename Air opcodes added in the previous patches.
+
+        ------------------
+        ### Part A BIC ###
+        ------------------
+        Given the operation:
+
+        bic Rd, Rn, Rm
+
+        The BIC (Bit Clear) instruction performs an AND operation on the bits in Rn with the 
+        complements of the corresponding bits in the value of Rm. The instruction selector can 
+        utilize this to lowering certain patterns in B3 IR before further Air optimization. 
+        The equivalent patterns of this instruction are:
+
+        Pattern 1:
+            d = n & (-m - 1)
+
+        Pattern 2:
+            d = n & (m ^ -1)
+
+        In order to get benefits for complement operation, current instruction selector uses 
+        mvn instruction to lower the pattern value ^ -1. Then, a new strength reduction rule is 
+        introduced:
+            Turn this: -value - 1 
+            Into this: value ^ -1
+
+        So, d = n & (m ^ -1) is selected as the canonical form.
+
+        Given B3 IR:
+        Int @0 = ArgumentReg(%x0)
+        Int @1 = ArgumentReg(%x1)
+        Int @2 = -1
+        Int @3 = BitXor(@1, @2)
+        Int @4 = BitAnd(@0, @3)
+        Void@5 = Return(@4, Terminal)
+
+        Before Adding BIC:
+        // Old optimized AIR
+        Not %x1, %x1,      @3
+        And %x0, %x1, %x0, @4
+        Ret %x0,           @5
+
+        After Adding BIC:
+        // New optimized AIR
+        Bic %x0, %x1, %x0, @4
+        Ret %x0,           @5
+
+        ------------------
+        ### Part A ORN ###
+        ------------------
+        Given the operation:
+
+        orn Rd, Rn, Rm
+
+        Bitwise OR NOT (shifted register) performs a bitwise (inclusive) OR of a register value 
+        Rn and the complement of an optionally-shifted register value Rm, and writes the result 
+        to the destination register Rd.
+
+        The equivalent patterns of this instruction are:
+
+        Pattern 1:
+            d = n | (-m - 1)
+
+        Pattern 2:
+            d = n | (m ^ -1)
+
+        Then, d = n | (m ^ -1) is selected as the canonical form.
+
+        Given B3 IR:
+        Int @0 = ArgumentReg(%x0)
+        Int @1 = ArgumentReg(%x1)
+        Int @2 = -1
+        Int @3 = BitXor(@1, @2)
+        Int @4 = BitOr(@0, @3)
+        Void@5 = Return(@4, Terminal)
+
+        Before Adding BIC:
+        // Old optimized AIR
+        Not %x1, %x1,      @3
+        Or  %x0, %x1, %x0, @4
+        Ret %x0,           @5
+
+        After Adding BIC:
+        // New optimized AIR
+        Orn %x0, %x1, %x0, @4
+        Ret %x0,           @5
+
+        --------------------
+        ### Part A FBXIL ###
+        --------------------
+        Given the operation:
+
+        bfxil Rd, Rn, lsb, width
+
+        Bitfield extract and insert at low end(FBXIL) copies any number of low-order bits 
+        from a source register into the same number of adjacent bits at the low end in 
+        the destination register, leaving other bits unchanged.
+
+        The equivalent patterns of this instruction are:
+
+        Pattern 1:
+        mask1 = (1 << width) - 1
+        mask2 = ~mask1
+        ((n >> lsb) & mask1) | (d & mask2)
+
+        Pattern 2:
+        mask1 = ((1 << width) - 1) << lsb
+        mask2 = ~(mask1 >> lsb)
+        ((n & mask1) >> lsb) | (d & mask2)
+
+        Then, introduce a strength reduction rule for easier recognization.
+        Turn this: (v & maskShift) >> shiftAmount
+        Into this: (v >> shiftAmount) & mask
+
+        with constraints:
+        1. maskShift = mask << lsb
+        2. mask = (1 << width) - 1
+        3. 0 <= shiftAmount < datasize
+        4. 0 < width < datasize
+        5. shiftAmount + width <= datasize
+
+        The canonical form to match FBXIL is d = ((n >> lsb) & mask1) | (d & mask2).
+        
+        Given B3 IR:
+        Int @0 = ArgumentReg(%x0)
+        Int @1 = ArgumentReg(%x1)
+        Int @2 = lsb
+        Int @3 = mask1
+        Int @4 = mask2
+        Int @5 = BitAnd(@1, @3)
+        Int @6 = BitAnd(@0, @4))
+        Int @7 = ZShr(@5, @2)
+        Int @8 = BitOr(@7, @6)
+        Void@9 = Return(@8, Terminal)
+
+        Before Adding BIC:
+        // Old optimized AIR
+        And                      mask2, %x0,   %x0,      @6
+        ExtractUnsignedBitfield    %x1, lsb, width, %x1, @7
+        Or                         %x0, %x1,   %x0,      @8
+        Ret                        %x0,                  @9
+
+        After Adding BIC:
+        // New optimized AIR
+        ExtractInsertBitfieldAtLowEnd %x1, lsb, width, %x0, @8
+        Ret64                         %x0,                  @9
+
+        --------------
+        ### Part B ###
+        --------------
+        The Bitfield Clear (BFC), leaving other bits unchanged, is similar to BFI which is an 
+        alias of BFM. Given the operation:
+
+        bfc Rd, lsb, width
+
+        The equivalent pattern of this instruction is:
+
+        mask = ((1 << width) - 1) << lsb
+        d = d & ~mask
+
+        Since mask is a constant and B3 performs constant fold in the optimization phase, this 
+        pattern will directly lower to the BitAnd binary operation. So, no need to match this pattern.
+
+        --------------
+        ### Part C ###
+        --------------
+        At MacroAssembler level, the emitters are exepected to be expressed in english 
+        (e.g. something like clearBitField for BFC). Do refactoring to rename Air opcode for 
+        UBFX, UBFIZ, BFI, and BIC.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::bfc):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::extractUnsignedBitfield32):
+        (JSC::MacroAssemblerARM64::extractUnsignedBitfield64):
+        (JSC::MacroAssemblerARM64::insertUnsignedBitfieldInZero32):
+        (JSC::MacroAssemblerARM64::insertUnsignedBitfieldInZero64):
+        (JSC::MacroAssemblerARM64::insertBitField32):
+        (JSC::MacroAssemblerARM64::insertBitField64):
+        (JSC::MacroAssemblerARM64::clearBitField32):
+        (JSC::MacroAssemblerARM64::clearBitField64):
+        (JSC::MacroAssemblerARM64::clearBitsWithMask32):
+        (JSC::MacroAssemblerARM64::clearBitsWithMask64):
+        (JSC::MacroAssemblerARM64::orNot32):
+        (JSC::MacroAssemblerARM64::orNot64):
+        (JSC::MacroAssemblerARM64::ubfx32): Deleted.
+        (JSC::MacroAssemblerARM64::ubfx64): Deleted.
+        (JSC::MacroAssemblerARM64::ubfiz32): Deleted.
+        (JSC::MacroAssemblerARM64::ubfiz64): Deleted.
+        (JSC::MacroAssemblerARM64::bitFieldInsert32): Deleted.
+        (JSC::MacroAssemblerARM64::bitFieldInsert64): Deleted.
+        * assembler/testmasm.cpp:
+        (JSC::testMultiplySignExtend32):
+        (JSC::testMultiplySubSignExtend32):
+        (JSC::testExtractUnsignedBitfield32):
+        (JSC::testExtractUnsignedBitfield64):
+        (JSC::testInsertUnsignedBitfieldInZero32):
+        (JSC::testInsertUnsignedBitfieldInZero64):
+        (JSC::testInsertBitField32):
+        (JSC::testInsertBitField64):
+        (JSC::testClearBitField32):
+        (JSC::testClearBitField64):
+        (JSC::testClearBitsWithMask32):
+        (JSC::testClearBitsWithMask64):
+        (JSC::testOrNot32):
+        (JSC::testOrNot64):
+        (JSC::testMul32SignExtend): Deleted.
+        (JSC::testMulSubSignExtend32): Deleted.
+        (JSC::testUbfx32): Deleted.
+        (JSC::testUbfx64): Deleted.
+        (JSC::testUbfiz32): Deleted.
+        (JSC::testUbfiz64): Deleted.
+        (JSC::testBitFieldInsert32): Deleted.
+        (JSC::testBitFieldInsert64): Deleted.
+        * b3/B3LowerToAir.cpp:
+        * b3/B3ReduceStrength.cpp:
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.h:
+        * b3/testb3_2.cpp:
+        (testInsertBitField32):
+        (testInsertBitField64):
+        (testBIC32):
+        (testBIC64):
+        (testOrNot32):
+        (testOrNot64):
+        (addBitTests):
+        (testBitFieldInsert32): Deleted.
+        (testBitFieldInsert64): Deleted.
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::cageWithoutUntagging):
+        (JSC::AssemblyHelpers::cageConditionallyAndUntag):
+
</ins><span class="cx"> 2021-06-28  Mikhail R. Gadelha  <mikhail@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         Add LLInt fast path for less, lesseq, greater and greatereq
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerARM64Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h   2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h      2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -833,6 +833,12 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template<int datasize>
</span><ins>+    ALWAYS_INLINE void bfc(RegisterID rd, int lsb, int width)
+    {
+        bfi<datasize>(rd, ARM64Registers::zr, lsb, width);
+    }
+
+    template<int datasize>
</ins><span class="cx">     ALWAYS_INLINE void bfi(RegisterID rd, RegisterID rn, int lsb, int width)
</span><span class="cx">     {
</span><span class="cx">         bfm<datasize>(rd, rn, (datasize - lsb) & (datasize - 1), width - 1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h      2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h 2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -390,26 +390,6 @@
</span><span class="cx">         and32(dataTempRegister, dest);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void ubfx32(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
-    {
-        m_assembler.ubfx<32>(dest, src, lsb.m_value, width.m_value);
-    }
-
-    void ubfx64(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
-    {
-        m_assembler.ubfx<64>(dest, src, lsb.m_value, width.m_value);
-    }
-
-    void ubfiz32(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
-    {
-        m_assembler.ubfiz<32>(dest, src, lsb.m_value, width.m_value);
-    }
-
-    void ubfiz64(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
-    {
-        m_assembler.ubfiz<64>(dest, src, lsb.m_value, width.m_value);
-    }
-
</del><span class="cx">     void and64(RegisterID src1, RegisterID src2, RegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.and_<64>(dest, src1, src2);
</span><span class="lines">@@ -468,6 +448,77 @@
</span><span class="cx">         m_assembler.and_<64>(dest, dest, dataTempRegister);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Bit Operations:
+    void extractUnsignedBitfield32(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.ubfx<32>(dest, src, lsb.m_value, width.m_value);
+    }
+
+    void extractUnsignedBitfield64(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.ubfx<64>(dest, src, lsb.m_value, width.m_value);
+    }
+
+    void insertUnsignedBitfieldInZero32(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.ubfiz<32>(dest, src, lsb.m_value, width.m_value);
+    }
+
+    void insertUnsignedBitfieldInZero64(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.ubfiz<64>(dest, src, lsb.m_value, width.m_value);
+    }
+
+    void insertBitField32(RegisterID source, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.bfi<32>(dest, source, lsb.m_value, width.m_value);
+    }
+
+    void insertBitField64(RegisterID source, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.bfi<64>(dest, source, lsb.m_value, width.m_value);
+    }
+
+    void clearBitField32(TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.bfc<32>(dest, lsb.m_value, width.m_value);
+    }
+
+    void clearBitField64(TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.bfc<64>(dest, lsb.m_value, width.m_value);
+    }
+
+    void clearBitsWithMask32(RegisterID src, RegisterID mask, RegisterID dest)
+    {
+        m_assembler.bic<32>(dest, src, mask);
+    }
+
+    void clearBitsWithMask64(RegisterID src, RegisterID mask, RegisterID dest)
+    {
+        m_assembler.bic<64>(dest, src, mask);
+    }
+
+    void orNot32(RegisterID src, RegisterID mask, RegisterID dest)
+    {
+        m_assembler.orn<32>(dest, src, mask);
+    }
+
+    void orNot64(RegisterID src, RegisterID mask, RegisterID dest)
+    {
+        m_assembler.orn<64>(dest, src, mask);
+    }
+
+    void extractInsertBitfieldAtLowEnd32(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.bfxil<32>(dest, src, lsb.m_value, width.m_value);
+    }
+
+    void extractInsertBitfieldAtLowEnd64(RegisterID src, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
+    {
+        m_assembler.bfxil<64>(dest, src, lsb.m_value, width.m_value);
+    }
+
</ins><span class="cx">     void clearBit64(RegisterID bitToClear, RegisterID dest, RegisterID scratchForMask = InvalidGPRReg)
</span><span class="cx">     {
</span><span class="cx">         if (scratchForMask == InvalidGPRReg)
</span><span class="lines">@@ -2752,18 +2803,6 @@
</span><span class="cx">         m_assembler.fcsel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Bit field operations:
-    void bitFieldInsert32(RegisterID source, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
-    {
-        m_assembler.bfi<32>(dest, source, lsb.m_value, width.m_value);
-    }
-
-    // destBitOffset is the top bit of the destination where the bits should be copied to. Zero is the lowest order bit.
-    void bitFieldInsert64(RegisterID source, TrustedImm32 lsb, TrustedImm32 width, RegisterID dest)
-    {
-        m_assembler.bfi<64>(dest, source, lsb.m_value, width.m_value);
-    }
-
</del><span class="cx">     // Forwards / external control flow operations:
</span><span class="cx">     //
</span><span class="cx">     // This set of jump and conditional branch operations return a Jump
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblertestmasmcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/testmasm.cpp (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/testmasm.cpp       2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/assembler/testmasm.cpp  2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -904,7 +904,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if CPU(ARM64)
</span><del>-void testMul32SignExtend()
</del><ins>+void testMultiplySignExtend32()
</ins><span class="cx"> {
</span><span class="cx">     for (auto value : int32Operands()) {
</span><span class="cx">         auto mul = compile([=] (CCallHelpers& jit) {
</span><span class="lines">@@ -1089,7 +1089,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testMulSubSignExtend32()
</del><ins>+void testMultiplySubSignExtend32()
</ins><span class="cx"> {
</span><span class="cx">     // d = a - SExt32(n) *  SExt32(m)
</span><span class="cx">     auto sub = compile([=] (CCallHelpers& jit) {
</span><span class="lines">@@ -1112,7 +1112,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testUbfx32()
</del><ins>+void testExtractUnsignedBitfield32()
</ins><span class="cx"> {
</span><span class="cx">     uint32_t src = 0xf0f0f0f0;
</span><span class="cx">     Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
</span><span class="lines">@@ -1122,7 +1122,7 @@
</span><span class="cx">                 auto ubfx32 = compile([=] (CCallHelpers& jit) {
</span><span class="cx">                     emitFunctionPrologue(jit);
</span><span class="cx"> 
</span><del>-                    jit.ubfx32(GPRInfo::argumentGPR0, 
</del><ins>+                    jit.extractUnsignedBitfield32(GPRInfo::argumentGPR0, 
</ins><span class="cx">                         CCallHelpers::TrustedImm32(lsb), 
</span><span class="cx">                         CCallHelpers::TrustedImm32(width), 
</span><span class="cx">                         GPRInfo::returnValueGPR);
</span><span class="lines">@@ -1136,7 +1136,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testUbfx64()
</del><ins>+void testExtractUnsignedBitfield64()
</ins><span class="cx"> {
</span><span class="cx">     uint64_t src = 0xf0f0f0f0f0f0f0f0;
</span><span class="cx">     Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
</span><span class="lines">@@ -1146,7 +1146,7 @@
</span><span class="cx">                 auto ubfx64 = compile([=] (CCallHelpers& jit) {
</span><span class="cx">                     emitFunctionPrologue(jit);
</span><span class="cx"> 
</span><del>-                    jit.ubfx64(GPRInfo::argumentGPR0, 
</del><ins>+                    jit.extractUnsignedBitfield64(GPRInfo::argumentGPR0, 
</ins><span class="cx">                         CCallHelpers::TrustedImm32(lsb), 
</span><span class="cx">                         CCallHelpers::TrustedImm32(width), 
</span><span class="cx">                         GPRInfo::returnValueGPR);
</span><span class="lines">@@ -1160,7 +1160,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testUbfiz32()
</del><ins>+void testInsertUnsignedBitfieldInZero32()
</ins><span class="cx"> {
</span><span class="cx">     uint32_t src = 0xf0f0f0f0;
</span><span class="cx">     Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
</span><span class="lines">@@ -1170,7 +1170,7 @@
</span><span class="cx">                 auto ubfiz32 = compile([=] (CCallHelpers& jit) {
</span><span class="cx">                     emitFunctionPrologue(jit);
</span><span class="cx"> 
</span><del>-                    jit.ubfiz32(GPRInfo::argumentGPR0, 
</del><ins>+                    jit.insertUnsignedBitfieldInZero32(GPRInfo::argumentGPR0, 
</ins><span class="cx">                         CCallHelpers::TrustedImm32(lsb), 
</span><span class="cx">                         CCallHelpers::TrustedImm32(width), 
</span><span class="cx">                         GPRInfo::returnValueGPR);
</span><span class="lines">@@ -1185,7 +1185,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testUbfiz64()
</del><ins>+void testInsertUnsignedBitfieldInZero64()
</ins><span class="cx"> {
</span><span class="cx">     uint64_t src = 0xf0f0f0f0f0f0f0f0;
</span><span class="cx">     Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
</span><span class="lines">@@ -1195,7 +1195,7 @@
</span><span class="cx">                 auto ubfiz64 = compile([=] (CCallHelpers& jit) {
</span><span class="cx">                     emitFunctionPrologue(jit);
</span><span class="cx"> 
</span><del>-                    jit.ubfiz64(GPRInfo::argumentGPR0, 
</del><ins>+                    jit.insertUnsignedBitfieldInZero64(GPRInfo::argumentGPR0, 
</ins><span class="cx">                         CCallHelpers::TrustedImm32(lsb), 
</span><span class="cx">                         CCallHelpers::TrustedImm32(width), 
</span><span class="cx">                         GPRInfo::returnValueGPR);
</span><span class="lines">@@ -1210,7 +1210,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testBitFieldInsert32()
</del><ins>+void testInsertBitField32()
</ins><span class="cx"> {
</span><span class="cx">     uint32_t src = 0x0f0f0f0f;
</span><span class="cx">     uint32_t dst = 0xf0f0f0f0;
</span><span class="lines">@@ -1221,7 +1221,7 @@
</span><span class="cx">                 auto bfi32 = compile([=] (CCallHelpers& jit) {
</span><span class="cx">                     emitFunctionPrologue(jit);
</span><span class="cx"> 
</span><del>-                    jit.bitFieldInsert64(GPRInfo::argumentGPR0, 
</del><ins>+                    jit.insertBitField32(GPRInfo::argumentGPR0, 
</ins><span class="cx">                         CCallHelpers::TrustedImm32(lsb), 
</span><span class="cx">                         CCallHelpers::TrustedImm32(width), 
</span><span class="cx">                         GPRInfo::argumentGPR1);
</span><span class="lines">@@ -1240,7 +1240,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testBitFieldInsert64()
</del><ins>+void testInsertBitField64()
</ins><span class="cx"> {
</span><span class="cx">     uint64_t src = 0x0f0f0f0f0f0f0f0f;
</span><span class="cx">     uint64_t dst = 0xf0f0f0f0f0f0f0f0;
</span><span class="lines">@@ -1251,7 +1251,7 @@
</span><span class="cx">                 auto bfi64 = compile([=] (CCallHelpers& jit) {
</span><span class="cx">                     emitFunctionPrologue(jit);
</span><span class="cx"> 
</span><del>-                    jit.bitFieldInsert64(GPRInfo::argumentGPR0, 
</del><ins>+                    jit.insertBitField64(GPRInfo::argumentGPR0, 
</ins><span class="cx">                         CCallHelpers::TrustedImm32(lsb), 
</span><span class="cx">                         CCallHelpers::TrustedImm32(width), 
</span><span class="cx">                         GPRInfo::argumentGPR1);
</span><span class="lines">@@ -1269,6 +1269,188 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+
+void testExtractInsertBitfieldAtLowEnd32()
+{
+    uint32_t src = 0xf0f0f0f0;
+    uint32_t dst = 0x0f0f0f0f;
+    Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
+    for (auto lsb : imms) {
+        for (auto width : imms) {
+            if (lsb >= 0 && width > 0 && lsb + width < 32) {
+                auto bfxil32 = compile([=] (CCallHelpers& jit) {
+                    emitFunctionPrologue(jit);
+
+                    jit.extractInsertBitfieldAtLowEnd32(GPRInfo::argumentGPR0, 
+                        CCallHelpers::TrustedImm32(lsb), 
+                        CCallHelpers::TrustedImm32(width), 
+                        GPRInfo::argumentGPR1);
+                    jit.move(GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+                    emitFunctionEpilogue(jit);
+                    jit.ret();
+                });
+                uint32_t mask1 = (1U << width) - 1U;
+                uint32_t mask2 = ~mask1;
+                uint32_t rhs = invoke<uint32_t>(bfxil32, src, dst);
+                uint32_t lhs = ((src >> lsb) & mask1) | (dst & mask2);
+                CHECK_EQ(rhs, lhs);
+            }
+        }
+    }
+}
+
+void testExtractInsertBitfieldAtLowEnd64()
+{
+    uint64_t src = 0x0f0f0f0f0f0f0f0f;
+    uint64_t dst = 0xf0f0f0f0f0f0f0f0;
+    Vector<uint64_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
+    for (auto lsb : imms) {
+        for (auto width : imms) {
+            if (lsb >= 0 && width > 0 && lsb + width < 64) {
+                auto bfxil64 = compile([=] (CCallHelpers& jit) {
+                    emitFunctionPrologue(jit);
+
+                    jit.extractInsertBitfieldAtLowEnd64(GPRInfo::argumentGPR0, 
+                        CCallHelpers::TrustedImm32(lsb), 
+                        CCallHelpers::TrustedImm32(width), 
+                        GPRInfo::argumentGPR1);
+                    jit.move(GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+                    emitFunctionEpilogue(jit);
+                    jit.ret();
+                });
+                uint64_t mask1 = (1ULL << width) - 1ULL;
+                uint64_t mask2 = ~mask1;
+                uint64_t rhs = invoke<uint64_t>(bfxil64, src, dst);
+                uint64_t lhs = ((src >> lsb) & mask1) | (dst & mask2);
+                CHECK_EQ(rhs, lhs);
+            }
+        }
+    }
+}
+
+void testClearBitField32()
+{
+    uint32_t src = std::numeric_limits<uint32_t>::max();
+    Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
+    for (auto lsb : imms) {
+        for (auto width : imms) {
+            if (lsb >= 0 && width > 0 && lsb + width < 32) {
+                auto bfc32 = compile([=] (CCallHelpers& jit) {
+                    emitFunctionPrologue(jit);
+
+                    jit.clearBitField32(CCallHelpers::TrustedImm32(lsb), CCallHelpers::TrustedImm32(width), GPRInfo::argumentGPR0);
+                    jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+
+                    emitFunctionEpilogue(jit);
+                    jit.ret();
+                });
+                uint32_t mask = ((1U << width) - 1U) << lsb;
+                uint32_t rhs = invoke<uint32_t>(bfc32, src);
+                uint32_t lhs = src & ~mask;
+                CHECK_EQ(rhs, lhs);
+            }
+        }
+    }
+}
+
+void testClearBitField64()
+{
+    uint64_t src = std::numeric_limits<uint64_t>::max();
+    Vector<uint32_t> imms = { 0, 1, 5, 7, 30, 31, 32, 42, 56, 62, 63, 64 };
+    for (auto lsb : imms) {
+        for (auto width : imms) {
+            if (lsb >= 0 && width > 0 && lsb + width < 32) {
+                auto bfc64 = compile([=] (CCallHelpers& jit) {
+                    emitFunctionPrologue(jit);
+
+                    jit.clearBitField64(CCallHelpers::TrustedImm32(lsb), CCallHelpers::TrustedImm32(width), GPRInfo::argumentGPR0);
+                    jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+
+                    emitFunctionEpilogue(jit);
+                    jit.ret();
+                });
+                uint64_t mask = ((1ULL << width) - 1ULL) << lsb;
+                uint64_t rhs = invoke<uint64_t>(bfc64, src);
+                uint64_t lhs = src & ~mask;
+                CHECK_EQ(rhs, lhs);
+            }
+        }
+    }
+}
+
+void testClearBitsWithMask32()
+{
+    auto test = compile([] (CCallHelpers& jit) {
+        emitFunctionPrologue(jit);
+
+        jit.clearBitsWithMask32(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+        emitFunctionEpilogue(jit);
+        jit.ret();
+    });
+
+    for (auto mask : int32Operands()) {
+        uint32_t src = std::numeric_limits<uint32_t>::max();
+        CHECK_EQ(invoke<uint32_t>(test, src, mask), (src & ~mask));
+        CHECK_EQ(invoke<uint32_t>(test, 0U, mask), 0U);
+    }
+}
+
+void testClearBitsWithMask64()
+{
+    auto test = compile([] (CCallHelpers& jit) {
+        emitFunctionPrologue(jit);
+
+        jit.clearBitsWithMask64(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+        emitFunctionEpilogue(jit);
+        jit.ret();
+    });
+
+    for (auto mask : int64Operands()) {
+        uint64_t src = std::numeric_limits<uint64_t>::max();
+        CHECK_EQ(invoke<uint64_t>(test, src, mask), (src & ~mask));
+        CHECK_EQ(invoke<uint64_t>(test, 0ULL, mask), 0ULL);
+    }
+}
+
+void testOrNot32()
+{
+    auto test = compile([] (CCallHelpers& jit) {
+        emitFunctionPrologue(jit);
+
+        jit.orNot32(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+        emitFunctionEpilogue(jit);
+        jit.ret();
+    });
+
+    for (auto mask : int32Operands()) {
+        int32_t src = std::numeric_limits<uint32_t>::max();
+        CHECK_EQ(invoke<int32_t>(test, src, mask), (src | ~mask));
+        CHECK_EQ(invoke<int32_t>(test, 0U, mask), ~mask);
+    }
+}
+
+void testOrNot64()
+{
+    auto test = compile([] (CCallHelpers& jit) {
+        emitFunctionPrologue(jit);
+
+        jit.orNot64(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+        emitFunctionEpilogue(jit);
+        jit.ret();
+    });
+
+    for (auto mask : int64Operands()) {
+        int64_t src = std::numeric_limits<uint64_t>::max();
+        CHECK_EQ(invoke<int64_t>(test, src, mask), (src | ~mask));
+        CHECK_EQ(invoke<int64_t>(test, 0ULL, mask), ~mask);
+    }
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86) || CPU(X86_64) || CPU(ARM64)
</span><span class="lines">@@ -3425,9 +3607,8 @@
</span><span class="cx"> #if CPU(ARM64)
</span><span class="cx">     RUN(testLoadStorePair64Int64());
</span><span class="cx">     RUN(testLoadStorePair64Double());
</span><del>-    RUN(testMul32SignExtend());
-    RUN(testMultiplyAddSignExtend32Left());
-    RUN(testMultiplyAddSignExtend32Right());
</del><ins>+    RUN(testMultiplySignExtend32());
+
</ins><span class="cx">     RUN(testSub32Args());
</span><span class="cx">     RUN(testSub32Imm());
</span><span class="cx">     RUN(testSub32ArgImm());
</span><span class="lines">@@ -3435,13 +3616,26 @@
</span><span class="cx">     RUN(testSub64ArgImm32());
</span><span class="cx">     RUN(testSub64Imm64());
</span><span class="cx">     RUN(testSub64ArgImm64());
</span><del>-    RUN(testMulSubSignExtend32());
-    RUN(testUbfx32());
-    RUN(testUbfx64());
-    RUN(testUbfiz32());
-    RUN(testUbfiz64());
-    RUN(testBitFieldInsert32());
-    RUN(testBitFieldInsert64());
</del><ins>+
+    RUN(testMultiplyAddSignExtend32Left());
+    RUN(testMultiplyAddSignExtend32Right());
+    RUN(testMultiplySubSignExtend32());
+
+    RUN(testExtractUnsignedBitfield32());
+    RUN(testExtractUnsignedBitfield64());
+    RUN(testInsertUnsignedBitfieldInZero32());
+    RUN(testInsertUnsignedBitfieldInZero64());
+    RUN(testInsertBitField32());
+    RUN(testInsertBitField64());
+    RUN(testExtractInsertBitfieldAtLowEnd32());
+    RUN(testExtractInsertBitfieldAtLowEnd64());
+    RUN(testClearBitField32());
+    RUN(testClearBitField64());
+    RUN(testClearBitsWithMask32());
+    RUN(testClearBitsWithMask64());
+
+    RUN(testOrNot32());
+    RUN(testOrNot64());
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86) || CPU(X86_64) || CPU(ARM64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp  2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp     2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -2764,7 +2764,7 @@
</span><span class="cx">             // UBFX Pattern: dest = (src >> lsb) & mask 
</span><span class="cx">             // Where: mask = (1 << width) - 1
</span><span class="cx">             auto tryAppendUBFX = [&] () -> bool {
</span><del>-                Air::Opcode opcode = opcodeForType(Ubfx32, Ubfx64, m_value->type());
</del><ins>+                Air::Opcode opcode = opcodeForType(ExtractUnsignedBitfield32, ExtractUnsignedBitfield64, m_value->type());
</ins><span class="cx">                 if (!isValidForm(opcode, Arg::Tmp, Arg::Imm, Arg::Imm, Arg::Tmp)) 
</span><span class="cx">                     return false;
</span><span class="cx">                 if (left->opcode() != ZShr || !canBeInternal(left))
</span><span class="lines">@@ -2780,7 +2780,7 @@
</span><span class="cx">                 if (!mask || mask & (mask + 1))
</span><span class="cx">                     return false;
</span><span class="cx">                 uint64_t width = WTF::bitCount(mask);
</span><del>-                uint64_t datasize = opcode == Ubfx32 ? 32 : 64;
</del><ins>+                uint64_t datasize = opcode == ExtractUnsignedBitfield32 ? 32 : 64;
</ins><span class="cx">                 if (lsb + width > datasize)
</span><span class="cx">                     return false;
</span><span class="cx"> 
</span><span class="lines">@@ -2792,6 +2792,28 @@
</span><span class="cx">             if (tryAppendUBFX())
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><ins>+            // BIC Pattern: d = n & (m ^ -1)
+            auto tryAppendBIC = [&] (Value* left, Value* right) -> bool {
+                Air::Opcode opcode = opcodeForType(ClearBitsWithMask32, ClearBitsWithMask64, m_value->type());
+                if (!isValidForm(opcode, Arg::Tmp, Arg::Tmp, Arg::Tmp)) 
+                    return false;
+                if (right->opcode() != BitXor || !canBeInternal(right))
+                    return false;
+
+                Value* nValue = left;
+                Value* mValue = right->child(0);
+                Value* minusOne = right->child(1);
+                if (m_locked.contains(nValue) || m_locked.contains(mValue) || !minusOne->hasInt() || !minusOne->isInt(-1))
+                    return false;
+
+                append(opcode, tmp(nValue), tmp(mValue), tmp(m_value));
+                commitInternal(right);
+                return true;
+            };
+
+            if (tryAppendBIC(left, right) || tryAppendBIC(right, left))
+                return;
+
</ins><span class="cx">             appendBinOp<And32, And64, AndDouble, AndFloat, Commutative>(left, right);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -2804,7 +2826,7 @@
</span><span class="cx">             // Where: mask1 = ((1 << width) - 1)
</span><span class="cx">             //        mask2 = ~(mask1 << lsb)
</span><span class="cx">             auto tryAppendBFI = [&] (Value* left, Value* right) -> bool {
</span><del>-                Air::Opcode opcode = opcodeForType(BitFieldInsert32, BitFieldInsert64, m_value->type());
</del><ins>+                Air::Opcode opcode = opcodeForType(InsertBitField32, InsertBitField64, m_value->type());
</ins><span class="cx">                 if (!isValidForm(opcode, Arg::Tmp, Arg::Imm, Arg::Imm, Arg::Tmp)) 
</span><span class="cx">                     return false;
</span><span class="cx">                 if (left->opcode() != Shl || !canBeInternal(left))
</span><span class="lines">@@ -2828,7 +2850,7 @@
</span><span class="cx">                 uint64_t mask1 = maskValue1->asInt();
</span><span class="cx">                 if (!mask1 || mask1 & (mask1 + 1))
</span><span class="cx">                     return false;
</span><del>-                uint64_t datasize = opcode == BitFieldInsert32 ? 32 : 64;
</del><ins>+                uint64_t datasize = opcode == InsertBitField32 ? 32 : 64;
</ins><span class="cx">                 uint64_t width = WTF::bitCount(mask1);
</span><span class="cx">                 if (lsb + width > datasize)
</span><span class="cx">                     return false;
</span><span class="lines">@@ -2857,6 +2879,84 @@
</span><span class="cx">             if (tryAppendBFI(left, right) || tryAppendBFI(right, left))
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><ins>+            // BFXIL Pattern: d = ((n >> lsb) & mask1) | (d & mask2)
+            // Where: mask1 = ((1 << width) - 1)
+            //        mask2 = ~mask1
+            auto tryAppendBFXIL = [&] (Value* left, Value* right) -> bool {
+                Air::Opcode opcode = opcodeForType(ExtractInsertBitfieldAtLowEnd32, ExtractInsertBitfieldAtLowEnd64, m_value->type());
+                if (!isValidForm(opcode, Arg::Tmp, Arg::Imm, Arg::Imm, Arg::Tmp)) 
+                    return false;
+                if (left->opcode() != BitAnd || !canBeInternal(left))
+                    return false;
+                if (left->child(0)->opcode() != ZShr || !canBeInternal(left->child(0)))
+                    return false;
+                if (right->opcode() != BitAnd || !canBeInternal(right))
+                    return false;
+
+                Value* nValue = left->child(0)->child(0);
+                Value* maskValue1 = left->child(1);
+                Value* lsbValue = left->child(0)->child(1);
+                Value* dValue = right->child(0);
+                Value* maskValue2 = right->child(1);
+                if (m_locked.contains(nValue) || m_locked.contains(dValue))
+                    return false;
+                if (!maskValue1->hasInt() || !imm(lsbValue) || lsbValue->asInt() < 0 || !maskValue2->hasInt())
+                    return false;
+
+                uint64_t lsb = lsbValue->asInt();
+                uint64_t mask1 = maskValue1->asInt();
+                if (!mask1 || mask1 & (mask1 + 1))
+                    return false;
+                uint64_t width = WTF::bitCount(mask1);
+                uint64_t datasize = opcode == ExtractInsertBitfieldAtLowEnd32 ? 32 : 64;
+                if (lsb + width > datasize)
+                    return false;
+                uint64_t mask2 = maskValue2->asInt();
+
+                auto isValidMask2 = [&] () -> bool {
+                    uint64_t mask = mask1 ^ mask2;
+                    uint64_t lowerSet = 0xffffffff;
+                    uint64_t fullSet = 0xffffffffffffffff;
+                    return datasize == 32 ? !((mask & lowerSet) ^ lowerSet) : !(mask ^ fullSet);
+                };
+
+                if (!isValidMask2())
+                    return false;
+
+                Tmp result = tmp(m_value);
+                append(relaxedMoveForType(m_value->type()), tmp(dValue), result);
+                append(opcode, tmp(nValue), imm(lsbValue), imm(width), result);
+                commitInternal(left->child(0));
+                commitInternal(left);
+                commitInternal(right);
+                return true;
+            };
+
+            if (tryAppendBFXIL(left, right) || tryAppendBFXIL(right, left))
+                return;
+
+            // ORN Pattern: d = n | (m ^ -1)
+            auto tryAppendORN = [&] (Value* left, Value* right) -> bool {
+                Air::Opcode opcode = opcodeForType(OrNot32, OrNot64, m_value->type());
+                if (!isValidForm(opcode, Arg::Tmp, Arg::Tmp, Arg::Tmp)) 
+                    return false;
+                if (right->opcode() != BitXor || !canBeInternal(right))
+                    return false;
+
+                Value* nValue = left;
+                Value* mValue = right->child(0);
+                Value* minusOne = right->child(1);
+                if (m_locked.contains(nValue) || m_locked.contains(mValue) || !minusOne->hasInt() || !minusOne->isInt(-1))
+                    return false;
+
+                append(opcode, tmp(nValue), tmp(mValue), tmp(m_value));
+                commitInternal(right);
+                return true;
+            };
+
+            if (tryAppendORN(left, right) || tryAppendORN(right, left))
+                return;
+
</ins><span class="cx">             appendBinOp<Or32, Or64, OrDouble, OrFloat, Commutative>(left, right);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -2899,7 +2999,7 @@
</span><span class="cx">             // UBFIZ Pattern: d = (n & mask) << lsb 
</span><span class="cx">             // Where: mask = (1 << width) - 1
</span><span class="cx">             auto tryAppendUBFZ = [&] () -> bool {
</span><del>-                Air::Opcode opcode = opcodeForType(Ubfiz32, Ubfiz64, m_value->type());
</del><ins>+                Air::Opcode opcode = opcodeForType(InsertUnsignedBitfieldInZero32, InsertUnsignedBitfieldInZero64, m_value->type());
</ins><span class="cx">                 if (!isValidForm(opcode, Arg::Tmp, Arg::Imm, Arg::Imm, Arg::Tmp))
</span><span class="cx">                     return false;
</span><span class="cx">                 if (left->opcode() != BitAnd || !canBeInternal(left))
</span><span class="lines">@@ -2915,7 +3015,7 @@
</span><span class="cx">                 if (!mask || mask & (mask + 1))
</span><span class="cx">                     return false;
</span><span class="cx">                 uint64_t width = WTF::bitCount(mask);
</span><del>-                uint64_t datasize = opcode == Ubfiz32 ? 32 : 64;
</del><ins>+                uint64_t datasize = opcode == InsertUnsignedBitfieldInZero32 ? 32 : 64;
</ins><span class="cx">                 if (lsb + width > datasize)
</span><span class="cx">                     return false;
</span><span class="cx"> 
</span><span class="lines">@@ -2942,7 +3042,10 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case ZShr: {
</span><del>-            appendShift<Urshift32, Urshift64>(m_value->child(0), m_value->child(1));
</del><ins>+            Value* left = m_value->child(0);
+            Value* right = m_value->child(1);
+
+            appendShift<Urshift32, Urshift64>(left, right);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp      2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp 2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -627,6 +627,18 @@
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             if (m_value->isInteger()) {
</span><ins>+                // Turn this: Sub(Neg(value), 1)
+                // Into this: BitXor(value, -1)
+                if (m_value->child(0)->opcode() == Neg && m_value->child(1)->isInt(1)) {
+                    Value* minusOne;
+                    if (m_value->child(0)->child(0)->type() == Int32)
+                        minusOne = m_insertionSet.insert<Const32Value>(m_index, m_value->origin(), -1);
+                    else
+                        minusOne = m_insertionSet.insert<Const64Value>(m_index, m_value->origin(), -1);
+                    replaceWithNew<Value>(BitXor, m_value->origin(), m_value->child(0)->child(0), minusOne);
+                    break;
+                }
+
</ins><span class="cx">                 // Turn this: Sub(value, constant)
</span><span class="cx">                 // Into this: Add(value, -constant)
</span><span class="cx">                 if (Value* negatedConstant = m_value->child(1)->negConstant(m_proc)) {
</span><span class="lines">@@ -1060,6 +1072,7 @@
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             // Turn this: BitAnd(Shl(value, shiftAmount), maskShift)
</span><ins>+            // Into this: Shl(BitAnd(value, mask), shiftAmount)
</ins><span class="cx">             // Conditions:
</span><span class="cx">             // 1. maskShift = mask << shiftAmount
</span><span class="cx">             // 2. mask = (1 << width) - 1
</span><span class="lines">@@ -1066,7 +1079,6 @@
</span><span class="cx">             // 3. 0 <= shiftAmount < datasize
</span><span class="cx">             // 4. 0 < width < datasize
</span><span class="cx">             // 5. shiftAmount + width <= datasize
</span><del>-            // Into this: Shl(BitAnd(value, mask), shiftAmount)
</del><span class="cx">             if (m_value->child(0)->opcode() == Shl
</span><span class="cx">                 && m_value->child(0)->child(1)->hasInt()
</span><span class="cx">                 && m_value->child(0)->child(1)->asInt() >= 0
</span><span class="lines">@@ -1424,6 +1436,38 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            // Turn this: ZShr(BitAnd(value, maskShift), shiftAmount)
+            // Into this: BitAnd(ZShr(value, shiftAmount), mask)
+            // Conditions:
+            // 1. maskShift = mask << shiftAmount
+            // 2. mask = (1 << width) - 1
+            // 3. 0 <= shiftAmount < datasize
+            // 4. 0 < width < datasize
+            // 5. shiftAmount + width <= datasize
+            if (m_value->child(0)->opcode() == BitAnd
+                && m_value->child(0)->child(1)->hasInt()
+                && m_value->child(1)->hasInt()
+                && m_value->child(1)->asInt() >= 0) {
+                uint64_t shiftAmount = m_value->child(1)->asInt();
+                uint64_t maskShift = m_value->child(0)->child(1)->asInt();
+                uint64_t maskShiftAmount = WTF::countTrailingZeros(maskShift);
+                uint64_t mask = maskShift >> maskShiftAmount;
+                uint64_t width = WTF::bitCount(mask);
+                uint64_t datasize = m_value->child(0)->child(0)->type() == Int64 ? 64 : 32;
+                bool isValidShiftAmount = maskShiftAmount == shiftAmount && shiftAmount < datasize;
+                bool isValidMask = mask && !(mask & (mask + 1)) && width < datasize;
+                if (isValidShiftAmount && isValidMask && shiftAmount + width <= datasize) {
+                    Value* maskValue;
+                    if (datasize == 32)
+                        maskValue = m_insertionSet.insert<Const32Value>(m_index, m_value->origin(), mask);
+                    else
+                        maskValue = m_insertionSet.insert<Const64Value>(m_index, m_value->origin(), mask);
+                    Value* shiftValue = m_insertionSet.insert<Value>(m_index, ZShr, m_value->origin(), m_value->child(0)->child(0), m_value->child(1));
+                    replaceWithNew<Value>(BitAnd, m_value->origin(), shiftValue, maskValue);
+                    break;
+                }
+            }
+
</ins><span class="cx">             handleShiftAmount();
</span><span class="cx">             break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes     2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -363,24 +363,6 @@
</span><span class="cx">     x86: Imm, Addr
</span><span class="cx">     x86: Imm, Index
</span><span class="cx"> 
</span><del>-arm64: Ubfx32 U:G:32, U:G:32, U:G:32, ZD:G:32
-    Tmp, Imm, Imm, Tmp
-
-arm64: Ubfx64 U:G:64, U:G:32, U:G:32, D:G:64
-    Tmp, Imm, Imm, Tmp
-
-arm64: Ubfiz32 U:G:32, U:G:32, U:G:32, ZD:G:32
-    Tmp, Imm, Imm, Tmp
-
-arm64: Ubfiz64 U:G:64, U:G:32, U:G:32, D:G:64
-    Tmp, Imm, Imm, Tmp
-
-arm64: BitFieldInsert32 U:G:32, U:G:32, U:G:32, ZD:G:32
-    Tmp, Imm, Imm, Tmp
-
-arm64: BitFieldInsert64 U:G:64, U:G:32, U:G:32, D:G:64
-    Tmp, Imm, Imm, Tmp
-
</del><span class="cx"> 64: And64 U:G:64, U:G:64, D:G:64
</span><span class="cx">     Tmp, Tmp, Tmp
</span><span class="cx">     arm64: BitImm64, Tmp, Tmp
</span><span class="lines">@@ -830,6 +812,48 @@
</span><span class="cx">     Tmp, Addr
</span><span class="cx">     Tmp, Index
</span><span class="cx"> 
</span><ins>+arm64: ExtractUnsignedBitfield32 U:G:32, U:G:32, U:G:32, ZD:G:32
+    Tmp, Imm, Imm, Tmp
+
+arm64: ExtractUnsignedBitfield64 U:G:64, U:G:32, U:G:32, D:G:64
+    Tmp, Imm, Imm, Tmp
+
+arm64: InsertUnsignedBitfieldInZero32 U:G:32, U:G:32, U:G:32, ZD:G:32
+    Tmp, Imm, Imm, Tmp
+
+arm64: InsertUnsignedBitfieldInZero64 U:G:64, U:G:32, U:G:32, D:G:64
+    Tmp, Imm, Imm, Tmp
+
+arm64: InsertBitField32 U:G:32, U:G:32, U:G:32, ZD:G:32
+    Tmp, Imm, Imm, Tmp
+
+arm64: InsertBitField64 U:G:64, U:G:32, U:G:32, D:G:64
+    Tmp, Imm, Imm, Tmp
+
+arm64: ClearBitField32 U:G:32, U:G:32, ZD:G:32
+    Imm, Imm, Tmp
+
+arm64: ClearBitField64 U:G:32, U:G:32, D:G:64
+    Imm, Imm, Tmp
+
+arm64: ClearBitsWithMask32 U:G:32, U:G:32, ZD:G:32
+    Tmp, Tmp, Tmp
+
+arm64: ClearBitsWithMask64 U:G:64, U:G:64, D:G:64
+    Tmp, Tmp, Tmp
+
+arm64: OrNot32 U:G:32, U:G:32, ZD:G:32
+    Tmp, Tmp, Tmp
+
+arm64: OrNot64 U:G:64, U:G:64, D:G:64
+    Tmp, Tmp, Tmp
+
+arm64: ExtractInsertBitfieldAtLowEnd32 U:G:32, U:G:32, U:G:32, ZD:G:32
+    Tmp, Imm, Imm, Tmp
+
+arm64: ExtractInsertBitfieldAtLowEnd64 U:G:64, U:G:32, U:G:32, D:G:64
+    Tmp, Imm, Imm, Tmp
+
</ins><span class="cx"> # The first operand is rax.
</span><span class="cx"> # FIXME: This formulation means that the boolean result cannot be put in eax, even though all users
</span><span class="cx"> # of this would be OK with that.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.h (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.h  2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/b3/testb3.h     2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -428,8 +428,14 @@
</span><span class="cx"> void testUbfiz64AndShiftMaskValue();
</span><span class="cx"> void testUbfiz64ShiftAnd();
</span><span class="cx"> void testUbfiz64AndShift();
</span><del>-void testBitFieldInsert32();
-void testBitFieldInsert64();
</del><ins>+void testInsertBitField32();
+void testInsertBitField64();
+void testExtractInsertBitfieldAtLowEnd32();
+void testExtractInsertBitfieldAtLowEnd64();
+void testBIC32();
+void testBIC64();
+void testOrNot32();
+void testOrNot64();
</ins><span class="cx"> void testBitAndZeroShiftRightArgImmMask32();
</span><span class="cx"> void testBitAndZeroShiftRightArgImmMask64();
</span><span class="cx"> void testBasicSelect();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3_2cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3_2.cpp (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3_2.cpp      2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/b3/testb3_2.cpp 2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -3158,13 +3158,13 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testBitFieldInsert32()
</del><ins>+void testInsertBitField32()
</ins><span class="cx"> {
</span><span class="cx">     if (JSC::Options::defaultB3OptLevel() < 2)
</span><span class="cx">         return;
</span><span class="cx">     uint32_t d = 0xf0f0f0f0;
</span><span class="cx">     uint32_t n = 0xffffffff;
</span><del>-    Vector<uint32_t> lsbs = { 1, 2, 14, 30, 30 };
</del><ins>+    Vector<uint32_t> lsbs = { 2, 2, 14, 30, 30 };
</ins><span class="cx">     Vector<uint32_t> widths = { 30, 3, 17, 1, 2 };
</span><span class="cx"> 
</span><span class="cx">     // Test Pattern: d = ((n & mask1) << lsb) | (d & mask2)
</span><span class="lines">@@ -3236,13 +3236,13 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void testBitFieldInsert64()
</del><ins>+void testInsertBitField64()
</ins><span class="cx"> {
</span><span class="cx">     if (JSC::Options::defaultB3OptLevel() < 2)
</span><span class="cx">         return;
</span><span class="cx">     uint64_t d = 0xf0f0f0f0f0f0f0f0;
</span><span class="cx">     uint64_t n = 0xffffffffffffffff;
</span><del>-    Vector<uint64_t> lsbs = { 1, 30, 14, 62, 62 };
</del><ins>+    Vector<uint64_t> lsbs = { 2, 30, 14, 62, 62 };
</ins><span class="cx">     Vector<uint64_t> widths = { 62, 33, 17, 1, 2 };
</span><span class="cx"> 
</span><span class="cx">     // Test Pattern: d = ((n & mask1) << lsb) | (d & mask2)
</span><span class="lines">@@ -3306,6 +3306,399 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testExtractInsertBitfieldAtLowEnd32()
+{
+    if (JSC::Options::defaultB3OptLevel() < 2)
+        return;
+    uint32_t d = 0xf0f0f0f0;
+    uint32_t n = 0xffffffff;
+    Vector<uint32_t> lsbs = { 1, 10, 14, 30 };
+    Vector<uint32_t> widths = { 30, 11, 17, 1 };
+
+    // BFXIL Pattern: d = ((n >> lsb) & mask1) | (d & mask2)
+    // Where: mask1 = ((1 << width) - 1)
+    //        mask2 = ~mask1
+    auto test1 = [&] (uint32_t lsb, uint32_t mask1, uint32_t mask2) -> uint32_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* dValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+        Value* nValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+        Value* lsbValue = root->appendNew<Const32Value>(proc, Origin(), lsb);
+        Value* maskValue1 = root->appendNew<Const32Value>(proc, Origin(), mask1);
+        Value* maskValue2 = root->appendNew<Const32Value>(proc, Origin(), mask2);
+
+        Value* shiftValue = root->appendNew<Value>(proc, ZShr, Origin(), nValue, lsbValue);
+        Value* leftAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), shiftValue, maskValue1);
+        Value* rightAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), dValue, maskValue2);
+        root->appendNewControlValue(
+            proc, Return, Origin(),
+            root->appendNew<Value>(proc, BitOr, Origin(), leftAndValue, rightAndValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bfxil");
+        return invoke<uint32_t>(*code, d, n);
+    };
+
+    for (size_t i = 0; i < lsbs.size(); ++i) {
+        uint32_t lsb = lsbs.at(i);
+        uint32_t mask1 = (1U << widths.at(i)) - 1U;
+        uint32_t mask2 = ~mask1;
+        CHECK(test1(lsb, mask1, mask2) == (((n >> lsb) & mask1) | (d & mask2)));
+    }
+
+    // BFXIL Pattern: d = ((n & mask1) >> lsb) | (d & mask2)
+    // Where: mask1 = ((1 << width) - 1) << lsb
+    //        mask2 = ~(mask1 >> lsb)
+    auto test2 = [&] (uint32_t lsb, uint32_t mask1, uint32_t mask2) -> uint32_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* dValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+        Value* nValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+        Value* lsbValue = root->appendNew<Const32Value>(proc, Origin(), lsb);
+        Value* maskValue1 = root->appendNew<Const32Value>(proc, Origin(), mask1);
+        Value* maskValue2 = root->appendNew<Const32Value>(proc, Origin(), mask2);
+
+        Value* leftAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), nValue, maskValue1);
+        Value* rightAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), dValue, maskValue2);
+        Value* shiftValue = root->appendNew<Value>(proc, ZShr, Origin(), leftAndValue, lsbValue);
+        root->appendNewControlValue(
+            proc, Return, Origin(),
+            root->appendNew<Value>(proc, BitOr, Origin(), shiftValue, rightAndValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bfxil");
+        return invoke<uint32_t>(*code, d, n);
+    };
+
+    for (size_t i = 0; i < lsbs.size(); ++i) {
+        uint32_t lsb = lsbs.at(i);
+        uint32_t mask1 = ((1U << widths.at(i)) - 1U) << lsb;
+        uint32_t mask2 = ~(mask1 >> lsb);
+        CHECK(test2(lsb, mask1, mask2) == (((n & mask1) >> lsb) | (d & mask2)));
+    }
+}
+
+void testExtractInsertBitfieldAtLowEnd64()
+{
+    if (JSC::Options::defaultB3OptLevel() < 2)
+        return;
+    uint64_t d = 0xf0f0f0f0f0f0f0f0;
+    uint64_t n = 0xffffffffffffffff;
+    Vector<uint64_t> lsbs = { 1, 30, 14, 62 };
+    Vector<uint64_t> widths = { 62, 33, 17, 1 };
+
+    // BFXIL Pattern: d = ((n >> lsb) & mask1) | (d & mask2)
+    // Where: mask1 = ((1 << width) - 1)
+    //        mask2 = ~mask1
+    auto test1 = [&] (uint64_t lsb, uint64_t mask1, uint64_t mask2) -> uint64_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* dValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* nValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* lsbValue = root->appendNew<Const32Value>(proc, Origin(), lsb);
+        Value* maskValue1 = root->appendNew<Const64Value>(proc, Origin(), mask1);
+        Value* maskValue2 = root->appendNew<Const64Value>(proc, Origin(), mask2);
+
+        Value* shiftValue = root->appendNew<Value>(proc, ZShr, Origin(), nValue, lsbValue);
+        Value* leftAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), shiftValue, maskValue1);
+        Value* rightAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), dValue, maskValue2);
+        root->appendNewControlValue(
+            proc, Return, Origin(),
+            root->appendNew<Value>(proc, BitOr, Origin(), leftAndValue, rightAndValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bfxil");
+        return invoke<uint64_t>(*code, d, n);
+    };
+
+    for (size_t i = 0; i < lsbs.size(); ++i) {
+        uint64_t lsb = lsbs.at(i);
+        uint64_t mask1 = (1ULL << widths.at(i)) - 1ULL;
+        uint64_t mask2 = ~mask1;
+        CHECK(test1(lsb, mask1, mask2) == (((n >> lsb) & mask1) | (d & mask2)));
+    }
+
+    // BFXIL Pattern: d = ((n & mask1) >> lsb) | (d & mask2)
+    // Where: mask1 = ((1 << width) - 1) << lsb
+    //        mask2 = ~(mask1 >> lsb)
+    auto test2 = [&] (uint64_t lsb, uint64_t mask1, uint64_t mask2) -> uint64_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* dValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* nValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* lsbValue = root->appendNew<Const32Value>(proc, Origin(), lsb);
+        Value* maskValue1 = root->appendNew<Const64Value>(proc, Origin(), mask1);
+        Value* maskValue2 = root->appendNew<Const64Value>(proc, Origin(), mask2);
+
+        Value* leftAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), nValue, maskValue1);
+        Value* rightAndValue = root->appendNew<Value>(proc, BitAnd, Origin(), dValue, maskValue2);
+        Value* shiftValue = root->appendNew<Value>(proc, ZShr, Origin(), leftAndValue, lsbValue);
+        root->appendNewControlValue(
+            proc, Return, Origin(),
+            root->appendNew<Value>(proc, BitOr, Origin(), shiftValue, rightAndValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bfxil");
+        return invoke<uint64_t>(*code, d, n);
+    };
+
+    for (size_t i = 0; i < lsbs.size(); ++i) {
+        uint64_t lsb = lsbs.at(i);
+        uint64_t mask1 = ((1ULL << widths.at(i)) - 1ULL) << lsb;
+        uint64_t mask2 = ~(mask1 >> lsb);
+        CHECK(test2(lsb, mask1, mask2) == (((n & mask1) >> lsb) | (d & mask2)));
+    }
+}
+
+void testBIC32()
+{
+    if (JSC::Options::defaultB3OptLevel() < 2)
+        return;
+
+    // Test Pattern: d = n & (-m - 1)
+    auto test1 = [&] (int32_t n, int32_t m) -> int32_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+        Value* mValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+        Value* const1 = root->appendNew<Const32Value>(proc, Origin(), 1);
+
+        Value* negValue = root->appendNew<Value>(proc, Neg, Origin(), mValue);
+        Value* subValue = root->appendNew<Value>(proc, Sub, Origin(), negValue, const1);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitAnd, Origin(), nValue, subValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bic");
+        return invoke<int32_t>(*code, n, m);
+    };
+
+    // Test Pattern: d = n & (m ^ -1)
+    auto test2 = [&] (int32_t n, int32_t m) -> int32_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+        Value* mValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+        Value* minusOneValue = root->appendNew<Const32Value>(proc, Origin(), -1);
+
+        Value* xorValue = root->appendNew<Value>(proc, BitXor, Origin(), mValue, minusOneValue);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitAnd, Origin(), nValue, xorValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bic");
+        return invoke<int32_t>(*code, n, m);
+    };
+
+    for (auto n : int32Operands()) {
+        for (auto m : int32Operands()) {
+            CHECK(test1(n.value, m.value) == (n.value & (-m.value - 1)));
+            CHECK(test2(n.value, m.value) == (n.value & (m.value ^ -1)));
+        }
+    }
+}
+
+void testBIC64()
+{
+    if (JSC::Options::defaultB3OptLevel() < 2)
+        return;
+
+    // Test Pattern: d = n & (-m - 1)
+    auto test1 = [&] (int64_t n, int64_t m) -> int64_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* mValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* const1 = root->appendNew<Const64Value>(proc, Origin(), 1);
+
+        Value* negValue = root->appendNew<Value>(proc, Neg, Origin(), mValue);
+        Value* subValue = root->appendNew<Value>(proc, Sub, Origin(), negValue, const1);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitAnd, Origin(), nValue, subValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bic");
+        return invoke<int64_t>(*code, n, m);
+    };
+
+    // Test Pattern: d = n & (m ^ -1)
+    auto test2 = [&] (int64_t n, int64_t m) -> int64_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* mValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* minusOneValue = root->appendNew<Const64Value>(proc, Origin(), -1);
+
+        Value* xorValue = root->appendNew<Value>(proc, BitXor, Origin(), mValue, minusOneValue);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitAnd, Origin(), nValue, xorValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "bic");
+        return invoke<int64_t>(*code, n, m);
+    };
+
+    for (auto n : int64Operands()) {
+        for (auto m : int64Operands()) {
+            CHECK(test1(n.value, m.value) == (n.value & (-m.value - 1LL)));
+            CHECK(test2(n.value, m.value) == (n.value & (m.value ^ -1LL)));
+        }
+    }
+}
+
+void testOrNot32()
+{
+    if (JSC::Options::defaultB3OptLevel() < 2)
+        return;
+
+    // Test Pattern: d = n | (-m - 1)
+    auto test1 = [&] (int32_t n, int32_t m) -> int32_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+        Value* mValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+        Value* const1 = root->appendNew<Const32Value>(proc, Origin(), 1);
+
+        Value* negValue = root->appendNew<Value>(proc, Neg, Origin(), mValue);
+        Value* subValue = root->appendNew<Value>(proc, Sub, Origin(), negValue, const1);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitOr, Origin(), nValue, subValue));
+
+        auto code = compileProc(proc);
+
+        if (isARM64())
+            checkUsesInstruction(*code, "orn");
+        return invoke<int32_t>(*code, n, m);
+    };
+
+    // Test Pattern: d = n | (m ^ -1)
+    auto test2 = [&] (int32_t n, int32_t m) -> int32_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+        Value* mValue = root->appendNew<Value>(
+            proc, Trunc, Origin(), 
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+        Value* minusOneValue = root->appendNew<Const32Value>(proc, Origin(), -1);
+
+        Value* xorValue = root->appendNew<Value>(proc, BitXor, Origin(), mValue, minusOneValue);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitOr, Origin(), nValue, xorValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "orn");
+        return invoke<int32_t>(*code, n, m);
+    };
+
+    for (auto n : int32Operands()) {
+        for (auto m : int32Operands()) {
+            CHECK(test1(n.value, m.value) == (n.value | (-m.value - 1)));
+            CHECK(test2(n.value, m.value) == (n.value | (m.value ^ -1)));
+        }
+    }
+}
+
+void testOrNot64()
+{
+    if (JSC::Options::defaultB3OptLevel() < 2)
+        return;
+
+    // Test Pattern: d = n | (-m - 1)
+    auto test1 = [&] (int64_t n, int64_t m) -> int64_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* mValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* const1 = root->appendNew<Const64Value>(proc, Origin(), 1);
+
+        Value* negValue = root->appendNew<Value>(proc, Neg, Origin(), mValue);
+        Value* subValue = root->appendNew<Value>(proc, Sub, Origin(), negValue, const1);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitOr, Origin(), nValue, subValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "orn");
+        return invoke<int64_t>(*code, n, m);
+    };
+
+    // Test Pattern: d = n | (m ^ -1)
+    auto test2 = [&] (int64_t n, int64_t m) -> int64_t {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* nValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* mValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* minusOneValue = root->appendNew<Const64Value>(proc, Origin(), -1);
+
+        Value* xorValue = root->appendNew<Value>(proc, BitXor, Origin(), mValue, minusOneValue);
+        root->appendNewControlValue(
+            proc, Return, Origin(), 
+            root->appendNew<Value>(proc, BitOr, Origin(), nValue, xorValue));
+
+        auto code = compileProc(proc);
+        if (isARM64())
+            checkUsesInstruction(*code, "orn");
+        return invoke<int64_t>(*code, n, m);
+    };
+
+    for (auto n : int64Operands()) {
+        for (auto m : int64Operands()) {
+            CHECK(test1(n.value, m.value) == (n.value | (-m.value - 1LL)));
+            CHECK(test2(n.value, m.value) == (n.value | (m.value ^ -1LL)));
+        }
+    }
+}
+
</ins><span class="cx"> void testBitAndZeroShiftRightArgImmMask32()
</span><span class="cx"> {
</span><span class="cx">     // Turn this: (tmp >> imm) & mask 
</span><span class="lines">@@ -4198,8 +4591,14 @@
</span><span class="cx">     RUN(testUbfiz64AndShiftMaskValue());
</span><span class="cx">     RUN(testUbfiz64ShiftAnd());
</span><span class="cx">     RUN(testUbfiz64AndShift());
</span><del>-    RUN(testBitFieldInsert32());
-    RUN(testBitFieldInsert64());
</del><ins>+    RUN(testInsertBitField32());
+    RUN(testInsertBitField64());
+    RUN(testExtractInsertBitfieldAtLowEnd32());
+    RUN(testExtractInsertBitfieldAtLowEnd64());
+    RUN(testBIC32());
+    RUN(testBIC64());
+    RUN(testOrNot32());
+    RUN(testOrNot64());
</ins><span class="cx">     RUN(testBitAndZeroShiftRightArgImmMask32());
</span><span class="cx">     RUN(testBitAndZeroShiftRightArgImmMask64());
</span><span class="cx">     RUN(testBitAndArgs(43, 43));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp      2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp 2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -16754,7 +16754,7 @@
</span><span class="cx">             merge->appendSomeRegister(ptr);
</span><span class="cx">             merge->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
</span><span class="cx">                 jit.move(params[2].gpr(), params[0].gpr());
</span><del>-                jit.bitFieldInsert64(params[1].gpr(), CCallHelpers::TrustedImm32(0), CCallHelpers::TrustedImm32(64 - MacroAssembler::maxNumberOfAllowedPACBits), params[0].gpr());
</del><ins>+                jit.insertBitField64(params[1].gpr(), CCallHelpers::TrustedImm32(0), CCallHelpers::TrustedImm32(64 - MacroAssembler::maxNumberOfAllowedPACBits), params[0].gpr());
</ins><span class="cx">             });
</span><span class="cx"> 
</span><span class="cx">             result = doUntagArrayPtr(merge);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp (279361 => 279362)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp      2021-06-29 03:11:28 UTC (rev 279361)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp 2021-06-29 04:05:14 UTC (rev 279362)
</span><span class="lines">@@ -1111,7 +1111,7 @@
</span><span class="cx">     addPtr(TrustedImmPtr(Gigacage::basePtr(kind)), storage);
</span><span class="cx"> #if CPU(ARM64E)
</span><span class="cx">     if (kind == Gigacage::Primitive)
</span><del>-        bitFieldInsert64(storage, TrustedImm32(0), TrustedImm32(64 - maxNumberOfAllowedPACBits), tempReg);
</del><ins>+        insertBitField64(storage, TrustedImm32(0), TrustedImm32(64 - maxNumberOfAllowedPACBits), tempReg);
</ins><span class="cx">     if (skip.isSet())
</span><span class="cx">         skip.link(this);
</span><span class="cx"> #endif
</span><span class="lines">@@ -1148,7 +1148,7 @@
</span><span class="cx">             ASSERT(LogicalImmediate::create64(Gigacage::mask(kind)).isValid());
</span><span class="cx">             andPtr(TrustedImmPtr(Gigacage::mask(kind)), tempReg);
</span><span class="cx">             addPtr(scratch, tempReg);
</span><del>-            bitFieldInsert64(tempReg, TrustedImm32(0), TrustedImm32(64 - maxNumberOfAllowedPACBits), storage);
</del><ins>+            insertBitField64(tempReg, TrustedImm32(0), TrustedImm32(64 - maxNumberOfAllowedPACBits), storage);
</ins><span class="cx"> #else
</span><span class="cx">             andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage);
</span><span class="cx">             addPtr(scratch, storage);
</span></span></pre>
</div>
</div>

</body>
</html>