/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <stdlib.h>

#include "jsatom.h"

#include "jit/shared/IonAssemblerBufferWithConstantPools.h"

#include "jsapi-tests/tests.h"

// Tests for classes in:
//
//   jit/shared/IonAssemblerBuffer.h
//   jit/shared/IonAssemblerBufferWithConstantPools.h
//
// Classes in js::jit tested:
//
//   BufferOffset
//   BufferSlice (implicitly)
//   AssemblerBuffer
//
//   BranchDeadlineSet
//   Pool (implicitly)
//   AssemblerBufferWithConstantPools
//

BEGIN_TEST(testAssemblerBuffer_BufferOffset)
{
    using js::jit::BufferOffset;

    BufferOffset off1;
    BufferOffset off2(10);

    CHECK(!off1.assigned());
    CHECK(off2.assigned());
    CHECK_EQUAL(off2.getOffset(), 10);
    off1 = off2;
    CHECK(off1.assigned());
    CHECK_EQUAL(off1.getOffset(), 10);

    return true;
}
END_TEST(testAssemblerBuffer_BufferOffset)

BEGIN_TEST(testAssemblerBuffer_AssemblerBuffer)
{
    using js::jit::BufferOffset;
    typedef js::jit::AssemblerBuffer<5 * sizeof(uint32_t), uint32_t> AsmBuf;

    AsmBuf ab;
    CHECK(ab.isAligned(16));
    CHECK_EQUAL(ab.size(), 0u);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 0);
    CHECK(!ab.oom());
    CHECK(!ab.bail());

    BufferOffset off1 = ab.putInt(1000017);
    CHECK_EQUAL(off1.getOffset(), 0);
    CHECK_EQUAL(ab.size(), 4u);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 4);
    CHECK(!ab.isAligned(16));
    CHECK(ab.isAligned(4));
    CHECK(ab.isAligned(1));
    CHECK_EQUAL(*ab.getInst(off1), 1000017u);

    BufferOffset off2 = ab.putInt(1000018);
    CHECK_EQUAL(off2.getOffset(), 4);

    BufferOffset off3 = ab.putInt(1000019);
    CHECK_EQUAL(off3.getOffset(), 8);

    BufferOffset off4 = ab.putInt(1000020);
    CHECK_EQUAL(off4.getOffset(), 12);
    CHECK_EQUAL(ab.size(), 16u);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 16);

    // Last one in the slice.
    BufferOffset off5 = ab.putInt(1000021);
    CHECK_EQUAL(off5.getOffset(), 16);
    CHECK_EQUAL(ab.size(), 20u);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 20);

    BufferOffset off6 = ab.putInt(1000022);
    CHECK_EQUAL(off6.getOffset(), 20);
    CHECK_EQUAL(ab.size(), 24u);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 24);

    // Reference previous slice. Excercise the finger.
    CHECK_EQUAL(*ab.getInst(off1), 1000017u);
    CHECK_EQUAL(*ab.getInst(off6), 1000022u);
    CHECK_EQUAL(*ab.getInst(off1), 1000017u);
    CHECK_EQUAL(*ab.getInst(off5), 1000021u);

    // Too much data for one slice.
    const uint32_t fixdata[] = { 2000036, 2000037, 2000038, 2000039, 2000040, 2000041 };

    // Split payload across multiple slices.
    CHECK_EQUAL(ab.nextOffset().getOffset(), 24);
    BufferOffset good1 = ab.putBytesLarge(sizeof(fixdata), fixdata);
    CHECK_EQUAL(good1.getOffset(), 24);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 48);
    CHECK_EQUAL(*ab.getInst(good1), 2000036u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(32)), 2000038u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(36)), 2000039u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(40)), 2000040u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(44)), 2000041u);

    return true;
}
END_TEST(testAssemblerBuffer_AssemblerBuffer)

