Title: [279889] trunk/Source/_javascript_Core
Revision
279889
Author
[email protected]
Date
2021-07-13 13:38:20 -0700 (Tue, 13 Jul 2021)

Log Message

Add a new Air::Arg kind ZeroReg to let AIR recognise the new instructions/forms accepting zero register in ARM64
https://bugs.webkit.org/show_bug.cgi?id=227510

Reviewed by Saam Barati.

B3 is designed to be portable to many kinds of CPUs. However, to effectively
compile code to different CPUs, the compiler must eventually make explicit
instruction set details. Then, Air is introduced, and it is designed to target
individual CPU architectures and generate instructions specific to those CPUs.

Previously, Air don't recognize the zero register. This problem has been pointed
out in #174821, which was trying to introduce the new opcodes to handle the zero
register.

To solve this problem in a modular reasoning approach, a new Air operand ZeroReg
should be introduced. Its goal is to closely match the CPU instructions
accepting the zero register in ARM64. Another reason is that the new overloads
of the instructions taking the zero register can benefit instruction selection
with this implementation.

Here, the ZeroReg is added as a new kind for Air::Arg, which acts as a "high
level" operand to be emitted with the associative opcodes. In ARM64, the ZeroReg
would be emitted as a zero register.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::storeZero64): Deleted.
(JSC::MacroAssemblerARM64::storeZero32): Deleted.
(JSC::MacroAssemblerARM64::storeZero16): Deleted.
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::storeZero32): Deleted.
(JSC::MacroAssemblerX86Common::storeZero16): Deleted.
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::storeZero64): Deleted.
* b3/B3LowerToAir.cpp:
* b3/air/AirArg.cpp:
(JSC::B3::Air::Arg::jsHash const):
(JSC::B3::Air::Arg::dump const):
(WTF::printInternal):
* b3/air/AirArg.h:
(JSC::B3::Air::Arg::zeroReg):
(JSC::B3::Air::Arg::isZeroReg const):
(JSC::B3::Air::Arg::isGP const):
(JSC::B3::Air::Arg::isFP const):
(JSC::B3::Air::Arg::isValidForm const):
(JSC::B3::Air::Arg::asZeroReg const):
* b3/air/AirLowerStackArgs.cpp:
(JSC::B3::Air::lowerStackArgs):
* b3/air/AirOpcode.opcodes:
* b3/air/opcode_generator.rb:
* b3/testb3.h:
* b3/testb3_1.cpp:
(run):
* b3/testb3_3.cpp:
(testStoreZeroReg):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (279888 => 279889)


--- trunk/Source/_javascript_Core/ChangeLog	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-07-13 20:38:20 UTC (rev 279889)
@@ -1,3 +1,60 @@
+2021-07-13  Yijia Huang  <[email protected]>
+
+        Add a new Air::Arg kind ZeroReg to let AIR recognise the new instructions/forms accepting zero register in ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=227510
+
+        Reviewed by Saam Barati.
+
+        B3 is designed to be portable to many kinds of CPUs. However, to effectively 
+        compile code to different CPUs, the compiler must eventually make explicit 
+        instruction set details. Then, Air is introduced, and it is designed to target 
+        individual CPU architectures and generate instructions specific to those CPUs. 
+
+        Previously, Air don't recognize the zero register. This problem has been pointed 
+        out in #174821, which was trying to introduce the new opcodes to handle the zero 
+        register. 
+
+        To solve this problem in a modular reasoning approach, a new Air operand ZeroReg 
+        should be introduced. Its goal is to closely match the CPU instructions 
+        accepting the zero register in ARM64. Another reason is that the new overloads 
+        of the instructions taking the zero register can benefit instruction selection 
+        with this implementation. 
+
+        Here, the ZeroReg is added as a new kind for Air::Arg, which acts as a "high 
+        level" operand to be emitted with the associative opcodes. In ARM64, the ZeroReg 
+        would be emitted as a zero register.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::storeZero64): Deleted.
+        (JSC::MacroAssemblerARM64::storeZero32): Deleted.
+        (JSC::MacroAssemblerARM64::storeZero16): Deleted.
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::storeZero32): Deleted.
+        (JSC::MacroAssemblerX86Common::storeZero16): Deleted.
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::storeZero64): Deleted.
+        * b3/B3LowerToAir.cpp:
+        * b3/air/AirArg.cpp:
+        (JSC::B3::Air::Arg::jsHash const):
+        (JSC::B3::Air::Arg::dump const):
+        (WTF::printInternal):
+        * b3/air/AirArg.h:
+        (JSC::B3::Air::Arg::zeroReg):
+        (JSC::B3::Air::Arg::isZeroReg const):
+        (JSC::B3::Air::Arg::isGP const):
+        (JSC::B3::Air::Arg::isFP const):
+        (JSC::B3::Air::Arg::isValidForm const):
+        (JSC::B3::Air::Arg::asZeroReg const):
+        * b3/air/AirLowerStackArgs.cpp:
+        (JSC::B3::Air::lowerStackArgs):
+        * b3/air/AirOpcode.opcodes:
+        * b3/air/opcode_generator.rb:
+        * b3/testb3.h:
+        * b3/testb3_1.cpp:
+        (run):
+        * b3/testb3_3.cpp:
+        (testStoreZeroReg):
+
 2021-07-12  Filip Pizlo  <[email protected]> and Yusuke Suzuki  <[email protected]>
 
         New malloc algorithm

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (279888 => 279889)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-07-13 20:38:20 UTC (rev 279889)
@@ -1731,16 +1731,6 @@
         m_assembler.str<64>(src, dest, simm);
     }
     
