18b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Copyright 2017, VIXL authors
294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// All rights reserved.
394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//
494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Redistribution and use in source and binary forms, with or without
594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// modification, are permitted provided that the following conditions are met:
694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//
794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//   * Redistributions of source code must retain the above copyright notice,
894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//     this list of conditions and the following disclaimer.
994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//   * Redistributions in binary form must reproduce the above copyright notice,
1094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//     this list of conditions and the following disclaimer in the documentation
1194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//     and/or other materials provided with the distribution.
1294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//   * Neither the name of ARM Limited nor the names of its contributors may be
1394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//     used to endorse or promote products derived from this software without
1494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//     specific prior written permission.
1594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois//
1694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
1794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
2094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
2794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#include <cstdio>
2894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#include <iostream>
291bce007699e07bd855b7d194ca93fa5504a73edaPierre Langlois#include <string>
3094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
3194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#include "test-runner.h"
3294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#include "test-utils.h"
3394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#include "aarch32/test-utils-aarch32.h"
3494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
3594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#include "aarch32/disasm-aarch32.h"
361bce007699e07bd855b7d194ca93fa5504a73edaPierre Langlois#include "aarch32/macro-assembler-aarch32.h"
3794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
3894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisnamespace vixl {
3994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisnamespace aarch32 {
4094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
4194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define STRINGIFY(x) #x
4294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
4394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_A32_ONLY
4494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST_T32(Name) \
4594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
4694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#else
4794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Tests declared with this macro will only target T32.
4894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST_T32(Name)                                          \
4994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa);                    \
5094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name() { Test##Name##Impl(T32); }                  \
5194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_T32_##Name), &Test##Name); \
5294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
5394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
5494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
5594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_T32_ONLY
5694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST_A32(Name) \
5794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
5894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#else
5994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Test declared with this macro will only target A32.
6094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST_A32(Name)                                          \
6194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa);                    \
6294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name() { Test##Name##Impl(A32); }                  \
6394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_A32_##Name), &Test##Name); \
6494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
6594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
6694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
6794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Tests declared with this macro will be run twice: once targeting A32 and
6894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// once targeting T32.
6994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#if defined(VIXL_INCLUDE_TARGET_A32_ONLY)
7094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST(Name) TEST_A32(Name)
7194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#elif defined(VIXL_INCLUDE_TARGET_T32_ONLY)
7294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST(Name) TEST_T32(Name)
7394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#else
7494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST(Name)                                              \
7594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa);                    \
7694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name() {                                           \
7794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Test##Name##Impl(A32);                                      \
7894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    printf(" > A32 done\n");                                    \
7994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Test##Name##Impl(T32);                                      \
8094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    printf(" > T32 done\n");                                    \
8194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }                                                             \
8294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_ASM_##Name), &Test##Name); \
8394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
8494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
8594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
8694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Tests declared with this macro are not expected to use any provided test
8794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// helpers such as SETUP, RUN, etc.
8894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define TEST_NOASM(Name)                                    \
8994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name();                                        \
9094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_##Name), &Test##Name); \
9194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void Test##Name()
9294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
9394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define __ masm.
948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#define __TESTOBJ test.
9594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define BUF_SIZE (4096)
9694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
978b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#define CHECK_POOL_SIZE(size)                    \
9894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  do {                                           \
998b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(__TESTOBJ GetPoolSize() == size); \
10094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  } while (false)
10194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
10294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
10394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// No simulator yet.
10494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
1058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#define SETUP()                       \
1068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  MacroAssembler masm(BUF_SIZE, isa); \
1078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  TestMacroAssembler test(&masm);
10894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
10994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define START() masm.GetBuffer()->Reset();
11094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define END() \
11294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Hlt(0);  \
11394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ FinalizeCode();
11494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define RUN() DISASSEMBLE();
11694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#else  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32.
11894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11974d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois#define SETUP()                       \
12074d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  RegisterDump core;                  \
12174d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  MacroAssembler masm(BUF_SIZE, isa); \
1228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  TestMacroAssembler test(&masm);     \
12374d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  UseScratchRegisterScope harness_scratch;
12474d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois
12574d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois#define START()                 \
12674d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  harness_scratch.Open(&masm);  \
12774d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  harness_scratch.ExcludeAll(); \
12874d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  masm.GetBuffer()->Reset();    \
12974d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r4);                  \
13074d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r5);                  \
13174d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r6);                  \
13274d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r7);                  \
13374d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r8);                  \
13474d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r9);                  \
13574d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r10);                 \
13674d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(r11);                 \
13774d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(ip);                  \
13874d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Push(lr);                  \
13974d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Mov(r0, 0);                \
14074d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ Msr(APSR_nzcvq, r0);       \
14135afe7ee222b8cf95c870f9f443491303a941e58Georgia Kouveli  __ Vmsr(FPSCR, r0);           \
14294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  harness_scratch.Include(ip);
14394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
14494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define END()                  \
14594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  harness_scratch.Exclude(ip); \
14694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  core.Dump(&masm);            \
14794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(lr);                  \
14894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(ip);                  \
14994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r11);                 \
15094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r10);                 \
15194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r9);                  \
15294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r8);                  \
15394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r7);                  \
15494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r6);                  \
15594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r5);                  \
15694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pop(r4);                  \
15794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bx(lr);                   \
15874d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  __ FinalizeCode();           \
15974d4ef31746fbfd90118858857502c7006e3e925Pierre Langlois  harness_scratch.Close();
16094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
16194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Execute the generated code from the MacroAssembler's automatic code buffer.
16294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Note the offset for ExecuteMemory since the PCS requires that
16394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// the address be odd in the case of branching to T32 code.
16494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define RUN()                                                 \
16594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  DISASSEMBLE();                                              \
16694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {                                                           \
16794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int pcs_offset = masm.IsUsingT32() ? 1 : 0;               \
16894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.GetBuffer()->SetExecutable();                        \
16994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(), \
17094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                  masm.GetSizeOfCodeGenerated(),              \
17194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                  pcs_offset);                                \
17294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.GetBuffer()->SetWritable();                          \
17394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
17494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
17594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
17694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
17794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
17894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// No simulator yet. We can't test the results.
17994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
18094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_32(expected, result)
18194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
18294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_64(expected, result)
18394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
18494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_128(expected_h, expected_l, result)
18594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
18694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_FP32(expected, result)
18794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
18894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_FP64(expected, result)
18994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
19094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_NZCV(expected)
19194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
19294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#else
19394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
19494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_32(expected, result) \
19594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(Equal32(expected, &core, result))
19694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
19794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_64(expected, result) \
19894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(Equal64(expected, &core, result))
19994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
20094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_128(expected_h, expected_l, result) \
20194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(Equal128(expected_h, expected_l, &core, result))
20294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
20394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_FP32(expected, result) \
20494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(EqualFP32(expected, &core, result))
20594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
20694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_FP64(expected, result) \
20794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(EqualFP64(expected, &core, result))
20894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
20994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ASSERT_EQUAL_NZCV(expected) \
21094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(EqualNzcv(expected, core.flags_nzcv()))
21194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
21294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
21394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
21494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define DISASSEMBLE()                                                          \
21594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (Test::disassemble()) {                                                   \
21694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    PrintDisassembler dis(std::cout, 0);                                       \
21794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingT32()) {                                                   \
21894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      dis.DisassembleT32Buffer(masm.GetBuffer()->GetStartAddress<uint16_t*>(), \
21994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               masm.GetCursorOffset());                        \
22094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    } else {                                                                   \
22194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      dis.DisassembleA32Buffer(masm.GetBuffer()->GetStartAddress<uint32_t*>(), \
22294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               masm.GetCursorOffset());                        \
22394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                          \
22494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
22594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
2268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
22794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// TODO: Add SBC to the ADC tests.
22894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
22994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
23094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(adc_shift) {
23194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
23294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
23394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
23494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Initialize registers.
23594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
23694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 1);
23794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x01234567);
23894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 0xfedcba98);
23994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
24094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
24194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
24294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
24394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r4, r2, r3);
24494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r5, r0, Operand(r1, LSL, 30));
24594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r6, r0, Operand(r2, LSR, 16));
24694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r7, r2, Operand(r3, ASR, 4));
24794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r8, r2, Operand(r3, ROR, 8));
24894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r9, r2, Operand(r3, RRX));
24994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
25094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
25194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
25294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
25394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r4);
25494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(INT32_C(1) << 30, r5);
25594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000123, r6);
25694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01111110, r7);
25794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x9a222221, r8);
25894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x8091a2b3, r9);
25994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
26094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
26194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Initialize registers.
26294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
26394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 1);
26494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x01234567);
26594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 0xfedcba98);
26694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r4, 0xffffffff);
26794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
26894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag.
26994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r4, r1);
27094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
27194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r5, r2, r3);
27294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r6, r0, Operand(r1, LSL, 30));
27394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r7, r0, Operand(r2, LSR, 16));
27494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r8, r2, Operand(r3, ASR, 4));
27594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r9, r2, Operand(r3, ROR, 8));
27694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r10, r2, Operand(r3, RRX));
27794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
27894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
27994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
28094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
28194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffff + 1, r5);
28294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, r6);
28394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000123 + 1, r7);
28494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01111110 + 1, r8);
28594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x9a222221 + 1, r9);
28694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0091a2b3 + 1, r10);
28794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
28894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that adc correctly sets the condition flags.
28994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
29094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
29194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xffffffff);
29294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 1);
29394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
29494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
29594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
29694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, r1);
29794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
29894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
29994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
30094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
30194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
30294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r3);
30394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
30494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
30594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
30694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x80000000);
30794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 1);
30894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
30994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
31094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
31194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, Operand(r1, ASR, 31));
31294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
31394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
31494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
31594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
31694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
31794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r3);
31894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
31994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
32094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
32194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x80000000);
32294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
32394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
32494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
32594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
32694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, Operand(r1, LSR, 31));
32794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
32894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
32994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
33094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
33194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
33294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r3);
33394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
33494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
33594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
33694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x07ffffff);
33794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x10);
33894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
33994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
34094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
34194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, Operand(r1, LSL, 4));
34294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
34394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
34594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NVFlag);
34794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x080000000, r3);
34894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
35094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
35194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xffffff00);
35294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xff000001);
35394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
35494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
35594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
35694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, Operand(r1, ROR, 8));
35794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
35894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
35994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
36094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
36194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
36294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r3);
36394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
36494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
36594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
36694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xffffffff);
36794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x1);
36894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
36994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
37094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
37194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, Operand(r1, RRX));
37294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
37394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
37494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
37594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
37694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NVFlag);
37794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r3);
37894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
37994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
38094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
38194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xffffffff);
38294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x1);
38394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
38494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
38594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r1, r2);
38694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adcs(r3, r2, Operand(r1, RRX));
38794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
38894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
38994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
39094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(CFlag);
39294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1, r3);
39394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
39494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(adc_wide_imm) {
39794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
39894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
40094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
40194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
40294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
40394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
40494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
40594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r1, r0, 0x12345678);
40694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r2, r0, 0xffffffff);
40794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
40894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag.
40994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r0, r0);
41094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
41194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r3, r0, 0x12345678);
41294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adc(r4, r0, 0xffffffff);
41394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
41494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
41594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
41694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
41794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
41894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r2);
41994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678 + 1, r3);
42094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r4);
42194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
42294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
42394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
42494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// TODO: Add SUB tests to the ADD tests.
42594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
42694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
42794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(add_imm) {
42894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
42994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
43094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
43194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
43294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x1111);
43394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
43494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 0x80000000);
43594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
43694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r4, r0, 0x12);
43794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r5, r1, 0x120000);
43894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r6, r0, 0xab << 12);
43994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r7, r2, 1);
44094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
44194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
44294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
44394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
44494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
44594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12, r4);
44694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x121111, r5);
44794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xab000, r6);
44894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0, r7);
44994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
45094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
45194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
45294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(add_wide_imm) {
45394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
45494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
45594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
45694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
45794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 1);
45894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
45994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r2, r0, 0x12345678);
46094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r1, 0xffff);
46194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
46294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
46394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
46494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
46594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
46694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00010000, r3);
46794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
46894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
46994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
47094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(add_shifted) {
47194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
47294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
47394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
47494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
47594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x01234567);
47694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x76543210);
47794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 0xffffffff);
47894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
47994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r4, r1, r2);
48094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r5, r0, Operand(r1, LSL, 8));
48194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r6, r0, Operand(r1, LSR, 8));
48294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r7, r0, Operand(r1, ASR, 8));
48394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r8, r3, Operand(r1, ROR, 8));
48494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
48594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag.
48694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r3, 1);
48794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r9, r3, Operand(r1, RRX));
48894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
48994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
49094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
49194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r10, r3, Operand(r1, RRX));
49294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
49494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
49694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x77777777, r4);
49894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x23456700, r5);
49994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00012345, r6);
50094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00012345, r7);
50194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x67012344, r8);
50294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x8091a2b2, r9);
50394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0091a2b2, r10);
50494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
50594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
50694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
50794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(and_) {
50894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
50994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
51094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
51194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x0000fff0);
51294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
51394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
51494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
51594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r3, r0, r1);
51694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r4, r0, Operand(r1, LSL, 4));
51794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r5, r0, Operand(r1, LSR, 1));
51894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r6, r0, Operand(r1, ASR, 20));
51994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r7, r0, Operand(r1, ROR, 28));
52094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r8, r0, 0xff);
52194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag.
52394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r9, r2, 1);
52494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r9, r1, Operand(r1, RRX));
52594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
52794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r10, r0, 0);
52894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r10, r1, Operand(r1, RRX));
52994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
53094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
53194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
53294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
53394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x000000f0, r3);
53494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000ff0, r4);
53594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000070, r5);
53694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0000ff00, r6);
53794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000ff0, r7);
53894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x000000f0, r8);
53994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xf000007f, r9);
54094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x7000007f, r10);
54194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
54294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
54394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
54494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ands) {
54594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
54694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
54794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
54894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
54994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
55094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
55194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r1, r1);
55294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
55394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
55494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
55594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
55694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
55794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xf00000ff, r0);
55894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
55994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
56094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x00fff000);
56194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
56294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
56394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, Operand(r1, LSL, 4));
56494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
56594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
56694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
56794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
56894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
56994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
57094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
57194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
57294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x0000fff0);
57394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
57494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
57594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, Operand(r1, LSR, 4));
57694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
57794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
57894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
57994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
58094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
58194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
58294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
58394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
58494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xf000fff0);
58594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
58694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
58794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, Operand(r1, ASR, 4));
58894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
58994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
59094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
59194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
59294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
59394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xf0000000, r0);
59494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
59594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
59694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x80000000);
59794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x00000001);
59894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
59994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, Operand(r1, ROR, 1));
60094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
60194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
60294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
60394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
60494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
60594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
60694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
60794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
60894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x80000000);
60994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x80000001);
61094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
61194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
61294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r2, r0, 0);
61394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r2, r0, Operand(r1, RRX));
61494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
61594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
61694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
61794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
61894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
61994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r2);
62094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
62194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
62294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x80000000);
62394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x80000001);
62494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
62594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
62694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
62794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r2, r2, 1);
62894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r2, r0, Operand(r1, RRX));
62994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
63094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
63194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
63294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
63394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
63494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r2);
63594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
63694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
63794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xfff0);
63894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
63994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, 0xf);
64094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
64194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
64294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
64394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
64494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
64594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
64694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
64794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
64894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xff000000);
64994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
65094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, 0x80000000);
65194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
65294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
65394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
65494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
65594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
65694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
65794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
65894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
65994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
66094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(adr_in_range) {
66194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
66294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
66394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label label_1, label_2, label_3, label_4;
66494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
66594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
66694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
66794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    size_t size_of_generated_code;
66894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingA32()) {
66994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      size_of_generated_code = 18 * kA32InstructionSizeInBytes;
67094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    } else {
67194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      size_of_generated_code = 18 * k32BitT32InstructionSizeInBytes +
67294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               3 * k16BitT32InstructionSizeInBytes;
67394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
67494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
67594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             size_of_generated_code,
67694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
67794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
67894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ mov(r0, 0x0);  // Set to zero to indicate success.
67994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r1, &label_3);
68094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
68194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r2, &label_1);  // Multiple forward references to the same label.
68294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r3, &label_1);
68394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r4, &label_1);
68494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
68594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&label_2);
68694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ eor(r5, r2, r3);  // Ensure that r2, r3 and r4 are identical.
68794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ eor(r6, r2, r4);
68894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ orr(r0, r5, r6);
68994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingT32()) {
69094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
69194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // that we are jumping into thumb mode.
69294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ orr(r2, r2, 1);
69394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
69494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bx(r2);  // label_1, label_3
69594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
69694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&label_3);
69794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r2, &label_3);  // Self-reference (offset 0).
69894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ eor(r1, r1, r2);
69994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r2, &label_4);  // Simple forward reference.
70094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingT32()) {
70194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
70294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // that we are jumping into thumb mode.
70394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ orr(r2, r2, 1);
70494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
70594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bx(r2);  // label_4
70694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
70794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&label_1);
70894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r2, &label_3);  // Multiple reverse references to the same label.
70994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r3, &label_3);
71094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r4, &label_3);
71194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r5, &label_2);  // Simple reverse reference.
71294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingT32()) {
71394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
71494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // that we are jumping into thumb mode.
71594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ orr(r5, r5, 1);
71694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
71794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bx(r5);  // label_2
71894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
71994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&label_4);
72094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
72194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
72294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
72394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
72494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
72594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0, r0);
72694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0, r1);
72794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
72894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
72994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
730c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard// Check that we can use adr with any alignement.
731c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent BelliardTEST(adr_unaligned) {
732c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  SETUP();
733c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard
7348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label label_end;
735c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard
736c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  START();
737c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  {
7388b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Location label_0, label_1, label_2, label_3;
739c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    // 5 instructions.
740c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    ExactAssemblyScope scope(&masm,
7418b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             5 * kA32InstructionSizeInBytes + 4,
742c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard                             ExactAssemblyScope::kExactSize);
743c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ adr(Wide, r0, &label_0);
744c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ adr(Wide, r1, &label_1);
745c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ adr(Wide, r2, &label_2);
746c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ adr(Wide, r3, &label_3);
747c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ b(Wide, &label_end);
7488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ bind(&label_0);
749c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ GetBuffer()->EmitData("a", 1);
7508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ bind(&label_1);
751c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ GetBuffer()->EmitData("b", 1);
7528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ bind(&label_2);
753c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ GetBuffer()->EmitData("c", 1);
7548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ bind(&label_3);
755c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ GetBuffer()->EmitData("d", 1);
7568b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
7578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
758c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ Bind(&label_end);
759c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ Ldrb(r0, MemOperand(r0));
760c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ Ldrb(r1, MemOperand(r1));
761c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ Ldrb(r2, MemOperand(r2));
762c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard    __ Ldrb(r3, MemOperand(r3));
763c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  }
764c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  END();
765c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard
766c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  RUN();
767c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard
768c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  ASSERT_EQUAL_32('a', r0);
769c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  ASSERT_EQUAL_32('b', r1);
770c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  ASSERT_EQUAL_32('c', r2);
771c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard  ASSERT_EQUAL_32('d', r3);
772c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard}
773c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard
774c9a1da70cea8c4f28bac34bad9f195c27f095bfaVincent Belliard
77594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(shift_imm) {
77694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
77794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
77894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
77994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
78094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xfedcba98);
78194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
78294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
78394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Lsl(r3, r1, 4);
78494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Lsr(r4, r1, 8);
78594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Asr(r5, r1, 16);
78694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ror(r6, r1, 20);
78794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
78894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
78994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
79094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
79194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xedcba980, r3);
79294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00fedcba, r4);
79394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xfffffedc, r5);
79494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcba98fed, r6);
79594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
79694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
79794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
79894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(shift_reg) {
79994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
80094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
80194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
80294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
80394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xfedcba98);
80494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
80594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
80694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r9, r0, 4);
80794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Lsl(r3, r1, r9);
80894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
80994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r9, r0, 8);
81094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Lsr(r4, r1, r9);
81194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
81294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r9, r0, 16);
81394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Asr(r5, r1, r9);
81494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
81594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r9, r0, 20);
81694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ror(r6, r1, r9);
81794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
81894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag.
81994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r7, r2, 1);
82094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Rrx(r7, r1);
82194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
82294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
82394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r8, r0, 0);
82494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Rrx(r8, r1);
82594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
82694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
82794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
82894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
82994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xedcba980, r3);
83094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00fedcba, r4);
83194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xfffffedc, r5);
83294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcba98fed, r6);
83394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xff6e5d4c, r7);
83494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x7f6e5d4c, r8);
83594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
83694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
83794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
83894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(branch_cond) {
83994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
84094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
84194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label done, wrong;
84294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
84394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
84494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x0);
84594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x1);
84694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x80000000);
84794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use r0 instead of r3 when r0 becomes available.
84894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 0x1);
84994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
85094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // For each 'cmp' instruction below, condition codes other than the ones
85194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // following it would branch.
85294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
85394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r1, 0);
85494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(eq, &wrong);
85594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(lo, &wrong);
85694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(mi, &wrong);
85794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(vs, &wrong);
85894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ls, &wrong);
85994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(lt, &wrong);
86094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(le, &wrong);
86194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label ok_1;
86294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ne, &ok_1);
86394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
86494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r0, 0x0);
86594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&ok_1);
86694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
86794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r1, 1);
86894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ne, &wrong);
86994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(lo, &wrong);
87094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(mi, &wrong);
87194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(vs, &wrong);
87294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(hi, &wrong);
87394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(lt, &wrong);
87494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(gt, &wrong);
87594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label ok_2;
87694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(pl, &ok_2);
87794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
87894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r0, 0x0);
87994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&ok_2);
88094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
88194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r1, 2);
88294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(eq, &wrong);
88394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(hs, &wrong);
88494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(pl, &wrong);
88594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(vs, &wrong);
88694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(hi, &wrong);
88794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ge, &wrong);
88894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(gt, &wrong);
88994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label ok_3;
89094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(vc, &ok_3);
89194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
89294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r0, 0x0);
89394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&ok_3);
89494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
89594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r2, 1);
89694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(eq, &wrong);
89794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(lo, &wrong);
89894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(mi, &wrong);
89994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(vc, &wrong);
90094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ls, &wrong);
90194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ge, &wrong);
90294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(gt, &wrong);
90394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label ok_4;
90494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(le, &ok_4);
90594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
90694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r0, 0x0);
90794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&ok_4);
90894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
90994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label ok_5;
91094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&ok_5);
91194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
91294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r0, 0x0);
91394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&ok_5);
91494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
91594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&done);
91694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
91794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&wrong);
91894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
91994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r3, r0, 0x0);
92094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
92194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&done);
92294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
92394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
92494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
92594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
92694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: Use r0.
92794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x1, r3);
92894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
92994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
93094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
93194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(bfc_bfi) {
93294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
93394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
93494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
93594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xffffffff);
93694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x01234567);
93794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x0);
93894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
93994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bfc(r0, 0, 3);
94094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bfc(r0, 16, 5);
94194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
94294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bfi(r2, r1, 0, 8);
94394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bfi(r2, r1, 16, 16);
94494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
94594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
94694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
94794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
94894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffe0fff8, r0);
94994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x45670067, r2);
95094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
95194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
95294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
95394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(bic) {
95494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
95594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
95694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
95794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xfff0);
95894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
95994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
96094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
96194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r3, r0, r1);
96294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r4, r0, Operand(r1, LSL, 4));
96394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r5, r0, Operand(r1, LSR, 1));
96494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r6, r0, Operand(r1, ASR, 20));
96594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r7, r0, Operand(r1, ROR, 28));
96694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r8, r0, 0x1f);
96794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
96894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag.
96994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r9, r2, 1);
97094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r9, r1, Operand(r1, RRX));
97194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
97294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag.
97394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r10, r0, 0);
97494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r10, r1, Operand(r1, RRX));
97594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
97694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
97794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
97894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
97994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0000ff00, r3);
98094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0000f000, r4);
98194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0000ff80, r5);
98294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x000000f0, r6);
98394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0000f000, r7);
98494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x0000ffe0, r8);
98594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000080, r9);
98694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000080, r10);
98794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
98894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
98994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
99094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(bics) {
99194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
99294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
99394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
99494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
99594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xf00000ff);
99694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
99794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r1, r1);
99894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
99994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
100094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
100194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
100294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
100394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
100494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
100594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
100694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x00fff000);
100794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x0fffff00);
100894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
100994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, Operand(r1, LSL, 4));
101094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
101194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
101294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
101394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
101494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
101594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
101694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
101794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
101894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x0000fff0);
101994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x0fffff00);
102094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
102194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, Operand(r1, LSR, 4));
102294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
102394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
102494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
102594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
102694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
102794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
102894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
102994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
103094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xf000fff0);
103194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x0fffff00);
103294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
103394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, Operand(r1, ASR, 4));
103494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
103594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
103694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
103794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
103894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
103994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xf0000000, r0);
104094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
104194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
104294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x80000000);
104394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xfffffffe);
104494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
104594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, Operand(r1, ROR, 1));
104694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
104794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
104894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
104994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
105094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
105194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
105294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
105394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
105494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x80000000);
105594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x80000001);
105694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
105794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
105894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r2, r0, 0);
105994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r2, r0, Operand(r1, RRX));
106094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
106194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
106294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
106394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
106494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
106594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r2);
106694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
106794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
106894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x80000000);
106994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x80000001);
107094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xffffffff);
107194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
107294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
107394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r2, r2, 1);
107494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r2, r0, Operand(r1, RRX));
107594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
107694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
107794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
107894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
107994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
108094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r2);
108194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
108294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
108394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xf000);
108494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
108594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, 0xf000);
108694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
108794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
108894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
108994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
109094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
109194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
109294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
109394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
109494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xff000000);
109594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
109694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, 0x7fffffff);
109794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
109894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
109994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
110094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
110194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
110294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
110394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
110494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
110594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Make sure calling a macro-assembler instruction will generate literal pools
110694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// if needed.
110794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_pool_generated_by_macro_instruction) {
110894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
110994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
111094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
111194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
111294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start, end;
111394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11148b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
111594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
111694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
111794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
111894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
111994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &end);
112094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
112294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
112394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate enough code so that, after the loop, no instruction can be
112494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // generated before we need to generate the veneer pool.
112594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Use `ExactAssemblyScope` and the assembler to generate the code.
11268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t space = test.GetPoolCheckpoint() - masm.GetCursorOffset();
112794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
112894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
112994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (space > 0) {
113094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
113194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      space -= k16BitT32InstructionSizeInBytes;
113294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
113394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
113494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // We should not have emitted the pool at this point.
11368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
11378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
113894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
113994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Now the pool will need to be generated before we can emit anything.
114094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label check;
114194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&check);
114294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
114394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We should have generated 3 wide instructions:
114494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     b.w past_veneer_pool
114594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     b.w end ;; veneer from CBZ to "end".
114694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   past_veneer_pool:
114794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     mov r0, #0
114894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) ==
114994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois             (3 * k32BitT32InstructionSizeInBytes));
115094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
115194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Branch back to make sure the veneers work.
115294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&start);
115394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
115494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11558b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
115694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
115794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
115894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
115994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
116094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
116194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
116294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
116394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11648b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// NOTE: This test has needed modifications for the new pool manager, as it
11658b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// was testing a corner case of the previous pool managers. We keep it as
11668b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// another testcase.
11678b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST(emit_reused_load_literal) {
116894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
116994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
117094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
117194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
117294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
11738b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
11748b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
117594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
117694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
117794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
117894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  std::string test_string(string_size, 'x');
117994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  StringLiteral big_literal(test_string.c_str());
118094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r4, &big_literal);
118194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
118294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This load has a wider range than the Ldrd used below for the same
118394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // literal.
118494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l1(0xcafebeefdeadbaba);
118594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, &l1);
118694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
11878b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // With the old pool manager, this Ldrd used to force pool emission before
11888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // being generated. Now, 'l1' and 'big_literal' can be reordered in the pool,
11898b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // and pool emission is not triggered anymore.
119094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, &l1);
119194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
119294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
119394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
119494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
119594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
119694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
119794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
119894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r0);
119994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
120094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
120194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x78787878, r4);
120294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
120394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
12048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// NOTE: This test has needed modifications for the new pool manager, as it
12058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// was testing a corner case of the previous pool managers. We keep it as
12068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// another testcase.
120794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_reused_load_literal_should_not_rewind) {
120894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This test checks that we are not conservative when rewinding a load of a
120994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // literal that is already in the literal pool.
121094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
121194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
121294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
121394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
121494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
12158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
12168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
121794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
121894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This load has a wider range than the Ldrd used below for the same
121994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // literal.
122094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l1(0xcafebeefdeadbaba);
122194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, &l1);
122294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
122394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add a large string to the literal pool, but only *after* l1, so the
122494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Ldrd below should not need to rewind.
122594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
122694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
122794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  std::string test_string(string_size, 'x');
122894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  StringLiteral big_literal(test_string.c_str());
122994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r4, &big_literal);
123094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, &l1);
123194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
12328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Here we used to check the pool size, which can now be zero as we emit the
12338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // literals in a different order.
123494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
123594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is emitted.
12368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
12378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
123894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
123994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
124094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
124194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
124294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
124394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
124494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
124594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r0);
124694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
124794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
124894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x78787878, r4);
124994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
125094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
125194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
125294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisvoid EmitReusedLoadLiteralStressTest(InstructionSet isa, bool conditional) {
125394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This test stresses loading a literal that is already in the literal pool,
12548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // for various positionings on the existing load from that literal. We try to
12558b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // exercise cases where the two loads result in similar checkpoints for the
12568b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // literal pool.
125794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
125894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
125994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
126094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldr_range = 4095;
126194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int nop_size = masm.IsUsingA32() ? 4 : 2;
126294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int nops = (ldr_range - ldrd_range) / nop_size;
126394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
126494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int n = nops - 10; n < nops + 10; ++n) {
126594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    START();
126694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
126794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Make sure the pool is empty.
12688b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
12698b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
127094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
127194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (conditional) {
127294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Mov(r1, 0);
127394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Cmp(r1, 0);
127494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
127594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
12768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // Add a large string to the pool, which will stress corner cases with the
12778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // Ldrd below (if the pool is not already emitted due to the Ldr).
127894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
127994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    std::string test_string(string_size, 'x');
128094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    StringLiteral big_literal(test_string.c_str());
128194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldr(r4, &big_literal);
128294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
128394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // This load has a wider range than the Ldrd used below for the same
128494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // literal.
128594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Literal<uint64_t> l1(0xcafebeefdeadbaba);
128694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldr(r0, &l1);
128794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
128894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate nops, in order to bring the checkpoints of the Ldr and Ldrd
128994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // closer.
129094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {
129194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm,
129294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               n * nop_size,
129394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               ExactAssemblyScope::kExactSize);
129494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (int i = 0; i < n; ++i) {
129594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ nop();
129694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
129794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
129894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
129994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (conditional) {
130094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Ldrd(eq, r2, r3, &l1);
130194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    } else {
130294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Ldrd(r2, r3, &l1);
130394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
13048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
13058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // Here we used to check that the pool is empty. Since the new pool manager
13068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // allows reordering of literals in the pool, this will not always be the
13078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // case. 'l1' can now be emitted before 'big_literal', allowing the pool to
13088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // be emitted after the ldrd when the number of nops is small enough.
130994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
131094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    END();
131194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
131294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    RUN();
131394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
131494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Check that the literals loaded correctly.
131594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0xdeadbaba, r0);
131694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0xdeadbaba, r2);
131794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0xcafebeef, r3);
131894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0x78787878, r4);
131994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
132094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
132194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
132294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
132394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_reused_load_literal_stress) {
132494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitReusedLoadLiteralStressTest(isa, false /*conditional*/);
132594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
132694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
132794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
132894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_reused_conditional_load_literal_stress) {
132994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitReusedLoadLiteralStressTest(isa, true /*conditional*/);
133094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
133194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
133294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
133394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(test_many_loads_from_same_literal) {
133494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This test generates multiple loads from the same literal in order to
133594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // test that the delegate recursion limit is appropriate for Ldrd with
133694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // large negative offsets.
133794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
133894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
133994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
134094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
134194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
13428b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
13438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
134494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
134594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l0(0xcafebeefdeadbaba);
134694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, &l0);
134794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < 10000; ++i) {
134894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Add(r2, r2, i);
134994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldrd(r4, r5, &l0);
135094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
135194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
135294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, &l0);
135394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
135494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
135594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
135694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
135794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
135894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
135994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r0);
136094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r1);
136194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
136294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
136394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r4);
136494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r5);
136594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
136694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
136794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
136894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Make sure calling a macro-assembler instruction will generate literal pools
136994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// if needed.
137094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(literal_pool_generated_by_macro_instruction) {
137194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
137294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
137394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
137494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
13758b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
137694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
137794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
137894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
13798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
138094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
138194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate enough code so that, after the loop, no instruction can be
138294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // generated before we need to generate the literal pool.
138394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Use `ExactAssemblyScope` and the assembler to generate the code.
13848b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t space = test.GetPoolCheckpoint() - masm.GetCursorOffset();
138594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
138694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
138794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (space > 0) {
138894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
138994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      space -= k16BitT32InstructionSizeInBytes;
139094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
139194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
139294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
139394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We should not have emitted the literal pool at this point.
13948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
13958b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
139694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
139794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Now the pool will need to be generated before we emit anything.
139894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label check;
139994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&check);
140094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0x12345678);
140194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We should have generated 3 wide instructions and 8 bytes of data:
140294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     b.w past_literal_pool
140394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     .bytes 0x1234567890abcdef
140494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   past_literal_pool:
140594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     mov r2, #22136
140694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //     movt r2, #4660
140794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) ==
140894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois             (3 * k32BitT32InstructionSizeInBytes + 8));
140994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
14108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
141194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
141294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
141394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
141494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
141594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
141694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
141794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
141894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
141994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
142094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
142194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_single_literal) {
142294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
142394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
142494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
142594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
14268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
14278b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
142894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
142994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create one literal pool entry.
143094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
14318b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(8);
143294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s0, 1.0);
143394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d1, 2.0);
143494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmov(d2, 4.1);
143594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmov(s8, 8.2);
14368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(20);
143794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
143894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
143994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
144094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
144194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
144294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
144394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
144494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(1.0f, s0);
144594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(2.0, d1);
144694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(4.1, d2);
144794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(8.2f, s8);
144894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
144994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
145094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
145194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef __
14528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#undef __TESTOBJ
145394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define __ masm->
14548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#define __TESTOBJ test->
145594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
145694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
14578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouvelivoid EmitLdrdLiteralTest(MacroAssembler* masm, TestMacroAssembler* test) {
145894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = masm->IsUsingA32() ? 255 : 1020;
145994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We want to emit code up to the maximum literal load range and ensure the
146094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // pool has not been emitted. Compute the limit (end).
146194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ptrdiff_t end = AlignDown(
146294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Align down the PC to 4 bytes as the instruction does when it's
146394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // executed.
146494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // The PC will be the cursor offset plus the architecture state PC
146594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // offset.
146694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      AlignDown(masm->GetBuffer()->GetCursorOffset() +
146794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                    masm->GetArchitectureStatePCOffset(),
146894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                4) +
146994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          // Maximum range allowed to access the constant.
147094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          ldrd_range -
14718b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli          // Take into account the branch over the pool.
14728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli          kMaxInstructionSizeInBytes,
147394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // AlignDown to 4 byte as the literals will be 4 byte aligned.
147494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      4);
147594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
147694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create one literal pool entry.
147794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
14788b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(8);
147994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
14808b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = test->GetPoolCheckpoint() - masm->GetCursorOffset();
14818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_ASSERT(end == test->GetPoolCheckpoint());
148294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
148394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(masm, margin, ExactAssemblyScope::kExactSize);
148494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Opening the scope should not have triggered the emission of the literal
148594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // pool.
14868b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(!test->PoolIsEmpty());
148794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm->GetCursorOffset() < end) {
148894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
148994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
149094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm->GetCursorOffset() == end);
149194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
149294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
149394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the pool has not been emited along the way.
14948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(8);
149594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This extra instruction should trigger an emit of the pool.
149694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
149794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The pool should have been emitted.
14988b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test->PoolIsEmpty());
149994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
150094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
150194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef __
15028b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#undef __TESTOBJ
150394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define __ masm.
15048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#define __TESTOBJ test.
150594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
15068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// NOTE: This test has needed modifications for the new pool manager, as it
15078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// was testing a corner case of the previous pool managers. We keep it as
15088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// another testcase.
150994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_literal_rewind) {
151094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
151194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
151294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
151394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
151494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
15158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
15168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
151794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
15188b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitLdrdLiteralTest(&masm, &test);
151994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
152094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
152194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
152294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  std::string test_string(string_size, 'x');
152394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  StringLiteral big_literal(test_string.c_str());
152494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r4, &big_literal);
152594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, 0xcafebeefdeadbaba);
15268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // With the old pool manager, the adr above would overflow the literal pool
15278b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // and force a rewind and pool emission.
15288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Here we used to check the pool size to confirm that 'big_literal' had
15298b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // already been emitted. This does not have to be the case now, as we can
15308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // emit the literals in a different order.
15318b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
15328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
15338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
153494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
153594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
153694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
153794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
153894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
153994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
154094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
154194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
154294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
154394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
154494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x78787878, r4);
154594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
154694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
15478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
15488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// NOTE: This test has needed modifications for the new pool manager, as it
15498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// was testing a corner case of the previous pool managers. We keep it as
15508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// another testcase.
155194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_literal_conditional_rewind) {
155294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
155394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
155494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
155594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
155694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This test is almost identical to the test above, but the Ldrd instruction
155794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // is conditional and there is a second conditional Ldrd instruction that will
15588b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // not be executed.
155994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
156094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
15618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
15628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
156394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
156494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
156594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
156694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  std::string test_string(string_size, 'x');
156794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  StringLiteral big_literal(test_string.c_str());
156894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r2, &big_literal);
156994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
157094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0);
157194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 1);
157294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r3, 1);
157394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
157494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
15758b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // With the old pool manager, the adr above would overflow the literal pool
15768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // and force a rewind and pool emission.
15778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Here we used to check the pool size to confirm that 'big_literal' had
15788b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // already been emitted. This does not have to be the case now, as we can
15798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // emit the literals in a different order.
15808b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
15818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
15828b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
158394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r2, MemOperand(r2));  // Load the first 4 characters in r2.
158494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
158594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
158694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
158794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
158894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
158994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r0);
159094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r1);
159194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x78787878, r2);
159294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
159394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
159494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisenum LiteralStressTestMode {
159594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  kUnconditional,
159694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  kConditionalTrue,
159794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  kConditionalFalse,
159894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  kConditionalBoth
159994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois};
160094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
160194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Test loading a literal when the size of the literal pool is close to the
160294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// maximum range of the load, with varying PC values (and alignment, for T32).
160394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// This test is similar to the tests above, with the difference that we allow
160494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// an extra offset to the string size in order to make sure that various pool
160594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// sizes close to the maximum supported offset will produce code that executes
16068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// correctly. As the Ldrd might or might not be emitted before the pool, we do
16078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// not assert on the size of the literal pool in this test.
160894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisvoid EmitLdrdLiteralStressTest(InstructionSet isa,
160994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               bool unaligned,
161094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               LiteralStressTestMode test_mode) {
161194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
161294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
161394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int offset = -10; offset <= 10; ++offset) {
161494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    START();
161594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
161694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (unaligned) {
161794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Nop();
161894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
161994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
162094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
162194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Make sure the pool is empty.
16228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
16238b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
162494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
162594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
162694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int string_size = ldrd_range + offset;
162794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    std::string test_string(string_size - 1, 'x');
162894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    StringLiteral big_literal(test_string.c_str());
162994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Adr(r2, &big_literal);
163094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r0, 0);
163194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r1, 0);
163294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    switch (test_mode) {
163394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      case kUnconditional:
163494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Ldrd(r0, r1, 0xcafebeefdeadbaba);
163594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        break;
163694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      case kConditionalTrue:
163794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r0, 0xffffffff);
163894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r1, r0);
163994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r3, 1);
164094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Cmp(r3, 1);
164194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
164294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        break;
164394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      case kConditionalFalse:
164494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r0, 0xdeadbaba);
164594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r1, 0xcafebeef);
164694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r3, 1);
164794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Cmp(r3, 1);
164894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
164994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        break;
165094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      case kConditionalBoth:
165194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r3, 1);
165294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Cmp(r3, 1);
165394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
165494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
165594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        break;
165694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
165794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
16588b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
16598b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
166094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldr(r2, MemOperand(r2));  // Load the first 4 characters in r2.
166194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    END();
166294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
166394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    RUN();
166494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
166594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Check that the literals loaded correctly.
166694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0xdeadbaba, r0);
166794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0xcafebeef, r1);
166894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0x78787878, r2);
166994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
167094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
167194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
167294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
16738b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST(emit_literal_stress) {
167494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kUnconditional);
167594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
167694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
167794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
16788b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_T32(emit_literal_stress_unaligned) {
167994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kUnconditional);
168094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
168194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
168294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
16838b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST(emit_literal_conditional_stress) {
168494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalTrue);
168594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalFalse);
168694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalBoth);
168794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
168894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
168994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
16908b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_T32(emit_literal_conditional_stress_unaligned) {
169194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalTrue);
169294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalFalse);
169394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalBoth);
169494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
169594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
169694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(emit_literal_unaligned) {
169794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
169894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
169994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
170094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
170194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
17028b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
17038b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
170494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
170594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate a nop to break the 4 bytes alignment.
170694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
170794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
17088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitLdrdLiteralTest(&masm, &test);
170994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
171094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
171194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
171294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
171394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
171494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
171594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
171694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
171794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
171894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
171994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(literal_multiple_uses) {
172094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
172194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
172294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
172394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int32_t> lit(42);
172494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, &lit);
17258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(4);
172694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
172794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Multiple uses of the same literal object should not make the
172894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // pool grow.
172994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r1, &lit);
173094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r2, &lit);
173194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r3, &lit);
173294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r4, &lit);
17338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(4);
173494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
173594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
173694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
173794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
173894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
173994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r0);
174094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r1);
174194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r2);
174294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r3);
174394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r4);
174494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
174594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
174694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
174794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// A test with two loads literal which go out of range at the same time.
174894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_A32(ldr_literal_range_same_time) {
174994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
175094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
175194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
175294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_range = 255;
175394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We need to take into account the jump over the pool.
175494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldrd_padding = ldrd_range - 2 * kA32InstructionSizeInBytes;
175594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldr_range = 4095;
175694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We need to take into account the ldrd padding and the ldrd instruction.
175794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int ldr_padding =
175894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ldr_range - ldrd_padding - 2 * kA32InstructionSizeInBytes;
175994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
176094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, 0x12121212);
17618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(4);
176294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
176394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
176494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int space = AlignDown(ldr_padding, kA32InstructionSizeInBytes);
176594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
176694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int32_t end = masm.GetCursorOffset() + space;
176794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm.GetCursorOffset() < end) {
176894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
176994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
177094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
177194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
177294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, 0x1234567890abcdef);
17738b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(12);
177494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
177594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
177694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int space = AlignDown(ldrd_padding, kA32InstructionSizeInBytes);
177794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
177894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t end = masm.GetCursorOffset() + space;
177994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         masm.GetCursorOffset() < end;) {
178094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
178194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
178294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
17838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(12);
178494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
178594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This mov will put the two loads literal out of range and will force
178694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // the literal pool emission.
178794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
17888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
178994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
179094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
179194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
179294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
179394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12121212, r1);
179494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r2);
179594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r3);
179694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
179794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
179894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
179994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldr_literal_mix_types) {
180094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
180194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
180294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
180394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l0(0x1234567890abcdef);
180494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int32_t> l1(0x12345678);
180594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint16_t> l2(1234);
180694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int16_t> l3(-678);
180794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint8_t> l4(42);
180894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int8_t> l5(-12);
180994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
181094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, &l0);
181194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r2, &l1);
181294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r3, &l2);
181394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r4, &l3);
181494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r5, &l4);
181594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r6, &l5);
18168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // The pool size does not include padding.
18178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(18);
181894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
181994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
182094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
182194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
182294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
182394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
182494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
182594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
182694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1234, r3);
182794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-678, r4);
182894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r5);
182994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-12, r6);
183094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
183194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
183294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
183394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldr_literal_conditional) {
183494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
183594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
183694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
183794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l0(0x1234567890abcdef);
183894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l0_not_taken(0x90abcdef12345678);
183994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int32_t> l1(0x12345678);
184094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int32_t> l1_not_taken(0x56781234);
184194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint16_t> l2(1234);
184294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint16_t> l2_not_taken(3412);
184394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int16_t> l3(-678);
184494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int16_t> l3_not_taken(678);
184594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint8_t> l4(42);
184694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint8_t> l4_not_taken(-42);
184794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int8_t> l5(-12);
184894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int8_t> l5_not_taken(12);
184994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<float> l6(1.2345f);
185094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<float> l6_not_taken(0.0f);
185194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<double> l7(1.3333);
185294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<double> l7_not_taken(0.0);
185394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
185494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that conditionally loading literals of different types works
185594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // correctly for both A32 and T32.
185694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r7, 1);
185794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r7, 1);
185894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(eq, r0, r1, &l0);
185994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(ne, r0, r1, &l0_not_taken);
186094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r7, 0);
186194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(gt, r2, &l1);
186294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(le, r2, &l1_not_taken);
186394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r7, 2);
186494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(lt, r3, &l2);
186594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(ge, r3, &l2_not_taken);
186694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(le, r4, &l3);
186794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(gt, r4, &l3_not_taken);
186894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r7, 1);
186994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(ge, r5, &l4);
187094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(lt, r5, &l4_not_taken);
187194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(eq, r6, &l5);
187294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(ne, r6, &l5_not_taken);
187394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(Condition(eq), s0, &l6);
187494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(Condition(ne), s0, &l6_not_taken);
187594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(Condition(eq), d1, &l7);
187694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(Condition(ne), d1, &l7_not_taken);
187794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
187894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
187994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
188094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
188194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
188294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
188394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
188494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
188594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1234, r3);
188694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-678, r4);
188794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r5);
188894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-12, r6);
188994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(1.2345f, s0);
189094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(1.3333, d1);
189194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
189294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
189394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
189494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisstruct LdrLiteralRangeTest {
189594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  void (MacroAssembler::*instruction)(Register, RawLiteral*);
189694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Register result_reg;
189794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int a32_range;
189894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int t32_range;
189994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t literal_value;
190094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t test_value;
190194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois};
190294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
190394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
190494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisconst LdrLiteralRangeTest kLdrLiteralRangeTestData[] =
190594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {{&MacroAssembler::Ldr, r1, 4095, 4095, 0x12345678, 0x12345678},
190694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois     {&MacroAssembler::Ldrh, r2, 255, 4095, 0xabcdefff, 0x0000efff},
190794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois     {&MacroAssembler::Ldrsh, r3, 255, 4095, 0x00008765, 0xffff8765},
190894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois     {&MacroAssembler::Ldrb, r4, 4095, 4095, 0x12345678, 0x00000078},
190994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois     {&MacroAssembler::Ldrsb, r5, 255, 4095, 0x00000087, 0xffffff87}};
191094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
191194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
191294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisvoid GenerateLdrLiteralTriggerPoolEmission(InstructionSet isa,
191394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                           bool unaligned_ldr) {
191494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
191594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
191694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
19178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
191894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
191994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    START();
192094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
192194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (unaligned_ldr) {
192294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Generate a nop to break the 4-byte alignment.
192394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Nop();
192494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
192594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
192694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
192794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldr(r6, 0x12345678);
19288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    CHECK_POOL_SIZE(4);
192994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
193094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // TODO: The MacroAssembler currently checks for more space than required
193194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // when emitting macro instructions, triggering emission of the pool before
193294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // absolutely required. For now we keep a buffer. Fix this test when the
193394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // MacroAssembler becomes precise again.
193494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int masm_check_margin = 10 * kMaxInstructionSizeInBytes;
19358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    int expected_pool_size = 4;
19368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    while ((test.GetPoolCheckpoint() - masm.GetCursorOffset() -
19378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli            masm_check_margin) >=
193894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois           static_cast<int32_t>(kMaxInstructionSizeInBytes)) {
193994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Ldr(r7, 0x90abcdef);
194094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Each ldr instruction will force a new literal value to be added
194194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // to the pool. Check that the literal pool grows accordingly.
194294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      expected_pool_size += 4;
19438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      CHECK_POOL_SIZE(expected_pool_size);
194494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
194594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
19468b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    int space = test.GetPoolCheckpoint() - masm.GetCursorOffset();
194794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int end = masm.GetCursorOffset() + space;
194894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {
194994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Generate nops precisely to fill the buffer.
195094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope accurate_scope(&masm, space);  // This should not
195194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                                        // trigger emission of
195294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                                        // the pool.
19538b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      VIXL_CHECK(!test.PoolIsEmpty());
195494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      while (masm.GetCursorOffset() < end) {
195594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ nop();
195694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
195794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
195894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
195994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // This ldr will force the literal pool to be emitted before emitting
196094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // the load and will create a new pool for the new literal used by this ldr.
19618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(!test.PoolIsEmpty());
19628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Literal<uint32_t> literal(test_case.literal_value);
19638b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    (masm.*test_case.instruction)(test_case.result_reg, &literal);
19648b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    CHECK_POOL_SIZE(4);
196594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
196694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    END();
196794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
196894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    RUN();
196994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
197094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0x12345678, r6);
197194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ASSERT_EQUAL_32(0x90abcdef, r7);
19728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ASSERT_EQUAL_32(test_case.test_value, test_case.result_reg);
197394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
197494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
197594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
197694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
197794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldr_literal_trigger_pool_emission) {
197894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  GenerateLdrLiteralTriggerPoolEmission(isa, false);
197994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
198094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
198194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
198294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(ldr_literal_trigger_pool_emission_unaligned) {
198394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  GenerateLdrLiteralTriggerPoolEmission(isa, true);
198494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
198594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
198694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisvoid GenerateLdrLiteralRangeTest(InstructionSet isa, bool unaligned_ldr) {
198794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
198894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
198994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
19908b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
199194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
199294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    START();
199394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
199494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Make sure the pool is empty.
19958b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
19968b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
199794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
199894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (unaligned_ldr) {
199994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Generate a nop to break the 4-byte alignment.
200094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Nop();
200194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
200294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
200394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
20048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Literal<uint32_t> literal(test_case.literal_value);
20058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    (masm.*test_case.instruction)(test_case.result_reg, &literal);
20068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    CHECK_POOL_SIZE(4);
200794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
200894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate enough instruction so that we go out of range for the load
200994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // literal we just emitted.
20108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ptrdiff_t end =
20118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli        masm.GetBuffer()->GetCursorOffset() +
20128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli        ((masm.IsUsingA32()) ? test_case.a32_range : test_case.t32_range);
201394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm.GetBuffer()->GetCursorOffset() < end) {
201494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Mov(r0, 0);
201594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
201694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
201794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // The literal pool should have been emitted now.
201894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(literal.IsBound());
20198b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
202094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
202194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    END();
202294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
202394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    RUN();
202494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
20258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ASSERT_EQUAL_32(test_case.test_value, test_case.result_reg);
202694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
202794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
202894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
202994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
203094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldr_literal_range) { GenerateLdrLiteralRangeTest(isa, false); }
203194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
203294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
203394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(ldr_literal_range_unaligned) {
203494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  GenerateLdrLiteralRangeTest(isa, true);
203594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
203694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
203794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
203894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(string_literal) {
203994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
204094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
204194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
204294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
20438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
20448b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
204594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
204694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  StringLiteral hello_string("hello");
204794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
204894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r1, &hello_string);
204994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
205094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r0, &hello_string);
205194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, MemOperand(r0));
205294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
205394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
205494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
205594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
205694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32('h', r1);
205794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32('h', r2);
205894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
205994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
206094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
206194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(custom_literal_in_pool) {
206294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
206394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
206494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
206594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
20668b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
20678b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
206894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
206994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint32_t> l0(static_cast<uint32_t>(0x12345678));
207094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, &l0);
20718b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
207294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, &l0);
20738b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
207494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
207594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> cafebeefdeadbaba(0xcafebeefdeadbaba);
207694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r8, r9, &cafebeefdeadbaba);
20778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
207894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, &cafebeefdeadbaba);
20798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
208094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
208194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint32_t> l1(0x09abcdef);
208294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r4, &l1);
208394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r4, MemOperand(r4));
208494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.EmitLiteralPool();
208594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r5, &l1);
208694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r5, MemOperand(r5));
20878b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
208894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
208994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
209094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
209194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
209294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
209394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
209494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r0);
209594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
209694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
209794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
209894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r8);
209994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r9);
210094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r4);
210194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r5);
210294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
210394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
210494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
210594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(custom_literal_place) {
210694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
210794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
210894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
210994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
21108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
21118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
211294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
211394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
211494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int32_t> l1(0x12345678, RawLiteral::kManuallyPlaced);
211594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint16_t> l2(4567, RawLiteral::kManuallyPlaced);
211694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int16_t> l3(-4567, RawLiteral::kManuallyPlaced);
211794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint8_t> l4(123, RawLiteral::kManuallyPlaced);
211894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int8_t> l5(-123, RawLiteral::kManuallyPlaced);
211994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
212094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, &l0);
212194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r2, &l1);
212294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r3, &l2);
212394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r4, &l3);
212494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r5, &l4);
212594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r6, &l5);
212694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
21278b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
212894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
212994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Manually generate a literal pool.
213094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label after_pool;
213194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&after_pool);
213294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Place(&l0);
213394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Place(&l1);
213494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Place(&l2);
213594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Place(&l3);
213694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Place(&l4);
213794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Place(&l5);
213894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&after_pool);
213994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
214094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
214194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    UseScratchRegisterScope temps(&masm);
214294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Register temp = temps.Acquire();
214394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temp.Is(r12));
214494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
214594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldrd(r8, r9, &l0);
214694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldr(r7, &l1);
214794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldrh(r10, &l2);
214894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldrsh(r11, &l3);
214994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldrb(temp, &l4);
215094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // We don't use any function call so we can use lr as an extra register.
215194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldrsb(lr, &l5);
215294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
215394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
21548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
215594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
215694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
215794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
215894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
215994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
216094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
216194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r0);
216294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r1);
216394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
216494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(4567, r3);
216594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-4567, r4);
216694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(123, r5);
216794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-123, r6);
216894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
216994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r8);
217094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r9);
217194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r7);
217294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(4567, r10);
217394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-4567, r11);
217494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(123, r12);
217594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(-123, lr);
217694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
217794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
217894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
217994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(custom_literal_place_shared) {
218094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
218194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
218294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
21838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
218494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
218594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    START();
218694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
218794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Make sure the pool is empty.
21888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
21898b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
219094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
21918b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Literal<uint32_t> before(test_case.literal_value,
21928b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             RawLiteral::kManuallyPlaced);
21938b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Literal<uint32_t> after(test_case.literal_value,
21948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                            RawLiteral::kManuallyPlaced);
219594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
219694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(!before.IsBound());
219794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(!after.IsBound());
219894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
219994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Manually generate a pool.
220094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label end_of_pool_before;
220194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&end_of_pool_before);
220294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Place(&before);
220394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&end_of_pool_before);
220494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
22058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
220694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(before.IsBound());
220794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(!after.IsBound());
220894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
220994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Load the entries several times to test that literals can be shared.
221094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < 20; i++) {
22118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      (masm.*test_case.instruction)(r0, &before);
22128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      (masm.*test_case.instruction)(r1, &after);
221394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
221494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
22158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
221694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(before.IsBound());
221794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(!after.IsBound());
221894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
221994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Manually generate a pool.
222094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label end_of_pool_after;
222194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&end_of_pool_after);
222294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Place(&after);
222394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&end_of_pool_after);
222494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
22258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(test.PoolIsEmpty());
222694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(before.IsBound());
222794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(after.IsBound());
222894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
222994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    END();
223094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
223194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    RUN();
223294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
22338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ASSERT_EQUAL_32(test_case.test_value, r0);
22348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ASSERT_EQUAL_32(test_case.test_value, r1);
223594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
223694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
223794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
223894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
223994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(custom_literal_place_range) {
224094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
224194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
224294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
22438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
224494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int nop_size = masm.IsUsingA32() ? kA32InstructionSizeInBytes
224594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                           : k16BitT32InstructionSizeInBytes;
22468b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    const int range =
22478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli        masm.IsUsingA32() ? test_case.a32_range : test_case.t32_range;
224894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // On T32 the PC will be 4-byte aligned to compute the range. The
224994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // MacroAssembler might also need to align the code buffer before emitting
225094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // the literal when placing it. We keep a margin to account for this.
225194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int margin = masm.IsUsingT32() ? 4 : 0;
225294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
225394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Take PC offset into account and make sure the literal is in the range.
225494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int padding_before =
225594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        range - masm.GetArchitectureStatePCOffset() - sizeof(uint32_t) - margin;
225694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
225794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // The margin computation below is correct because the ranges are not
225894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // 4-byte aligned. Otherwise this test would insert the exact number of
225994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // instructions to cover the range and the literal would end up being
226094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // placed outside the range.
226194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT((range % 4) != 0);
226294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
226394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // The range is extended by the PC offset but we need to consider the ldr
226494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // instruction itself and the branch over the pool.
226594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int padding_after = range + masm.GetArchitectureStatePCOffset() -
226694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                              (2 * kMaxInstructionSizeInBytes) - margin;
226794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    START();
226894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
22698b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Literal<uint32_t> before(test_case.literal_value,
22708b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             RawLiteral::kManuallyPlaced);
22718b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    Literal<uint32_t> after(test_case.literal_value,
22728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                            RawLiteral::kManuallyPlaced);
227394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
227494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label test_start;
227594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&test_start);
227694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Place(&before);
227794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
227894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {
227994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      int space = AlignDown(padding_before, nop_size);
228094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
228194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (int32_t end = masm.GetCursorOffset() + space;
228294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois           masm.GetCursorOffset() < end;) {
228394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ nop();
228494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
228594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
228694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
228794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&test_start);
22888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    (masm.*test_case.instruction)(r0, &before);
22898b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    (masm.*test_case.instruction)(r1, &after);
229094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
229194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {
229294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      int space = AlignDown(padding_after, nop_size);
229394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
229494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (int32_t end = masm.GetCursorOffset() + space;
229594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois           masm.GetCursorOffset() < end;) {
229694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ nop();
229794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
229894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
229994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
230094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label after_pool;
230194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&after_pool);
230294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Place(&after);
230394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&after_pool);
230494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
230594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    END();
230694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
230794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    RUN();
230894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
23098b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ASSERT_EQUAL_32(test_case.test_value, r0);
23108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ASSERT_EQUAL_32(test_case.test_value, r1);
231194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
231294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
231394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
231494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
231594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(emit_big_pool) {
231694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
231794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
231894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
231994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
23208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
232194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
232294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
232394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
232494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 1000; i > 0; --i) {
232594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Ldr(r0, i);
232694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
232794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
232894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&start) == 4000);
232994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
23308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(4000);
233194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
233294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
233394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
233494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
233594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
233694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1, r0);
233794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
233894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
233994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
234094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(too_far_cbz) {
234194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
234294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
234394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
234494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
234594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label end;
234694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label exit;
234794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
234894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&start);
234994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
235094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
235194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&exit);
235294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
235394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Cbz is only defined for forward jump. Check that it will work (substituted
235494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // by Cbnz/B).
235594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &end);
235694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&exit);
235794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
235894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
235994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
236094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
236194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1, r0);
236294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
236394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
236494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
236594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(close_cbz) {
236694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
236794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
236894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
236994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label first;
237094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label second;
237194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
237294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0);
237394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0);
237494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &first);
237594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&first);
237694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 1);
237794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbnz(r0, &second);
237894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&second);
237994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 2);
238094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
238194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
238294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
238394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
238494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
238594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1, r1);
238694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(2, r2);
238794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
238894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
238994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
239094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(close_cbz2) {
239194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
239294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
239394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
239494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label first;
239594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label second;
239694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
239794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0);
239894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0);
239994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r0, 0);
240094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ne, &first);
240194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(gt, &second);
240294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &first);
240394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&first);
240494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 1);
240594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbnz(r0, &second);
240694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&second);
240794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 2);
240894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
240994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
241094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
241194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
241294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
241394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(1, r1);
241494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(2, r2);
241594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
241694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
241794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
241894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(not_close_cbz) {
241994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
242094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
242194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
242294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label first;
242394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label second;
242494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &first);
242594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ne, &first);
242694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&first);
242794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbnz(r0, &second);
242894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(gt, &second);
242994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&second);
243094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
243194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
243294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
243394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
243494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
243594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
243694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneers) {
243794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
243894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
243994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
244094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label zero;
244194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label exit;
244294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
244394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create one literal pool entry.
244494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, 0x12345678);
24458b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(4);
244694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &zero);
244794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
244894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&exit);
244994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 32; i > 0; i--) {
245094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r1, 0);
245194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
24528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Assert that the pool contains only the two veneers.
24538b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kVeneerSize = 4;
24548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(2 * kVeneerSize);
245594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&zero);
245694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 2);
245794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&exit);
245894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
245994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
246094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
246194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
246294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(2, r0);
246394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
246494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
246594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
246694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
246794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// This test checks that veneers are sorted. If not, the test failed as the
246894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// veneer for "exit" is emitted before the veneer for "zero" and the "zero"
246994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// veneer is out of range for Cbz.
247094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneers_labels_sort) {
247194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
247294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
247394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
247494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
247594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label zero;
247694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label exit;
247794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Movs(r0, 0);
247894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ne, &exit);
247994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&start);
248094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 1048400; i > 0; i -= 4) {
248194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r1, 0);
248294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
248394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
248494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &zero);
248594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
248694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&exit);
248794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 32; i > 0; i--) {
248894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r1, 0);
248994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
249094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&zero);
249194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 2);
249294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&exit);
249394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
249494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
249594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
249694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
249794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(2, r0);
249894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
249994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
250094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that a label bound within the assembler is effectively removed from
250194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// the veneer pool.
250294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_bind) {
250394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
2504b815212d28120f65e1e808faadfc503e89a45990Pierre Langlois  START();
2505b815212d28120f65e1e808faadfc503e89a45990Pierre Langlois
250694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label target;
250794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &target);
250894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
250994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
251094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
251194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Bind the target label using the `Assembler`.
251294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
251394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kMaxInstructionSizeInBytes,
251494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kMaximumSize);
251594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&target);
251694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ nop();
251794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
251894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
251994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(target.IsBound());
25208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
252194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
252294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
252394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
252494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
252594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
252694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that the veneer pool is correctly emitted even if we do enough narrow
252794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// branches before a cbz so that the cbz needs its veneer emitted first in the
252894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// pool in order to work.
252994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_narrow_and_cbz_sort) {
253094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
253194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
253294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
253394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int kLabelsCount = 40;
253494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int kNops = 30;
253594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label b_labels[kLabelsCount];
253694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label cbz_label;
253794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
253894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
253994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
254094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
254194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r0, 0);
254294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
254394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; ++i) {
254494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(ne, &b_labels[i], kNear);
254594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
254694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
254794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
254894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
254994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes * kNops,
255094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
255194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < kNops; i++) {
255294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
255394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
255494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
255594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
255694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The pool should not be emitted here.
255794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &cbz_label);
255894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
255994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Force pool emission. If the labels are not sorted, the cbz will be out
256094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // of range.
25618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = test.GetPoolCheckpoint();
25628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = end - masm.GetCursorOffset();
256394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
256494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
256594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
256694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm.GetCursorOffset() < end) {
256794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
256894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
256994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
257094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
257194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
257294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
257394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; ++i) {
257494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&b_labels[i]);
257594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
257694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
257794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&cbz_label);
257894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
257994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
258094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
258194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
258294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
258394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
258494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
258594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
258694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
258794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_narrow_and_cbz_sort_2) {
258894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
258994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
259094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
259194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int kLabelsCount = 40;
259294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int kNops = 30;
259394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label b_labels[kLabelsCount];
259494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label cbz_label;
259594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
259694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
259794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r0, 0);
259894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
259994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; ++i) {
260094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(ne, &b_labels[i], kNear);
260194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
260294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
260394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
260494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
260594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes * kNops,
260694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
260794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < kNops; i++) {
260894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
260994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
261094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
261194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
261294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The pool should not be emitted here.
261394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &cbz_label);
261494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
261594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Force pool emission. If the labels are not sorted, the cbz will be out
261694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // of range.
26178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = test.GetPoolCheckpoint();
261894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
261994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  while (masm.GetCursorOffset() < end) __ Nop();
262094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
262194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
262294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
262394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; ++i) {
262494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&b_labels[i]);
262594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
262694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
262794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&cbz_label);
262894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
262994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
263094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
263194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
263294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
263394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
263494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
263594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
263694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
263794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(long_branch) {
263894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
263994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
264094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
264194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int label_count = 128; label_count < 2048; label_count *= 2) {
264294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label* l = new Label[label_count];
264394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
264494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < label_count; i++) {
264594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ B(&l[i]);
264694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
264794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
264894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < label_count; i++) {
264994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ B(ne, &l[i]);
265094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
265194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
265294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < 261625; i++) {
265394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Clz(r0, r0);
265494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
265594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
265694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = label_count - 1; i >= 0; i--) {
265794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Bind(&l[i]);
265894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Nop();
265994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
266094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
266194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    delete[] l;
266294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
266394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
266494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.FinalizeCode();
266594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
266694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
266794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
266894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
266994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
267094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
267194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(unaligned_branch_after_literal) {
267294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
267394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
267494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
267594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
267694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This test manually places a 32-bit literal after a 16-bit branch
267794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // which branches over the literal to an unaligned PC.
267894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<int32_t> l0(0x01234567, RawLiteral::kManuallyPlaced);
267994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
268094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, &l0);
26818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
268294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
26838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
26848b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
268594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
268694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Manually generate a literal pool.
268794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
268894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label after_pool;
268994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
269094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes + sizeof(int32_t),
269194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             CodeBufferCheckScope::kMaximumSize);
269294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ b(Narrow, &after_pool);
269394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ place(&l0);
269494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
269594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&after_pool);
269694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
269794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
26988b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
269994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
270094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
270194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
270294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
270394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
270494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literal was loaded correctly.
270594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01234567, r0);
270694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
270794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
270894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
270994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// This test check that we can update a Literal after usage.
271094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(literal_update) {
271194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
271294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
271394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
271494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label exit;
271594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint32_t>* a32 =
271694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint32_t>(0xabcdef01, RawLiteral::kDeletedOnPoolDestruction);
271794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* a64 =
271894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0xabcdef01abcdef01),
271994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
272094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, a32);
272194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, a64);
272294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ EmitLiteralPool();
272394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint32_t>* b32 =
272494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint32_t>(0x10fedcba, RawLiteral::kDeletedOnPoolDestruction);
272594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* b64 =
272694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x10fedcba10fedcba),
272794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
272894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, b32);
272994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r4, r5, b64);
273094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Update literals' values. "a32" and "a64" are already emitted. "b32" and
273194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // "b64" will only be emitted when "END()" will be called.
273294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  a32->UpdateValue(0x12345678, masm.GetBuffer());
273394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  a64->UpdateValue(UINT64_C(0x13579bdf02468ace), masm.GetBuffer());
273494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  b32->UpdateValue(0x87654321, masm.GetBuffer());
273594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  b64->UpdateValue(UINT64_C(0x1032547698badcfe), masm.GetBuffer());
273694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
273794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
273894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
273994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
274094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r0);
274194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x87654321, r1);
274294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x02468ace, r2);
274394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x13579bdf, r3);
274494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x98badcfe, r4);
274594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x10325476, r5);
274694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
274794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
274894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
274994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(claim_peek_poke) {
275094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
275194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
275294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
275394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
275494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
275594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
275694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Claim(0);
275794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Drop(0);
275894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK((masm.GetCursorOffset() - start.GetLocation()) == 0);
275994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
276094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Claim(32);
276194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, 0xcafe0000);
276294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, 0xcafe0001);
276394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r2, 0xcafe0002);
276494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Poke(r0, 0);
276594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Poke(r1, 4);
276694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Poke(r2, 8);
276794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Peek(r2, 0);
276894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Peek(r0, 4);
276994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Peek(r1, 8);
277094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Drop(32);
277194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
277294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
277394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
277494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
277594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
277694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafe0001, r0);
277794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafe0002, r1);
277894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafe0000, r2);
277994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
278094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
278194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
278294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(msr_i) {
278394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
278494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
278594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
278694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xdead);
278794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xdead);
278894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r2, 0xdead);
278994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 0xb);
279094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Msr(APSR_nzcvqg, 0);
279194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mrs(r0, APSR);
279294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Msr(APSR_nzcvqg, 0xffffffff);
279394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mrs(r1, APSR);
279494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Only modify nzcvq => keep previous g.
279594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Lsl(r4, r3, 28);
279694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Msr(APSR_nzcvq, r4);
279794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mrs(r2, APSR);
279894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
279994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
280094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
280194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
280294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x10, r0);
280394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xf80f0010, r1);
280494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xb00f0010, r2);
280594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
280694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
280794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
280807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent BelliardTEST(vcmp_s) {
280907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  SETUP();
281007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
281107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  START();
281207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
281307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(s0, 1.0);
281407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(s1, 2.0);
281507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(s2, 0.0);
281607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
28173fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  __ Vcmp(F32, s0, s1);
281807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
281907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
282007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmp(F32, s0, 0.0f);
282107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
282207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
282307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmp(F32, s2, 0.0f);
282407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
282507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
282607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  END();
282707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
282807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  RUN();
282907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
28303fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // N is for less than.
28313fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(NFlag, r0);
28323fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // C is for greater than.
28333fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(CFlag, r1);
28343fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // ZC is for equal.
28353fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(ZCFlag, r2);
283607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard}
283707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
283807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
283907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent BelliardTEST(vcmp_d) {
284007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  SETUP();
284107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
284207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  START();
284307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
284407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(d0, 1.0);
284507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(d1, 2.0);
284607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(d2, 0.0);
284707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
28483fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  __ Vcmp(F64, d0, d1);
284907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
285007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
285107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmp(F64, d0, 0.0);
285207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
285307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
285407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmp(F64, d2, 0.0);
285507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
285607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
285707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  END();
285807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
285907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  RUN();
286007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
28613fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // N is for less than.
28623fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(NFlag, r0);
28633fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // C is for greater than.
28643fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(CFlag, r1);
28653fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // ZC is for equal.
28663fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(ZCFlag, r2);
286707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard}
286807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
286907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
287007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent BelliardTEST(vcmpe_s) {
287107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  SETUP();
287207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
287307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  START();
287407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
287507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(s0, 1.0);
287607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(s1, 2.0);
287707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(s2, 0.0);
287807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
28793fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  __ Vcmpe(F32, s0, s1);
288007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
288107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
288207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmpe(F32, s0, 0.0f);
288307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
288407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
288507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmpe(F32, s2, 0.0f);
288607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
288707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
288807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  END();
288907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
289007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  RUN();
289107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
28923fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // N is for less than.
28933fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(NFlag, r0);
28943fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // C is for greater than.
28953fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(CFlag, r1);
28963fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // ZC is for equal.
28973fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(ZCFlag, r2);
289807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard}
289907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
290007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
290107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent BelliardTEST(vcmpe_d) {
290207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  SETUP();
290307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
290407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  START();
290507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
290607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(d0, 1.0);
290707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(d1, 2.0);
290807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmov(d2, 0.0);
290907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
29103fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  __ Vcmpe(F64, d0, d1);
291107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
291207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
291307f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmpe(F64, d0, 0.0);
291407f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
291507f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
291607f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vcmpe(F64, d2, 0.0);
291707f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
291807f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
291907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  END();
292007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
292107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard  RUN();
292207f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
29233fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // N is for less than.
29243fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(NFlag, r0);
29253fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // C is for greater than.
29263fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(CFlag, r1);
29273fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  // ZC is for equal.
29283fab627d900c0bc5056c07df260e14f6eb155584Pierre Langlois  ASSERT_EQUAL_32(ZCFlag, r2);
292907f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard}
293007f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
293107f9e742691f10b7ff8b0107415eb94e157c2b33Vincent Belliard
293294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(vmrs_vmsr) {
293394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
293494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
293594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
293694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Move some value to FPSCR and get them back to test vmsr/vmrs instructions.
293794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x2a000000);
293894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmsr(FPSCR, r0);
293994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
294094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
294194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x5a000000);
294294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmsr(FPSCR, r0);
294394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
294494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
294594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Move to APSR_nzcv.
294694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR);
294794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mrs(r3, APSR);
294894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r3, r3, 0xf0000000);
294994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
295094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
295194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
295294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
295394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
295494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x2a000000, r1);
295594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x5a000000, r2);
295694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x50000000, r3);
295794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
295894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
295994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
296094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(printf) {
296194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
296294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
296394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
296494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xb00e0000);
296594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Msr(APSR_nzcvqg, r0);
296694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, sp);
296794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Printf("sp=%x\n", r0);
296894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //  __ Printf("Hello world!\n");
296994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x1234);
297094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x5678);
297194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  StringLiteral literal("extra string");
297294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adr(r2, &literal);
297394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r3, 5);
297494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r4, 0xdead4444);
297594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r5, 0xdead5555);
297694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r6, 0xdead6666);
297794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r7, 0xdead7777);
297894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r8, 0xdead8888);
297994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r9, 0xdead9999);
298094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r10, 0xdeadaaaa);
298194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r11, 0xdeadbbbb);
298294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d0, 1.2345);
298394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d1, 2.9876);
298494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s4, 1.3333);
298594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s5, 3.21);
298694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d3, 3.333);
298794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d4, 4.444);
298894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d5, 5.555);
298994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d6, 6.666);
299094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d7, 7.777);
299194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d8, 8.888);
299294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d9, 9.999);
299394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d10, 10.000);
299494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d11, 11.111);
299594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d12, 12.222);
299694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d13, 13.333);
299794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d14, 14.444);
299894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d15, 15.555);
299994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d16, 16.666);
300094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d17, 17.777);
300194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d18, 18.888);
300294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d19, 19.999);
300394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d20, 20.000);
300494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d21, 21.111);
300594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d22, 22.222);
300694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d23, 23.333);
300794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d24, 24.444);
300894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d25, 25.555);
300994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d26, 26.666);
301094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d27, 27.777);
301194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d28, 28.888);
301294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d29, 29.999);
301394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d30, 30.000);
301494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d31, 31.111);
301594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
301694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    UseScratchRegisterScope temps(&masm);
301794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // For effective use as an inspection tool, Printf must work without any
301894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // scratch registers.
301994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(r12.Is(temps.Acquire()));
302094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r12, 0xdeadcccc);
302194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm.GetScratchRegisterList()->IsEmpty());
302294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
302394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("%% r0=%x r1=%x str=<%.*s>\n", r0, r1, r3, r2);
302494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("r0=%d r1=%d str=<%s>\n", r0, r1, r2);
302594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("d0=%g\n", d0);
302694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("s4=%g\n", s4);
302794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("d0=%g d1=%g s4=%g s5=%g\n", d0, d1, s4, s5);
302894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("d0=%g r0=%x s4=%g r1=%x\n", d0, r0, s4, r1);
302994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("r0=%x d0=%g r1=%x s4=%g\n", r0, d0, r1, s4);
303094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r0, sp);
303194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Printf("sp=%x\n", r0);
303294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mrs(r0, APSR);
303394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Only keep R/W fields.
303494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Mov(r2, 0xf80f0200);
303594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ And(r0, r0, r2);
303694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
303794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
303894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
303994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
304094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
304194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xb00e0000, r0);
304294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x5678, r1);
304394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(5, r3);
304494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdead4444, r4);
304594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdead5555, r5);
304694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdead6666, r6);
304794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdead7777, r7);
304894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdead8888, r8);
304994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdead9999, r9);
305094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadaaaa, r10);
305194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbbbb, r11);
305294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadcccc, r12);
305394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(1.2345, d0);
305494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(2.9876, d1);
305594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(1.3333, s4);
305694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(3.21, s5);
305794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(4.444, d4);
305894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(5.555, d5);
305994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(6.666, d6);
306094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(7.777, d7);
306194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(8.888, d8);
306294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(9.999, d9);
306394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(10.000, d10);
306494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(11.111, d11);
306594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(12.222, d12);
306694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(13.333, d13);
306794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(14.444, d14);
306894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(15.555, d15);
306994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(16.666, d16);
307094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(17.777, d17);
307194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(18.888, d18);
307294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(19.999, d19);
307394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(20.000, d20);
307494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(21.111, d21);
307594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(22.222, d22);
307694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(23.333, d23);
307794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(24.444, d24);
307894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(25.555, d25);
307994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(26.666, d26);
308094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(27.777, d27);
308194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(28.888, d28);
308294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(29.999, d29);
308394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(30.000, d30);
308494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(31.111, d31);
308594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
308694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
308794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(printf2) {
308894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
308994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
309094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
309194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x1234);
309294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0x5678);
309394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d0, 1.2345);
309494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s2, 2.9876);
309594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Printf("d0=%g d1=%g r0=%x r1=%x\n", d0, s2, r0, r1);
309694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
309794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
309894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
309994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
310094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
310194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
310294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloistemplate <typename T>
310394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisvoid CheckInstructionSetA32(const T& assm) {
310494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(assm.IsUsingA32());
310594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(!assm.IsUsingT32());
310694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(assm.GetInstructionSetInUse() == A32);
310794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
310894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
310994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
311094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloistemplate <typename T>
311194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langloisvoid CheckInstructionSetT32(const T& assm) {
311294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(assm.IsUsingT32());
311394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(!assm.IsUsingA32());
311494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(assm.GetInstructionSetInUse() == T32);
311594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
311694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
311794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
311894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_NOASM(set_isa_constructors) {
311994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  byte buffer[1024];
312094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
312194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifndef VIXL_INCLUDE_TARGET_T32_ONLY
312294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // A32 by default.
312394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(Assembler());
312494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(Assembler(1024));
312594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(Assembler(buffer, sizeof(buffer)));
312694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
312794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(MacroAssembler());
312894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(MacroAssembler(1024));
312994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer)));
313094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#else
313194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // T32 by default.
313294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(Assembler());
313394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(Assembler(1024));
313494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(Assembler(buffer, sizeof(buffer)));
313594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
313694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(MacroAssembler());
313794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(MacroAssembler(1024));
313894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer)));
313994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
314094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
314194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_A32
314294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Explicit A32.
314394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(Assembler(A32));
314494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(Assembler(1024, A32));
314594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(Assembler(buffer, sizeof(buffer), A32));
314694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
314794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(MacroAssembler(A32));
314894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(MacroAssembler(1024, A32));
314994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer), A32));
315094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
315194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
315294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_T32
315394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Explicit T32.
315494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(Assembler(T32));
315594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(Assembler(1024, T32));
315694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(Assembler(buffer, sizeof(buffer), T32));
315794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
315894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(MacroAssembler(T32));
315994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(MacroAssembler(1024, T32));
316094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer), T32));
316194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
316294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
316394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
316494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
316594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_NOASM(set_isa_empty) {
316694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// It is possible to change the instruction set if no instructions have yet
316794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// been generated. This test only makes sense when both A32 and T32 are
316894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// supported.
316994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_AARCH32
317094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Assembler assm;
317194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(assm);
317294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  assm.UseT32();
317394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(assm);
317494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  assm.UseA32();
317594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(assm);
317694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  assm.UseInstructionSet(T32);
317794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(assm);
317894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  assm.UseInstructionSet(A32);
317994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(assm);
318094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
318194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  MacroAssembler masm;
318294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(masm);
318394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.UseT32();
318494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(masm);
318594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.UseA32();
318694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(masm);
318794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.UseInstructionSet(T32);
318894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetT32(masm);
318994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.UseInstructionSet(A32);
319094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CheckInstructionSetA32(masm);
319194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
319294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
319394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
319494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
319594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_NOASM(set_isa_noop) {
319694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// It is possible to call a no-op UseA32/T32 or UseInstructionSet even if
319794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// one or more instructions have been generated.
319894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_A32
319994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
320094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Assembler assm(A32);
320194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(assm);
320294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
320394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.bx(lr);
320494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(assm.GetCursorOffset() > 0);
320594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(assm);
320694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.UseA32();
320794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(assm);
320894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.UseInstructionSet(A32);
320994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(assm);
321094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.FinalizeCode();
321194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
321294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
321394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    MacroAssembler masm(A32);
321494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(masm);
321594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.Bx(lr);
321694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm.GetCursorOffset() > 0);
321794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(masm);
321894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.UseA32();
321994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(masm);
322094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.UseInstructionSet(A32);
322194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetA32(masm);
322294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.FinalizeCode();
322394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
322494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
322594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
322694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_T32
322794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
322894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Assembler assm(T32);
322994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(assm);
323094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
323194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.bx(lr);
323294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(assm.GetCursorOffset() > 0);
323394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(assm);
323494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.UseT32();
323594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(assm);
323694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.UseInstructionSet(T32);
323794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(assm);
323894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    assm.FinalizeCode();
323994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
324094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
324194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    MacroAssembler masm(T32);
324294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(masm);
324394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.Bx(lr);
324494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm.GetCursorOffset() > 0);
324594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(masm);
324694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.UseT32();
324794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(masm);
324894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.UseInstructionSet(T32);
324994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    CheckInstructionSetT32(masm);
325094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm.FinalizeCode();
325194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
325294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
325394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
325494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
325594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
325694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(logical_arithmetic_identities) {
325794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
325894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
325994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
326094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
326194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_1;
326294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_1);
326394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(r0, r0, 0);
326494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, 0xffffffff);
326594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r0, r0, 0);
326694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Eor(r0, r0, 0);
326794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Orn(r0, r0, 0xffffffff);
326894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Orr(r0, r0, 0);
326994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Sub(r0, r0, 0);
327094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_1) == 0);
327194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
327294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_2;
327394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_2);
327494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Adds(r0, r0, 0);
327594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_2) != 0);
327694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
327794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_3;
327894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_3);
327994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ands(r0, r0, 0);
328094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_3) != 0);
328194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
328294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_4;
328394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_4);
328494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bics(r0, r0, 0);
328594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_4) != 0);
328694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
328794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_5;
328894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_5);
328994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Eors(r0, r0, 0);
329094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_5) != 0);
329194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
329294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_6;
329394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_6);
329494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Orns(r0, r0, 0);
329594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_6) != 0);
329694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
329794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_7;
329894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_7);
329994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Orrs(r0, r0, 0);
330094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_7) != 0);
330194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
330294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label blob_8;
330394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&blob_8);
330494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Subs(r0, r0, 0);
330594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_8) != 0);
330694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
330794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xbad);
330894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r1, r0, 0);
330994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bic(r2, r0, 0xffffffff);
331094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Eor(r3, r0, 0xffffffff);
331194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Orn(r4, r0, 0);
331294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Orr(r5, r0, 0xffffffff);
331394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
331494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
331594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
331694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
331794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
331894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xbad, r0);
331994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r1);
332094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r2);
332194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(~0xbad, r3);
332294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r4);
332394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r5);
332494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
332594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
332694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
332794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(scratch_register_checks) {
332894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // It is unsafe for users to use registers that the MacroAssembler is also
332994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // using as scratch registers. This test checks the MacroAssembler's checking
333094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // mechanism itself.
333194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
333294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
333394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
333494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    UseScratchRegisterScope temps(&masm);
333594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // 'ip' is a scratch register by default.
333694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm.GetScratchRegisterList()->GetList() ==
333794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois               (1u << ip.GetCode()));
333894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(ip));
333994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
334094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Integer registers have no complicated aliasing so
334194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // masm.AliasesAvailableScratchRegister(reg) == temps.IsAvailable(reg).
334294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (unsigned i = 0; i < kNumberOfRegisters; i++) {
334394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      Register reg(i);
334494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      VIXL_CHECK(masm.AliasesAvailableScratchRegister(reg) ==
334594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                 temps.IsAvailable(reg));
334694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
334794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
334894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
334994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
335094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
335194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
335294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(scratch_register_checks_v) {
335394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // It is unsafe for users to use registers that the MacroAssembler is also
335494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // using as scratch registers. This test checks the MacroAssembler's checking
335594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // mechanism itself.
335694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
335794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
335894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    UseScratchRegisterScope temps(&masm);
335994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // There is no default floating-point scratch register. Add temps of various
336094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // sizes to check handling of aliased registers.
336194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() == 0);
336294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(q15);
336394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(d15);
336494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(s15);
336594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(d4);
336694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(d5);
336794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(s24);
336894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(s25);
336994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(s26);
337094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(s27);
337194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(q0);
337294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // See VRegisterList for details of the list encoding.
337394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() ==
337494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois               UINT64_C(0xf0000000cf008f0f));
337594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //                    |       ||  || |
337694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //                   q15    d15|  || q0
337794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //                        s24-s27 |d4-d5
337894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //                               s15
337994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
338094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Simple checks: Included registers are available.
338194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(q15));
338294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(d15));
338394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(s15));
338494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(d4));
338594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(d5));
338694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(s24));
338794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(s25));
338894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(s26));
338994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(s27));
339094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(temps.IsAvailable(q0));
339194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
339294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Each available S register should mark the corresponding D and Q registers
339394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // as aliasing an available scratch register.
339494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (unsigned s = 0; s < kNumberOfSRegisters; s++) {
339594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      if (temps.IsAvailable(SRegister(s))) {
339694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(masm.AliasesAvailableScratchRegister(SRegister(s)));
339794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(s / 2)));
339894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(s / 4)));
339994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      } else {
340094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // AliasesAvailableScratchRegiters == IsAvailable for S registers.
340194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(!masm.AliasesAvailableScratchRegister(SRegister(s)));
340294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
340394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
340494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
340594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Similar checks for high D registers.
340694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    unsigned first_high_d_register = kNumberOfSRegisters / 2;
340794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (unsigned d = first_high_d_register; d < kMaxNumberOfDRegisters; d++) {
340894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      if (temps.IsAvailable(DRegister(d))) {
340994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(d)));
341094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(d / 2)));
341194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      } else {
341294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // AliasesAvailableScratchRegiters == IsAvailable for high D registers.
341394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        VIXL_CHECK(!masm.AliasesAvailableScratchRegister(DRegister(d)));
341494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
341594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
341694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
341794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
341894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
341994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
342094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(nop) {
342194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
342294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
342394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
342494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
342594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
342694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  size_t nop_size = (isa == T32) ? k16BitT32InstructionSizeInBytes
342794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                 : kA32InstructionSizeInBytes;
342894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // `MacroAssembler::Nop` must generate at least one nop.
342994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) >= nop_size);
343094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
343194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.FinalizeCode();
343294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
343394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Check that `GetPoolCheckpoint()` is precise.
343594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(literal_pool_margin) {
343694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
343794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
343894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
343994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34408b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
344194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
344294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create a single literal.
344394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
344494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34458b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
344694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
344794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate code to fill all the margin we have before generating the literal
344894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // pool.
34498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
34508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = test.GetPoolCheckpoint();
345194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
345294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
345394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Opening the scope should not have triggered the emission of the literal
345494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // pool.
34558b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(!test.PoolIsEmpty());
345694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm.GetCursorOffset() < end) {
345794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
345894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
345994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm.GetCursorOffset() == end);
346094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
346194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
346294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // There should be no margin left to emit the literal pool.
34638b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
34648b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
346594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
346694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // So emitting a single instruction should force emission of the pool.
346794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
34688b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
346994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
347094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
347194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
347294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
347394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
347494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
347594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
347694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
347794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
347894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Check that `GetPoolCheckpoint()` is precise.
348094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(veneer_pool_margin) {
348194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
348294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
348394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
348494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34858b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
348694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
348794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create a single veneer.
348894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label target;
348994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(eq, &target);
349094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
34918b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
349294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
349394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate code to fill all the margin we have before generating the veneer
349494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // pool.
34958b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
34968b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = test.GetPoolCheckpoint();
349794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
349894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
349994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Opening the scope should not have triggered the emission of the veneer
350094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // pool.
35018b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    VIXL_CHECK(!test.PoolIsEmpty());
350294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm.GetCursorOffset() < end) {
350394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
350494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
350594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(masm.GetCursorOffset() == end);
350694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
350794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // There should be no margin left to emit the veneer pool.
35088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
350994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
351094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // So emitting a single instruction should force emission of the pool.
351194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We cannot simply check that the veneer pool is empty, because the veneer
351294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // emitted for the CBZ instruction above is itself tracked by the veneer
351394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // mechanisms. Instead, check that some 'unexpected' code is generated.
351494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label check;
351594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&check);
351694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
351794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
351894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Do not actually generate any code.
351994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
352094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) > 0);
352194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&target);
35228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
352394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
352494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
352594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
352694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
352794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
352894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
352994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(near_branch_fuzz) {
353094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
353194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
353294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
353394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint16_t seed[3] = {1, 2, 3};
353494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  seed48(seed);
353594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
353694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int label_count = 31;
353794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  bool allbound;
353894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label* l;
353994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
354094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Use multiple iterations, as each produces a different predictably random
354194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // sequence.
354294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int iterations = 64;
354394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
354494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int loop_count = 0;
354594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0);
354694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
354794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Initialise the status flags to Z set.
354894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cmp(r1, r1);
354994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
355094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Gradually increasing the number of cases effectively increases the
355194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // probability of nops being emitted in the sequence. The branch-to-bind
355294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // ratio in the sequence is fixed at 4:1 by the ratio of cases.
355394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int case_count = 6; case_count < 37; case_count++) {
355494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int iter = 0; iter < iterations; iter++) {
355594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Reset local state.
355694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      allbound = false;
355794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      l = new Label[label_count];
355894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
355994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Set r0 != 0 to force no branches to be taken. Also acts as a marker
356094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // between each iteration in the disassembly.
356194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Mov(r0, 1);
356294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
356394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (;;) {
356494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        uint32_t inst_case = static_cast<uint32_t>(mrand48()) % case_count;
356594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        uint32_t label_index = static_cast<uint32_t>(mrand48()) % label_count;
356694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
356794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        switch (inst_case) {
356894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          case 0:  // Bind.
356994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            if (!l[label_index].IsBound()) {
357094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&l[label_index]);
357194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
357294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              // We should hit each label exactly once (because the branches are
357394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              // never taken). Keep a counter to verify this.
357494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              loop_count++;
357594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Add(r1, r1, 1);
357694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
357794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            break;
357894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          case 1:  // Compare and branch if zero (untaken as r0 == 1).
357994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ Cbz(r0, &l[label_index]);
358094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            break;
358194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          case 2: {  // Compare and branch if not zero.
358294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            Label past_branch;
358394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ B(eq, &past_branch, kNear);
358494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ Cbnz(r0, &l[label_index]);
358594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ Bind(&past_branch);
358694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            break;
358794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          }
358894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          case 3: {  // Unconditional branch preferred near.
358994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            Label past_branch;
359094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ B(eq, &past_branch, kNear);
359194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ B(&l[label_index], kNear);
359294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ Bind(&past_branch);
359394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            break;
359494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          }
359594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          case 4:  // Conditional branch (untaken as Z set) preferred near.
359694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ B(ne, &l[label_index], kNear);
359794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            break;
359894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          default:  // Nop.
359994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            __ Nop();
360094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            break;
360194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        }
360294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
360394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // If all labels have been bound, exit the inner loop and finalise the
360494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // code.
360594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        allbound = true;
360694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        for (int i = 0; i < label_count; i++) {
360794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          allbound = allbound && l[i].IsBound();
360894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        }
360994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        if (allbound) break;
361094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
361194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
361294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // Ensure that the veneer pools are emitted, to keep each branch/bind test
361394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // independent. We will generate more code following this.
361494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      masm.FinalizeCode(MacroAssembler::kFallThrough);
361594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      delete[] l;
361694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
361794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
361894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
361994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
362094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
362194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
362294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(loop_count, r1);
362394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
362494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
362594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
362694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(near_branch_and_literal_fuzz) {
362794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
362894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
362994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
363094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint16_t seed[3] = {1, 2, 3};
363194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  seed48(seed);
363294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
363394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int label_count = 15;
363494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int literal_count = 31;
363594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  bool allbound;
363694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label* labels;
363794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint64_t* literal_values;
363894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literals[literal_count];
363994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
364094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Use multiple iterations, as each produces a different predictably random
364194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // sequence.
364294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int iterations = 128;
364394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int n_cases = 20;
364494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
364594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int loop_count = 0;
364694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0);
364794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
364894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // If the value of r4 changes then the test fails.
364994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r4, 42);
365094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
365194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This test generates a mix of 20 different code sequences (see switch case
365294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // below). The cases are split in 4 groups:
365394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //
365494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - 0..3: Generate various amount of nops.
365594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - 4..7: Generate various load intstructions with literals.
365694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - 8..14: Generate various branch instructions.
365794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - 15..19: Generate various amount of nops.
365894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //
365994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The idea behind this is that we can have a window of size N which we can
366094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // slide across these cases. And as a result, randomly generate sequences with
366194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // a different ratio of:
366294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - "nops vs literals"
366394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - "literal vs veneers"
366494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //   - "veneers vs nops"
366594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //
366694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // In this test, we grow a window from 5 to 14, and then slide this window
366794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // across all cases each time. We call this sliding a "ratio", which is in
366894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // fact an offset from the first case of the switch.
366994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
367094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (uint32_t window = 5; window < 14; window++) {
367194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (uint32_t ratio = 0; ratio < static_cast<uint32_t>(n_cases - window);
367294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         ratio++) {
367394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (int iter = 0; iter < iterations; iter++) {
367494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        Label fail;
367594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        Label end;
367694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
367794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // Reset local state.
367894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        allbound = false;
367994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        labels = new Label[label_count];
368094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
368194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // Create new literal values.
368294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        literal_values = new uint64_t[literal_count];
368394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        for (int lit = 0; lit < literal_count; lit++) {
368494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          // TODO: Generate pseudo-random data for literals. At the moment, the
368594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          // disassembler breaks if we do this.
368694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          literal_values[lit] = lit;
368794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          literals[lit] = new Literal<uint64_t>(literal_values[lit]);
368894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        }
368994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
369094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        for (;;) {
369194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          uint32_t inst_case =
369294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              (static_cast<uint32_t>(mrand48()) % window) + ratio;
369394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          uint32_t label_index = static_cast<uint32_t>(mrand48()) % label_count;
369494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          uint32_t literal_index =
369594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              static_cast<uint32_t>(mrand48()) % literal_count;
369694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
369794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          if (inst_case == ratio) {
369894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            if (!labels[label_index].IsBound()) {
369994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&labels[label_index]);
370094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
370194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              // We should hit each label exactly once (because the branches are
370294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              // never taken). Keep a counter to verify this.
370394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              loop_count++;
370494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Add(r1, r1, 1);
370594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              continue;
370694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
370794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          }
370894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
370994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          switch (inst_case) {
371094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 0:
371194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
371294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
371394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 1:
371494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
371594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
371694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
371794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
371894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
371994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
372494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 2:
372594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
372894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
372994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 3:
373094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
373794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
373894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 4:
373994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Ldr(r2, literals[literal_index]);
374094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Cmp(r2, static_cast<uint32_t>(literal_values[literal_index]));
374194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &fail);
374294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Mov(r2, 0);
374394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
374494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 5:
374594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Ldrb(r2, literals[literal_index]);
374694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Cmp(r2,
374794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     static_cast<uint32_t>(literal_values[literal_index]) &
374894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                         0xff);
374994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &fail);
375094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Mov(r2, 0);
375194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
375294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 6:
375394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Ldrd(r2, r3, literals[literal_index]);
375494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Cmp(r2, static_cast<uint32_t>(literal_values[literal_index]));
375594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &fail);
375694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Mov(r2, 0);
375794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Cmp(r3,
375894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     static_cast<uint32_t>(literal_values[literal_index] >>
375994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                           32));
376094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &fail);
376194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Mov(r3, 0);
376294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
376394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 7:
376494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Vldr(s0, literals[literal_index]);
376594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Vmov(s1, static_cast<uint32_t>(literal_values[literal_index]));
376694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Vcmp(s0, s1);
376794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &fail);
376894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Vmov(s0, 0);
376994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
377094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 8: {
377194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
377294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
377394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Cbz(r0, &labels[label_index]);
377494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
377594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
377694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
377794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 9: {
377894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
377994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
378094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Cbnz(r0, &labels[label_index]);
378194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
378294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
378394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
378494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 10: {
378594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
378694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
378794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &labels[label_index], kNear);
378894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
378994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
379094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
379194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 11: {
379294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
379394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
379494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&labels[label_index], kNear);
379594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
379694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
379794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
379894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 12: {
379994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
380094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
380194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(ne, &labels[label_index]);
380294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
380394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
380494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
380594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 13: {
380694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
380794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
380894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&labels[label_index]);
380994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
381094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
381194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
381294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 14: {
381394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              Label past_branch;
381494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ B(&past_branch, kNear);
381594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bl(&labels[label_index]);
381694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Bind(&past_branch);
381794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
381894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            }
381994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 15:
382094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
382694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 16:
382794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
382994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
383494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 17:
383594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
383994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
384094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 18:
384194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
384994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
385094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            case 19:
385194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
385294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              __ Nop();
385394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
385494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            default:
385594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              VIXL_UNREACHABLE();
385694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              break;
385794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          }
385894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
385994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          // If all labels have been bound, exit the inner loop and finalise the
386094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          // code.
386194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          allbound = true;
386294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          for (int i = 0; i < label_count; i++) {
386394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            allbound = allbound && labels[i].IsBound();
386494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          }
386594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          if (allbound) break;
386694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        }
386794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
386894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ B(&end);
386994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Bind(&fail);
387094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Mov(r4, 0);
387194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ Bind(&end);
387294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
387394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // Ensure that the veneer pools are emitted, to keep each branch/bind
387494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // test
387594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        // independent.
387694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        masm.FinalizeCode(MacroAssembler::kFallThrough);
387794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        delete[] labels;
387894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        for (int lit = 0; lit < literal_count; lit++) {
387994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois          delete literals[lit];
388094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        }
388194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
388294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
388394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
388494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
388594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
388694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
388794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
388894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(loop_count, r1);
388994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(42, r4);
389094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
389194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
389294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
389394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_T32
389494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_NOASM(code_buffer_precise_growth) {
389594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kBaseBufferSize = 16;
389694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  MacroAssembler masm(kBaseBufferSize, T32);
389794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
389894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
389994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
390094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
390194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Fill the buffer with nops.
390294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
390394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBaseBufferSize,
390494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
390594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < kBaseBufferSize; i += k16BitT32InstructionSizeInBytes) {
390694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
390794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
390894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
390994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
391094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The buffer should not have grown yet.
391194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
391294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
391394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generating a single instruction should force the buffer to grow.
391494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
391594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
391694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetBuffer()->GetCapacity() > kBaseBufferSize);
391794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
391894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.FinalizeCode();
391994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
392094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
392194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
392294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#ifdef VIXL_INCLUDE_TARGET_T32
3923a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia KouveliTEST_NOASM(out_of_space_immediately_before_EnsureEmitFor) {
392494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kBaseBufferSize = 64;
392594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  MacroAssembler masm(kBaseBufferSize, T32);
39268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  TestMacroAssembler test(&masm);
392794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
392894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
392994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
393194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
393294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create a veneer.
393394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label target;
393494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &target);
393594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
393794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
393894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
393994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t space = static_cast<uint32_t>(masm.GetBuffer()->GetRemainingBytes());
394094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
394194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Fill the buffer with nops.
394294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
394394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (uint32_t i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
394494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
394594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
394694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
394794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
394994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
395094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The buffer should not have grown yet, and there should be no space left.
395194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
395294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  VIXL_CHECK(masm.GetBuffer()->GetRemainingBytes() == 0);
395394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
395494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Force emission of the veneer, at a point where there is no space available
395594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // in the buffer.
39568b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t past_cbz_range =
39578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      test.GetPoolCheckpoint() - masm.GetCursorOffset() + 1;
395894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.EnsureEmitFor(past_cbz_range);
395994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
396094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&target);
396194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
39628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
396394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
396494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  masm.FinalizeCode();
396594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
396694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
396794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
396894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
3969a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia KouveliTEST_NOASM(EnsureEmitFor) {
3970a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  static const int kBaseBufferSize = 32;
3971a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  MacroAssembler masm(kBaseBufferSize);
3972a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli
3973a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3974a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli
3975a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3976a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  int32_t space = static_cast<int32_t>(masm.GetBuffer()->GetRemainingBytes());
3977a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  int32_t end = __ GetCursorOffset() + space;
3978a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  {
3979a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli    // Fill the buffer with nops.
3980a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3981a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli    while (__ GetCursorOffset() != end) {
3982a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli      __ nop();
3983a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli    }
3984a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  }
3985a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli
3986a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  // Test that EnsureEmitFor works.
3987a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  VIXL_CHECK(!masm.GetBuffer()->HasSpaceFor(4));
3988a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  masm.EnsureEmitFor(4);
3989a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  VIXL_CHECK(masm.GetBuffer()->HasSpaceFor(4));
3990a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  __ Nop();
3991a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli
3992a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  masm.FinalizeCode();
3993a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli}
3994a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli
399594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(distant_literal_references) {
399694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
399794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
399894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
399994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literal =
400094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
400194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
400294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
400394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Refer to the literal so that it is emitted early.
400494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, literal);
400594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
400694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add enough nops to exceed the range of all loads.
400794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int space = 5000;
400894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
400994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
401094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm.IsUsingT32());
401194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
401294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
401394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
401494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
401594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
401694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ENSURE_ALIGNED()                                                      \
401794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  do {                                                                        \
401894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
401994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            masm.GetCursorOffset())) {                                        \
402094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm,                                         \
402194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               k16BitT32InstructionSizeInBytes,               \
402294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               ExactAssemblyScope::kExactSize);               \
402394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();                                                               \
402494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                         \
402594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(                                                              \
402694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
402794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  } while (0)
402894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
402994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The literal has already been emitted, and is out of range of all of these
403094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // instructions. The delegates must generate fix-up code.
403194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
403294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, literal);
403394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
403494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, literal);
403594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
403694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r3, literal);
403794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
403894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r4, literal);
403994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
404094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r5, literal);
404194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
404294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, literal);
404394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
404494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d0, literal);
404594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
404694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s3, literal);
404794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
404894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef ENSURE_ALIGNED
404994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
405094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
405194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
405294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
405394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
405494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r0);
405594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r1);
405694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xef, r2);
405794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffef, r3);
405894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcdef, r4);
405994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffcdef, r5);
406094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r6);
406194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01234567, r7);
406294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
406394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
406494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
406594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
406694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
406794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(distant_literal_references_unaligned_pc) {
406894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
406994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
407094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
407194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literal =
407294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
407394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
407494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
407594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Refer to the literal so that it is emitted early.
407694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, literal);
407794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
407894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add enough nops to exceed the range of all loads, leaving the PC aligned
407994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // to only a two-byte boundary.
408094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int space = 5002;
408194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
408294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
408394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm.IsUsingT32());
408494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
408594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
408694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
408794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
408894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
408994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ENSURE_NOT_ALIGNED()                                                   \
409094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  do {                                                                         \
409194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
409294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm,                                          \
409394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               k16BitT32InstructionSizeInBytes,                \
409494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               ExactAssemblyScope::kExactSize);                \
409594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();                                                                \
409694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                          \
409794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(                                                               \
409894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
409994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  } while (0)
410094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
410194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The literal has already been emitted, and is out of range of all of these
410294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // instructions. The delegates must generate fix-up code.
410394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
410494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, literal);
410594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
410694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, literal);
410794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
410894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r3, literal);
410994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
411094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r4, literal);
411194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
411294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r5, literal);
411394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
411494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, literal);
411594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
411694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // TODO: We currently require an extra scratch register for these cases
411794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // because MemOperandComputationHelper isn't able to fit add_sub_offset into
411894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // a single 'sub' instruction, so 'pc' gets preserved first. The same
411994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // problem technically exists for the other loads, but vldr is particularly
412094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // badly affected because vldr cannot set the low bits in its offset mask,
412194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // so the add/sub operand is likely to be difficult to encode.
412294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //
412394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // At the moment, we get this:
412494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     mov r8, pc
412594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     mov ip, #5118
412694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     sub r8, pc
412794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     vldr d0, [r8, #48]
412894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //
412994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // We should be able to generate something like this:
413094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     sub ip, pc, #0x1300    // 5118 & 0xff00
413194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     sub ip, #0xfe          // 5118 & 0x00ff
413294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    //     vldr d0, [ip, #48]
413394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    UseScratchRegisterScope temps(&masm);
413494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(r8);
413594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ENSURE_NOT_ALIGNED();
413694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Vldr(d0, literal);
413794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ENSURE_NOT_ALIGNED();
413894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Vldr(s3, literal);
413994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
414094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
414194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef ENSURE_NOT_ALIGNED
414294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
414394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
414494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
414594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
414694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
414794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r0);
414894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r1);
414994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xef, r2);
415094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffef, r3);
415194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcdef, r4);
415294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffcdef, r5);
415394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r6);
415494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01234567, r7);
415594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
415694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
415794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
415894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
415994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
416094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(distant_literal_references_short_range) {
416194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
416294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
416394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
416494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literal =
416594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
416694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
416794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
416894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Refer to the literal so that it is emitted early.
416994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s4, literal);
417094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
417194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add enough nops to exceed the range of the loads, but not the adr that will
417294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // be generated to read the PC.
417394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int space = 4000;
417494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
417594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
417694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm.IsUsingT32());
417794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
417894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
417994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
418094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
418194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
418294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ENSURE_ALIGNED()                                                      \
418394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  do {                                                                        \
418494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
418594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois            masm.GetCursorOffset())) {                                        \
418694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm,                                         \
418794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               k16BitT32InstructionSizeInBytes,               \
418894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               ExactAssemblyScope::kExactSize);               \
418994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();                                                               \
419094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                         \
419194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(                                                              \
419294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
419394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  } while (0)
419494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
419594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The literal has already been emitted, and is out of range of all of these
419694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // instructions. The delegates must generate fix-up code.
419794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
419894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, literal);
419994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
420094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, literal);
420194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
420294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r3, literal);
420394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
420494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r4, literal);
420594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
420694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r5, literal);
420794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
420894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, literal);
420994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
421094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d0, literal);
421194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_ALIGNED();
421294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s3, literal);
421394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
421494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef ENSURE_ALIGNED
421594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
421694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
421794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
421894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
421994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
422094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
422194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r1);
422294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xef, r2);
422394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffef, r3);
422494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcdef, r4);
422594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffcdef, r5);
422694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r6);
422794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01234567, r7);
422894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
422994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
423094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
423194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
423294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
423394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(distant_literal_references_short_range_unaligned_pc) {
423494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
423594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
423694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
423794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literal =
423894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
423994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
424094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
424194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Refer to the literal so that it is emitted early.
424294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s4, literal);
424394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
424494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add enough nops to exceed the range of the loads, but not the adr that will
424594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // be generated to read the PC.
424694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int space = 4000;
424794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
424894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
424994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm.IsUsingT32());
425094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
425194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
425294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
425394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
425494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
425594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define ENSURE_NOT_ALIGNED()                                                   \
425694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  do {                                                                         \
425794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
425894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm,                                          \
425994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               k16BitT32InstructionSizeInBytes,                \
426094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               ExactAssemblyScope::kExactSize);                \
426194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();                                                                \
426294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                          \
426394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(                                                               \
426494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
426594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  } while (0)
426694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
426794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The literal has already been emitted, and is out of range of all of these
426894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // instructions. The delegates must generate fix-up code.
426994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
427094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, literal);
427194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
427294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, literal);
427394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
427494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r3, literal);
427594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
427694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r4, literal);
427794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
427894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r5, literal);
427994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
428094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, literal);
428194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
428294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d0, literal);
428394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ENSURE_NOT_ALIGNED();
428494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s3, literal);
428594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
428694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef ENSURE_NOT_ALIGNED
428794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
428894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
428994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
429094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
429194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
429294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
429394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r1);
429494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xef, r2);
429594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffef, r3);
429694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcdef, r4);
429794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffcdef, r5);
429894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r6);
429994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01234567, r7);
430094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
430194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
430294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
430394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
430494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
430594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(distant_literal_references_long_range) {
430694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
430794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
430894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
430994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literal =
431094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
431194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
431294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
431394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Refer to the literal so that it is emitted early.
431494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r0, literal);
431594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
431694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define PAD_WITH_NOPS(space)                                             \
431794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  do {                                                                   \
431894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {                                                                    \
431994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope scope(&masm,                                    \
432094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               space,                                    \
432194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               CodeBufferCheckScope::kExactSize);        \
432294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      VIXL_ASSERT(masm.IsUsingT32());                                    \
432394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) { \
432494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ nop();                                                        \
432594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }                                                                  \
432694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                    \
432794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  } while (0)
432894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
432994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add enough nops to exceed the range of all loads.
433094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  PAD_WITH_NOPS(5000);
433194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
433294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The literal has already been emitted, and is out of range of all of these
433394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // instructions. The delegates must generate fix-up code.
433494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, literal);
433594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, literal);
433694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r3, literal);
433794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r4, literal);
433894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r5, literal);
433994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, literal);
434094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(d0, literal);
434194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Vldr(s3, literal);
434294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
434394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add enough nops to exceed the range of the adr+sub sequence.
434494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  PAD_WITH_NOPS(0x421000);
434594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
434694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r1, literal);
434794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrb(r2, literal);
434894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsb(r3, literal);
434994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrh(r4, literal);
435094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrsh(r5, literal);
435194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, literal);
435294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
435394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // TODO: We currently require an extra scratch register for these cases. We
435494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // should be able to optimise the code generation to avoid this requirement
435594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // (and in many cases avoid a 32-bit instruction).
435694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    UseScratchRegisterScope temps(&masm);
435794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    temps.Include(r8);
435894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Vldr(d0, literal);
435994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Vldr(s3, literal);
436094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
436194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
436294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#undef PAD_WITH_NOPS
436394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
436494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
436594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
436694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
436794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
436894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r0);
436994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r1);
437094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xef, r2);
437194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffffef, r3);
437294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcdef, r4);
437394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xffffcdef, r5);
437494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x89abcdef, r6);
437594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x01234567, r7);
437694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
437794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
437894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
437994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
438094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
438194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(barriers) {
438294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate all supported barriers, this is just a smoke test
438394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
438494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
438594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
438694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
438794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // DMB
438894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(SY);
438994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(ST);
439094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(ISH);
439194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(ISHST);
439294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(NSH);
439394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(NSHST);
439494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(OSH);
439594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dmb(OSHST);
439694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
439794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // DSB
439894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(SY);
439994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(ST);
440094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(ISH);
440194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(ISHST);
440294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(NSH);
440394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(NSHST);
440494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(OSH);
440594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Dsb(OSHST);
440694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
440794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // ISB
440894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Isb(SY);
440994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
441094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
441194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
441294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
441394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
441494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(preloads) {
441594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Smoke test for various pld/pli forms.
441694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
441794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
441894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
441994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
442094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // PLD immediate
442194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(sp, 0));
442294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r0, 0));
442394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r1, 123));
442494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r2, 1234));
442594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r3, 4095));
442694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r4, -123));
442794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r5, -255));
442894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
442994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (masm.IsUsingA32()) {
443094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pld(MemOperand(r6, -1234));
443194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pld(MemOperand(r7, -4095));
443294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
443394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
443494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
443594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // PLDW immediate
443694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(sp, 0));
443794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r0, 0));
443894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r1, 123));
443994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r2, 1234));
444094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r3, 4095));
444194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r4, -123));
444294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r5, -255));
444394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
444494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (masm.IsUsingA32()) {
444594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pldw(MemOperand(r6, -1234));
444694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pldw(MemOperand(r7, -4095));
444794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
444894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
444994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // PLD register
445094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r0, r1));
445194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r0, r1, LSL, 1));
445294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r0, r1, LSL, 2));
445394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pld(MemOperand(r0, r1, LSL, 3));
445494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
445594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (masm.IsUsingA32()) {
445694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pld(MemOperand(r0, r1, LSL, 4));
445794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pld(MemOperand(r0, r1, LSL, 20));
445894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
445994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
446094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // PLDW register
446194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r0, r1));
446294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r0, r1, LSL, 1));
446394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r0, r1, LSL, 2));
446494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pldw(MemOperand(r0, r1, LSL, 3));
446594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
446694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (masm.IsUsingA32()) {
446794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pldw(MemOperand(r0, r1, LSL, 4));
446894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pldw(MemOperand(r0, r1, LSL, 20));
446994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
447094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
447194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // PLI immediate
447294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(sp, 0));
447394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r0, 0));
447494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r1, 123));
447594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r2, 1234));
447694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r3, 4095));
447794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r4, -123));
447894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r5, -255));
447994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
448094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (masm.IsUsingA32()) {
448194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pli(MemOperand(r6, -1234));
448294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pli(MemOperand(r7, -4095));
448394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
448494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
448594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // PLI register
448694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r0, r1));
448794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r0, r1, LSL, 1));
448894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r0, r1, LSL, 2));
448994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Pli(MemOperand(r0, r1, LSL, 3));
449094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
449194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  if (masm.IsUsingA32()) {
449294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pli(MemOperand(r0, r1, LSL, 4));
449394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Pli(MemOperand(r0, r1, LSL, 20));
449494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
449594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
449694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
449794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
449894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
449994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
450094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_mirrored_branches) {
450194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
450294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
450394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
450494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
450594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int kMaxBranchCount = 256;
450694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
450794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int branch_count = 1; branch_count < kMaxBranchCount; branch_count++) {
450894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    Label* targets = new Label[branch_count];
450994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
451094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < branch_count; i++) {
451194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Cbz(r0, &targets[i]);
451294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
451394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
451494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < branch_count; i++) {
451594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Bind(&targets[branch_count - i - 1]);
451694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ Orr(r0, r0, r0);
451794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
451894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
451994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    delete[] targets;
452094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
452194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
452294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
452394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
452494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
452594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
452694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(branch_fuzz_example) {
452794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
452894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
452994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
453094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
453194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label l[64];
453294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
453394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
453494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
453594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
453694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
453794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
453894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
453994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
454094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
454194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[26]);
454294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[29]);
454394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
454494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
454594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
454694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[12]);
454794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[22]);
454894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
454994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
455094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
455194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
455294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
455394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
455494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[7]);
455594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[18]);
455694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[14]);
455794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
455894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[18]);
455994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
456094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
456194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[21]);
456294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
456394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
456494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
456594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
456694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[23]);
456794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
456894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
456994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
457094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[9]);
457194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
457294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
457394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
457494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
457594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[8]);
457694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
457794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
457894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
457994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
458094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[10]);
458194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[8]);
458294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
458394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
458494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[28]);
458594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
458694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
458794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[19]);
458894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[14]);
458994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
459094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[26]);
459194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
459294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
459394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[24]);
459494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
459594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
459694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
459794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
459894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[26]);
459994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
460094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
460194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
460294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[14]);
460394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
460494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[18]);
460594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
460694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
460794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
460894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
460994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[0]);
461094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
461194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
461294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
461394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[8]);
461494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
461594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
461694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
461794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[12]);
461894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[0]);
461994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[23]);
462094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
462194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
462294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
462394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
462494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
462594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
462694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
462794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[23]);
462894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[16]);
462994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
463094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
463194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[12]);
463294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
463394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
463494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
463594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
463694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
463794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[18]);
463894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[4]);
463994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[31]);
464094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
464194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
464294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
464394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
464494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
464594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
464694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
464794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[1]);
464894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
464994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[13]);
465094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
465194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
465294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
465394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
465494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[7]);
465594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
465694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[0]);
465794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[13]);
465894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
465994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
466094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
466194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
466294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
466394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
466494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[31]);
466594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[2]);
466694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
466794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
466894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[27]);
466994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[13]);
467094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[23]);
467194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[7]);
467294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[2]);
467394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
467494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
467594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[15]);
467694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[13]);
467794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
467894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[8]);
467994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
468094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[8]);
468194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
468294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[2]);
468394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[31]);
468494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
468594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
468694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[29]);
468794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[7]);
468894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
468994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[11]);
469094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
469194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
469294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
469394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
469494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
469594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
469694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
469794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[6]);
469894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
469994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
470094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
470194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
470294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[23]);
470394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[12]);
470494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
470594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
470694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
470794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
470894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
470994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
471094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[20]);
471194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
471294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[4]);
471394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
471494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
471594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
471694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[20]);
471794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[29]);
471894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
471994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
472094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
472194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
472294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
472394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[26]);
472494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
472594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
472694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
472794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[17]);
472894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
472994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
473094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
473194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
473294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
473394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
473494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
473594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[26]);
473694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
473794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
473894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[20]);
473994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
474094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
474194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
474294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
474394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
474494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[13]);
474594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
474694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
474794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[8]);
474894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
474994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[23]);
475094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[6]);
475194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
475294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[13]);
475394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[31]);
475494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[14]);
475594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
475694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
475794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
475894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[27]);
475994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[10]);
476094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
476194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[14]);
476294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
476394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[26]);
476494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
476594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[2]);
476694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
476794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
476894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
476994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
477094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
477194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
477294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
477394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
477494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
477594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
477694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[17]);
477794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[12]);
477894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
477994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
478094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
478194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[31]);
478294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
478394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
478494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
478594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[13]);
478694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[14]);
478794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
478894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[5]);
478994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[12]);
479094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
479194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
479294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[11]);
479394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
479494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[20]);
479594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[22]);
479694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
479794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
479894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
479994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
480094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
480194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[0]);
480294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
480394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[16]);
480494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[28]);
480594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[18]);
480694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
480794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
480894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
480994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[8]);
481094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[25]);
481194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
481294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[21]);
481394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[1]);
481494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[29]);
481594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[15]);
481694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
481794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
481894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[3]);
481994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
482094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[9]);
482194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[24]);
482294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
482394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[19]);
482494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ And(r0, r0, r0);
482594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &l[30]);
482694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[25]);
482794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[3]);
482894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[30]);
482994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&l[5]);
483094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
483194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
483294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
483394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
483494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
483594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Generate a "B" and a "Cbz" which have the same checkpoint. Without proper
483694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// management (i.e. if the veneers were only generated at the shared
483794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// checkpoint), one one of the branches would be out of range.
483894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_simultaneous) {
483994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
484094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
484194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
484294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
484394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // `2046` max range - the size of the B.EQ itself.
484494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kMaxBCondRange = 1048574;
484594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
484694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label target_1;
484794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label target_2;
484894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
484994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(eq, &target_1);
485094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
485194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int target_1_size_1 =
485294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
485394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int end_1 = masm.GetCursorOffset() + target_1_size_1;
485494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  while (masm.GetCursorOffset() < end_1) {
485594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
485694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
485794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
485894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &target_2);
485994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
486094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
486194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int end_2 = masm.GetCursorOffset() + target_1_size_2;
486294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  while (masm.GetCursorOffset() < end_2) {
486394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
486494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
486594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
486694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
486794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
486894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&target_1);
486994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&target_2);
487094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
487194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
487294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
487394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
487494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
487594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Generate a "B" and a "Cbz" which have the same checkpoint and the same label.
487694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_simultaneous_one_label) {
487794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
487894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
487994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
488094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
488194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // `2046` max range - the size of the B.EQ itself.
488294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kMaxBCondRange = 1048574;
488394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
488494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label target;
488594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
488694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(eq, &target);
488794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
488894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int target_1_size_1 =
488994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
489094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int end_1 = masm.GetCursorOffset() + target_1_size_1;
489194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  while (masm.GetCursorOffset() < end_1) {
489294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
489394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
489494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
489594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r0, &target);
489694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
489794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
489894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int end_2 = masm.GetCursorOffset() + target_1_size_2;
489994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  while (masm.GetCursorOffset() < end_2) {
490094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
490194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
490294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
490394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
490494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
490594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&target);
490694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
490794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
490894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
490994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// NOTE: This test has needed modifications for the new pool manager, as it
49118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// was testing a corner case of the previous pool managers. We keep it as
49128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// another testcase.
491394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_and_literal) {
491494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
491594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
491694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
491794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49188b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
491994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
492094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t ldrd_range = 1020;
492194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t cbz_range = 126;
492294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t kLabelsCount = 20;
492394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label labels[kLabelsCount];
492494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
492594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create one literal pool entry.
492694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
492794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
492894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate some nops.
492994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t i = 0;
493094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (; i < ldrd_range - cbz_range - 40;
493194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois       i += k16BitT32InstructionSizeInBytes) {
493294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
493394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
493494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
493594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // At this point, it remains cbz_range + 40 => 166 bytes before ldrd becomes
493694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // out of range.
493794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We generate kLabelsCount * 4 => 80 bytes. We shouldn't generate the
493894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // literal pool.
493994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (uint32_t j = 0; j < kLabelsCount; j++) {
494094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Cbz(r0, &labels[j]);
494194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
494294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    i += 2 * k16BitT32InstructionSizeInBytes;
494394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
494494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
494594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We generate a few more instructions.
494694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (; i < ldrd_range - 4 * kA32InstructionSizeInBytes;
494794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois       i += k16BitT32InstructionSizeInBytes) {
494894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
494994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
495094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
495194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Bind all the used labels.
495294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (uint32_t j = 0; j < kLabelsCount; j++) {
495394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&labels[j]);
495494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
495594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
495694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Now that all the labels have been bound, we have no more veneers.
49588b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
495994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
496094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
496194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
496294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
496394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
496494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
496594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
496694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
496794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
496894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49698b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// NOTE: This test has needed modifications for the new pool manager, as it
49708b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// was testing a corner case of the previous pool managers. We keep it as
49718b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// another testcase.
497294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_and_literal2) {
497394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
497494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
497594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
497694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
49778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
497894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
497994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t ldrd_range = 1020;
498094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t cbz_range = 126;
498194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t kLabelsCount = 20;
498294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int32_t kTypicalMacroInstructionMaxSize =
498394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      8 * kMaxInstructionSizeInBytes;
498494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label labels[kLabelsCount];
498594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
498694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create one literal pool entry.
498794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
498894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
498994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (uint32_t i = 0; i < ldrd_range - cbz_range - 4 * kLabelsCount;
499094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois       i += k16BitT32InstructionSizeInBytes) {
499194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
499294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
499394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
499494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Add entries to the veneer pool.
499594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (uint32_t i = 0; i < kLabelsCount; i++) {
499694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Cbz(r0, &labels[i]);
499794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
499894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
499994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
500094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Generate nops up to the literal pool limit.
50018b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  while (test.GetPoolCheckpoint() - masm.GetCursorOffset() >=
500294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         kTypicalMacroInstructionMaxSize) {
500394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
500494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
500594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
500694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // At this point, no literals and no veneers have been generated.
50078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_ASSERT(!test.PoolIsEmpty());
500894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The literal pool needs to be generated.
50098b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_ASSERT(test.GetPoolCheckpoint() - masm.GetCursorOffset() <
501094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois              kTypicalMacroInstructionMaxSize);
501194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
50128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // This extra Nop will generate the pools.
501394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
501494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
501594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Bind all the used labels.
501694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (uint32_t j = 0; j < kLabelsCount; j++) {
501794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&labels[j]);
501894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
501994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
502094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
50218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Now that all the labels have been bound, we have no more veneers.
50228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
502394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
502494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
502594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
502694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
502794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
502894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
502994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
503094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
503194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
503294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
503394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
503494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Use a literal when we already have a veneer pool potential size greater than
503594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// the literal range => generate the literal immediately (not optimum but it
503694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// works).
503794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_and_literal3) {
503894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
503994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
504094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
504194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
504294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kLabelsCount = 1000;
504394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
504494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label labels[kLabelsCount];
504594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
504694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the Z flag so that the following branches are not taken.
504794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Movs(r0, 0);
504894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
504994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
505094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(ne, &labels[i]);
505194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
505294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
505394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Create one literal pool entry.
505494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
505594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
505694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < 10; i++) {
505794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Nop();
505894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
505994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
506094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
506194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&labels[i]);
506294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
506394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
506494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
506594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
506694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
506794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
506894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
506994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
507094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
507194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
507294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
507394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
507494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Literal has to be generated sooner than veneers. However, as the literal
507594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// pool generation would make the veneers out of range, generate the veneers
507694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// first.
507794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_and_literal4) {
507894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
507994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
508094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
508194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
508294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label end;
508394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
508494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Set the Z flag so that the following branch is not taken.
508594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Movs(r0, 0);
508694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(ne, &end);
508794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
508894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t value = 0x1234567;
508994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint32_t>* literal =
509094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint32_t>(value,
509194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
509294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
509394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
509494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldr(r11, literal);
509594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
509694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // The range for ldr is 4095, the range for cbz is 127. Generate nops
509794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // to have the ldr becomming out of range just before the cbz.
509894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int NUM_NOPS = 2044;
509994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int NUM_RANGE = 58;
510094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
510194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int NUM1 = NUM_NOPS - NUM_RANGE;
510294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int NUM2 = NUM_RANGE;
510394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
510494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
510594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope aas(&masm, 2 * NUM1, CodeBufferCheckScope::kMaximumSize);
510694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < NUM1; i++) {
510794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
510894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
510994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
511094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
511194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r1, &end);
511294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
511394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
511494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope aas(&masm, 2 * NUM2, CodeBufferCheckScope::kMaximumSize);
511594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < NUM2; i++) {
511694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
511794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
511894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
511994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
512094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
512194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
512294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ add(r1, r1, 3);
512394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
512494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
512594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
512694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
512794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
512894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
512994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
513094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
513194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x1234567, r11);
513294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
513394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
513494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
513594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Literal has to be generated sooner than veneers. However, as the literal
513694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// pool generation would make the veneers out of range, generate the veneers
513794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// first.
513894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_and_literal5) {
513994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
514094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
514194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
514294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
514394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kTestCount = 100;
514494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label labels[kTestCount];
514594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
514694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int first_test = 2000;
514794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Test on both sizes of the Adr range which is 4095.
514894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int test = 0; test < kTestCount; test++) {
514994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    const int string_size = 1000;  // A lot more than the cbz range.
515094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    std::string test_string(string_size, 'x');
515194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    StringLiteral big_literal(test_string.c_str());
515294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
515394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Adr(r11, &big_literal);
515494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
515594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {
515694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      int num_nops = first_test + test;
515794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope aas(&masm,
515894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             2 * num_nops,
515994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             CodeBufferCheckScope::kMaximumSize);
516094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      for (int i = 0; i < num_nops; i++) {
516194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        __ nop();
516294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }
516394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
516494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
516594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Cbz(r1, &labels[test]);
516694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
516794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    {
516894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
516994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ add(r1, r1, 3);
517094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
517194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&labels[test]);
517294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Emit the literal pool if it has not beeen emitted (it's the case for
517394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // the lower values of test).
51748b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
517594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
517694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
517794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
517894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
517994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
518094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that veneer and literals are well generated when they are out of
518194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// range at the same time.
518294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(veneer_and_literal6) {
518394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
518494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
518594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
518694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
518794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label t1, t2, t3, t4, t5;
518894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kLdrdRange = 1020;
518994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kSizeForCbz = k16BitT32InstructionSizeInBytes;
519094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
519194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, 0x1111111111111111);
519294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, 0x2222222222222222);
519394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r4, r5, 0x3333333333333333);
519494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r6, r7, 0x4444444444444444);
519594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r8, r9, 0x5555555555555555);
519694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r10, r11, 0x6666666666666666);
519794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r10, r11, 0x1234567890abcdef);
519894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
519994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Ldrd has a bigger range that cbz. Generate some nops before the cbzs in
520094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // order to reach the maximum range of ldrd and cbz at the same time.
520194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
520294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int nop_size = kLdrdRange - kCbzCbnzRange - 5 * kSizeForCbz;
520394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
520494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
520594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
520694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
520794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
520894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
520994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r2, &t1);
521094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r2, &t2);
521194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r2, &t3);
521294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r2, &t4);
521394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Cbz(r2, &t5);
521494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
521594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // At this point, the ldrds are not out of range. It remains a kCbzCbnzRange
521694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // margin (minus the size of the veneers).
521794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
521894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // At this point, the literal and the veneer pools are not emitted.
52198b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kLdrdLiteralSize = 8;
52208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kVeneerSize = 4;
52218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(7 * kLdrdLiteralSize + 5 * kVeneerSize);
52228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.GetPoolCheckpoint() - masm.GetCursorOffset() < kCbzCbnzRange);
522394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
522494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This scope will generate both veneers (they are both out of range).
522594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
522694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int nop_size = kCbzCbnzRange;
522794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
522894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
522994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
523094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
523194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
523294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Check that both literals and veneers have been emitted.
52348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(5 * kVeneerSize);
52358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.GetPoolCheckpoint() - masm.GetCursorOffset() > kCbzCbnzRange);
523694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
523794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&t1);
523894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&t2);
523994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&t3);
524094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&t4);
524194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&t5);
524294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(0);
52448b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
524594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
524694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
524794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
524894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
524994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
525094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, r0);
525194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, r1);
525294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, r2);
525394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, r3);
525494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, r4);
525594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, r5);
525694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, r6);
525794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, r7);
525894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x55555555, r8);
525994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x55555555, r9);
526094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r10);
526194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r11);
526294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
526394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
526494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that a label which is just bound during the MacroEmissionCheckScope
526594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// can be used.
526694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldr_label_bound_during_scope) {
526794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
526894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
526994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
527094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t>* literal =
527194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x1234567890abcdef),
527294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
527394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
527494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, literal);
527594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int nop_size = masm.IsUsingA32() ? 4 : 2;
52778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  while (test.GetPoolCheckpoint() >=
52788b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli         (masm.GetCursorOffset() +
52798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli          static_cast<int32_t>(kMaxInstructionSizeInBytes))) {
52808b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(&masm, nop_size, ExactAssemblyScope::kExactSize);
52818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ nop();
528294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
528394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52848b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_ASSERT(!test.PoolIsEmpty());
528594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
528694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // This Ldrd will first generate the pool and then use literal which has just
528794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // been bound.
528894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r2, r3, literal);
528994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
52908b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_ASSERT(test.PoolIsEmpty());
529194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
529294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
529394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
529494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
529594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
529694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
529794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
529894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
529994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r2);
530094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r3);
530194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
530294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
530394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
530494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(test_it_scope_and_literal_pool) {
5305a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  // This test stresses the ITScope to make sure the number of bytes it tries
5306a6090f84eb54fab650f7ac4acc45e8a895eaf598Georgia Kouveli  // to emit is in sync with the MacroEmissionCheckScope that is around it.
530794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
530894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
530994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
531094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
531194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Make sure the pool is empty.
53128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
53138b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
531494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
531594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Literal<uint64_t> l0(0xcafebeefdeadbaba);
531694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldrd(r0, r1, &l0);
531794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Leave exactly as many bytes between cursor and pool emission checkpoint as
531894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // the typical macro instruction needs (and MacroEmissionCheckScope allows
531994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // for).
532094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const int32_t kTypicalMacroInstructionMaxSize =
532194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      8 * kMaxInstructionSizeInBytes;
53228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset() -
53238b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                   kTypicalMacroInstructionMaxSize;
532494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  int32_t end = masm.GetCursorOffset() + margin;
532594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
532694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
532794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
532894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    while (masm.GetCursorOffset() < end) {
532994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
533094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
533194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
53328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK((test.GetPoolCheckpoint() - masm.GetCursorOffset()) ==
533394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois             kTypicalMacroInstructionMaxSize);
533494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
533594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // We cannot use an IT block for this instruction, hence ITScope will
533694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // generate a branch over it.
533794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Add(ne, r8, r9, 256);
533894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
533994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
534094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
534194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
534294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
534394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Check that the literals loaded correctly.
534494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r0);
534594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r1);
534694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
534794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
534894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
534994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// TODO: Remove this limitation by having a sandboxing mechanism.
535094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#if defined(VIXL_HOST_POINTER_32)
535194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldm_stm_no_writeback) {
535294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
535394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
535494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
535594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
535694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
535794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
535894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
535994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
536094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, reinterpret_cast<uintptr_t>(src));
536194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
536294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
536394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
536494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, reinterpret_cast<uintptr_t>(dst1));
536594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
536694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
536794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, reinterpret_cast<uintptr_t>(dst2));
536894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
536994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
537094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
537194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
537294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
537394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
537494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
537594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r2);
537694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, r3);
537794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, r4);
537894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
537994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r5);
538094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r6);
538194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, r9);
538294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, r11);
538394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
538494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, dst1[0]);
538594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, dst1[1]);
538694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, dst1[2]);
538794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, dst1[3]);
538894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
538994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, dst2[0]);
539094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, dst2[1]);
539194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, dst2[2]);
539294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, dst2[3]);
539394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
539494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
539594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
539694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldm_stm_writeback) {
539794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
539894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
539994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
540094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
540194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
540294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t dst[8] = {0x00000000,
540394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000,
540494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000,
540594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000,
540694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000,
540794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000,
540894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000,
540994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                     0x00000000};
541094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
541194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, reinterpret_cast<uintptr_t>(src));
541294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldm(r0, WRITE_BACK, RegisterList(r2, r3));
541394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldm(r0, WRITE_BACK, RegisterList(r4, r5));
541494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
541594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, reinterpret_cast<uintptr_t>(dst));
541694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
541794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
541894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
541994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
542094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
542194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
542294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
542394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 4), r0);
542494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 8), r1);
542594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
542694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
542794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r3);
542894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, r4);
542994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, r5);
543094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
543194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, dst[0]);
543294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, dst[1]);
543394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, dst[2]);
543494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, dst[3]);
543594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x12345678, dst[4]);
543694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, dst[5]);
543794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xc001c0de, dst[6]);
543894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0xdeadbeef, dst[7]);
543994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
544094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
544194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
544294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_A32(ldm_stm_da_ib) {
544394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
544494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
544594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
544694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
544794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t src1[4] = {0x33333333, 0x44444444, 0x11111111, 0x22222222};
544894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t src2[4] = {0x11111111, 0x22222222, 0x33333333, 0x44444444};
544994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
545094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
545194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
545294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
545394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r11, reinterpret_cast<uintptr_t>(src1 + 3));
545494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmda(r11, WRITE_BACK, RegisterList(r0, r1));
545594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3));
545694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
54576c266808812883d690cb944c2763d22c50d116a6Pierre Langlois  __ Mov(r10, reinterpret_cast<uintptr_t>(src2) - sizeof(src2[0]));
545894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmib(r10, WRITE_BACK, RegisterList(r4, r5));
545994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmib(r10, NO_WRITE_BACK, RegisterList(r6, r7));
546094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
546194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r9, reinterpret_cast<uintptr_t>(dst1 + 3));
546294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmda(r9, WRITE_BACK, RegisterList(r0, r1));
546394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmda(r9, NO_WRITE_BACK, RegisterList(r2, r3));
546494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
54656c266808812883d690cb944c2763d22c50d116a6Pierre Langlois  __ Mov(r8, reinterpret_cast<uintptr_t>(dst2) - sizeof(dst2[0]));
546694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmib(r8, WRITE_BACK, RegisterList(r4, r5));
546794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmib(r8, NO_WRITE_BACK, RegisterList(r6, r7));
546894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
546994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
547094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
547194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
547294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
547394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
547494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src1 + 1), r11);
547594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src2 + 1), r10);
547694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst1 + 1), r9);
547794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst2 + 1), r8);
547894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
547994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, r0);
548094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, r1);
548194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, r2);
548294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, r3);
548394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
548494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, r4);
548594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, r5);
548694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, r6);
548794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, r7);
548894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
548994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, dst1[0]);
549094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, dst1[1]);
549194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, dst1[2]);
549294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, dst1[3]);
549394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
549494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, dst2[0]);
549594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, dst2[1]);
549694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, dst2[2]);
549794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, dst2[3]);
549894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
549994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
550094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
550194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(ldmdb_stmdb) {
550294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
550394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
550494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
550594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
550694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  const uint32_t src[6] =
550794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      {0x55555555, 0x66666666, 0x33333333, 0x44444444, 0x11111111, 0x22222222};
550894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
550994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  uint32_t dst[6] =
551094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
551194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
551294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r11, reinterpret_cast<uintptr_t>(src + 6));
551394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmdb(r11, WRITE_BACK, RegisterList(r1, r2));
551494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmdb(r11, WRITE_BACK, RegisterList(r3, r4));
551594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Ldmdb(r11, NO_WRITE_BACK, RegisterList(r5, r6));
551694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
551794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r10, reinterpret_cast<uintptr_t>(dst + 6));
551894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmdb(r10, WRITE_BACK, RegisterList(r5, r6));
551994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmdb(r10, WRITE_BACK, RegisterList(r3, r4));
552094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Stmdb(r10, NO_WRITE_BACK, RegisterList(r1, r2));
552194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
552294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
552394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
552494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
552594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
552694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 2), r11);
552794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 2), r10);
552894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
552994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, r1);
553094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, r2);
553194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, r3);
553294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, r4);
553394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x55555555, r5);
553494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x66666666, r6);
553594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
553694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, dst[0]);
553794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, dst[1]);
553894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x33333333, dst[2]);
553994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x44444444, dst[3]);
554094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x55555555, dst[4]);
554194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x66666666, dst[5]);
554294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
554394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#endif
554494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
554594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
554694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST(blx) {
554794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
554894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
554994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
555094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
555194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO(all): Ideally this test should jump back and forth between ARM and
555294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Thumb mode and should also cover BLX immediate. Update this test if we
555394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // allow VIXL assembler to change ISA anywhere in the code buffer.
555494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
555594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label test_start;
555694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label func1;
555794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label func2;
555894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
555994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ B(&test_start);
556094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
556194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&func1);
556294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0x11111111);
556394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Push(lr);
556494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
556594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    size_t size_of_generated_code;
556694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingA32()) {
556794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      size_of_generated_code = 7 * kA32InstructionSizeInBytes;
556894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    } else {
556994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      size_of_generated_code = 5 * k32BitT32InstructionSizeInBytes +
557094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                               3 * k16BitT32InstructionSizeInBytes;
557194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
557294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
557394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             size_of_generated_code,
557494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
557594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ adr(r11, &func2);
557694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (masm.IsUsingT32()) {
557794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
557894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      // that we are jumping into thumb mode.
557994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ orr(r11, r11, 1);
558094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
558194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ blx(r11);
558294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ pop(lr);
558394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bx(lr);
558494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
558594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bind(&func2);
558694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ movw(r1, 0x2222);
558794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ movt(r1, 0x2222);
558894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ bx(lr);
558994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
559094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
559194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&test_start);
559294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0xdeadc0de);
559394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r1, 0xdeadc0de);
559494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bl(&func1);
559594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
559694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
559794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
559894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
559994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
560094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Really basic test to check that we reached the different parts of the test.
560194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x11111111, r0);
560294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0x22222222, r1);
560394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
560494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
560594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that B with a near hint use a narrow branch when it can.
560694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_near_hint) {
560794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
560894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
560994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
561094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
561194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label end;
561294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
561394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
561494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
561594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
561694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
561794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be narrow.
561894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
561994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes,
562094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
562194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&start, kNear);
562294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
562394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
562494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
562594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBNarrowRange,
562694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
562794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t i = 0; i < kBNarrowRange;
562894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         i += k16BitT32InstructionSizeInBytes) {
562994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
563094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
563194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
563294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
563394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be wide.
563494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
563594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k32BitT32InstructionSizeInBytes,
563694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
563794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&start, kNear);
563894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
563994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
564094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a forward branch which should be narrow.
564194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
564294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes,
564394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
564494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&end, kNear);
564594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
564694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
56478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
56488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(margin < kBNarrowRange);
564994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
565094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
565194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
565294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBNarrowRange,
565394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
565494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t i = 0; i < kBNarrowRange;
565594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         i += k16BitT32InstructionSizeInBytes) {
565694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
565794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
565894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
565994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
566094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // A veneer should have been generated.
56618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
56628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(margin > kBNarrowRange);
566394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
566494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
566594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
566694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
566794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
566894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  DISASSEMBLE();
566994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
567094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
567194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that B with a far hint use a narrow branch only for a near backward
567294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// branch.
567394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_far_hint) {
567494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
567594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
567694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
567794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
567894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label end;
567994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
568094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
568194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
568294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
568394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
568494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be narrow.
568594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
568694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes,
568794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
568894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&start, kFar);
568994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
569094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
569194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
569294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBNarrowRange,
569394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
569494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t i = 0; i < kBNarrowRange;
569594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         i += k16BitT32InstructionSizeInBytes) {
569694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
569794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
569894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
569994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
570094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be wide.
570194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
570294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k32BitT32InstructionSizeInBytes,
570394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
570494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&start, kFar);
570594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
570694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
570794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a forward branch which should be wide.
570894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
570994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k32BitT32InstructionSizeInBytes,
571094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
571194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&end, kFar);
571294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
571394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
571494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
571594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
571694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
571794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
571894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  DISASSEMBLE();
571994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
572094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
572194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that conditional B with a near hint use a narrow branch when it can.
572294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_conditional_near_hint) {
572394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
572494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
572594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
572694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
572794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label end;
572894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
572994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
573094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
573194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
573294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be narrow.
573394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
573494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes,
573594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
573694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(eq, &start, kNear);
573794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
573894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
573994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
574094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBConditionalNarrowRange,
574194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
574294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t i = 0; i < kBConditionalNarrowRange;
574394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         i += k16BitT32InstructionSizeInBytes) {
574494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
574594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
574694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
574794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
574894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be wide.
574994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
575094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k32BitT32InstructionSizeInBytes,
575194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
575294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(eq, &start, kNear);
575394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
575494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
575594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a forward branch which should be narrow.
575694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
575794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes,
575894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
575994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(eq, &end, kNear);
576094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
576194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
57628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
57638b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(margin < kBConditionalNarrowRange);
576494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
576594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
576694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
576794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBConditionalNarrowRange,
576894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
576994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t i = 0; i < kBConditionalNarrowRange;
577094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         i += k16BitT32InstructionSizeInBytes) {
577194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
577294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
577394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
577494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
577594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // A veneer should have been generated.
57768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
57778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(margin > kBConditionalNarrowRange);
577894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
577994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
578094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
578194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
578294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
578394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  DISASSEMBLE();
578494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
578594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
578694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that conditional B with a far hint use a narrow branch only for a
578794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// near backward branch.
578894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_conditional_far_hint) {
578994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
579094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
579194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
579294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label start;
579394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label end;
579494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
579594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&start);
579694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
579794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
579894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
579994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be narrow.
580094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
580194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k16BitT32InstructionSizeInBytes,
580294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
580394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(eq, &start, kFar);
580494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
580594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
580694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    ExactAssemblyScope scope(&masm,
580794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             kBConditionalNarrowRange,
580894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             ExactAssemblyScope::kExactSize);
580994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    for (int32_t i = 0; i < kBConditionalNarrowRange;
581094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois         i += k16BitT32InstructionSizeInBytes) {
581194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      __ nop();
581294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }
581394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
581494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
581594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a branch which should be wide.
581694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
581794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k32BitT32InstructionSizeInBytes,
581894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
581994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(eq, &start, kFar);
582094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
582194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {
582294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    // Generate a forward branch which should be wide.
582394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    EmissionCheckScope scope(&masm,
582494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             k32BitT32InstructionSizeInBytes,
582594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                             EmissionCheckScope::kExactSize);
582694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(eq, &end, kFar);
582794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
582894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
582994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Bind(&end);
583094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
583194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
583294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
583394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  DISASSEMBLE();
583494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
583594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
583694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
583794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that the veneer pool is correctly emitted even if we do a lot of narrow
583894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// branches.
583994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_narrow_many) {
584094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
584194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
584294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
584394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kLabelsCount = kBNarrowRange / 2;
584494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
584594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label labels[kLabelsCount];
584694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
584794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
584894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
584994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
585094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&labels[i], kNear);
585194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
585294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
585394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
585494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
585594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&labels[i]);
585694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
585794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
585894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
585994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
586094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
586194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
586294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
586394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(0, r0);
586494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
586594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
586694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
586794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// Check that the veneer pool is correctly emitted even if we do a lot of narrow
586894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois// branches and cbz.
586994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(b_narrow_and_cbz) {
587094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  SETUP();
587194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  START();
587294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
587394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  static const int kLabelsCount = kBNarrowRange / 4;
587494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
587594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label b_labels[kLabelsCount];
587694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  Label cbz_labels[kLabelsCount];
587794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
587894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 0);
587994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
588094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
588194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ B(&b_labels[i], kNear);
588294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Cbz(r0, &cbz_labels[i]);
588394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
588494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
588594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 1);
588694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
588794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&b_labels[i]);
588894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
588994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
589094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Mov(r0, 2);
589194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  for (int i = 0; i < kLabelsCount; i++) {
589294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    __ Bind(&cbz_labels[i]);
589394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
589494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
589594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  __ Nop();
589694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
589794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  END();
589894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
589994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  RUN();
590094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
590194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  ASSERT_EQUAL_32(2, r0);
590294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
590394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
590494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
590594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois#define CHECK_SIZE_MATCH(ASM1, ASM2)                                 \
590694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  {                                                                  \
590794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    MacroAssembler masm1(BUF_SIZE);                                  \
590894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm1.UseInstructionSet(isa);                                    \
590994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm1.GetCursorOffset() == 0);                       \
591094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm1.ASM1;                                                      \
591194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm1.FinalizeCode();                                            \
591294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int size1 = masm1.GetCursorOffset();                             \
591394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                                                     \
591494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    MacroAssembler masm2(BUF_SIZE);                                  \
591594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm2.UseInstructionSet(isa);                                    \
591694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_ASSERT(masm2.GetCursorOffset() == 0);                       \
591794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm2.ASM2;                                                      \
591894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    masm2.FinalizeCode();                                            \
591994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    int size2 = masm2.GetCursorOffset();                             \
592094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                                                     \
592194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    bool disassemble = Test::disassemble();                          \
592294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (size1 != size2) {                                            \
592394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      printf("Sizes did not match:\n");                              \
592494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      disassemble = true;                                            \
592594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                \
592694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    if (disassemble) {                                               \
592794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      PrintDisassembler dis(std::cout, 0);                           \
592894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      printf("// " #ASM1 "\n");                                      \
592994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      if (masm1.IsUsingT32()) {                                      \
593094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        dis.DisassembleT32Buffer(masm1.GetBuffer()                   \
593194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                     ->GetStartAddress<uint16_t*>(), \
593294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                 size1);                             \
593394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      } else {                                                       \
593494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        dis.DisassembleA32Buffer(masm1.GetBuffer()                   \
593594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                     ->GetStartAddress<uint32_t*>(), \
593694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                 size1);                             \
593794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }                                                              \
593894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      printf("\n");                                                  \
593994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                                                     \
594094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      dis.SetCodeAddress(0);                                         \
594194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      printf("// " #ASM2 "\n");                                      \
594294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      if (masm2.IsUsingT32()) {                                      \
594394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        dis.DisassembleT32Buffer(masm2.GetBuffer()                   \
594494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                     ->GetStartAddress<uint16_t*>(), \
594594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                 size2);                             \
594694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      } else {                                                       \
594794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois        dis.DisassembleA32Buffer(masm2.GetBuffer()                   \
594894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                     ->GetStartAddress<uint32_t*>(), \
594994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                                 size2);                             \
595094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      }                                                              \
595194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois      printf("\n");                                                  \
595294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    }                                                                \
595394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois    VIXL_CHECK(size1 == size2);                                      \
595494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  }
595594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
595694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
595794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre LangloisTEST_T32(macro_assembler_commute) {
595894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // Test that the MacroAssembler will commute operands if it means it can use a
595994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // 16-bit instruction with the same effect.
596094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
596194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // TODO: The commented-out tests should pass, but don't. When they are fixed,
596294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // we should update this test.
596394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
596494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Adc(DontCare, r7, r6, r7),
596594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Adc(DontCare, r7, r7, r6));
596694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
596794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Adc(DontCare, eq, r7, r6, r7),
596894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Adc(DontCare, eq, r7, r7, r6));
596994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
597094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Add(DontCare, r1, r2, r7), Add(DontCare, r1, r7, r2));
597194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
597294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Add(DontCare, lt, r1, r2, r7),
597394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois                   Add(DontCare, lt, r1, r7, r2));
597494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
597594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(DontCare, r4, r4, r10),
597694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(DontCare, r4, r10, r4));
597794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
597894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(DontCare, eq, r4, r4, r10),
597994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(DontCare, eq, r4, r10, r4));
598094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
598194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(DontCare, r7, sp, r7),
598294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(DontCare, r7, r7, sp));
598394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
598494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(DontCare, eq, r7, sp, r7),
598594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(DontCare, eq, r7, r7, sp));
598694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
598794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(DontCare, sp, sp, r10),
598894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(DontCare, sp, r10, sp));
598994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
599094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(DontCare, eq, sp, sp, r10),
599194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(DontCare, eq, sp, r10, sp));
599294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
599394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(And(DontCare, r7, r7, r6),
599494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  And(DontCare, r7, r6, r7));
599594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
599694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(And(DontCare, eq, r7, r7, r6),
599794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  And(DontCare, eq, r7, r6, r7));
599894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
599994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Eor(DontCare, r7, r7, r6),
600094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Eor(DontCare, r7, r6, r7));
600194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
600294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Eor(DontCare, eq, r7, r7, r6),
600394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Eor(DontCare, eq, r7, r6, r7));
600494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
600594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Mul(DontCare, r0, r1, r0),
600694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Mul(DontCare, r0, r0, r1));
600794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
600894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Mul(DontCare, eq, r0, r1, r0),
600994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Mul(DontCare, eq, r0, r0, r1));
601094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
601194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Orr(DontCare, r7, r7, r6),
601294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Orr(DontCare, r7, r6, r7));
601394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
601494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Orr(DontCare, eq, r7, r7, r6),
601594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Orr(DontCare, eq, r7, r6, r7));
601694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
601794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
601894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adc(r7, r6, r7), Adc(r7, r7, r6));
601994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
602094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Adc(eq, r7, r6, r7),
602194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Adc(eq, r7, r7, r6));
602294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
602394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Add(r1, r2, r7), Add(r1, r7, r2));
602494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
602594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Add(lt, r1, r2, r7), Add(lt, r1, r7, r2));
602694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
602794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(r4, r4, r10),
602894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(r4, r10, r4));
602994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
603094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(eq, r4, r4, r10),
603194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(eq, r4, r10, r4));
603294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
603394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(r7, sp, r7),
603494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(r7, r7, sp));
603594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
603694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(eq, r7, sp, r7),
603794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(eq, r7, r7, sp));
603894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
603994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(sp, sp, r10),
604094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(sp, r10, sp));
604194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
604294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Add(eq, sp, sp, r10),
604394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Add(eq, sp, r10, sp));
604494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
604594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(And(r7, r7, r6), And(r7, r6, r7));
604694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
604794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(And(eq, r7, r7, r6),
604894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  And(eq, r7, r6, r7));
604994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
605094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Eor(r7, r7, r6), Eor(r7, r6, r7));
605194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
605294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Eor(eq, r7, r7, r6),
605394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Eor(eq, r7, r6, r7));
605494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
605594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Mul(r0, r1, r0), Mul(r0, r0, r1));
605694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
605794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Mul(eq, r0, r1, r0),
605894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Mul(eq, r0, r0, r1));
605994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
606094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Orr(r7, r7, r6), Orr(r7, r6, r7));
606194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
606294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Orr(eq, r7, r7, r6),
606394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Orr(eq, r7, r6, r7));
606494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
606594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
606694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Adcs(r7, r6, r7),
606794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Adcs(r7, r7, r6));
606894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
606994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Adcs(eq, r7, r6, r7),
607094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Adcs(eq, r7, r7, r6));
607194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
607294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(r1, r2, r7), Adds(r1, r7, r2));
607394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
607494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(lt, r1, r2, r7), Adds(lt, r1, r7, r2));
607594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
607694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(r4, r4, r10), Adds(r4, r10, r4));
607794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
607894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(eq, r4, r4, r10), Adds(eq, r4, r10, r4));
607994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
608094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(r7, sp, r7), Adds(r7, r7, sp));
608194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
608294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(eq, r7, sp, r7), Adds(eq, r7, r7, sp));
608394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
608494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(sp, sp, r10), Adds(sp, r10, sp));
608594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
608694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  CHECK_SIZE_MATCH(Adds(eq, sp, sp, r10), Adds(eq, sp, r10, sp));
608794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
608894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Ands(r7, r7, r6),
608994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Ands(r7, r6, r7));
609094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
609194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Ands(eq, r7, r7, r6),
609294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Ands(eq, r7, r6, r7));
609394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
609494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Eors(r7, r7, r6),
609594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Eors(r7, r6, r7));
609694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
609794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Eors(eq, r7, r7, r6),
609894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Eors(eq, r7, r6, r7));
609994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
610094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Muls(r0, r1, r0),
610194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Muls(r0, r0, r1));
610294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
610394a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Muls(eq, r0, r1, r0),
610494a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Muls(eq, r0, r0, r1));
610594a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
610694a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Orrs(r7, r7, r6),
610794a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Orrs(r7, r6, r7));
610894a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
610994a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  // CHECK_SIZE_MATCH(Orrs(eq, r7, r7, r6),
611094a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois  //                  Orrs(eq, r7, r6, r7));
611194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}
611294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
61138b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST(emit_pool_when_manually_placing_literal) {
61148b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
61158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
61168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Literal that will be manually placed.
61188b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
61198b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Create one literal pool entry.
61218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r0, r1, 0x1234567890abcdef);
61228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61238b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Branch using the assembler, to avoid introducing a veneer.
61248b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label over_literal;
61258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kBranchSize = 4;
61268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
61278b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(&masm,
61288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             kBranchSize,
61298b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             ExactAssemblyScope::kExactSize);
61308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ b(&over_literal);
61318b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
61328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Almost reach the pool checkpoint.
61348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin =
61358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      test.GetPoolCheckpoint() - masm.GetCursorOffset() - l0.GetSize() / 2;
61368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = masm.GetCursorOffset() + margin;
61378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
61388b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
61398b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    while (masm.GetCursorOffset() < end) {
61408b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      __ nop();
61418b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    }
61428b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
61438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61448b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
61458b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Place(&l0);
61468b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // The pool must now have been emitted.
61478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
61488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Bind(&over_literal);
61508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61518b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r2, r3, &l0);
61528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61538b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
61548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61558b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
61568b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  ASSERT_EQUAL_32(0x90abcdef, r0);
61588b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  ASSERT_EQUAL_32(0x12345678, r1);
61598b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r2);
61608b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r3);
61618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
61628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61638b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61648b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// The addition of padding only happens for T32.
61658b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_T32(emit_pool_when_adding_padding_due_to_bind) {
61668b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
61678b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
61688b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61698b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Make sure we start with a 4-byte aligned address, in order for the
61708b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // location where we will call Bind() to be 4-byte aligned.
61718b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
61728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(&masm,
61738b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             k16BitT32InstructionSizeInBytes,
61748b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             ExactAssemblyScope::kMaximumSize);
61758b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    while (masm.GetCursorOffset() % 4 != 0) {
61768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      __ nop();
61778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    }
61788b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
61798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61808b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Create one literal pool entry.
61818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r0, r1, 0x1234567890abcdef);
61828b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Almost reach the pool checkpoint.
61848b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kPaddingBytes = 2;
61858b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t margin =
61868b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      test.GetPoolCheckpoint() - masm.GetCursorOffset() - kPaddingBytes;
61878b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = masm.GetCursorOffset() + margin;
61888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
61898b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
61908b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    while (masm.GetCursorOffset() < end) {
61918b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      __ nop();
61928b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    }
61938b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
61948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61958b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label label;
61968b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Cbz(r0, &label);
61978b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
61988b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
61998b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // In order to hit the case where binding the label needs to add padding,
62008b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // we need this to be a 4-byte aligned address.
62018b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 0);
62028b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62038b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Bind(&label);
62048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // The pool must now have been emitted.
62058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
62068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
62088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62098b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
62108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  ASSERT_EQUAL_32(0x90abcdef, r0);
62128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  ASSERT_EQUAL_32(0x12345678, r1);
62138b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
62148b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouvelistatic void AddBranchesAndGetCloseToCheckpoint(MacroAssembler* masm,
62168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                               TestMacroAssembler* test,
62178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                               const int kLabelsCount,
62188b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                               Label b_labels[],
62198b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                               int32_t margin) {
62208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Add many veneers to the pool.
62218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kLabelsCount; i++) {
62228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm->B(&b_labels[i]);
62238b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
62248b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Get close to the veneer emission margin (considering the heuristic).
62268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Use add instead of nop to make viewing the disassembled code easier.
62278b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kAddSize = masm->IsUsingT32() ? k16BitT32InstructionSizeInBytes
62288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                          : kA32InstructionSizeInBytes;
62298b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t end = test->GetPoolCheckpoint();
62308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  int32_t space = end - masm->GetCursorOffset() - margin;
62318b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
62328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(masm, space, ExactAssemblyScope::kExactSize);
62338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    while (space > 0) {
62348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      masm->add(r0, r0, r0);
62358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      space -= kAddSize;
62368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    }
62378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
62388b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62398b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Make sure the veneers have not yet been emitted.
62408b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kVeneerSize = 4;
62418b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test->GetPoolSize() == kLabelsCount * kVeneerSize);
62428b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
62438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62448b57c86886020cf0a5331823be4789ee558764e2Georgia Kouvelistatic void EmitIndividualNops(MacroAssembler* masm, const int kNops) {
62458b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kNops; ++i) {
62468b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    masm->Nop();
62478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
62488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
62498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouvelistatic void EmitNopsInExactAssemblyScope(MacroAssembler* masm,
62518b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                         const int kNops) {
62528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kNopSize = masm->IsUsingT32() ? k16BitT32InstructionSizeInBytes
62538b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                          : kA32InstructionSizeInBytes;
62548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
62558b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(masm,
62568b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             kNops * kNopSize,
62578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                             ExactAssemblyScope::kExactSize);
62588b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    for (int i = 0; i < kNops; i++) {
62598b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli      masm->nop();
62608b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    }
62618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
62628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
62638b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62648b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_A32(literal_and_veneer_interaction_1) {
62658b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
62668b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
62678b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62688b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  static const int kLabelsCount = 100;
62698b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62708b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label b_labels[kLabelsCount];
62718b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  AddBranchesAndGetCloseToCheckpoint(&masm,
62738b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     &test,
62748b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     kLabelsCount,
62758b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     b_labels,
62768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     1 * KBytes);
62778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62788b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Emit a load of a large string. In the past, we have attempted to emit
62798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // the literal load without emitting the veneers, which meant that we were
62808b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // left with an impossible scheduling problem for the pool objects (due to
62818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // the short range of the ldrd).
62828b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  std::string test_string(2 * KBytes, 'x');
62838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  StringLiteral big_literal(test_string.c_str());
62848b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r0, r1, &big_literal);
62858b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62868b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitIndividualNops(&masm, 1000);
62878b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // We can now safely bind the labels.
62898b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kLabelsCount; i++) {
62908b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ Bind(&b_labels[i]);
62918b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
62928b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62938b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
62948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62958b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
62968b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
62978b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62988b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
62998b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_A32(literal_and_veneer_interaction_2) {
63008b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
63018b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
63028b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63038b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  static const int kLabelsCount = 100;
63048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label b_labels[kLabelsCount];
63068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  AddBranchesAndGetCloseToCheckpoint(&masm,
63088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     &test,
63098b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     kLabelsCount,
63108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     b_labels,
63118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     1 * KBytes);
63128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63138b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // This is similar to the test above. The Ldr instruction can be emitted with
63148b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // no problems. The Ldrd used to force emission of the literal pool, pushing
63158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // the veneers out of range - we make sure this does not happen anymore.
63168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  std::string test_string(2 * KBytes, 'z');
63178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  StringLiteral big_literal(test_string.c_str());
63188b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldr(r2, &big_literal);
63198b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const int kVeneerSize = 4;
63218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  CHECK_POOL_SIZE(kLabelsCount * kVeneerSize + big_literal.GetSize());
63228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63238b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  std::string test_string2(2 * KBytes, 'x');
63248b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  StringLiteral big_literal2(test_string.c_str());
63258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r0, r1, &big_literal2);
63268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63278b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitIndividualNops(&masm, 1000);
63288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63298b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kLabelsCount; i++) {
63308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ Bind(&b_labels[i]);
63318b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
63328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
63348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
63368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
63378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63388b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63398b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_A32(literal_and_veneer_interaction_3) {
63408b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
63418b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
63428b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  static const int kLabelsCount = 100;
63448b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label b_labels[kLabelsCount];
63458b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63468b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  AddBranchesAndGetCloseToCheckpoint(&masm,
63478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     &test,
63488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     kLabelsCount,
63498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     b_labels,
63508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     1 * KBytes);
63518b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Here, we used to emit the Ldrd instruction and then emit the veneers
63538b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // before the literal is emitted, hence pushing the Ldrd out of range.
63548b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Make sure this does not happen anymore.
63558b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r2, r3, 0x12345678);
63568b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63578b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // The issue would only appear when emitting the nops in a single scope.
63588b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitNopsInExactAssemblyScope(&masm, 4096);
63598b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63608b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kLabelsCount; i++) {
63618b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ Bind(&b_labels[i]);
63628b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
63638b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63648b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
63658b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63668b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
63678b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
63688b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63698b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63708b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Equivalent to literal_and_veneer_interaction_1, but for T32.
63718b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_T32(literal_and_veneer_interaction_4) {
63728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
63738b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
63748b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63758b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  static const int kLabelsCount = 550;
63768b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63778b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label b_labels[kLabelsCount];
63788b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63798b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  AddBranchesAndGetCloseToCheckpoint(&masm,
63808b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     &test,
63818b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     kLabelsCount,
63828b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     b_labels,
63838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     KBytes / 2);
63848b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63858b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  std::string test_string(3 * KBytes, 'x');
63868b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  StringLiteral big_literal(test_string.c_str());
63878b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r0, r1, &big_literal);
63888b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63898b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitIndividualNops(&masm, 2000);
63908b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63918b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kLabelsCount; i++) {
63928b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ Bind(&b_labels[i]);
63938b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
63948b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63958b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
63968b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
63978b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
63988b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
63998b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64008b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Equivalent to literal_and_veneer_interaction_3, but for T32.
64018b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_T32(literal_and_veneer_interaction_5) {
64028b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
64038b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
64048b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64058b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  static const int kLabelsCount = 550;
64068b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label b_labels[kLabelsCount];
64078b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64088b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  AddBranchesAndGetCloseToCheckpoint(&masm,
64098b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     &test,
64108b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     kLabelsCount,
64118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     b_labels,
64128b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli                                     1 * KBytes);
64138b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64148b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ Ldrd(r2, r3, 0x12345678);
64158b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64168b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitNopsInExactAssemblyScope(&masm, 4096);
64178b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64188b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  for (int i = 0; i < kLabelsCount; i++) {
64198b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ Bind(&b_labels[i]);
64208b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
64218b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64228b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
64238b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64248b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
64258b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
64268b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64278b57c86886020cf0a5331823be4789ee558764e2Georgia KouveliTEST_T32(assembler_bind_label) {
64288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  SETUP();
64298b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  START();
64308b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64318b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  Label label;
64328b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  __ B(eq, &label, kNear);
64338b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64348b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // At this point we keep track of the veneer in the pool.
64358b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(!test.PoolIsEmpty());
64368b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64378b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  {
64388b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    // Bind the label with the assembler.
64398b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
64408b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    __ bind(&label);
64418b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  }
64428b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64438b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  // Make sure the pool is now empty.
64448b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  VIXL_CHECK(test.PoolIsEmpty());
64458b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64468b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  EmitNopsInExactAssemblyScope(&masm, 4096);
64478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  END();
64498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
64508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  RUN();
64518b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli}
645294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois
64535d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli#ifdef VIXL_DEBUG
64545d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli#define TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)    \
64555d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli  POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM) \
64565d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli  NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)
64575d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli#else
64585d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli// Skip the negative tests for release builds, as they require debug-only checks
64595d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli// in ExactAssemblyScope.
64605d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli#define TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM) \
64615d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli  POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)
64625d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli#endif
64635d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli
64645d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli#define POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)                \
64654b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  can_encode = masm.INFO;                                                    \
64664b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  VIXL_CHECK(can_encode);                                                    \
64674b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  {                                                                          \
64684b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ExactAssemblyScope scope(&masm,                                          \
64694b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             info->size,                                     \
64704b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             ExactAssemblyScope::kExactSize);                \
64714b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
64728b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
64734b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli      pc = AlignDown(pc, 4);                                                 \
64744b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    }                                                                        \
64754b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    Label label(pc + info->min_offset);                                      \
64764b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    masm.ASM;                                                                \
64774b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  }                                                                          \
64784b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  {                                                                          \
64794b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ExactAssemblyScope scope(&masm,                                          \
64804b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             info->size,                                     \
64814b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             ExactAssemblyScope::kExactSize);                \
64824b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
64838b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
64844b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli      pc = AlignDown(pc, 4);                                                 \
64854b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    }                                                                        \
64864b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    Label label(pc + info->max_offset);                                      \
64874b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    masm.ASM;                                                                \
64885d1d9ee085e6f297b4b74a26719dcf8700a125a4Georgia Kouveli  }
64894b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
64904b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli#ifdef VIXL_NEGATIVE_TESTING
64914b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli#define NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)                      \
64924b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  try {                                                                      \
64934b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ExactAssemblyScope scope(&masm,                                          \
64944b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             info->size,                                     \
64954b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             ExactAssemblyScope::kMaximumSize);              \
64964b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
64978b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
64984b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli      pc = AlignDown(pc, 4);                                                 \
64994b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    }                                                                        \
65004b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    Label label(pc + info->max_offset + info->alignment);                    \
65014b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    masm.ASM;                                                                \
65024b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    printf("Negative test for forward reference failed for %s.\n", INST);    \
65034b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    abort();                                                                 \
65044b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  } catch (std::runtime_error) {                                             \
65054b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  }                                                                          \
65064b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  try {                                                                      \
65074b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ExactAssemblyScope scope(&masm,                                          \
65084b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             info->size,                                     \
65094b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli                             ExactAssemblyScope::kMaximumSize);              \
65104b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
65118b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli    if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
65124b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli      pc = AlignDown(pc, 4);                                                 \
65134b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    }                                                                        \
65144b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    Label label(pc + info->min_offset - info->alignment);                    \
65154b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    masm.ASM;                                                                \
65164b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    printf("Negative test for forward reference failed for %s.\n", INST);    \
65174b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    abort();                                                                 \
65184b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  } catch (std::runtime_error) {                                             \
65194b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  }
65204b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli#else
65214b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli#define NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)
65224b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli#endif
65234b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65244b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia KouveliTEST_T32(forward_reference_info_T32) {
65254b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  MacroAssembler masm(BUF_SIZE, T32);
65264b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65274b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  Label unbound;
65288b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const ReferenceInfo* info;
65294b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  bool can_encode;
65304b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65314b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  // clang-format off
65324b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65334b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65344b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "adr",
65354b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr_info(al, Narrow, r0, &unbound, &info),
65364b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr(al, Narrow, r0, &label));
65374b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65384b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65394b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "adr",
65404b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr_info(al, Wide, r0, &unbound, &info),
65414b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr(al, Wide, r0, &label));
65424b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65434b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65444b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "adr",
65454b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr_info(al, Best, r0, &unbound, &info),
65464b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr(al, Best, r0, &label));
65474b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65484b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65494b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
65504b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(al, Narrow, &unbound, &info),
65514b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(al, Narrow, &label));
65524b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65534b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65544b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
65554b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(al, Wide, &unbound, &info),
65564b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(al, Wide, &label));
65574b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65584b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65594b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
65604b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(al, Best, &unbound, &info),
65614b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(al, Best, &label));
65624b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65634b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65644b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
65654b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(gt, Narrow, &unbound, &info),
65664b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(gt, Narrow, &label));
65674b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65684b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65694b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
65704b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(gt, Wide, &unbound, &info),
65714b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(gt, Wide, &label));
65724b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65734b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65744b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
65754b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(gt, Best, &unbound, &info),
65764b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(gt, Best, &label));
65774b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65784b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65794b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "bl",
65804b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    bl_info(al, &unbound, &info),
65814b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    bl(al, &label));
65824b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65834b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65844b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "blx",
65854b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    blx_info(al, &unbound, &info),
65864b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    blx(al, &label));
65874b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65884b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65894b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "cbnz",
65904b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    cbnz_info(r0, &unbound, &info),
65914b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    cbnz(r0, &label));
65924b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65934b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65944b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "cbz",
65954b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    cbz_info(r0, &unbound, &info),
65964b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    cbz(r0, &label));
65974b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
65984b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
65994b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldr",
66004b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr_info(al, Narrow, r0, &unbound, &info),
66014b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr(al, Narrow, r0, &label));
66024b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66034b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66044b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldr",
66054b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr_info(al, Wide, r0, &unbound, &info),
66064b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr(al, Wide, r0, &label));
66074b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66084b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66094b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldr",
66104b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr_info(al, Best, r0, &unbound, &info),
66114b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr(al, Best, r0, &label));
66124b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66134b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66144b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrb",
66154b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrb_info(al, r0, &unbound, &info),
66164b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrb(al, r0, &label));
66174b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66184b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66194b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrd",
66204b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrd_info(al, r0, r1, &unbound, &info),
66214b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrd(al, r0, r1, &label));
66224b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66234b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66244b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrh",
66254b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrh_info(al, r0, &unbound, &info),
66264b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrh(al, r0, &label));
66274b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66284b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66294b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrsb",
66304b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsb_info(al, r0, &unbound, &info),
66314b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsb(al, r0, &label));
66324b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66334b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66344b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrsh",
66354b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsh_info(al, r0, &unbound, &info),
66364b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsh(al, r0, &label));
66374b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66384b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66394b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "pld",
66404b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pld_info(al, &unbound, &info),
66414b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pld(al, &label));
66424b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66434b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66444b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "pli",
66454b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pli_info(al, &unbound, &info),
66464b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pli(al, &label));
66474b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66484b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66494b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "vldr",
66504b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr_info(al, Untyped64, d0, &unbound, &info),
66514b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr(al, Untyped64, d0, &label));
66524b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66534b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66544b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "vldr",
66554b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr_info(al, Untyped32, s0, &unbound, &info),
66564b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr(al, Untyped32, s0, &label));
66574b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66584b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  // clang-format on
66594b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66604b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  masm.FinalizeCode();
66614b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli}
66624b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66634b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia KouveliTEST_A32(forward_reference_info_A32) {
66644b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  MacroAssembler masm(BUF_SIZE, A32);
66654b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  Label unbound;
66668b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli  const ReferenceInfo* info;
66674b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  bool can_encode;
66684b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66694b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  // clang-format off
66704b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66714b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66724b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "adr",
66734b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr_info(al, Best, r0, &unbound, &info),
66744b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    adr(al, Best, r0, &label));
66754b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66764b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66774b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
66784b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(al, Best, &unbound, &info),
66794b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(al, Best, &label));
66804b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66814b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66824b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "b",
66834b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b_info(gt, Best, &unbound, &info),
66844b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    b(gt, Best, &label));
66854b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66864b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66874b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "bl",
66884b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    bl_info(al, &unbound, &info),
66894b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    bl(al, &label));
66904b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66914b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66924b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "blx",
66934b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    blx_info(al, &unbound, &info),
66944b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    blx(al, &label));
66954b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
66964b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
66974b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldr",
66984b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr_info(al, Best, r0, &unbound, &info),
66994b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldr(al, Best, r0, &label));
67004b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67014b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67024b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrb",
67034b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrb_info(al, r0, &unbound, &info),
67044b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrb(al, r0, &label));
67054b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67064b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67074b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrd",
67084b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrd_info(al, r0, r1, &unbound, &info),
67094b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrd(al, r0, r1, &label));
67104b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67114b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67124b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrh",
67134b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrh_info(al, r0, &unbound, &info),
67144b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrh(al, r0, &label));
67154b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67164b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67174b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrsb",
67184b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsb_info(al, r0, &unbound, &info),
67194b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsb(al, r0, &label));
67204b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67214b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67224b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "ldrsh",
67234b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsh_info(al, r0, &unbound, &info),
67244b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    ldrsh(al, r0, &label));
67254b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67264b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67274b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "pld",
67284b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pld_info(al, &unbound, &info),
67294b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pld(al, &label));
67304b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67314b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67324b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "pli",
67334b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pli_info(al, &unbound, &info),
67344b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    pli(al, &label));
67354b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67364b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67374b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "vldr",
67384b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr_info(al, Untyped64, d0, &unbound, &info),
67394b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr(al, Untyped64, d0, &label));
67404b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67414b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  TEST_FORWARD_REFERENCE_INFO(
67424b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    "vldr",
67434b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr_info(al, Untyped32, s0, &unbound, &info),
67444b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli    vldr(al, Untyped32, s0, &label));
67454b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67464b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  // clang-format on
67474b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
67484b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli  masm.FinalizeCode();
67494b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli}
67504b139a2dd8a7c32fc0f7df0cfd36d6c1336bc26cGeorgia Kouveli
675194a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}  // namespace aarch32
675294a02bb2b5f7c85dc5a3852aac8c6692f9c6c446Pierre Langlois}  // namespace vixl
6753