BEGIN_TEST(testAssemblerBuffer_BranchDeadlineSet)
{
    typedef js::jit::BranchDeadlineSet<3> DLSet;
    using js::jit::BufferOffset;

    js::LifoAlloc alloc(1024);
    DLSet dls(alloc);

    CHECK(dls.empty());
    CHECK(alloc.isEmpty()); // Constructor must be infallible.
    CHECK_EQUAL(dls.size(), 0u);
    CHECK_EQUAL(dls.maxRangeSize(), 0u);

    // Removing non-existant deadline is OK.
    dls.removeDeadline(1, BufferOffset(7));

    // Add deadlines in increasing order as intended. This is optimal.
    dls.addDeadline(1, BufferOffset(10));
    CHECK(!dls.empty());
    CHECK_EQUAL(dls.size(), 1u);
    CHECK_EQUAL(dls.maxRangeSize(), 1u);
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
    CHECK_EQUAL(dls.earliestDeadlineRange(), 1u);

    // Removing non-existant deadline is OK.
    dls.removeDeadline(1, BufferOffset(7));
    dls.removeDeadline(1, BufferOffset(17));
    dls.removeDeadline(0, BufferOffset(10));
    CHECK_EQUAL(dls.size(), 1u);
    CHECK_EQUAL(dls.maxRangeSize(), 1u);

    // Two identical deadlines for different ranges.
    dls.addDeadline(2, BufferOffset(10));
    CHECK(!dls.empty());
    CHECK_EQUAL(dls.size(), 2u);
    CHECK_EQUAL(dls.maxRangeSize(), 1u);
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);

    // It doesn't matter which range earliestDeadlineRange() reports first,
    // but it must report both.
    if (dls.earliestDeadlineRange() == 1) {
        dls.removeDeadline(1, BufferOffset(10));
        CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
        CHECK_EQUAL(dls.earliestDeadlineRange(), 2u);
    } else {
        CHECK_EQUAL(dls.earliestDeadlineRange(), 2u);
        dls.removeDeadline(2, BufferOffset(10));
        CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
        CHECK_EQUAL(dls.earliestDeadlineRange(), 1u);
    }

    // Add deadline which is the front of range 0, but not the global earliest.
    dls.addDeadline(0, BufferOffset(20));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
    CHECK(dls.earliestDeadlineRange() > 0);

    // Non-optimal add to front of single-entry range 0.
    dls.addDeadline(0, BufferOffset(15));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
    CHECK(dls.earliestDeadlineRange() > 0);

    // Append to 2-entry range 0.
    dls.addDeadline(0, BufferOffset(30));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
    CHECK(dls.earliestDeadlineRange() > 0);

    // Add penultimate entry.
    dls.addDeadline(0, BufferOffset(25));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
    CHECK(dls.earliestDeadlineRange() > 0);

    // Prepend, stealing earliest from other range.
    dls.addDeadline(0, BufferOffset(5));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 5);
    CHECK_EQUAL(dls.earliestDeadlineRange(), 0u);

    // Remove central element.
    dls.removeDeadline(0, BufferOffset(20));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 5);
    CHECK_EQUAL(dls.earliestDeadlineRange(), 0u);

    // Remove front, giving back the lead.
    dls.removeDeadline(0, BufferOffset(5));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 10);
    CHECK(dls.earliestDeadlineRange() > 0);

    // Remove front, giving back earliest to range 0.
    dls.removeDeadline(dls.earliestDeadlineRange(), BufferOffset(10));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 15);
    CHECK_EQUAL(dls.earliestDeadlineRange(), 0u);

    // Remove tail.
    dls.removeDeadline(0, BufferOffset(30));
    CHECK_EQUAL(dls.earliestDeadline().getOffset(), 15);
    CHECK_EQUAL(dls.earliestDeadlineRange(), 0u);

    // Now range 0 = [15, 25].
    CHECK_EQUAL(dls.size(), 2u);
    dls.removeDeadline(0, BufferOffset(25));
    dls.removeDeadline(0, BufferOffset(15));
    CHECK(dls.empty());

    return true;
}
END_TEST(testAssemblerBuffer_BranchDeadlineSet)

