Changeset 194011 in webkit


Ignore:
Timestamp:
Dec 12, 2015 3:04:54 PM (8 years ago)
Author:
benjamin@webkit.org
Message:

[JSC] Add lowering for B3's Store8 opcode
https://bugs.webkit.org/show_bug.cgi?id=152208

Reviewed by Geoffrey Garen.

B3 has an opcode to store 8bit values but it had
no lowering.

  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::createStore):
(JSC::B3::Air::LowerToAir::lower):

  • b3/air/AirOpcode.opcodes:
  • b3/testb3.cpp:

(JSC::B3::testStore8Arg):
(JSC::B3::testStore8Imm):
(JSC::B3::testStorePartial8BitRegisterOnX86):
(JSC::B3::run):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r194007 r194011  
     12015-12-12  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        [JSC] Add lowering for B3's Store8 opcode
     4        https://bugs.webkit.org/show_bug.cgi?id=152208
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        B3 has an opcode to store 8bit values but it had
     9        no lowering.
     10
     11        * b3/B3LowerToAir.cpp:
     12        (JSC::B3::Air::LowerToAir::createStore):
     13        (JSC::B3::Air::LowerToAir::lower):
     14        * b3/air/AirOpcode.opcodes:
     15        * b3/testb3.cpp:
     16        (JSC::B3::testStore8Arg):
     17        (JSC::B3::testStore8Imm):
     18        (JSC::B3::testStorePartial8BitRegisterOnX86):
     19        (JSC::B3::run):
     20
    1212015-12-12  Csaba Osztrogonác  <ossy@webkit.org>
    222
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r194003 r194011  
    747747    }
    748748
    749     Inst createStore(Value* value, const Arg& dest)
    750     {
    751         Air::Opcode move = moveForType(value->type());
    752 
     749    Inst createStore(Air::Opcode move, Value* value, const Arg& dest)
     750    {
    753751        if (imm(value) && isValidForm(move, Arg::Imm, dest.kind()))
    754752            return Inst(move, m_value, imm(value), dest);
    755753
    756754        return Inst(move, m_value, tmp(value), dest);
     755    }
     756
     757    Inst createStore(Value* value, const Arg& dest)
     758    {
     759        Air::Opcode moveOpcode = moveForType(value->type());
     760        return createStore(moveOpcode, value, dest);
    757761    }
    758762
     
    15581562        }
    15591563
     1564        case B3::Store8: {
     1565            Value* valueToStore = m_value->child(0);
     1566            m_insts.last().append(createStore(Air::Store8, valueToStore, addr(m_value)));
     1567            return;
     1568        }
     1569
    15601570        case Trunc: {
    15611571            ASSERT(tmp(m_value->child(0)) == tmp(m_value));
  • trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes

    r194003 r194011  
    326326    Index, Tmp
    327327
     328Store8 U:G, D:G
     329    Tmp, Index
     330    Tmp, Addr
     331    Imm, Index
     332    Imm, Addr
     333
    328334Load8SignedExtendTo32 U:G, D:G
    329335    Addr, Tmp
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r194003 r194011  
    37033703    CHECK(!compileAndRun<int>(proc));
    37043704    CHECK(slot == value);
     3705}
     3706
     3707void testStore8Arg()
     3708{
     3709    { // Direct addressing.
     3710        Procedure proc;
     3711        BasicBlock* root = proc.addBlock();
     3712
     3713        Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
     3714            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
     3715        Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
     3716
     3717        root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
     3718        root->appendNew<ControlValue>(proc, Return, Origin(), value);
     3719
     3720        int8_t storage = 0;
     3721        CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
     3722        CHECK(storage == 42);
     3723    }
     3724
     3725    { // Indexed addressing.
     3726        Procedure proc;
     3727        BasicBlock* root = proc.addBlock();
     3728
     3729        Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
     3730            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
     3731        Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
     3732        Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
     3733        Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
     3734
     3735        Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
     3736        Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
     3737
     3738        root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
     3739        root->appendNew<ControlValue>(proc, Return, Origin(), value);
     3740
     3741        int8_t storage = 0;
     3742        CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
     3743        CHECK(storage == 42);
     3744    }
     3745}
     3746
     3747void testStore8Imm()
     3748{
     3749    { // Direct addressing.
     3750        Procedure proc;
     3751        BasicBlock* root = proc.addBlock();
     3752
     3753        Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
     3754        Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     3755
     3756        root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
     3757        root->appendNew<ControlValue>(proc, Return, Origin(), value);
     3758
     3759        int8_t storage = 0;
     3760        CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
     3761        CHECK(storage == 42);
     3762    }
     3763
     3764    { // Indexed addressing.
     3765        Procedure proc;
     3766        BasicBlock* root = proc.addBlock();
     3767
     3768        Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
     3769        Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     3770        Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
     3771        Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
     3772
     3773        Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
     3774        Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
     3775
     3776        root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
     3777        root->appendNew<ControlValue>(proc, Return, Origin(), value);
     3778
     3779        int8_t storage = 0;
     3780        CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
     3781        CHECK(storage == 42);
     3782    }
     3783}
     3784
     3785void testStorePartial8BitRegisterOnX86()
     3786{
     3787    Procedure proc;
     3788    BasicBlock* root = proc.addBlock();
     3789
     3790    // We want to have this in ECX.
     3791    Value* returnValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     3792
     3793    // We want this suck in EDX.
     3794    Value* whereToStore = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
     3795
     3796    // The patch point is there to help us force the hand of the compiler.
     3797    PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
     3798
     3799    // For the value above to be materialized and give the allocator
     3800    // a stronger insentive to name those register the way we need.
     3801    patchpoint->append(ConstrainedValue(returnValue, ValueRep(GPRInfo::regT3)));
     3802    patchpoint->append(ConstrainedValue(whereToStore, ValueRep(GPRInfo::regT2)));
     3803
     3804    // We'll produce EDI.
     3805    patchpoint->resultConstraint = ValueRep::reg(GPRInfo::regT6);
     3806
     3807    // Give the allocator a good reason not to use any other register.
     3808    RegisterSet clobberSet = RegisterSet::allGPRs();
     3809    clobberSet.exclude(RegisterSet::stackRegisters());
     3810    clobberSet.exclude(RegisterSet::reservedHardwareRegisters());
     3811    clobberSet.clear(GPRInfo::regT3);
     3812    clobberSet.clear(GPRInfo::regT2);
     3813    clobberSet.clear(GPRInfo::regT6);
     3814    patchpoint->clobberLate(clobberSet);
     3815
     3816    // Set EDI.
     3817    patchpoint->setGenerator(
     3818        [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     3819            AllowMacroScratchRegisterUsage allowScratch(jit);
     3820            jit.xor64(params[0].gpr(), params[0].gpr());
     3821        });
     3822
     3823    // If everything went well, we should have the big number in eax,
     3824    // patchpoint == EDI and whereToStore = EDX.
     3825    // Since EDI == 5, and AH = 5 on 8 bit store, this would go wrong
     3826    // if we use X86 partial registers.
     3827    root->appendNew<MemoryValue>(proc, Store8, Origin(), patchpoint, whereToStore);
     3828
     3829    root->appendNew<ControlValue>(proc, Return, Origin(), returnValue);
     3830
     3831    int8_t storage = 0xff;
     3832    CHECK(compileAndRun<int64_t>(proc, 0x12345678abcdef12, &storage) == 0x12345678abcdef12);
     3833    CHECK(!storage);
    37053834}
    37063835
     
    81408269    RUN(testStoreConstant(49));
    81418270    RUN(testStoreConstantPtr(49));
     8271    RUN(testStore8Arg());
     8272    RUN(testStore8Imm());
     8273    RUN(testStorePartial8BitRegisterOnX86());
    81428274    RUN(testTrunc((static_cast<int64_t>(1) << 40) + 42));
    81438275    RUN(testAdd1(45));
Note: See TracChangeset for help on using the changeset viewer.