-    void storeZero64(ImplicitAddress address)
-    {
-        store64(ARM64Registers::zr, address);
-    }
-    
-    void storeZero64(BaseIndex address)
-    {
-        store64(ARM64Registers::zr, address);
-    }
-    
     DataLabel32 store64WithAddressOffsetPatch(RegisterID src, Address address)
     {
         DataLabel32 label(this);
@@ -1838,16 +1828,6 @@
         store32(dataTempRegister, address);
     }
 
-    void storeZero32(ImplicitAddress address)
-    {
-        store32(ARM64Registers::zr, address);
-    }
-
-    void storeZero32(BaseIndex address)
-    {
-        store32(ARM64Registers::zr, address);
-    }
-
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
         DataLabel32 label(this);
@@ -1893,16 +1873,6 @@
         store16(dataTempRegister, address);
     }
 
-    void storeZero16(ImplicitAddress address)
-    {
-        store16(ARM64Registers::zr, address);
-    }
-
-    void storeZero16(BaseIndex address)
-    {
-        store16(ARM64Registers::zr, address);
-    }
-
     void store8(RegisterID src, BaseIndex address)
     {
         if (!address.offset && !address.scale) {

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (279888 => 279889)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2021-07-13 20:38:20 UTC (rev 279889)
@@ -1337,26 +1337,6 @@
         m_assembler.movl_i32m(imm.m_value, address.offset, address.base, address.index, address.scale);
     }
 
-    void storeZero32(ImplicitAddress address)
-    {
-        store32(TrustedImm32(0), address);
-    }
-
-    void storeZero32(BaseIndex address)
-    {
-        store32(TrustedImm32(0), address);
-    }
-
-    void storeZero16(ImplicitAddress address)
-    {
-        store16(TrustedImm32(0), address);
-    }
-
-    void storeZero16(BaseIndex address)
-    {
-        store16(TrustedImm32(0), address);
-    }
-
     void store8(TrustedImm32 imm, Address address)
     {
         TrustedImm32 imm8(static_cast<int8_t>(imm.m_value));

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (279888 => 279889)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2021-07-13 20:38:20 UTC (rev 279889)
@@ -1015,16 +1015,6 @@
         m_assembler.movq_rm(scratchRegister(), address.offset, address.base, address.index, address.scale);
     }
     
-    void storeZero64(ImplicitAddress address)
-    {
-        store64(TrustedImm32(0), address);
-    }
-    
-    void storeZero64(BaseIndex address)
-    {
-        store64(TrustedImm32(0), address);
-    }
-    
     DataLabel32 store64WithAddressOffsetPatch(RegisterID src, Address address)
     {
         padBeforePatch();

Modified: trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp	2021-07-13 20:38:20 UTC (rev 279889)
@@ -702,6 +702,11 @@
         return Arg();
     }
 
+    Arg zeroReg()
+    {
+        return Arg::zeroReg();
+    }
+
     Arg immOrTmp(Value* value)
     {
         if (Arg result = imm(value))
@@ -1094,17 +1099,17 @@
     {
         using namespace Air;
         if (auto imm_value = imm(value)) {
-            if (isARM64() && imm_value.value() == 0) {
+            if (!imm_value.value()) {
                 switch (move.opcode) {
                 default:
                     break;
                 case Air::Move32:
-                    if (isValidForm(StoreZero32, dest.kind()) && dest.isValidForm(Width32))
-                        return Inst(StoreZero32, m_value, dest);
+                    if (isValidForm(Store32, Arg::ZeroReg, dest.kind()) && dest.isValidForm(Width32))
+                        return Inst(Store32, m_value, zeroReg(), dest);
                     break;
                 case Air::Move:
-                    if (isValidForm(StoreZero64, dest.kind()) && dest.isValidForm(Width64))
-                        return Inst(StoreZero64, m_value, dest);
+                    if (isValidForm(Store64, Arg::ZeroReg, dest.kind()) && dest.isValidForm(Width64))
+                        return Inst(Store64, m_value, zeroReg(), dest);
                     break;
                 }
             }

Modified: trunk/Source/_javascript_Core/b3/air/AirArg.cpp (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/air/AirArg.cpp	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/air/AirArg.cpp	2021-07-13 20:38:20 UTC (rev 279889)
@@ -102,6 +102,7 @@
         break;
     case Imm:
     case BitImm:
+    case ZeroReg:
     case CallArg:
     case RelCond:
     case ResCond:
@@ -159,6 +160,9 @@
     case BitImm64:
         out.printf("$0x%llx", static_cast<long long unsigned>(m_offset));
         return;
+    case ZeroReg:
+        out.print("%%xzr");
+        return;
     case SimpleAddr:
         out.print("(", base(), ")");
         return;
@@ -236,6 +240,9 @@
     case Arg::BitImm64:
         out.print("BitImm64");
         return;
+    case Arg::ZeroReg:
+        out.print("ZeroReg");
+        return;
     case Arg::SimpleAddr:
         out.print("SimpleAddr");
         return;

Modified: trunk/Source/_javascript_Core/b3/air/AirArg.h (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/air/AirArg.h	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/air/AirArg.h	2021-07-13 20:38:20 UTC (rev 279889)
@@ -85,7 +85,10 @@
         DoubleCond,
         StatusCond,
         Special,
-        WidthArg
+        WidthArg,
+
+        // ZeroReg is interpreted as a zero register in ARM64
+        ZeroReg
     };
     
     enum Temperature : int8_t {
@@ -693,6 +696,14 @@
         return result;
     }
 
+    static Arg zeroReg()
+    {
+        Arg result;
+        result.m_kind = ZeroReg;
+        result.m_offset = 0;
+        return result;
+    }
+
     bool operator==(const Arg& other) const
     {
         return m_offset == other.m_offset
@@ -739,6 +750,11 @@
         return kind() == BitImm64;
     }
 
+    bool isZeroReg() const
+    {
+        return kind() == ZeroReg;
+    }
+
     bool isSomeImm() const
     {
         switch (kind()) {
@@ -1022,6 +1038,7 @@
         case BigImm:
         case BitImm:
         case BitImm64:
+        case ZeroReg:
         case SimpleAddr:
         case Addr:
         case ExtendedOffsetAddr:
@@ -1057,6 +1074,7 @@
         case Special:
         case WidthArg:
         case Invalid:
+        case ZeroReg:
             return false;
         case SimpleAddr:
         case Addr:
@@ -1236,6 +1254,7 @@
             return isValidBitImmForm(value());
         case BitImm64:
             return isValidBitImm64Form(value());
+        case ZeroReg:
         case SimpleAddr:
         case ExtendedOffsetAddr:
             return true;
@@ -1331,6 +1350,13 @@
     }
 #endif
 
+#if CPU(ARM64)
+    MacroAssembler::RegisterID asZeroReg() const
+    {
+        return ARM64Registers::zr;
+    }
+#endif
+
     MacroAssembler::TrustedImmPtr asTrustedImmPtr() const
     {
         if (is64Bit())

Modified: trunk/Source/_javascript_Core/b3/air/AirLowerStackArgs.cpp (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/air/AirLowerStackArgs.cpp	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/air/AirLowerStackArgs.cpp	2021-07-13 20:38:20 UTC (rev 279889)
@@ -157,9 +157,20 @@
                             RELEASE_ASSERT(slot->byteSize() == 8);
                             RELEASE_ASSERT(width == Width32);
 
-                            RELEASE_ASSERT(isValidForm(StoreZero32, Arg::Stack));
+#if CPU(ARM64)
+                            Air::Opcode storeOpcode = Store32;
+                            Air::Arg::Kind operandKind = Arg::ZeroReg;
+                            Air::Arg operand = Arg::zeroReg();
+#elif CPU(X86_64)
+                            Air::Opcode storeOpcode = Move32;
+                            Air::Arg::Kind operandKind = Arg::Imm;
+                            Air::Arg operand = Arg::imm(0);
+#else
+#error Unhandled architecture.
+#endif
+                            RELEASE_ASSERT(isValidForm(storeOpcode, operandKind, Arg::Stack));
                             insertionSet.insert(
-                                instIndex + 1, StoreZero32, inst.origin,
+                                instIndex + 1, storeOpcode, inst.origin, operand,
                                 stackAddr(arg.offset() + 4 + slot->offsetFromFP()));
                         }
                         arg = stackAddr(arg.offset() + slot->offsetFromFP());

Modified: trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes	2021-07-13 20:38:20 UTC (rev 279889)
@@ -675,14 +675,13 @@
 Move32 U:G:32, ZD:G:32, S:G:32
     Addr, Addr, Tmp
 
-# FIXME: StoreZero32 and StoreZero64 are hacks on ARM64, we can do better: https://bugs.webkit.org/show_bug.cgi?id=174821
-StoreZero32 D:G:32
-    Addr
-    Index
+arm64: Store32 U:G:32, ZD:G:32
+    ZeroReg, Addr
+    ZeroReg, Index
 
-64: StoreZero64 D:G:64
-    Addr
-    Index
+arm64: Store64 U:G:64, D:G:64
+    ZeroReg, Addr
+    ZeroReg, Index
 
 SignExtend32ToPtr U:G:32, D:G:Ptr
     Tmp, Tmp

Modified: trunk/Source/_javascript_Core/b3/air/opcode_generator.rb (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/air/opcode_generator.rb	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/air/opcode_generator.rb	2021-07-13 20:38:20 UTC (rev 279889)
@@ -229,7 +229,7 @@
 end
 
 def isKind(token)
-    token =~ /\A((Tmp)|(Imm)|(BigImm)|(BitImm)|(BitImm64)|(SimpleAddr)|(Addr)|(ExtendedOffsetAddr)|(Index)|(RelCond)|(ResCond)|(DoubleCond)|(StatusCond))\Z/
+    token =~ /\A((Tmp)|(Imm)|(BigImm)|(BitImm)|(BitImm64)|(ZeroReg)|(SimpleAddr)|(Addr)|(ExtendedOffsetAddr)|(Index)|(RelCond)|(ResCond)|(DoubleCond)|(StatusCond))\Z/
 end
 
 def isArch(token)
@@ -303,7 +303,7 @@
 
     def consumeKind
         result = token.string
-        parseError("Expected kind (Imm, BigImm, BitImm, BitImm64, Tmp, SimpleAddr, Addr, ExtendedOffsetAddr, Index, RelCond, ResCond, DoubleCond, or StatusCond)") unless isKind(result)
+        parseError("Expected kind (Imm, BigImm, BitImm, BitImm64, ZeroReg, Tmp, SimpleAddr, Addr, ExtendedOffsetAddr, Index, RelCond, ResCond, DoubleCond, or StatusCond)") unless isKind(result)
         advance
         result
     end
@@ -475,6 +475,14 @@
                                     parseError("Form has an immediate for a non-general-purpose argument")
                                 end
                             end
+                            if kind.name == "ZeroReg"
+                                if signature[index].role != "U"
+                                    parseError("Zero immediate must be a use argument")
+                                end
+                                if signature[index].bank != "G"
+                                    parseError("Zero immediate must be a general-purpose argument")
+                                end
+                            end
                         }
                         forms << Form.new(kinds, altName, intersectArchs(opcodeArchs, formArchs))
 
@@ -926,6 +934,7 @@
                 when "ResCond"
                 when "DoubleCond"
                 when "StatusCond"
+                when "ZeroReg"
                 else
                     raise "Unexpected kind: #{kind.name}"
                 end
@@ -1220,6 +1229,8 @@
                     outp.print "args[#{index}].asTrustedImm32()"
                 when "BigImm", "BitImm64"
                     outp.print "args[#{index}].asTrustedImm64()"
+                when "ZeroReg"
+                    outp.print "args[#{index}].asZeroReg()"
                 when "SimpleAddr", "Addr", "ExtendedOffsetAddr"
                     outp.print "args[#{index}].asAddress()"
                 when "Index"

Modified: trunk/Source/_javascript_Core/b3/testb3.h (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/testb3.h	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/testb3.h	2021-07-13 20:38:20 UTC (rev 279889)
@@ -681,6 +681,7 @@
 void testIToF32Imm(int32_t value);
 void testIToDReducedToIToF64Arg();
 void testIToDReducedToIToF32Arg();
+void testStoreZeroReg();
 void testStore32(int value);
 void testStoreConstant(int value);
 void testStoreConstantPtr(intptr_t value);

Modified: trunk/Source/_javascript_Core/b3/testb3_1.cpp (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/testb3_1.cpp	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/testb3_1.cpp	2021-07-13 20:38:20 UTC (rev 279889)
@@ -338,6 +338,7 @@
     RUN_UNARY(testCheckAddRemoveCheckWithSExt32, int32Operands());
     RUN_UNARY(testCheckAddRemoveCheckWithZExt32, int32Operands());
 
+    RUN(testStoreZeroReg());
     RUN(testStore32(44));
     RUN(testStoreConstant(49));
     RUN(testStoreConstantPtr(49));

Modified: trunk/Source/_javascript_Core/b3/testb3_3.cpp (279888 => 279889)


--- trunk/Source/_javascript_Core/b3/testb3_3.cpp	2021-07-13 20:13:07 UTC (rev 279888)
+++ trunk/Source/_javascript_Core/b3/testb3_3.cpp	2021-07-13 20:38:20 UTC (rev 279889)
@@ -2888,6 +2888,83 @@
         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
 }
 
+void testStoreZeroReg()
+{
+    // Direct addressing
+    {
+        int32_t slot32 = 0xbaadbeef;
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* value = root->appendNew<Const32Value>(proc, Origin(), 0);
+        root->appendNew<MemoryValue>(
+            proc, Store, Origin(), value,
+            root->appendNew<ConstPtrValue>(proc, Origin(), &slot32), 0);
+        root->appendNewControlValue(proc, Return, Origin(), value);
+
+        auto code = compileProc(proc);
+        invoke<int>(*code);
+        CHECK_EQ(slot32, 0);
+    }
+
+    {
+        int64_t slot64 = 0xbaadbeef;
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* value = root->appendNew<Const64Value>(proc, Origin(), 0);
+        root->appendNew<MemoryValue>(
+            proc, Store, Origin(), value,
+            root->appendNew<ConstPtrValue>(proc, Origin(), &slot64), 0);
+        root->appendNewControlValue(proc, Return, Origin(), value);
+
+        auto code = compileProc(proc);
+        invoke<int>(*code);
+        CHECK_EQ(slot64, 0);
+    }
+
+    // Indexed addressing
+    {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* value = root->appendNew<Const32Value>(proc, Origin(), 0);
+        Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
+
+        Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
+        Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
+
+        root->appendNew<MemoryValue>(proc, Store, Origin(), value, address, 0);
+        root->appendNewControlValue(proc, Return, Origin(), value);
+
+        int32_t slot32 = 0xbaadbeef;
+        compileAndRun<int32_t>(proc, &slot32, 1);
+        CHECK_EQ(slot32, 0);
+    }
+
+    {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+
+        Value* value = root->appendNew<Const64Value>(proc, Origin(), 0);
+        Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+        Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+        Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
+
+        Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
+        Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
+
+        root->appendNew<MemoryValue>(proc, Store, Origin(), value, address, 0);
+        root->appendNewControlValue(proc, Return, Origin(), value);
+
+        int64_t slot64 = 0xbaadbeef;
+        compileAndRun<int64_t>(proc, &slot64, 1);
+        CHECK_EQ(slot64, 0);
+    }
+}
+
 void testStore32(int value)
 {
     Procedure proc;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to