// Mock Assembler class for testing the AssemblerBufferWithConstantPools
// callbacks.
namespace {

struct TestAssembler;

typedef js::jit::AssemblerBufferWithConstantPools<
  /* SliceSize */ 5 * sizeof(uint32_t),
  /* InstSize */ 4,
  /* Inst */ uint32_t,
  /* Asm */ TestAssembler,
  /* NumShortBranchRanges */ 3> AsmBufWithPool;

struct TestAssembler
{
    // Mock instruction set:
    //
    //   0x1111xxxx - align filler instructions.
    //   0x2222xxxx - manually inserted 'arith' instructions.
    //   0xaaaaxxxx - noop filler instruction.
    //   0xb0bbxxxx - branch xxxx bytes forward. (Pool guard).
    //   0xb1bbxxxx - branch xxxx bytes forward. (Short-range branch).
    //   0xb2bbxxxx - branch xxxx bytes forward. (Veneer branch).
    //   0xb3bbxxxx - branch xxxx bytes forward. (Patched short-range branch).
    //   0xc0ccxxxx - constant pool load (uninitialized).
    //   0xc1ccxxxx - constant pool load to index xxxx.
    //   0xc2ccxxxx - constant pool load xxxx bytes ahead.
    //   0xffffxxxx - pool header with xxxx bytes.

    static const unsigned BranchRange = 36;

    static void InsertIndexIntoTag(uint8_t* load_, uint32_t index)
    {
        uint32_t* load = reinterpret_cast<uint32_t*>(load_);
        MOZ_ASSERT(*load == 0xc0cc0000, "Expected uninitialized constant pool load");
        MOZ_ASSERT(index < 0x10000);
        *load = 0xc1cc0000 + index;
    }

    static void PatchConstantPoolLoad(void* loadAddr, void* constPoolAddr)
    {
        uint32_t* load = reinterpret_cast<uint32_t*>(loadAddr);
        uint32_t index = *load & 0xffff;
        MOZ_ASSERT(*load == (0xc1cc0000 | index), "Expected constant pool load(index)");
        ptrdiff_t offset =
          reinterpret_cast<uint8_t*>(constPoolAddr) - reinterpret_cast<uint8_t*>(loadAddr);
        offset += index * 4;
        MOZ_ASSERT(offset % 4 == 0, "Unaligned constant pool");
        MOZ_ASSERT(offset > 0 && offset < 0x10000, "Pool out of range");
        *load = 0xc2cc0000 + offset;
    }

    static void WritePoolGuard(js::jit::BufferOffset branch, uint32_t* dest,
                               js::jit::BufferOffset afterPool)
    {
        MOZ_ASSERT(branch.assigned());
        MOZ_ASSERT(afterPool.assigned());
        size_t branchOff = branch.getOffset();
        size_t afterPoolOff = afterPool.getOffset();
        MOZ_ASSERT(afterPoolOff > branchOff);
        uint32_t delta = afterPoolOff - branchOff;
        *dest = 0xb0bb0000 + delta;
    }

    static void WritePoolHeader(void* start, js::jit::Pool* p, bool isNatural)
    {
        MOZ_ASSERT(!isNatural, "Natural pool guards not implemented.");
        uint32_t* hdr = reinterpret_cast<uint32_t*>(start);
        *hdr = 0xffff0000 + p->getPoolSize();
    }

    static void PatchShortRangeBranchToVeneer(AsmBufWithPool* buffer, unsigned rangeIdx,
                                              js::jit::BufferOffset deadline,
                                              js::jit::BufferOffset veneer)
    {
        size_t branchOff = deadline.getOffset() - BranchRange;
        size_t veneerOff = veneer.getOffset();
        uint32_t *branch = buffer->getInst(js::jit::BufferOffset(branchOff));

        MOZ_ASSERT((*branch & 0xffff0000) == 0xb1bb0000,
                   "Expected short-range branch instruction");
        // Copy branch offset to veneer. A real instruction set would require
        // some adjustment of the label linked-list.
        *buffer->getInst(veneer) = 0xb2bb0000 | (*branch & 0xffff);
        MOZ_ASSERT(veneerOff > branchOff, "Veneer should follow branch");
        *branch = 0xb3bb0000 + (veneerOff - branchOff);
    }
};
}

BEGIN_TEST(testAssemblerBuffer_AssemblerBufferWithConstantPools)
{
    using js::jit::BufferOffset;

    AsmBufWithPool ab(/* guardSize= */ 1,
                      /* headerSize= */ 1,
                      /* instBufferAlign(unused)= */ 0,
                      /* poolMaxOffset= */ 17,
                      /* pcBias= */ 0,
                      /* alignFillInst= */ 0x11110000,
                      /* nopFillInst= */ 0xaaaa0000,
                      /* nopFill= */ 0);

    CHECK(ab.isAligned(16));
    CHECK_EQUAL(ab.size(), 0u);
    CHECK_EQUAL(ab.nextOffset().getOffset(), 0);
    CHECK(!ab.oom());
    CHECK(!ab.bail());

    // Each slice holds 5 instructions. Trigger a constant pool inside the slice.
    uint32_t poolLoad[] = { 0xc0cc0000 };
    uint32_t poolData[] = { 0xdddd0000, 0xdddd0001, 0xdddd0002, 0xdddd0003 };
    AsmBufWithPool::PoolEntry pe;
    BufferOffset load = ab.allocEntry(1, 1, (uint8_t*)poolLoad, (uint8_t*)poolData, &pe);
    CHECK_EQUAL(pe.index(), 0u);
    CHECK_EQUAL(load.getOffset(), 0);

    // Pool hasn't been emitted yet. Load has been patched by
    // InsertIndexIntoTag.
    CHECK_EQUAL(*ab.getInst(load), 0xc1cc0000);

    // Expected layout:
    //
    //   0: load [pc+16]
    //   4: 0x22220001
    //   8: guard branch pc+12
    //  12: pool header
    //  16: poolData
    //  20: 0x22220002
    //
    ab.putInt(0x22220001);
    // One could argue that the pool should be flushed here since there is no
    // more room. However, the current implementation doesn't dump pool until
    // asked to add data:
    ab.putInt(0x22220002);

    CHECK_EQUAL(*ab.getInst(BufferOffset(0)), 0xc2cc0010u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(4)), 0x22220001u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(8)), 0xb0bb000cu);
    CHECK_EQUAL(*ab.getInst(BufferOffset(12)), 0xffff0004u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(16)), 0xdddd0000u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(20)), 0x22220002u);

    // allocEntry() overwrites the load instruction! Restore the original.
    poolLoad[0] = 0xc0cc0000;

    // Now try with load and pool data on separate slices.
    load = ab.allocEntry(1, 1, (uint8_t*)poolLoad, (uint8_t*)poolData, &pe);
    CHECK_EQUAL(pe.index(), 1u); // Global pool entry index.
    CHECK_EQUAL(load.getOffset(), 24);
    CHECK_EQUAL(*ab.getInst(load), 0xc1cc0000); // Index into current pool.
    ab.putInt(0x22220001);
    ab.putInt(0x22220002);
    CHECK_EQUAL(*ab.getInst(BufferOffset(24)), 0xc2cc0010u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(28)), 0x22220001u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(32)), 0xb0bb000cu);
    CHECK_EQUAL(*ab.getInst(BufferOffset(36)), 0xffff0004u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(40)), 0xdddd0000u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(44)), 0x22220002u);

    // Two adjacent loads to the same pool.
    poolLoad[0] = 0xc0cc0000;
    load = ab.allocEntry(1, 1, (uint8_t*)poolLoad, (uint8_t*)poolData, &pe);
    CHECK_EQUAL(pe.index(), 2u); // Global pool entry index.
    CHECK_EQUAL(load.getOffset(), 48);
    CHECK_EQUAL(*ab.getInst(load), 0xc1cc0000); // Index into current pool.

    poolLoad[0] = 0xc0cc0000;
    load = ab.allocEntry(1, 1, (uint8_t*)poolLoad, (uint8_t*)(poolData + 1), &pe);
    CHECK_EQUAL(pe.index(), 3u); // Global pool entry index.
    CHECK_EQUAL(load.getOffset(), 52);
    CHECK_EQUAL(*ab.getInst(load), 0xc1cc0001); // Index into current pool.

    ab.putInt(0x22220005);

    CHECK_EQUAL(*ab.getInst(BufferOffset(48)), 0xc2cc0010u); // load pc+16.
    CHECK_EQUAL(*ab.getInst(BufferOffset(52)), 0xc2cc0010u); // load pc+16.
    CHECK_EQUAL(*ab.getInst(BufferOffset(56)), 0xb0bb0010u); // guard branch pc+16.
    CHECK_EQUAL(*ab.getInst(BufferOffset(60)), 0xffff0008u); // header 8 bytes.
    CHECK_EQUAL(*ab.getInst(BufferOffset(64)), 0xdddd0000u); // datum 1.
    CHECK_EQUAL(*ab.getInst(BufferOffset(68)), 0xdddd0001u); // datum 2.
    CHECK_EQUAL(*ab.getInst(BufferOffset(72)), 0x22220005u); // putInt(0x22220005)

    // Two loads as above, but the first load has an 8-byte pool entry, and the
    // second load wouldn't be able to reach its data. This must produce two
    // pools.
    poolLoad[0] = 0xc0cc0000;
    load = ab.allocEntry(1, 2, (uint8_t*)poolLoad, (uint8_t*)(poolData+2), &pe);
    CHECK_EQUAL(pe.index(), 4u); // Global pool entry index.
    CHECK_EQUAL(load.getOffset(), 76);
    CHECK_EQUAL(*ab.getInst(load), 0xc1cc0000); // Index into current pool.

    poolLoad[0] = 0xc0cc0000;
    load = ab.allocEntry(1, 1, (uint8_t*)poolLoad, (uint8_t*)poolData, &pe);
    CHECK_EQUAL(pe.index(), 6u); // Global pool entry index. (Prev one is two indexes).
    CHECK_EQUAL(load.getOffset(), 96);
    CHECK_EQUAL(*ab.getInst(load), 0xc1cc0000); // Index into current pool.

    CHECK_EQUAL(*ab.getInst(BufferOffset(76)), 0xc2cc000cu); // load pc+12.
    CHECK_EQUAL(*ab.getInst(BufferOffset(80)), 0xb0bb0010u); // guard branch pc+16.
    CHECK_EQUAL(*ab.getInst(BufferOffset(84)), 0xffff0008u); // header 8 bytes.
    CHECK_EQUAL(*ab.getInst(BufferOffset(88)), 0xdddd0002u); // datum 1.
    CHECK_EQUAL(*ab.getInst(BufferOffset(92)), 0xdddd0003u); // datum 2.

    // Second pool is not flushed yet, and there is room for one instruction
    // after the load. Test the keep-together feature.
    ab.enterNoPool(2);
    ab.putInt(0x22220006);
    ab.putInt(0x22220007);
    ab.leaveNoPool();

    CHECK_EQUAL(*ab.getInst(BufferOffset( 96)), 0xc2cc000cu); // load pc+16.
    CHECK_EQUAL(*ab.getInst(BufferOffset(100)), 0xb0bb000cu); // guard branch pc+12.
    CHECK_EQUAL(*ab.getInst(BufferOffset(104)), 0xffff0004u); // header 4 bytes.
    CHECK_EQUAL(*ab.getInst(BufferOffset(108)), 0xdddd0000u); // datum 1.
    CHECK_EQUAL(*ab.getInst(BufferOffset(112)), 0x22220006u);
    CHECK_EQUAL(*ab.getInst(BufferOffset(116)), 0x22220007u);

    return true;
}
END_TEST(testAssemblerBuffer_AssemblerBufferWithConstantPools)

BEGIN_TEST(testAssemblerBuffer_AssemblerBufferWithConstantPools_ShortBranch)
{
    using js::jit::BufferOffset;

    AsmBufWithPool ab(/* guardSize= */ 1,
                      /* headerSize= */ 1,
                      /* instBufferAlign(unused)= */ 0,
                      /* poolMaxOffset= */ 17,
                      /* pcBias= */ 0,
                      /* alignFillInst= */ 0x11110000,
                      /* nopFillInst= */ 0xaaaa0000,
                      /* nopFill= */ 0);

    // Insert short-range branch.
    BufferOffset br1 = ab.putInt(0xb1bb00cc);
    ab.registerBranchDeadline(1, BufferOffset(br1.getOffset() + TestAssembler::BranchRange));
    ab.putInt(0x22220001);
    BufferOffset off = ab.putInt(0x22220002);
    ab.registerBranchDeadline(1, BufferOffset(off.getOffset() + TestAssembler::BranchRange));
    ab.putInt(0x22220003);
    ab.putInt(0x22220004);

    // Second short-range branch that will be swiped up by hysteresis.
    BufferOffset br2 = ab.putInt(0xb1bb0d2d);
    ab.registerBranchDeadline(1, BufferOffset(br2.getOffset() + TestAssembler::BranchRange));

    // Branch should not have been patched yet here.
    CHECK_EQUAL(*ab.getInst(br1), 0xb1bb00cc);
    CHECK_EQUAL(*ab.getInst(br2), 0xb1bb0d2d);

    // Cancel one of the pending branches.
    // This is what will happen to most branches as they are bound before
    // expiring by Assembler::bind().
    ab.unregisterBranchDeadline(1, BufferOffset(off.getOffset() + TestAssembler::BranchRange));

    off = ab.putInt(0x22220006);
    // Here we may or may not have patched the branch yet, but it is inevitable now:
    //
    //  0: br1 pc+36
    //  4: 0x22220001
    //  8: 0x22220002 (unpatched)
    // 12: 0x22220003
    // 16: 0x22220004
    // 20: br2 pc+20
    // 24: 0x22220006
    CHECK_EQUAL(off.getOffset(), 24);
    // 28: guard branch pc+16
    // 32: pool header
    // 36: veneer1
    // 40: veneer2
    // 44: 0x22220007

    off = ab.putInt(0x22220007);
    CHECK_EQUAL(off.getOffset(), 44);

    // Now the branch must have been patched.
    CHECK_EQUAL(*ab.getInst(br1), 0xb3bb0000 + 36);         // br1 pc+36 (patched)
    CHECK_EQUAL(*ab.getInst(BufferOffset(8)), 0x22220002u);  // 0x22220002 (unpatched)
    CHECK_EQUAL(*ab.getInst(br2), 0xb3bb0000 + 20);         // br2 pc+20 (patched)
    CHECK_EQUAL(*ab.getInst(BufferOffset(28)), 0xb0bb0010u); // br pc+16 (guard)
    CHECK_EQUAL(*ab.getInst(BufferOffset(32)), 0xffff0000u); // pool header 0 bytes.
    CHECK_EQUAL(*ab.getInst(BufferOffset(36)), 0xb2bb00ccu); // veneer1 w/ original 'cc' offset.
    CHECK_EQUAL(*ab.getInst(BufferOffset(40)), 0xb2bb0d2du); // veneer2 w/ original 'd2d' offset.
    CHECK_EQUAL(*ab.getInst(BufferOffset(44)), 0x22220007u);

    return true;
}
END_TEST(testAssemblerBuffer_AssemblerBufferWithConstantPools_ShortBranch)

// Test that everything is put together correctly in the ARM64 assembler.
#if defined(JS_CODEGEN_ARM64)

#include "jit/MacroAssembler-inl.h"

BEGIN_TEST(testAssemblerBuffer_ARM64)
{
    using namespace js::jit;

    js::LifoAlloc lifo(4096);
    TempAllocator alloc(&lifo);
    JitContext jc(cx, &alloc);
    rt->getJitRuntime(cx);
    MacroAssembler masm;

    // Branches to an unbound label.
    Label lab1;
    masm.branch(Assembler::Equal, &lab1);
    masm.branch(Assembler::LessThan, &lab1);
    masm.bind(&lab1);
    masm.branch(Assembler::Equal, &lab1);

    CHECK_EQUAL(masm.getInstructionAt(BufferOffset(0))->InstructionBits(),
                vixl::B_cond | vixl::Assembler::ImmCondBranch(2) | vixl::eq);
    CHECK_EQUAL(masm.getInstructionAt(BufferOffset(4))->InstructionBits(),
                vixl::B_cond | vixl::Assembler::ImmCondBranch(1) | vixl::lt);
    CHECK_EQUAL(masm.getInstructionAt(BufferOffset(8))->InstructionBits(),
                vixl::B_cond | vixl::Assembler::ImmCondBranch(0) | vixl::eq);

    // Branches can reach the label, but the linked list of uses needs to be
    // rearranged. The final conditional branch cannot reach the first branch.
    Label lab2a;
    Label lab2b;
    masm.bind(&lab2a);
    masm.B(&lab2b);
    // Generate 1,100,000 bytes of NOPs.
    for (unsigned n = 0; n < 1100000; n += 4)
        masm.Nop();
    masm.branch(Assembler::LessThan, &lab2b);
    masm.bind(&lab2b);
    CHECK_EQUAL(masm.getInstructionAt(BufferOffset(lab2a.offset()))->InstructionBits(),
                vixl::B | vixl::Assembler::ImmUncondBranch(1100000 / 4 + 2));
    CHECK_EQUAL(masm.getInstructionAt(BufferOffset(lab2b.offset() - 4))->InstructionBits(),
                vixl::B_cond | vixl::Assembler::ImmCondBranch(1) | vixl::lt);

    // Generate a conditional branch that can't reach its label.
    Label lab3a;
    Label lab3b;
    masm.bind(&lab3a);
    masm.branch(Assembler::LessThan, &lab3b);
    for (unsigned n = 0; n < 1100000; n += 4)
        masm.Nop();
    masm.bind(&lab3b);
    masm.B(&lab3a);
    Instruction* bcond3 = masm.getInstructionAt(BufferOffset(lab3a.offset()));
    CHECK_EQUAL(bcond3->BranchType(), vixl::CondBranchType);
    ptrdiff_t delta = bcond3->ImmPCRawOffset() * 4;
    Instruction* veneer = masm.getInstructionAt(BufferOffset(lab3a.offset() + delta));
    CHECK_EQUAL(veneer->BranchType(), vixl::UncondBranchType);
    delta += veneer->ImmPCRawOffset() * 4;
    CHECK_EQUAL(delta, lab3b.offset() - lab3a.offset());
    Instruction* b3 = masm.getInstructionAt(BufferOffset(lab3b.offset()));
    CHECK_EQUAL(b3->BranchType(), vixl::UncondBranchType);
    CHECK_EQUAL(4 * b3->ImmPCRawOffset(), -delta);

    return true;
}
END_TEST(testAssemblerBuffer_ARM64)
#endif /* JS_CODEGEN_ARM64 */
