1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2015, VIXL authors
288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// All rights reserved.
388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//
488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Redistribution and use in source and binary forms, with or without
588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// modification, are permitted provided that the following conditions are met:
688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//
788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//   * Redistributions of source code must retain the above copyright notice,
888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//     this list of conditions and the following disclaimer.
988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//   * Redistributions in binary form must reproduce the above copyright notice,
1088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//     this list of conditions and the following disclaimer in the documentation
1188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//     and/or other materials provided with the distribution.
1288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//   * Neither the name of ARM Limited nor the names of its contributors may be
1388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//     used to endorse or promote products derived from this software without
1488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//     specific prior written permission.
1588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois//
1688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
1788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
2088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
2778973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langlois#include <cstdio>
2888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include <string>
2988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include <iostream>
3088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
3188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include "test-runner.h"
3288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include "test-utils.h"
33d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/test-utils-aarch32.h"
3488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
35d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/macro-assembler-aarch32.h"
36d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/disasm-aarch32.h"
3788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
3888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace vixl {
3988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch32 {
4088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
412ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta#define STRINGIFY(x) #x
422ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta
439a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_A32_ONLY
44bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST_T32(Name) \
45bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
469a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#else
479a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta// Tests declared with this macro will only target T32.
48bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST_T32(Name)                                          \
49bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa);                    \
50bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name() { Test##Name##Impl(T32); }                  \
51bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_T32_##Name), &Test##Name); \
52bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
539a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
542ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta
559a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_T32_ONLY
56bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST_A32(Name) \
57bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
589a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#else
592ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta// Test declared with this macro will only target A32.
60bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST_A32(Name)                                          \
61bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa);                    \
62bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name() { Test##Name##Impl(A32); }                  \
63bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_A32_##Name), &Test##Name); \
64bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
659a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
662ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta
679a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta// Tests declared with this macro will be run twice: once targeting A32 and
689a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta// once targeting T32.
699a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#if defined(VIXL_INCLUDE_TARGET_A32_ONLY)
70bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST(Name) TEST_A32(Name)
719a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#elif defined(VIXL_INCLUDE_TARGET_T32_ONLY)
72bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST(Name) TEST_T32(Name)
739a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#else
74bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST(Name)                                              \
75bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa);                    \
76bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name() {                                           \
77bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    Test##Name##Impl(A32);                                      \
78bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    printf(" > A32 done\n");                                    \
79bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    Test##Name##Impl(T32);                                      \
80bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    printf(" > T32 done\n");                                    \
81bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  }                                                             \
82bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_ASM_##Name), &Test##Name); \
83bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
849a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
852ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta
862ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta// Tests declared with this macro are not expected to use any provided test
872ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta// helpers such as SETUP, RUN, etc.
88bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEST_NOASM(Name)                                    \
89bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name();                                        \
90bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  Test test_##Name(STRINGIFY(AARCH32_##Name), &Test##Name); \
91bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  void Test##Name()
9288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
932ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta#define __ masm.
9488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define BUF_SIZE (4096)
9588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
96bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_LITERAL_POOL_SIZE(size)           \
97bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  do {                                           \
98bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_CHECK(__ GetLiteralPoolSize() == size); \
99bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  } while (false)
10088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
1011e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
10288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// No simulator yet.
10388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
104bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define SETUP() MacroAssembler masm(BUF_SIZE, isa);
10588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
106bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define START() masm.GetBuffer()->Reset();
10788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
108bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define END() \
109bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Hlt(0);  \
11088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ FinalizeCode();
11188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
112bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define RUN() DISASSEMBLE();
11388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
11488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define TEARDOWN()
11588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
1161e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#else  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32.
11788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
118bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define SETUP()                                   \
119bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  RegisterDump core;                              \
120bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  MacroAssembler masm(BUF_SIZE, isa);             \
121bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  UseScratchRegisterScope harness_scratch(&masm); \
1224cb13e841305b38acbd8195b1c511d59c91ec8d9Georgia Kouveli  harness_scratch.ExcludeAll();
12388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
124bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define START()              \
125bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  masm.GetBuffer()->Reset(); \
126bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r4);               \
127bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r5);               \
128bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r6);               \
129bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r7);               \
130bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r8);               \
131bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r9);               \
132bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r10);              \
133bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(r11);              \
134bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(ip);               \
135bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Push(lr);               \
136bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Mov(r0, 0);             \
137bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Msr(APSR_nzcvq, r0);    \
1384cb13e841305b38acbd8195b1c511d59c91ec8d9Georgia Kouveli  harness_scratch.Include(ip);
13988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
140bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define END()                  \
141bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  harness_scratch.Exclude(ip); \
142bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  core.Dump(&masm);            \
143bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(lr);                  \
144bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(ip);                  \
145bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r11);                 \
146bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r10);                 \
147bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r9);                  \
148bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r8);                  \
149bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r7);                  \
150bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r6);                  \
151bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r5);                  \
152bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Pop(r4);                  \
153bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Bx(lr);                   \
154cb6592f4b00347a84f9d7638473f0af8f1b6b1ddGeorgia Kouveli  __ FinalizeCode();
15588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
15631dd2ae90d5e82871667fbf3ee2697a155e7c3acAlex Gilday// Execute the generated code from the MacroAssembler's automatic code buffer.
15731dd2ae90d5e82871667fbf3ee2697a155e7c3acAlex Gilday// Note the offset for ExecuteMemory since the PCS requires that
15888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// the address be odd in the case of branching to T32 code.
159bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define RUN()                                                 \
160bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  DISASSEMBLE();                                              \
161bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  {                                                           \
162bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    int pcs_offset = masm.IsUsingT32() ? 1 : 0;               \
163bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm.GetBuffer()->SetExecutable();                        \
164bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(), \
165bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                  masm.GetSizeOfCodeGenerated(),              \
166bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                  pcs_offset);                                \
167bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm.GetBuffer()->SetWritable();                          \
16888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
16988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
170bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define TEARDOWN() harness_scratch.Close();
17188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
1721e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#endif  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
17388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
1741e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
17588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// No simulator yet. We can't test the results.
17688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
17788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define ASSERT_EQUAL_32(expected, result)
17888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
17988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define ASSERT_EQUAL_64(expected, result)
18088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
18188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define ASSERT_EQUAL_128(expected_h, expected_l, result)
18288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define ASSERT_EQUAL_FP32(expected, result)
18488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
18588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define ASSERT_EQUAL_FP64(expected, result)
18688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
18788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define ASSERT_EQUAL_NZCV(expected)
18888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
18988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#else
19088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
191bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_EQUAL_32(expected, result) \
1920ec9dc10536b569b807274627e8c61bf6d6ceae7Pierre Langlois  VIXL_CHECK(Equal32(expected, &core, result))
19388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
194bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_EQUAL_64(expected, result) \
1950ec9dc10536b569b807274627e8c61bf6d6ceae7Pierre Langlois  VIXL_CHECK(Equal64(expected, &core, result))
19688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
197bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_EQUAL_128(expected_h, expected_l, result) \
1980ec9dc10536b569b807274627e8c61bf6d6ceae7Pierre Langlois  VIXL_CHECK(Equal128(expected_h, expected_l, &core, result))
19988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
200bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_EQUAL_FP32(expected, result) \
2010ec9dc10536b569b807274627e8c61bf6d6ceae7Pierre Langlois  VIXL_CHECK(EqualFP32(expected, &core, result))
20288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
203bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_EQUAL_FP64(expected, result) \
2040ec9dc10536b569b807274627e8c61bf6d6ceae7Pierre Langlois  VIXL_CHECK(EqualFP64(expected, &core, result))
20588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
206bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ASSERT_EQUAL_NZCV(expected) \
2070ec9dc10536b569b807274627e8c61bf6d6ceae7Pierre Langlois  VIXL_CHECK(EqualNzcv(expected, core.flags_nzcv()))
20888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
20988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif
21088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
211bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define DISASSEMBLE()                                                          \
212bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois  if (Test::disassemble()) {                                                   \
213bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois    PrintDisassembler dis(std::cout, 0);                                       \
214bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois    if (masm.IsUsingT32()) {                                                   \
215919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames      dis.DisassembleT32Buffer(masm.GetBuffer()->GetStartAddress<uint16_t*>(), \
216bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois                               masm.GetCursorOffset());                        \
217bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois    } else {                                                                   \
218919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames      dis.DisassembleA32Buffer(masm.GetBuffer()->GetStartAddress<uint32_t*>(), \
219bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois                               masm.GetCursorOffset());                        \
220bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois    }                                                                          \
221bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois  }
222bc01be684fe63a8a8c785f92e8aaa080cb6e87faPierre Langlois
22388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// TODO: Add SBC to the ADC tests.
22488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
22588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
22688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(adc_shift) {
22788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
22888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
22988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
23088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Initialize registers.
23188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
23288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 1);
23388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x01234567);
23488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 0xfedcba98);
23588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
23688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
23788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
23888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
23988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r4, r2, r3);
24088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r5, r0, Operand(r1, LSL, 30));
24188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r6, r0, Operand(r2, LSR, 16));
24288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r7, r2, Operand(r3, ASR, 4));
24388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r8, r2, Operand(r3, ROR, 8));
24488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r9, r2, Operand(r3, RRX));
24588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
24688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
24788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
24888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
24988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r4);
25088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(INT32_C(1) << 30, r5);
25188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000123, r6);
25288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x01111110, r7);
25388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x9a222221, r8);
25488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x8091a2b3, r9);
25588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
25688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
25788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Initialize registers.
25888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
25988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 1);
26088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x01234567);
26188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 0xfedcba98);
26288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r4, 0xffffffff);
26388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
26488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag.
26588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r4, r1);
26688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
26788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r5, r2, r3);
26888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r6, r0, Operand(r1, LSL, 30));
26988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r7, r0, Operand(r2, LSR, 16));
27088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r8, r2, Operand(r3, ASR, 4));
27188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r9, r2, Operand(r3, ROR, 8));
27288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r10, r2, Operand(r3, RRX));
27388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
27488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
27588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
27688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
27788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xffffffff + 1, r5);
27888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, r6);
27988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000123 + 1, r7);
28088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x01111110 + 1, r8);
28188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x9a222221 + 1, r9);
28288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0091a2b3 + 1, r10);
28388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
28488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that adc correctly sets the condition flags.
28588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
28688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
28788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xffffffff);
28888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 1);
28988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
29088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
29188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
29288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, r1);
29388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
29488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
29588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
29688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
29788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
29888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r3);
29988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
30088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x80000000);
30388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 1);
30488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
30588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
30688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
30788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, Operand(r1, ASR, 31));
30888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
30988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
31088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
31188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
31288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
31388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r3);
31488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
31588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
31688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
31788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x80000000);
31888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
31988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
32088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
32188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
32288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, Operand(r1, LSR, 31));
32388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
32488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
32588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
32688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
32788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
32888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r3);
32988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
33088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
33188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
33288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x07ffffff);
33388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x10);
33488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
33588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
33688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
33788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, Operand(r1, LSL, 4));
33888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
33988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
34088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
34188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
34288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NVFlag);
34388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x080000000, r3);
34488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
34588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
34688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
34788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xffffff00);
34888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xff000001);
34988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
35088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
35188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
35288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, Operand(r1, ROR, 8));
35388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
35588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
35688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
35788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
35888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r3);
35988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
36088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
36188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
36288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xffffffff);
36388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x1);
36488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
36588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
36688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
36788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, Operand(r1, RRX));
36888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
36988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
37088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
37188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
37288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NVFlag);
37388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r3);
37488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
37588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
37688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
37788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xffffffff);
37888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x1);
37988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
38088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
38188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r1, r2);
38288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adcs(r3, r2, Operand(r1, RRX));
38388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
38488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
38588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
38688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
38788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(CFlag);
38888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(1, r3);
38988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
39088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
39188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
39288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
39388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
39488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(adc_wide_imm) {
39588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
39688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
39788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
39888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
39988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
40088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
40188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
40288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
40388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r1, r0, 0x12345678);
40488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r2, r0, 0xffffffff);
40588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
40688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag.
40788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cmp(r0, r0);
40888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
40988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r3, r0, 0x12345678);
41088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adc(r4, r0, 0xffffffff);
41188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
41288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
41388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
41488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
41588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
41688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r2);
41788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678 + 1, r3);
41888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r4);
41988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
42088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
42188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
42288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
42388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
42488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// TODO: Add SUB tests to the ADD tests.
42588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
42688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
42788c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(add_imm) {
42888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
42988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
43088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
43188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
43288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x1111);
43388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
43488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 0x80000000);
43588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
43688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r4, r0, 0x12);
43788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r5, r1, 0x120000);
43888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r6, r0, 0xab << 12);
43988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r7, r2, 1);
44088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
44188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
44288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
44388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
44488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
44588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12, r4);
44688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x121111, r5);
44788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xab000, r6);
44888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0, r7);
44988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
45088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
45188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
45288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
45388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
45488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(add_wide_imm) {
45588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
45688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
45788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
45888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
45988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 1);
46088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
46188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r2, r0, 0x12345678);
46288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r1, 0xffff);
46388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
46488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
46588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
46688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
46788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
46888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00010000, r3);
46988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
47088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
47188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
47288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
47388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
47488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(add_shifted) {
47588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
47688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
47788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
47888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
47988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x01234567);
48088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x76543210);
48188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 0xffffffff);
48288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
48388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r4, r1, r2);
48488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r5, r0, Operand(r1, LSL, 8));
48588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r6, r0, Operand(r1, LSR, 8));
48688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r7, r0, Operand(r1, ASR, 8));
48788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r8, r3, Operand(r1, ROR, 8));
48888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
48988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag.
49088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r3, 1);
49188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r9, r3, Operand(r1, RRX));
49288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
49388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
49488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r0, r0, 0);
49588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r10, r3, Operand(r1, RRX));
49688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
49788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
49888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
49988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
50088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
50188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x77777777, r4);
50288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x23456700, r5);
50388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00012345, r6);
50488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00012345, r7);
50588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x67012344, r8);
50688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x8091a2b2, r9);
50788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0091a2b2, r10);
50888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
50988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
51088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
51188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
51288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
51388c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(and_) {
51488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
51588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
51688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
51788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x0000fff0);
51888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
51988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
52088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
52188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r3, r0, r1);
52288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r4, r0, Operand(r1, LSL, 4));
52388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r5, r0, Operand(r1, LSR, 1));
52488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r6, r0, Operand(r1, ASR, 20));
52588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r7, r0, Operand(r1, ROR, 28));
52688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r8, r0, 0xff);
52788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
52888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag.
52988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r9, r2, 1);
53088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r9, r1, Operand(r1, RRX));
53188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
53288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
53388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r10, r0, 0);
53488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ And(r10, r1, Operand(r1, RRX));
53588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
53688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
53788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
53888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
53988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x000000f0, r3);
54088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000ff0, r4);
54188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000070, r5);
54288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0000ff00, r6);
54388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000ff0, r7);
54488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x000000f0, r8);
54588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xf000007f, r9);
54688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x7000007f, r10);
54788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
54888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
54988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
55088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
55188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
55288c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(ands) {
55388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
55488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
55588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
55688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
55788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
55888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
55988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r1, r1);
56088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
56188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
56288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
56388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
56488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
56588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xf00000ff, r0);
56688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
56788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
56888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x00fff000);
56988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
57088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
57188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r0, Operand(r1, LSL, 4));
57288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
57388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
57488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
57588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
57688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
57788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
57888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
57988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
58088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x0000fff0);
58188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
58288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
58388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r0, Operand(r1, LSR, 4));
58488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
58588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
58688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
58788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
58888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
58988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
59088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
59188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
59288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xf000fff0);
59388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
59488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
59588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r0, Operand(r1, ASR, 4));
59688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
59788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
59888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
59988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
60088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
60188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xf0000000, r0);
60288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
60388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
60488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x80000000);
60588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x00000001);
60688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
60788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r0, Operand(r1, ROR, 1));
60888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
60988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
61088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
61188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
61388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
61488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
61588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
61688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x80000000);
61788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x80000001);
61888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
61988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
62088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r2, r0, 0);
62188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r2, r0, Operand(r1, RRX));
62288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
62388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
62488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
62588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
62688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
62788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r2);
62888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
62988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
63088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x80000000);
63188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x80000001);
63288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
63388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
63488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
63588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r2, r2, 1);
63688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r2, r0, Operand(r1, RRX));
63788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
63888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
63988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
64088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
64188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
64288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r2);
64388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
64488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
64588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xfff0);
64688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
64788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r0, 0xf);
64888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
64988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
65088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
65188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
65288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
65388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
65488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
65588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
65688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xff000000);
65788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
65888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ands(r0, r0, 0x80000000);
65988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
66088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
66188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
66288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
66388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
66488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
66588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
66688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
66788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
66888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
66988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
6705c01c410ae559d0a77d68a023957c5bc9de143e0Pierre LangloisTEST(adr_in_range) {
67188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
67288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
67388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label label_1, label_2, label_3, label_4;
67488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
67588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
6765c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois  {
6775c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    size_t size_of_generated_code;
6785c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    if (masm.IsUsingA32()) {
6795c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      size_of_generated_code = 18 * kA32InstructionSizeInBytes;
6805c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    } else {
6815c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      size_of_generated_code = 18 * k32BitT32InstructionSizeInBytes +
6825c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois                               3 * k16BitT32InstructionSizeInBytes;
6835c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    }
684bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm,
685bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                             size_of_generated_code,
6865c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois                             ExactAssemblyScope::kExactSize);
6875c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
688bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ mov(r0, 0x0);  // Set to zero to indicate success.
6895c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ adr(r1, &label_3);
6905c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
691bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ adr(r2, &label_1);  // Multiple forward references to the same label.
6925c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ adr(r3, &label_1);
6935c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ adr(r4, &label_1);
6945c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
6955c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bind(&label_2);
6965c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ eor(r5, r2, r3);  // Ensure that r2, r3 and r4 are identical.
6975c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ eor(r6, r2, r4);
6985c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ orr(r0, r5, r6);
6995c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    if (masm.IsUsingT32()) {
7005c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
7015c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // that we are jumping into thumb mode.
7025c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      __ orr(r2, r2, 1);
7035c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    }
7045c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bx(r2);  // label_1, label_3
7055c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
7065c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bind(&label_3);
707bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ adr(r2, &label_3);  // Self-reference (offset 0).
7085c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ eor(r1, r1, r2);
709bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ adr(r2, &label_4);  // Simple forward reference.
7105c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    if (masm.IsUsingT32()) {
7115c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
7125c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // that we are jumping into thumb mode.
7135c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      __ orr(r2, r2, 1);
7145c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    }
7155c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bx(r2);  // label_4
7165c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
7175c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bind(&label_1);
718bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ adr(r2, &label_3);  // Multiple reverse references to the same label.
7195c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ adr(r3, &label_3);
7205c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ adr(r4, &label_3);
721bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ adr(r5, &label_2);  // Simple reverse reference.
7225c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    if (masm.IsUsingT32()) {
7235c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
7245c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // that we are jumping into thumb mode.
7255c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      __ orr(r5, r5, 1);
7265c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    }
7275c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bx(r5);  // label_2
7285c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
7295c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bind(&label_4);
7305c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois  }
73188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
73288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
73388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
73488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
73588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0, r0);
73688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0, r1);
73788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
73888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
73988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
74088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
74188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
74288c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(shift_imm) {
74388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
74488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
74588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
74688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
74788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xfedcba98);
74888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
74988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
75088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Lsl(r3, r1, 4);
75188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Lsr(r4, r1, 8);
75288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Asr(r5, r1, 16);
75388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ror(r6, r1, 20);
75488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
75588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
75688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
75788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
75888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xedcba980, r3);
75988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00fedcba, r4);
76088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xfffffedc, r5);
76188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcba98fed, r6);
76288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
76388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
76488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
76588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
76688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
76788c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(shift_reg) {
76888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
76988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
77088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
77188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
77288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xfedcba98);
77388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
77488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
77588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r9, r0, 4);
77688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Lsl(r3, r1, r9);
77788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
77888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r9, r0, 8);
77988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Lsr(r4, r1, r9);
78088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
78188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r9, r0, 16);
78288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Asr(r5, r1, r9);
78388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
78488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r9, r0, 20);
78588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ror(r6, r1, r9);
78688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
78788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag.
78888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r7, r2, 1);
78988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Rrx(r7, r1);
79088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
79188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
79288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r8, r0, 0);
79388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Rrx(r8, r1);
79488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
79588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
79688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
79788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
79888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xedcba980, r3);
79988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00fedcba, r4);
80088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xfffffedc, r5);
80188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcba98fed, r6);
80288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xff6e5d4c, r7);
80388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x7f6e5d4c, r8);
80488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
80588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
80688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
80788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
80888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
80988c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(branch_cond) {
81088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
81188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
81288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label done, wrong;
81388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
81488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
81588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x0);
81688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x1);
81788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x80000000);
81888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use r0 instead of r3 when r0 becomes available.
81988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 0x1);
82088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
82188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // For each 'cmp' instruction below, condition codes other than the ones
82288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // following it would branch.
82388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
82488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cmp(r1, 0);
82588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(eq, &wrong);
82688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(lo, &wrong);
82788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(mi, &wrong);
82888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(vs, &wrong);
82988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ls, &wrong);
83088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(lt, &wrong);
83188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(le, &wrong);
83288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label ok_1;
83388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ne, &ok_1);
83488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
83588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r0, 0x0);
83688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&ok_1);
83788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
83888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cmp(r1, 1);
83988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ne, &wrong);
84088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(lo, &wrong);
84188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(mi, &wrong);
84288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(vs, &wrong);
84388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(hi, &wrong);
84488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(lt, &wrong);
84588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(gt, &wrong);
84688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label ok_2;
84788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(pl, &ok_2);
84888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
84988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r0, 0x0);
85088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&ok_2);
85188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
85288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cmp(r1, 2);
85388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(eq, &wrong);
85488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(hs, &wrong);
85588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(pl, &wrong);
85688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(vs, &wrong);
85788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(hi, &wrong);
85888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ge, &wrong);
85988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(gt, &wrong);
86088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label ok_3;
86188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(vc, &ok_3);
86288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
86388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r0, 0x0);
86488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&ok_3);
86588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
86688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cmp(r2, 1);
86788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(eq, &wrong);
86888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(lo, &wrong);
86988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(mi, &wrong);
87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(vc, &wrong);
87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ls, &wrong);
87288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ge, &wrong);
87388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(gt, &wrong);
87488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label ok_4;
87588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(le, &ok_4);
87688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
87788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r0, 0x0);
87888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&ok_4);
87988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
88088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label ok_5;
88188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&ok_5);
88288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
88388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r0, 0x0);
88488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&ok_5);
88588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&done);
88788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&wrong);
88988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use __ Mov(r0, 0x0) instead.
89088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Add(r3, r0, 0x0);
89188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
89288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&done);
89388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
89488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
89588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
89688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
89788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // TODO: Use r0.
89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x1, r3);
89988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
90088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
90188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
90288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
90388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
90488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(bfc_bfi) {
90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
90688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
90788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
90888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xffffffff);
90988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x01234567);
91088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0x0);
91188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
91288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bfc(r0, 0, 3);
91388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bfc(r0, 16, 5);
91488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
91588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bfi(r2, r1, 0, 8);
91688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bfi(r2, r1, 16, 16);
91788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
91888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
91988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
92088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
92188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xffe0fff8, r0);
92288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x45670067, r2);
92388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
92488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
92588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
92688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
92788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
92888c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(bic) {
92988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
93088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
93188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
93288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xfff0);
93388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
93488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
93588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
93688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r3, r0, r1);
93788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r4, r0, Operand(r1, LSL, 4));
93888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r5, r0, Operand(r1, LSR, 1));
93988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r6, r0, Operand(r1, ASR, 20));
94088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r7, r0, Operand(r1, ROR, 28));
94188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r8, r0, 0x1f);
94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
94388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag.
94488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r9, r2, 1);
94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r9, r1, Operand(r1, RRX));
94688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
94788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag.
94888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r10, r0, 0);
94988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bic(r10, r1, Operand(r1, RRX));
95088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
95188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
95288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
95388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
95488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0000ff00, r3);
95588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0000f000, r4);
95688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0000ff80, r5);
95788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x000000f0, r6);
95888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0000f000, r7);
95988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x0000ffe0, r8);
96088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000080, r9);
96188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000080, r10);
96288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
96388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
96488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
96588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
96688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
96788c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(bics) {
96888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
96988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
97088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
97188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
97288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xf00000ff);
97388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
97488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r1, r1);
97588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
97688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
97788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
97888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
97988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
98088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r0);
98188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
98288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
98388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x00fff000);
98488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x0fffff00);
98588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
98688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r0, Operand(r1, LSL, 4));
98788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
98888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
98988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
99088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
99188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
99288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
99388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
99488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
99588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x0000fff0);
99688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x0fffff00);
99788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
99888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r0, Operand(r1, LSR, 4));
99988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
100088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
100188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
100288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
100388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
100488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
100588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
100688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
100788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xf000fff0);
100888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x0fffff00);
100988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
101088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r0, Operand(r1, ASR, 4));
101188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
101288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
101388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
101488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
101588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
101688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xf0000000, r0);
101788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
101888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
101988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x80000000);
102088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xfffffffe);
102188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
102288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r0, Operand(r1, ROR, 1));
102388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
102488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
102588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
102688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
102788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
102888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
102988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
103088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
103188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x80000000);
103288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x80000001);
103388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
103488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
103588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r2, r0, 0);
103688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r2, r0, Operand(r1, RRX));
103788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
103888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
103988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
104088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
104188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NCFlag);
104288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r2);
104388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
104488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
104588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x80000000);
104688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x80000001);
104788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xffffffff);
104888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
104988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
105088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Adds(r2, r2, 1);
105188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r2, r0, Operand(r1, RRX));
105288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
105388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
105488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
105588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
105688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZCFlag);
105788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0, r2);
105888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
105988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
106088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xf000);
106188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
106288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r0, 0xf000);
106388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
106488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
106588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
106688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
106788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(ZFlag);
106888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x00000000, r0);
106988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
107088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
107188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xff000000);
107288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
107388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bics(r0, r0, 0x7fffffff);
107488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
107588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
107688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
107788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
107888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_NZCV(NFlag);
107988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x80000000, r0);
108088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
108188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
108288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
108388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
108488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
108557544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois// Make sure calling a macro-assembler instruction will generate literal pools
108657544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois// if needed.
108757544695f27605ae5a54bcfd2b6b508ea6b13387Pierre LangloisTEST_T32(veneer_pool_generated_by_macro_instruction) {
1088dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  SETUP();
1089dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
10902ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
1091be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
109257544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  Label start, end;
1093be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1094be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1095be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1096be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1097dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  __ Mov(r0, 1);
109857544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois
109957544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  __ Bind(&start);
1100dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  __ Cbz(r0, &end);
1101be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1102be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
1103be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1104be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
110557544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // Generate enough code so that, after the loop, no instruction can be
110657544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // generated before we need to generate the veneer pool.
11071661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames  // Use `ExactAssemblyScope` and the assembler to generate the code.
110857544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  int32_t space = masm.GetMarginBeforeVeneerEmission();
1109be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  {
11101661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1111be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames    while (space > 0) {
1112be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames      __ nop();
1113be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames      space -= k16BitT32InstructionSizeInBytes;
1114be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames    }
1115dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  }
1116be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1117be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  // We should not have emitted the veneer pool at this point.
1118dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
1119be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
112057544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() == 0);
112157544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois
112257544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // Now the pool will need to be generated before we can emit anything.
1123dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  Label check;
1124dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  __ Bind(&check);
112557544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  __ Mov(r0, 0);
112657544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // We should have generated 3 wide instructions:
112757544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     b.w past_veneer_pool
112857544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     b.w end ;; veneer from CBZ to "end".
112957544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //   past_veneer_pool:
113057544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     mov r0, #0
113157544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) ==
113257544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois             (3 * k32BitT32InstructionSizeInBytes));
113357544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois
113457544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // Branch back to make sure the veneers work.
113557544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  __ B(&start);
1136dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  __ Bind(&end);
1137be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
113857544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  VIXL_CHECK(masm.VeneerPoolIsEmpty());
113957544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  VIXL_CHECK(masm.LiteralPoolIsEmpty());
114057544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois
1141dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  END();
1142dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
1143dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  RUN();
1144dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
114557544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  ASSERT_EQUAL_32(0, r0);
1146dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
1147dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  TEARDOWN();
1148dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard}
1149dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
115050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
115150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia KouveliTEST(emit_reused_load_literal_rewind) {
115250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // This test generates an Ldrd that needs to be rewinded and loads a literal
115350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // that already is in the pool (hence it will be part of the pool that gets
115450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // emitted as part of the rewind).
115550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  SETUP();
115650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
115750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  START();
115850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
115950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Make sure the pool is empty.
116050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
116150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
116250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
116350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
116450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
116550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  std::string test_string(string_size, 'x');
116650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  StringLiteral big_literal(test_string.c_str());
116750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Adr(r4, &big_literal);
116850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
116950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // This load has a wider range than the Ldrd used below for the same
117050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // literal.
117150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  Literal<uint64_t> l1(0xcafebeefdeadbaba);
117250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Ldr(r0, &l1);
117350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
117450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // This Ldrd will be emitted and then rewinded, forcing the pool to be
117550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // emitted before we regenerate the instruction, so l1 will be bound and the
117650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // literal pool empty afterwards.
117750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Ldrd(r2, r3, &l1);
117850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
117950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
118050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
118150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  END();
118250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
118350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  RUN();
118450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
118550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Check that the literals loaded correctly.
118650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r0);
118750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r2);
118850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r3);
118950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0x78787878, r4);
119050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
119150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  TEARDOWN();
119250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli}
119350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
119450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
119550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia KouveliTEST(emit_reused_load_literal_should_not_rewind) {
1196cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  // This test checks that we are not conservative when rewinding a load of a
1197cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  // literal that is already in the literal pool.
119850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  SETUP();
119950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
120050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  START();
120150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
120250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Make sure the pool is empty.
120350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
120450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
120550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
120650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // This load has a wider range than the Ldrd used below for the same
120750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // literal.
120850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  Literal<uint64_t> l1(0xcafebeefdeadbaba);
120950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Ldr(r0, &l1);
121050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
121150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Add a large string to the literal pool, but only *after* l1, so the
121250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Ldrd below should not need to rewind.
121350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
121450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
121550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  std::string test_string(string_size, 'x');
121650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  StringLiteral big_literal(test_string.c_str());
121750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Adr(r4, &big_literal);
121850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Ldrd(r2, r3, &l1);
121950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
1220cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(AlignUp(string_size + 1, 4) + l1.GetSize());
122150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
122250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Make sure the pool is emitted.
122350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
122450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
122550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
122650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
122750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  END();
122850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
122950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  RUN();
123050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
123150e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  // Check that the literals loaded correctly.
123250e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r0);
123350e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r2);
123450e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r3);
123550e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  ASSERT_EQUAL_32(0x78787878, r4);
123650e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
123750e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli  TEARDOWN();
123850e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli}
123950e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
124050e45c514c11300c91b370c251235a9a77bdaf5fGeorgia Kouveli
1241be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouvelivoid EmitReusedLoadLiteralStressTest(InstructionSet isa, bool conditional) {
1242bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  // This test stresses loading a literal that is already in the literal pool,
1243bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  // for
1244bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  // various positionings on the existing load from that literal. We try to
1245bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  // exercise
1246bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  // cases where the two loads result in similar checkpoints for the literal
1247bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  // pool.
1248cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  SETUP();
1249cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1250cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1251cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  const int ldr_range = 4095;
1252cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  const int nop_size = masm.IsUsingA32() ? 4 : 2;
1253cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  const int nops = (ldr_range - ldrd_range) / nop_size;
1254cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1255cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  for (int n = nops - 10; n < nops + 10; ++n) {
1256cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    START();
1257cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1258cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // Make sure the pool is empty.
1259cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1260cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    ASSERT_LITERAL_POOL_SIZE(0);
1261cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1262be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    if (conditional) {
1263be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      __ Mov(r1, 0);
1264be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      __ Cmp(r1, 0);
1265be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    }
1266be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1267cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // Add a large string to the pool, which will force the Ldrd below to rewind
1268cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // (if the pool is not already emitted due to the Ldr).
1269cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1270cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    std::string test_string(string_size, 'x');
1271cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    StringLiteral big_literal(test_string.c_str());
1272cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    __ Ldr(r4, &big_literal);
1273cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1274cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // This load has a wider range than the Ldrd used below for the same
1275cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // literal.
1276cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    Literal<uint64_t> l1(0xcafebeefdeadbaba);
1277cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    __ Ldr(r0, &l1);
1278cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1279bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    // Generate nops, in order to bring the checkpoints of the Ldr and Ldrd
1280bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    // closer.
1281cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    {
1282bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope scope(&masm,
1283bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               n * nop_size,
1284bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               ExactAssemblyScope::kExactSize);
1285cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli      for (int i = 0; i < n; ++i) {
1286cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli        __ nop();
1287cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli      }
1288cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    }
1289cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1290be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    if (conditional) {
1291be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      __ Ldrd(eq, r2, r3, &l1);
1292be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    } else {
1293be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      __ Ldrd(r2, r3, &l1);
1294be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    }
1295cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // At this point, the pool will be emitted either because Ldrd needed to
1296cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // rewind, or because Ldr reached its range.
1297cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    ASSERT_LITERAL_POOL_SIZE(0);
1298cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1299cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    END();
1300cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1301cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    RUN();
1302cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1303cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    // Check that the literals loaded correctly.
1304cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    ASSERT_EQUAL_32(0xdeadbaba, r0);
1305cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    ASSERT_EQUAL_32(0xdeadbaba, r2);
1306cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    ASSERT_EQUAL_32(0xcafebeef, r3);
1307cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli    ASSERT_EQUAL_32(0x78787878, r4);
1308cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  }
1309cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1310cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli  TEARDOWN();
1311cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli}
1312cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1313cf91ee6bcaabf00356516bbc2d478acbeb8bed9aGeorgia Kouveli
1314be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(emit_reused_load_literal_stress) {
1315be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitReusedLoadLiteralStressTest(isa, false /*conditional*/);
1316be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1317be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1318be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1319be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(emit_reused_conditional_load_literal_stress) {
1320be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitReusedLoadLiteralStressTest(isa, true /*conditional*/);
1321be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1322be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1323be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
13244f002a865b625dc388e9175bfdda285812e17f2bGeorgia KouveliTEST(test_many_loads_from_same_literal) {
13254f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  // This test generates multiple loads from the same literal in order to
13264f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  // test that the delegate recursion limit is appropriate for Ldrd with
13274f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  // large negative offsets.
13284f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  SETUP();
13294f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13304f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  START();
13314f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13324f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  // Make sure the pool is empty.
13334f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
13344f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
13354f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13364f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  Literal<uint64_t> l0(0xcafebeefdeadbaba);
13374f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  __ Ldrd(r0, r1, &l0);
13384f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  for (int i = 0; i < 10000; ++i) {
1339bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    __ Add(r2, r2, i);
13404f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli    __ Ldrd(r4, r5, &l0);
13414f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  }
13424f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13434f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  __ Ldrd(r2, r3, &l0);
13444f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13454f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  END();
13464f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13474f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  RUN();
13484f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13494f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  // Check that the literals loaded correctly.
13504f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r0);
13514f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r1);
13524f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r2);
13534f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r3);
13544f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r4);
13554f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r5);
13564f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13574f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli  TEARDOWN();
13584f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli}
13594f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
13604f002a865b625dc388e9175bfdda285812e17f2bGeorgia Kouveli
136157544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois// Make sure calling a macro-assembler instruction will generate literal pools
136257544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois// if needed.
136357544695f27605ae5a54bcfd2b6b508ea6b13387Pierre LangloisTEST_T32(literal_pool_generated_by_macro_instruction) {
1364dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  SETUP();
1365dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
1366dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  START();
1367be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1368be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1369be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1370be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1371dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  __ Ldrd(r0, r1, 0x1234567890abcdef);
1372be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1373be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1374be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
1375be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
137657544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // Generate enough code so that, after the loop, no instruction can be
137757544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // generated before we need to generate the literal pool.
137857544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // Use `ExactAssemblyScope` and the assembler to generate the code.
137957544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  int32_t space = masm.GetMarginBeforeLiteralEmission();
1380be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  {
13811661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1382be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames    while (space > 0) {
1383be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames      __ nop();
1384be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames      space -= k16BitT32InstructionSizeInBytes;
1385be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames    }
1386dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  }
1387be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1388be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  // We should not have emitted the literal pool at this point.
1389be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1390dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
139157544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  VIXL_CHECK(masm.GetMarginBeforeLiteralEmission() == 0);
139257544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois
139357544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // Now the pool will need to be generated before we emit anything.
1394dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  Label check;
1395dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  __ Bind(&check);
139657544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  __ Mov(r2, 0x12345678);
139757544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  // We should have generated 3 wide instructions and 8 bytes of data:
139857544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     b.w past_literal_pool
139957544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     .bytes 0x1234567890abcdef
140057544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //   past_literal_pool:
140157544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     mov r2, #22136
140257544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  //     movt r2, #4660
140357544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) ==
140457544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois             (3 * k32BitT32InstructionSizeInBytes + 8));
1405be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1406be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1407be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1408be370b630bc10bf728ed662594ca09d42e254192Alexandre Rames
1409dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  END();
1410dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
1411dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  RUN();
1412dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
141357544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
1414dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r1);
141557544695f27605ae5a54bcfd2b6b508ea6b13387Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r2);
1416dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
1417dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard  TEARDOWN();
1418dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard}
1419dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
1420dcffac4d0a5a586d3c14971e33bd28fc848bc148Vincent Belliard
142188c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(emit_single_literal) {
142288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
142388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
142488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
142588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Make sure the pool is empty.
142688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
142788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
142888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
142988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Create one literal pool entry.
143088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
143188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(8);
143288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(s0, 1.0);
143388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d1, 2.0);
143488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vmov(d2, 4.1);
143588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vmov(s8, 8.2);
143688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(20);
143788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
143888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
143988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
144088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
144188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that the literals loaded correctly.
144288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
144388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
144488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP32(1.0f, s0);
144588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(2.0, d1);
144688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(4.1, d2);
144788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP32(8.2f, s8);
144888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
144988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
145088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
145188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
145288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
145340b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard#undef __
145440b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard#define __ masm->
145540b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
145640b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
145740b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliardvoid EmitLdrdLiteralTest(MacroAssembler* masm) {
145840b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  const int ldrd_range = masm->IsUsingA32() ? 255 : 1020;
145940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // We want to emit code up to the maximum literal load range and ensure the
146040b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // pool has not been emitted. Compute the limit (end).
1461bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  ptrdiff_t end = AlignDown(
1462bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      // Align down the PC to 4 bytes as the instruction does when it's
1463bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      // executed.
1464bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      // The PC will be the cursor offset plus the architecture state PC
1465bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      // offset.
1466bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      AlignDown(masm->GetBuffer()->GetCursorOffset() +
1467bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                    masm->GetArchitectureStatePCOffset(),
1468bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                4) +
146940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard          // Maximum range allowed to access the constant.
147040b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard          ldrd_range -
1471bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard          // The literal pool has a two instruction margin.
1472bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard          2 * kMaxInstructionSizeInBytes,
1473bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      // AlignDown to 4 byte as the literals will be 4 byte aligned.
1474bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      4);
147588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
147688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Create one literal pool entry.
147788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldrd(r0, r1, 0x1234567890abcdef);
147888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(8);
147988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
14800eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  int32_t margin = masm->GetMarginBeforeLiteralEmission();
14810eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  {
14821661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(masm, margin, ExactAssemblyScope::kExactSize);
14830eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // Opening the scope should not have triggered the emission of the literal
14840eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // pool.
14850eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    VIXL_CHECK(!masm->LiteralPoolIsEmpty());
14860eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    while (masm->GetCursorOffset() < end) {
14870eb25b040732354c6273c93df709f8d585a140deAlexandre Rames      __ nop();
14880eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    }
14890eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    VIXL_CHECK(masm->GetCursorOffset() == end);
149088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
14910eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
149288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that the pool has not been emited along the way.
149388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(8);
149488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // This extra instruction should trigger an emit of the pool.
149540b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  __ Nop();
149688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // The pool should have been emitted.
149788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
149840b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard}
149940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
150040b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
150140b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard#undef __
150240b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard#define __ masm.
150340b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
150440b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
1505be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(emit_literal_rewind) {
150640b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  SETUP();
150740b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
150840b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  START();
150940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
151040b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // Make sure the pool is empty.
151140b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
151240b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  ASSERT_LITERAL_POOL_SIZE(0);
151340b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
151440b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  EmitLdrdLiteralTest(&masm);
151588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
151640b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
151740b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1518dbc19e4a4f4117fdaa81265e6371178d2c107ac2Baptiste Afsa  std::string test_string(string_size, 'x');
1519dbc19e4a4f4117fdaa81265e6371178d2c107ac2Baptiste Afsa  StringLiteral big_literal(test_string.c_str());
152025e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Adr(r4, &big_literal);
1521be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // This adr will overflow the literal pool and force a rewind.
152240b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // That means that the string will be generated then, then Ldrd and the
1523be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // Ldrd's value will be alone in the pool.
152488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldrd(r2, r3, 0xcafebeefdeadbaba);
152588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(8);
152688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
152788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
152888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
1529024aa58e9d83147f57a2509cf115b9fc9d260477Alexandre Rames  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
153088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
153188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
153288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
153388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
153488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that the literals loaded correctly.
153588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x90abcdef, r0);
153688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
153788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
153888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
153988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x78787878, r4);
154088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
154188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
154288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
154388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
1544be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(emit_literal_conditional_rewind) {
1545be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  SETUP();
1546be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1547be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  START();
1548be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1549be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // This test is almost identical to the test above, but the Ldrd instruction
1550be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // is conditional and there is a second conditional Ldrd instruction that will
1551be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // not be executed. This is to check that reverting the emission of a load
1552be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // literal instruction, rewinding, emitting the literal pool and then emitting
1553be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // the instruction again works correctly when the load is conditional.
1554be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1555be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // Make sure the pool is empty.
1556be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1557be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
1558be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1559be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1560be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1561be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  std::string test_string(string_size, 'x');
1562be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  StringLiteral big_literal(test_string.c_str());
1563be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Adr(r2, &big_literal);
1564be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // This adr will overflow the literal pool and force a rewind.
1565be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // That means that the string will be generated then, then Ldrd and the
1566be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // Ldrd's value will be alone in the pool.
1567be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Mov(r0, 0);
1568be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Mov(r1, 0);
1569be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Mov(r3, 1);
1570be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Cmp(r3, 1);
1571be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
1572be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
1573be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(16);
1574be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1575be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1576be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
1577be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldr(r2, MemOperand(r2));  // Load the first 4 characters in r2.
1578be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  END();
1579be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1580be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  RUN();
1581be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1582be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // Check that the literals loaded correctly.
1583be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r0);
1584be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r1);
1585be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(0x78787878, r2);
1586be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1587be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  TEARDOWN();
1588be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1589be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1590be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouvelienum LiteralStressTestMode {
1591be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  kUnconditional,
1592be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  kConditionalTrue,
1593be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  kConditionalFalse,
1594be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  kConditionalBoth
1595be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli};
1596be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1597be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// Test loading a literal when the size of the literal pool is close to the
1598be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// maximum range of the load, with varying PC values (and alignment, for T32).
1599be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// This test is similar to the tests above, with the difference that we allow
1600be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// an extra offset to the string size in order to make sure that various pool
1601be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// sizes close to the maximum supported offset will produce code that executes
1602be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// correctly. As the Ldrd might or might not be rewinded, we do not assert on
1603be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli// the size of the literal pool in this test.
1604bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisvoid EmitLdrdLiteralStressTest(InstructionSet isa,
1605bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               bool unaligned,
1606be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli                               LiteralStressTestMode test_mode) {
1607be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  SETUP();
1608be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1609be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  for (int offset = -10; offset <= 10; ++offset) {
1610be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    START();
1611be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1612be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    if (unaligned) {
1613be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      __ Nop();
1614be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
1615be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    }
1616be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1617be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    // Make sure the pool is empty.
1618be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1619be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    ASSERT_LITERAL_POOL_SIZE(0);
1620be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1621be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1622be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    const int string_size = ldrd_range + offset;
1623be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    std::string test_string(string_size - 1, 'x');
1624be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    StringLiteral big_literal(test_string.c_str());
1625be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    __ Adr(r2, &big_literal);
1626be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    __ Mov(r0, 0);
1627be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    __ Mov(r1, 0);
1628be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    switch (test_mode) {
1629be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      case kUnconditional:
1630be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Ldrd(r0, r1, 0xcafebeefdeadbaba);
1631be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        break;
1632be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      case kConditionalTrue:
1633be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r0, 0xffffffff);
1634be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r1, r0);
1635be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r3, 1);
1636be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Cmp(r3, 1);
1637be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
1638be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        break;
1639be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      case kConditionalFalse:
1640be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r0, 0xdeadbaba);
1641be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r1, 0xcafebeef);
1642be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r3, 1);
1643be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Cmp(r3, 1);
1644be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
1645be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        break;
1646be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli      case kConditionalBoth:
1647be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Mov(r3, 1);
1648be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Cmp(r3, 1);
1649be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
1650be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
1651be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli        break;
1652be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    }
1653be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1654be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1655be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    ASSERT_LITERAL_POOL_SIZE(0);
1656be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    __ Ldr(r2, MemOperand(r2));  // Load the first 4 characters in r2.
1657be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    END();
1658be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1659be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    RUN();
1660be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1661be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    // Check that the literals loaded correctly.
1662be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    ASSERT_EQUAL_32(0xdeadbaba, r0);
1663be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    ASSERT_EQUAL_32(0xcafebeef, r1);
1664be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli    ASSERT_EQUAL_32(0x78787878, r2);
1665be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  }
1666be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1667be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  TEARDOWN();
1668be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1669be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1670be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1671be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(emit_literal_rewind_stress) {
1672be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kUnconditional);
1673be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1674be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1675be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1676be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST_T32(emit_literal_rewind_stress_unaligned) {
1677be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kUnconditional);
1678be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1679be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1680be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1681be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(emit_literal_conditional_rewind_stress) {
1682be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalTrue);
1683be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalFalse);
1684be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalBoth);
1685be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1686be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1687be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1688be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST_T32(emit_literal_conditional_rewind_stress_unaligned) {
1689be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalTrue);
1690be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalFalse);
1691be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalBoth);
1692be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1693be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1694be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
169540b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent BelliardTEST_T32(emit_literal_unaligned) {
169640b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  SETUP();
169740b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
169840b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  START();
169940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
170040b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // Make sure the pool is empty.
170140b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
170240b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  ASSERT_LITERAL_POOL_SIZE(0);
170340b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
170440b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // Generate a nop to break the 4 bytes alignment.
170540b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  __ Nop();
170640b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
170740b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  EmitLdrdLiteralTest(&masm);
170840b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
170940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  END();
171040b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
171140b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  RUN();
171240b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
171340b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  // Check that the literals loaded correctly.
171440b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r0);
171540b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r1);
171640b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
171740b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard  TEARDOWN();
171840b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard}
171940b7e470e71b158158ef6ce8a1a3f701857ce0e2Vincent Belliard
1720bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1721bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste AfsaTEST(literal_multiple_uses) {
1722bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  SETUP();
1723bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1724bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  START();
1725bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<int32_t> lit(42);
1726bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldr(r0, &lit);
1727bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(4);
1728bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1729bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  // Multiple uses of the same literal object should not make the
1730bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  // pool grow.
1731bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrb(r1, &lit);
1732bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrsb(r2, &lit);
1733bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrh(r3, &lit);
1734bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrsh(r4, &lit);
1735bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(4);
1736bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1737bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  END();
1738bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1739bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  RUN();
1740bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1741bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(42, r0);
1742bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(42, r1);
1743bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(42, r2);
1744bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(42, r3);
1745bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(42, r4);
1746bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1747bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  TEARDOWN();
1748bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
1749bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1750bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1751bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa// A test with two loads literal which go out of range at the same time.
1752bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste AfsaTEST_A32(ldr_literal_range_same_time) {
1753bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  SETUP();
1754bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1755bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  START();
1756bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  const int ldrd_range = 255;
1757bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  // We need to take into account the jump over the pool.
1758bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const int ldrd_padding = ldrd_range - 2 * kA32InstructionSizeInBytes;
1759bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  const int ldr_range = 4095;
1760bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  // We need to take into account the ldrd padding and the ldrd instruction.
1761bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const int ldr_padding =
1762bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ldr_range - ldrd_padding - 2 * kA32InstructionSizeInBytes;
1763bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1764bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldr(r1, 0x12121212);
1765bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(4);
1766bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
17678d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames  {
17688d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    int space = AlignDown(ldr_padding, kA32InstructionSizeInBytes);
17691661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
17708d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    int32_t end = masm.GetCursorOffset() + space;
17718d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    while (masm.GetCursorOffset() < end) {
17728d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames      __ nop();
17738d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    }
1774bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  }
1775bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1776bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrd(r2, r3, 0x1234567890abcdef);
1777bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(12);
1778bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
17798d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames  {
17808d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    int space = AlignDown(ldrd_padding, kA32InstructionSizeInBytes);
17811661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
17828d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    for (int32_t end = masm.GetCursorOffset() + space;
17838d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames         masm.GetCursorOffset() < end;) {
17848d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames      __ nop();
17858d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    }
1786bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  }
1787bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(12);
1788bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1789bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  // This mov will put the two loads literal out of range and will force
1790bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  // the literal pool emission.
1791bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Mov(r0, 0);
1792bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(0);
1793bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  END();
1794bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1795bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  RUN();
1796bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1797bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(0x12121212, r1);
1798bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(0x90abcdef, r2);
1799bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r3);
1800bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1801bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  TEARDOWN();
1802bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
1803bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1804bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1805bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste AfsaTEST(ldr_literal_mix_types) {
1806bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  SETUP();
1807bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1808bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  START();
1809bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<uint64_t> l0(0x1234567890abcdef);
1810bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<int32_t> l1(0x12345678);
1811bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<uint16_t> l2(1234);
1812bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<int16_t> l3(-678);
1813bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<uint8_t> l4(42);
1814bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Literal<int8_t> l5(-12);
1815bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1816bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrd(r0, r1, &l0);
1817bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldr(r2, &l1);
1818bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrh(r3, &l2);
1819bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrsh(r4, &l3);
1820bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrb(r5, &l4);
1821bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  __ Ldrsb(r6, &l5);
1822bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_LITERAL_POOL_SIZE(28);
1823bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1824bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  END();
1825bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1826bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  RUN();
1827bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1828bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(0x90abcdef, r0);
1829bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r1);
1830bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r2);
1831bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(1234, r3);
1832bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(-678, r4);
1833bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(42, r5);
1834bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  ASSERT_EQUAL_32(-12, r6);
1835bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1836bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  TEARDOWN();
1837bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
1838bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1839bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1840be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia KouveliTEST(ldr_literal_conditional) {
1841be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  SETUP();
1842be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1843be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  START();
1844be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<uint64_t> l0(0x1234567890abcdef);
1845be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<uint64_t> l0_not_taken(0x90abcdef12345678);
1846be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<int32_t> l1(0x12345678);
1847be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<int32_t> l1_not_taken(0x56781234);
1848be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<uint16_t> l2(1234);
1849be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<uint16_t> l2_not_taken(3412);
1850be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<int16_t> l3(-678);
1851be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<int16_t> l3_not_taken(678);
1852be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<uint8_t> l4(42);
1853be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<uint8_t> l4_not_taken(-42);
1854be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<int8_t> l5(-12);
1855be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<int8_t> l5_not_taken(12);
1856be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<float> l6(1.2345f);
1857be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<float> l6_not_taken(0.0f);
1858be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<double> l7(1.3333);
1859be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  Literal<double> l7_not_taken(0.0);
1860be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1861be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // Check that conditionally loading literals of different types works
1862be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  // correctly for both A32 and T32.
1863be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Mov(r7, 1);
1864be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Cmp(r7, 1);
1865be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrd(eq, r0, r1, &l0);
1866be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrd(ne, r0, r1, &l0_not_taken);
1867be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Cmp(r7, 0);
1868be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldr(gt, r2, &l1);
1869be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldr(le, r2, &l1_not_taken);
1870be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Cmp(r7, 2);
1871be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrh(lt, r3, &l2);
1872be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrh(ge, r3, &l2_not_taken);
1873be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrsh(le, r4, &l3);
1874be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrsh(gt, r4, &l3_not_taken);
1875be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Cmp(r7, 1);
1876be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrb(ge, r5, &l4);
1877be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrb(lt, r5, &l4_not_taken);
1878be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrsb(eq, r6, &l5);
1879be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Ldrsb(ne, r6, &l5_not_taken);
1880be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Vldr(Condition(eq), s0, &l6);
1881be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Vldr(Condition(ne), s0, &l6_not_taken);
1882be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Vldr(Condition(eq), d1, &l7);
1883be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  __ Vldr(Condition(ne), d1, &l7_not_taken);
1884be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1885be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  END();
1886be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1887be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  RUN();
1888be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1889be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(0x90abcdef, r0);
1890be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(0x12345678, r1);
1891be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(0x12345678, r2);
1892be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(1234, r3);
1893be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(-678, r4);
1894be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(42, r5);
1895be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_32(-12, r6);
1896be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_FP32(1.2345f, s0);
1897be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  ASSERT_EQUAL_FP64(1.3333, d1);
1898be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1899be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli  TEARDOWN();
1900be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli}
1901be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1902be9c4d02c96eaa6cdc9a9a5ae3cc65f57d54585cGeorgia Kouveli
1903bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsastruct LdrLiteralRangeTest {
1904bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  void (MacroAssembler::*instruction)(Register, RawLiteral*);
1905bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  Register result_reg;
1906bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  int a32_range;
1907bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  int t32_range;
1908bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  uint32_t literal_value;
1909bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  uint32_t test_value;
1910bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa};
1911bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1912bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1913bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisconst LdrLiteralRangeTest kLdrLiteralRangeTestData[] =
1914bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    {{&MacroAssembler::Ldr, r1, 4095, 4095, 0x12345678, 0x12345678},
1915bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois     {&MacroAssembler::Ldrh, r2, 255, 4095, 0xabcdefff, 0x0000efff},
1916bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois     {&MacroAssembler::Ldrsh, r3, 255, 4095, 0x00008765, 0xffff8765},
1917bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois     {&MacroAssembler::Ldrb, r4, 4095, 4095, 0x12345678, 0x00000078},
1918bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois     {&MacroAssembler::Ldrsb, r5, 255, 4095, 0x00000087, 0xffffff87}};
1919bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1920bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1921bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsavoid GenerateLdrLiteralTriggerPoolEmission(InstructionSet isa,
1922bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa                                           bool unaligned_ldr) {
1923bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  SETUP();
1924bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1925bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1926bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
1927bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1928bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    START();
1929bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1930bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    if (unaligned_ldr) {
1931bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      // Generate a nop to break the 4-byte alignment.
1932bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      __ Nop();
1933bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
1934bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    }
1935bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1936bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    __ Ldr(r6, 0x12345678);
1937bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(4);
1938bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
19398d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    // TODO: The MacroAssembler currently checks for more space than required
19408d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    // when emitting macro instructions, triggering emission of the pool before
19418d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    // absolutely required. For now we keep a buffer. Fix this test when the
19428d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    // MacroAssembler becomes precise again.
19438d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    int masm_check_margin = 10 * kMaxInstructionSizeInBytes;
1944bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    size_t expected_pool_size = 4;
19458d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    while ((masm.GetMarginBeforeLiteralEmission() - masm_check_margin) >=
1946e44090587ff7104b4ad3f786e64940c82838387cPierre Langlois           static_cast<int32_t>(kMaxInstructionSizeInBytes)) {
1947bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      __ Ldr(r7, 0x90abcdef);
1948bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      // Each ldr instruction will force a new literal value to be added
1949bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      // to the pool. Check that the literal pool grows accordingly.
1950bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      expected_pool_size += 4;
1951bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      ASSERT_LITERAL_POOL_SIZE(expected_pool_size);
1952bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    }
1953bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
19548d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    int space = masm.GetMarginBeforeLiteralEmission();
19558d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    int end = masm.GetCursorOffset() + space;
19568d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    {
19578d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames      // Generate nops precisely to fill the buffer.
1958bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope accurate_scope(&masm, space);  // This should not
1959bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                                        // trigger emission of
1960bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                                        // the pool.
19618d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames      VIXL_CHECK(!masm.LiteralPoolIsEmpty());
19628d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames      while (masm.GetCursorOffset() < end) {
19638d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames        __ nop();
19648d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames      }
19658d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    }
19668d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames
1967bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    // This ldr will force the literal pool to be emitted before emitting
1968bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    // the load and will create a new pool for the new literal used by this ldr.
19698d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    VIXL_CHECK(!masm.LiteralPoolIsEmpty());
1970bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    Literal<uint32_t> literal(test.literal_value);
1971bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    (masm.*test.instruction)(test.result_reg, &literal);
1972bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(4);
1973bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1974bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    END();
1975bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1976bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    RUN();
1977bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1978bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_EQUAL_32(0x12345678, r6);
1979bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_EQUAL_32(0x90abcdef, r7);
1980bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_EQUAL_32(test.test_value, test.result_reg);
1981bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  }
1982bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1983bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  TEARDOWN();
1984bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
1985bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1986bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1987bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste AfsaTEST(ldr_literal_trigger_pool_emission) {
1988bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  GenerateLdrLiteralTriggerPoolEmission(isa, false);
1989bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
1990bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1991bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1992bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste AfsaTEST_T32(ldr_literal_trigger_pool_emission_unaligned) {
1993bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  GenerateLdrLiteralTriggerPoolEmission(isa, true);
1994bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
1995bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1996bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
1997bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsavoid GenerateLdrLiteralRangeTest(InstructionSet isa, bool unaligned_ldr) {
1998bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  SETUP();
1999bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2000bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
2001bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
2002bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2003bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    START();
2004bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2005bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    // Make sure the pool is empty.
2006bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
2007bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(0);
2008bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2009bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    if (unaligned_ldr) {
2010bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      // Generate a nop to break the 4-byte alignment.
2011bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      __ Nop();
2012bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
2013bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    }
2014bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2015bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    Literal<uint32_t> literal(test.literal_value);
2016bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    (masm.*test.instruction)(test.result_reg, &literal);
2017bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(4);
2018bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2019bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    // Generate enough instruction so that we go out of range for the load
2020bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    // literal we just emitted.
2021bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ptrdiff_t end = masm.GetBuffer()->GetCursorOffset() +
2022bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                    ((masm.IsUsingA32()) ? test.a32_range : test.t32_range);
2023bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    while (masm.GetBuffer()->GetCursorOffset() < end) {
2024bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa      __ Mov(r0, 0);
2025bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    }
2026bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2027bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    // The literal pool should have been emitted now.
2028bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    VIXL_CHECK(literal.IsBound());
2029bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(0);
2030bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2031bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    END();
2032bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2033bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    RUN();
2034bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2035bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa    ASSERT_EQUAL_32(test.test_value, test.result_reg);
2036bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  }
2037bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2038bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  TEARDOWN();
2039bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
2040bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2041bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2042bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre LangloisTEST(ldr_literal_range) { GenerateLdrLiteralRangeTest(isa, false); }
2043bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2044bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2045bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste AfsaTEST_T32(ldr_literal_range_unaligned) {
2046bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa  GenerateLdrLiteralRangeTest(isa, true);
2047bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa}
2048bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
2049bfde9ad1b9ca9b857aca6b29aac9146a6572d256Baptiste Afsa
205025e3987b3b684df88edc8069d60b483b95587be5Pierre LangloisTEST(string_literal) {
205125e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  SETUP();
205225e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
205325e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  START();
205425e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  // Make sure the pool is empty.
205525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
205625e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
205725e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
205825e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  StringLiteral hello_string("hello");
205925e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
206025e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Ldrb(r1, &hello_string);
206125e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
206225e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Adr(r0, &hello_string);
206325e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Ldrb(r2, MemOperand(r0));
206425e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  END();
206525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
206625e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  RUN();
206725e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
206825e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_EQUAL_32('h', r1);
206925e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_EQUAL_32('h', r2);
207025e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
207125e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  TEARDOWN();
207225e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois}
207325e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
207488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
207588c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(custom_literal_in_pool) {
207688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
207788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
207888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
207988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Make sure the pool is empty.
208088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
208188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
208288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
208388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Literal<uint32_t> l0(static_cast<uint32_t>(0x12345678));
208488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldr(r0, &l0);
208588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
208688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldr(r1, &l0);
208788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
208888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
208988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Literal<uint64_t> cafebeefdeadbaba(0xcafebeefdeadbaba);
209088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldrd(r8, r9, &cafebeefdeadbaba);
209188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
209288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldrd(r2, r3, &cafebeefdeadbaba);
209388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
209488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
209525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  Literal<uint32_t> l1(0x09abcdef);
209625e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Adr(r4, &l1);
209725e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Ldr(r4, MemOperand(r4));
209825e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  masm.EmitLiteralPool();
209925e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Adr(r5, &l1);
210025e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Ldr(r5, MemOperand(r5));
210125e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
210225e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois
210388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
210488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
210588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
210688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
210788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that the literals loaded correctly.
210888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r0);
210988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
211025e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r2);
211125e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r3);
211288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r8);
211388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r9);
211425e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r4);
211525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  ASSERT_EQUAL_32(0x09abcdef, r5);
211688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
211788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
211888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
211988c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(custom_literal_place) {
212088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
212188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
212288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
212388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Make sure the pool is empty.
212488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
212588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
212688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
21272e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
21282e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  Literal<int32_t> l1(0x12345678, RawLiteral::kManuallyPlaced);
2129bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  Literal<uint16_t> l2(4567, RawLiteral::kManuallyPlaced);
21302e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  Literal<int16_t> l3(-4567, RawLiteral::kManuallyPlaced);
21312e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  Literal<uint8_t> l4(123, RawLiteral::kManuallyPlaced);
21322e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  Literal<int8_t> l5(-123, RawLiteral::kManuallyPlaced);
21332e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
21342e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Ldrd(r0, r1, &l0);
21352e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Ldr(r2, &l1);
21362e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Ldrh(r3, &l2);
21372e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Ldrsh(r4, &l3);
21382e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Ldrb(r5, &l4);
21392e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Ldrsb(r6, &l5);
214088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
214188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
214288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
21432e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  // Manually generate a literal pool.
21442e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  Label after_pool;
21452e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ B(&after_pool);
21462e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Place(&l0);
21472e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Place(&l1);
21482e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Place(&l2);
21492e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Place(&l3);
21502e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Place(&l4);
21512e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Place(&l5);
21522e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  __ Bind(&after_pool);
21532e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
2154e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley  {
2155e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    UseScratchRegisterScope temps(&masm);
2156e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    Register temp = temps.Acquire();
2157e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    VIXL_CHECK(temp.Is(r12));
2158e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley
2159e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    __ Ldrd(r8, r9, &l0);
2160e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    __ Ldr(r7, &l1);
2161e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    __ Ldrh(r10, &l2);
2162e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    __ Ldrsh(r11, &l3);
2163e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    __ Ldrb(temp, &l4);
2164e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    // We don't use any function call so we can use lr as an extra register.
2165e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley    __ Ldrsb(lr, &l5);
2166e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley  }
21672e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
216888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
21692e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
217088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
217188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
217288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
217388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
217488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that the literals loaded correctly.
21752e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbaba, r0);
21762e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(0xcafebeef, r1);
21772e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r2);
21782e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(4567, r3);
21792e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(-4567, r4);
21802e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(123, r5);
21812e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(-123, r6);
21822e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
218388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdeadbaba, r8);
218488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcafebeef, r9);
21852e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r7);
21862e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(4567, r10);
21872e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(-4567, r11);
2188e8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66Jacob Bramley  ASSERT_EQUAL_32(123, r12);
21892e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  ASSERT_EQUAL_32(-123, lr);
21902e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
21912e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  TEARDOWN();
21922e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa}
21932e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
21942e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
21952e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste AfsaTEST(custom_literal_place_shared) {
21962e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  SETUP();
21972e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
21982e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
21992e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
22002e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22012e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    START();
22022e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22032e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    // Make sure the pool is empty.
22042e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
22052e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(0);
22062e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22072e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    Literal<uint32_t> before(test.literal_value, RawLiteral::kManuallyPlaced);
22082e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    Literal<uint32_t> after(test.literal_value, RawLiteral::kManuallyPlaced);
22092e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22102e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(!before.IsBound());
22112e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(!after.IsBound());
22122e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22132e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    // Manually generate a pool.
22142e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    Label end_of_pool_before;
22152e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    __ B(&end_of_pool_before);
22162e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    __ Place(&before);
22172e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    __ Bind(&end_of_pool_before);
22182e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22192e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(0);
22202e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(before.IsBound());
22212e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(!after.IsBound());
22222e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
2223bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    // Load the entries several times to test that literals can be shared.
22242e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    for (int i = 0; i < 20; i++) {
22252e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa      (masm.*test.instruction)(r0, &before);
22262e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa      (masm.*test.instruction)(r1, &after);
22272e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    }
22282e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22292e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(0);
22302e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(before.IsBound());
22312e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(!after.IsBound());
22322e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22332e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    // Manually generate a pool.
22342e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    Label end_of_pool_after;
22352e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    __ B(&end_of_pool_after);
22362e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    __ Place(&after);
22372e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    __ Bind(&end_of_pool_after);
22382e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22392e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    ASSERT_LITERAL_POOL_SIZE(0);
22402e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(before.IsBound());
22412e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    VIXL_CHECK(after.IsBound());
22422e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22432e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    END();
22442e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22452e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    RUN();
22462e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
22472e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    ASSERT_EQUAL_32(test.test_value, r0);
22482e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    ASSERT_EQUAL_32(test.test_value, r1);
22492e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa  }
22502e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22512e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa  TEARDOWN();
22522e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa}
22532e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22542e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22552e7b9043baf27f8a4487403e24666203981ba57bBaptiste AfsaTEST(custom_literal_place_range) {
22562e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa  SETUP();
22572e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22582e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
22592e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
22602e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    const int nop_size = masm.IsUsingA32() ? kA32InstructionSizeInBytes
22612e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa                                           : k16BitT32InstructionSizeInBytes;
22622e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    const int range = masm.IsUsingA32() ? test.a32_range : test.t32_range;
22632e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // On T32 the PC will be 4-byte aligned to compute the range. The
22642e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // MacroAssembler might also need to align the code buffer before emitting
22652e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // the literal when placing it. We keep a margin to account for this.
22662e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    const int margin = masm.IsUsingT32() ? 4 : 0;
22672e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22682e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // Take PC offset into account and make sure the literal is in the range.
22692e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    const int padding_before =
22702e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa        range - masm.GetArchitectureStatePCOffset() - sizeof(uint32_t) - margin;
22712e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22722e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // The margin computation below is correct because the ranges are not
22732e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // 4-byte aligned. Otherwise this test would insert the exact number of
22742e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // instructions to cover the range and the literal would end up being
22752e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // placed outside the range.
22762e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    VIXL_ASSERT((range % 4) != 0);
22772e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22782e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // The range is extended by the PC offset but we need to consider the ldr
22792e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    // instruction itself and the branch over the pool.
22802e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    const int padding_after = range + masm.GetArchitectureStatePCOffset() -
22812e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa                              (2 * kMaxInstructionSizeInBytes) - margin;
22822e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    START();
22832e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22842e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    Literal<uint32_t> before(test.literal_value, RawLiteral::kManuallyPlaced);
22852e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    Literal<uint32_t> after(test.literal_value, RawLiteral::kManuallyPlaced);
22862e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22872e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    Label test_start;
22882e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    __ B(&test_start);
22892e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    __ Place(&before);
22902e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
22912e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    {
22922e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa      int space = AlignDown(padding_before, nop_size);
22937027d2f28e155bb1dfc360b4c69c8f86320a6094Alexandre Rames      ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
22942e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa      for (int32_t end = masm.GetCursorOffset() + space;
22952e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa           masm.GetCursorOffset() < end;) {
22962e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa        __ nop();
22972e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa      }
22982e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    }
22992e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
23002e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    __ Bind(&test_start);
23012e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    (masm.*test.instruction)(r0, &before);
23022e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    (masm.*test.instruction)(r1, &after);
23032e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
23042e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    {
23052e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa      int space = AlignDown(padding_after, nop_size);
23067027d2f28e155bb1dfc360b4c69c8f86320a6094Alexandre Rames      ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
23072e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa      for (int32_t end = masm.GetCursorOffset() + space;
23082e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa           masm.GetCursorOffset() < end;) {
23092e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa        __ nop();
23102e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa      }
23112e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    }
23122e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
23132e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    Label after_pool;
23142e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    __ B(&after_pool);
23152e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    __ Place(&after);
23162e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    __ Bind(&after_pool);
23172e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
23182e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    END();
23192e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
23202e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    RUN();
23212e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa
23222e7b9043baf27f8a4487403e24666203981ba57bBaptiste Afsa    ASSERT_EQUAL_32(test.test_value, r0);
23232e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa    ASSERT_EQUAL_32(test.test_value, r1);
23242e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  }
23252e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa
23262e5ad788a3a6c591d6c486d2a7c410926a165a58Baptiste Afsa  TEARDOWN();
232788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
232888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
232988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
233088c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(emit_big_pool) {
233188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
233288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
233388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
233488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Make sure the pool is empty.
233588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
233688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
233788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label start;
233888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&start);
233988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  for (int i = 1000; i > 0; --i) {
234088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    __ Ldr(r0, i);
234188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
234288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
234388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&start) == 4000);
234488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
234588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(4000);
234688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
234788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
234888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
234988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
235088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Check that the literals loaded correctly.
235188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(1, r0);
235288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
235388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
235488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
235588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
235688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
23572ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_T32(too_far_cbz) {
235888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
235988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
23602ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
236188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label start;
236288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label end;
236388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label exit;
236488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
236588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&start);
236688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&end);
236788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 1);
236888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&exit);
236988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&start);
237088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Cbz is only defined for forward jump. Check that it will work (substituted
237188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // by Cbnz/B).
237288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cbz(r0, &end);
237388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&exit);
237488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
237588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
237688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
237788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
237888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(1, r0);
237988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
238088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
238188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
23822ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_T32(close_cbz) {
2383f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  SETUP();
2384f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
23852ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
2386f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  Label first;
2387f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  Label second;
2388f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r0, 0);
2389f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r1, 0);
2390f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r2, 0);
2391f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cbz(r0, &first);
2392f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Bind(&first);
2393f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r1, 1);
2394f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cbnz(r0, &second);
2395f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Bind(&second);
2396f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r2, 2);
2397f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  END();
2398f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2399f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  RUN();
2400f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2401f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  ASSERT_EQUAL_32(0, r0);
2402f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  ASSERT_EQUAL_32(1, r1);
2403f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  ASSERT_EQUAL_32(2, r2);
2404f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard}
2405f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2406f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
24072ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_T32(close_cbz2) {
2408f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  SETUP();
2409f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
24102ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
2411f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  Label first;
2412f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  Label second;
2413f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r0, 0);
2414f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r1, 0);
2415f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r2, 0);
2416f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cmp(r0, 0);
2417f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ B(ne, &first);
2418f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ B(gt, &second);
2419f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cbz(r0, &first);
2420f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Bind(&first);
2421f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r1, 1);
2422f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cbnz(r0, &second);
2423f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Bind(&second);
2424f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Mov(r2, 2);
2425f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  END();
2426f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2427f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  RUN();
2428f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2429f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  ASSERT_EQUAL_32(0, r0);
2430f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  ASSERT_EQUAL_32(1, r1);
2431f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  ASSERT_EQUAL_32(2, r2);
2432f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard}
2433f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2434f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
24352ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_T32(not_close_cbz) {
2436f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  SETUP();
2437f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
24382ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
2439f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  Label first;
2440f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  Label second;
2441f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cbz(r0, &first);
2442f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ B(ne, &first);
2443f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Bind(&first);
2444f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Cbnz(r0, &second);
2445f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ B(gt, &second);
2446f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  __ Bind(&second);
2447f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  END();
2448f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2449f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard  RUN();
2450f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard}
2451f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
2452f8833fa525b25cb1d72beb4f2d033d5ad9a3eb80Vincent Belliard
24532ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_T32(veneers) {
245488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
245588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
24562ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
245788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label zero;
245888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label exit;
245988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0);
246088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Create one literal pool entry.
246188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldr(r1, 0x12345678);
246288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(4);
246388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cbz(r0, &zero);
246488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 1);
246588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&exit);
246688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  for (int i = 32; i > 0; i--) {
246788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    __ Mov(r1, 0);
246888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
246988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Assert that the literal pool has been generated with the veneers.
247088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_LITERAL_POOL_SIZE(0);
247188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&zero);
247288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 2);
247388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&exit);
247488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
247588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
247688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
247788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
247888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(2, r0);
247988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x12345678, r1);
248088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
248188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
248288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
248388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// This test checks that veneers are sorted. If not, the test failed as the
248488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// veneer for "exit" is emitted before the veneer for "zero" and the "zero"
248588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// veneer is out of range for Cbz.
24862ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_T32(veneers_labels_sort) {
248788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
248888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
24892ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
249088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label start;
249188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label zero;
249288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label exit;
249388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Movs(r0, 0);
249488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(ne, &exit);
249588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&start);
249688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  for (int i = 1048400; i > 0; i -= 4) {
249788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    __ Mov(r1, 0);
249888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
249988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&start);
250088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Cbz(r0, &zero);
250188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 1);
250288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ B(&exit);
250388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  for (int i = 32; i > 0; i--) {
250488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    __ Mov(r1, 0);
250588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
250688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&zero);
250788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 2);
250888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&exit);
250988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
251088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
251188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
251288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
251388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(2, r0);
251488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
251588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
25167827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard// Check that a label bound within the assembler is effectively removed from
25177827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard// the veneer pool.
25187827144797ee5ebfa0b574f45ad8ff235f919304Vincent BelliardTEST_T32(veneer_bind) {
25197827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  SETUP();
25207827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  Label target;
25217827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  __ Cbz(r0, &target);
25227827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  __ Nop();
25237827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard
25247827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  {
25257827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard    // Bind the target label using the `Assembler`.
25263e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    ExactAssemblyScope scope(&masm,
25273e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli                             kMaxInstructionSizeInBytes,
25283e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli                             ExactAssemblyScope::kMaximumSize);
25297827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard    __ bind(&target);
25307827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard    __ nop();
25317827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  }
25327827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard
25337827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  VIXL_CHECK(target.IsBound());
25347827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  VIXL_CHECK(masm.VeneerPoolIsEmpty());
25357827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard
25367827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard  END();
25377827144797ee5ebfa0b574f45ad8ff235f919304Vincent Belliard}
253888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
25393e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
25402272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard// Check that the veneer pool is correctly emitted even if we do enough narrow
25412272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard// branches before a cbz so that the cbz needs its veneer emitted first in the
25422272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard// pool in order to work.
25432272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent BelliardTEST_T32(b_narrow_and_cbz_sort) {
25442272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  SETUP();
25452272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  START();
25462272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25472272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  const int kLabelsCount = 40;
25482272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  const int kNops = 30;
25492272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  Label b_labels[kLabelsCount];
25502272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  Label cbz_label;
25512272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25522272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Nop();
25532272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25542272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Mov(r0, 0);
25552272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Cmp(r0, 0);
25562272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25572272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  for (int i = 0; i < kLabelsCount; ++i) {
25582272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    __ B(ne, &b_labels[i], kNear);
25592272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
25602272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25612272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  {
25622272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    ExactAssemblyScope scope(&masm,
25632272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard                             k16BitT32InstructionSizeInBytes * kNops,
25642272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard                             ExactAssemblyScope::kExactSize);
25652272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    for (int i = 0; i < kNops; i++) {
25662272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard      __ nop();
25672272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    }
25682272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
25692272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25702272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  // The pool should not be emitted here.
25712272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Cbz(r0, &cbz_label);
25722272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25732272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  // Force pool emission. If the labels are not sorted, the cbz will be out
25742272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  // of range.
25752272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  int32_t margin = masm.GetMarginBeforeVeneerEmission();
25762272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  int32_t end = masm.GetCursorOffset() + margin;
25772272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25782272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  {
25792272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
25802272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    while (masm.GetCursorOffset() < end) {
25812272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard      __ nop();
25822272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    }
25832272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
25842272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25852272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Mov(r0, 1);
25862272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25872272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  for (int i = 0; i < kLabelsCount; ++i) {
25882272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    __ Bind(&b_labels[i]);
25892272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
25902272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25912272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Bind(&cbz_label);
25922272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25932272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  END();
25942272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25952272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  RUN();
25962272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25972272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  ASSERT_EQUAL_32(0, r0);
25982272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
25992272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  TEARDOWN();
26002272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard}
26012272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26022272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26032272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent BelliardTEST_T32(b_narrow_and_cbz_sort_2) {
26042272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  SETUP();
26052272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  START();
26062272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26072272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  const int kLabelsCount = 40;
26082272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  const int kNops = 30;
26092272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  Label b_labels[kLabelsCount];
26102272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  Label cbz_label;
26112272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26122272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Mov(r0, 0);
26132272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Cmp(r0, 0);
26142272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26152272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  for (int i = 0; i < kLabelsCount; ++i) {
26162272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    __ B(ne, &b_labels[i], kNear);
26172272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
26182272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26192272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  {
26202272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    ExactAssemblyScope scope(&masm,
26212272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard                             k16BitT32InstructionSizeInBytes * kNops,
26222272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard                             ExactAssemblyScope::kExactSize);
26232272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    for (int i = 0; i < kNops; i++) {
26242272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard      __ nop();
26252272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    }
26262272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
26272272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26282272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  // The pool should not be emitted here.
26292272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Cbz(r0, &cbz_label);
26302272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26312272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  // Force pool emission. If the labels are not sorted, the cbz will be out
26322272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  // of range.
26332272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  int32_t margin = masm.GetMarginBeforeVeneerEmission();
26342272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  int32_t end = masm.GetCursorOffset() + margin;
26352272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26362272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  while (masm.GetCursorOffset() < end) __ Nop();
26372272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26382272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Mov(r0, 1);
26392272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26402272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  for (int i = 0; i < kLabelsCount; ++i) {
26412272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard    __ Bind(&b_labels[i]);
26422272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  }
26432272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26442272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  __ Bind(&cbz_label);
26452272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26462272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  END();
26472272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26482272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  RUN();
26492272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26502272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  ASSERT_EQUAL_32(0, r0);
26512272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26522272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard  TEARDOWN();
26532272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard}
26542272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
26552272afbda5f15c4bfb25c3c9bf95d960c9df39d6Vincent Belliard
2656a4cbc576a003da934ab58b293d9023d9b6f3077bVincent BelliardTEST_T32(long_branch) {
2657a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  SETUP();
2658a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  START();
2659a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2660a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  for (int label_count = 128; label_count < 2048; label_count *= 2) {
2661a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    Label* l = new Label[label_count];
2662a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2663a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    for (int i = 0; i < label_count; i++) {
2664a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard      __ B(&l[i]);
2665a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    }
2666a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2667a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    for (int i = 0; i < label_count; i++) {
2668a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard      __ B(ne, &l[i]);
2669a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    }
2670a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2671a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    for (int i = 0; i < 261625; i++) {
2672a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard      __ Clz(r0, r0);
2673a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    }
2674a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2675a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    for (int i = label_count - 1; i >= 0; i--) {
2676a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard      __ Bind(&l[i]);
2677a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard      __ Nop();
2678a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    }
2679a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2680a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard    delete[] l;
2681a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  }
2682a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2683a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  masm.FinalizeCode();
2684a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2685a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  END();
2686a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  RUN();
2687a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard  TEARDOWN();
2688a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard}
2689a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
2690a4cbc576a003da934ab58b293d9023d9b6f3077bVincent Belliard
26913e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia KouveliTEST_T32(unaligned_branch_after_literal) {
26923e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  SETUP();
26933e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
26943e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  START();
26953e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
26963e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  // This test manually places a 32-bit literal after a 16-bit branch
26973e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  // which branches over the literal to an unaligned PC.
26983e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  Literal<int32_t> l0(0x01234567, RawLiteral::kManuallyPlaced);
26993e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27003e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  __ Ldr(r0, &l0);
27013e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
27023e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27033e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
27043e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
27053e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27063e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  // Manually generate a literal pool.
27073e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  {
27083e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    Label after_pool;
27093e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    ExactAssemblyScope scope(&masm,
27103e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli                             k16BitT32InstructionSizeInBytes + sizeof(int32_t),
27113e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli                             CodeBufferCheckScope::kMaximumSize);
27123e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    __ b(Narrow, &after_pool);
27133e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    __ place(&l0);
27143e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
27153e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli    __ bind(&after_pool);
27163e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  }
27173e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27183e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
27193e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27203e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  END();
27213e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27223e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  RUN();
27233e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27243e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  // Check that the literal was loaded correctly.
27253e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  ASSERT_EQUAL_32(0x01234567, r0);
27263e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27273e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli  TEARDOWN();
27283e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli}
27293e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27303e1f5530fae1bf65c565f5dc757bd58913ffd2a2Georgia Kouveli
27313e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard// This test check that we can update a Literal after usage.
27323e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent BelliardTEST(literal_update) {
27333e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  SETUP();
27343e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard
27353e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  START();
27363e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  Label exit;
27373e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  Literal<uint32_t>* a32 =
27383e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard      new Literal<uint32_t>(0xabcdef01, RawLiteral::kDeletedOnPoolDestruction);
27393e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  Literal<uint64_t>* a64 =
2740bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      new Literal<uint64_t>(UINT64_C(0xabcdef01abcdef01),
2741bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
27423e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  __ Ldr(r0, a32);
27433e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  __ Ldrd(r2, r3, a64);
27443e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  __ EmitLiteralPool();
27453e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  Literal<uint32_t>* b32 =
27463e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard      new Literal<uint32_t>(0x10fedcba, RawLiteral::kDeletedOnPoolDestruction);
27473e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  Literal<uint64_t>* b64 =
2748bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      new Literal<uint64_t>(UINT64_C(0x10fedcba10fedcba),
2749bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
27503e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  __ Ldr(r1, b32);
27513e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  __ Ldrd(r4, r5, b64);
27523e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  // Update literals' values. "a32" and "a64" are already emitted. "b32" and
27533e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  // "b64" will only be emitted when "END()" will be called.
2754919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames  a32->UpdateValue(0x12345678, masm.GetBuffer());
2755919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames  a64->UpdateValue(UINT64_C(0x13579bdf02468ace), masm.GetBuffer());
2756919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames  b32->UpdateValue(0x87654321, masm.GetBuffer());
2757919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames  b64->UpdateValue(UINT64_C(0x1032547698badcfe), masm.GetBuffer());
27583e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  END();
27593e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard
27603e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  RUN();
27613e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard
27623e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r0);
27633e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard  ASSERT_EQUAL_32(0x87654321, r1);
2764ace89ae8424261309696af6f71c37d09c55fdd84Pierre Langlois  ASSERT_EQUAL_32(0x02468ace, r2);
2765ace89ae8424261309696af6f71c37d09c55fdd84Pierre Langlois  ASSERT_EQUAL_32(0x13579bdf, r3);
2766ace89ae8424261309696af6f71c37d09c55fdd84Pierre Langlois  ASSERT_EQUAL_32(0x98badcfe, r4);
2767ace89ae8424261309696af6f71c37d09c55fdd84Pierre Langlois  ASSERT_EQUAL_32(0x10325476, r5);
27683e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard}
27693e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard
27703e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard
277188c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(claim_peek_poke) {
277288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
277388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
277488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
277588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
277688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  Label start;
277788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Bind(&start);
277888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Claim(0);
277988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Drop(0);
2780919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames  VIXL_CHECK((masm.GetCursorOffset() - start.GetLocation()) == 0);
278188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
278288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Claim(32);
278388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldr(r0, 0xcafe0000);
278488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldr(r1, 0xcafe0001);
278588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Ldr(r2, 0xcafe0002);
278688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Poke(r0, 0);
278788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Poke(r1, 4);
278888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Poke(r2, 8);
278988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Peek(r2, 0);
279088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Peek(r0, 4);
279188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Peek(r1, 8);
279288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Drop(32);
279388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
279488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
279588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
279688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
279788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
279888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcafe0001, r0);
279988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcafe0002, r1);
280088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xcafe0000, r2);
280188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
280288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
280388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
280488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
280588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
280688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(msr_i) {
280788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
280888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
28092ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph Perfetta  START();
281088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xdead);
281188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0xdead);
281288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r2, 0xdead);
281388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 0xb);
281488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Msr(APSR_nzcvqg, 0);
281588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mrs(r0, APSR);
281688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Msr(APSR_nzcvqg, 0xffffffff);
281788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mrs(r1, APSR);
281888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Only modify nzcvq => keep previous g.
2819a01fbf25f9e2c9c53e82774126c4717ee37c1d91Georgia Kouveli  __ Lsl(r4, r3, 28);
2820a01fbf25f9e2c9c53e82774126c4717ee37c1d91Georgia Kouveli  __ Msr(APSR_nzcvq, r4);
282188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mrs(r2, APSR);
282288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
282388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
282488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
282588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
282688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x10, r0);
282788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xf80f0010, r1);
282888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xb00f0010, r2);
282988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
283088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
283188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
283288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
283388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
28346dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste AfsaTEST(vmrs_vmsr) {
28356dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  SETUP();
28366dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28376dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  START();
28386dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  // Move some value to FPSCR and get them back to test vmsr/vmrs instructions.
28396dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Mov(r0, 0x2a000000);
28406dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Vmsr(FPSCR, r0);
28416dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
28426dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28436dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Mov(r0, 0x5a000000);
28446dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Vmsr(FPSCR, r0);
28456dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
28466dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28476dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  // Move to APSR_nzcv.
28486dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR);
28496dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ Mrs(r3, APSR);
28506dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  __ And(r3, r3, 0xf0000000);
28516dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28526dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  END();
28536dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28546dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  RUN();
28556dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28566dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  ASSERT_EQUAL_32(0x2a000000, r1);
28576dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  ASSERT_EQUAL_32(0x5a000000, r2);
28586dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  ASSERT_EQUAL_32(0x50000000, r3);
28596dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28606dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa  TEARDOWN();
28616dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa}
28626dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
28636dce099abc8c1c4b3d052080c7f4e330915edb79Baptiste Afsa
286488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(printf) {
286588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
286688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
286788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
286888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0xb00e0000);
286988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Msr(APSR_nzcvqg, r0);
287088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, sp);
287188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Printf("sp=%x\n", r0);
2872bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  //  __ Printf("Hello world!\n");
287388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x1234);
287488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x5678);
287525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  StringLiteral literal("extra string");
287625e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois  __ Adr(r2, &literal);
287788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r3, 5);
287888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r4, 0xdead4444);
287988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r5, 0xdead5555);
288088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r6, 0xdead6666);
288188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r7, 0xdead7777);
288288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r8, 0xdead8888);
288388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r9, 0xdead9999);
288488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r10, 0xdeadaaaa);
288588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r11, 0xdeadbbbb);
288688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d0, 1.2345);
288788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d1, 2.9876);
288888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(s4, 1.3333);
288988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(s5, 3.21);
289088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d3, 3.333);
289188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d4, 4.444);
289288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d5, 5.555);
289388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d6, 6.666);
289488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d7, 7.777);
289588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d8, 8.888);
289688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d9, 9.999);
289788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d10, 10.000);
289888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d11, 11.111);
289988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d12, 12.222);
290088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d13, 13.333);
290188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d14, 14.444);
290288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d15, 15.555);
290388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d16, 16.666);
290488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d17, 17.777);
290588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d18, 18.888);
290688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d19, 19.999);
290788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d20, 20.000);
290888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d21, 21.111);
290988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d22, 22.222);
291088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d23, 23.333);
291188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d24, 24.444);
291288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d25, 25.555);
291388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d26, 26.666);
291488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d27, 27.777);
291588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d28, 28.888);
291688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d29, 29.999);
291788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d30, 30.000);
291888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d31, 31.111);
2919cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  {
2920cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    UseScratchRegisterScope temps(&masm);
2921cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // For effective use as an inspection tool, Printf must work without any
2922cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // scratch registers.
2923cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(r12.Is(temps.Acquire()));
2924cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Mov(r12, 0xdeadcccc);
2925cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(masm.GetScratchRegisterList()->IsEmpty());
2926cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
2927cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("%% r0=%x r1=%x str=<%.*s>\n", r0, r1, r3, r2);
2928cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("r0=%d r1=%d str=<%s>\n", r0, r1, r2);
2929cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("d0=%g\n", d0);
2930cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("s4=%g\n", s4);
2931cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("d0=%g d1=%g s4=%g s5=%g\n", d0, d1, s4, s5);
2932cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("d0=%g r0=%x s4=%g r1=%x\n", d0, r0, s4, r1);
2933cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("r0=%x d0=%g r1=%x s4=%g\n", r0, d0, r1, s4);
2934cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Mov(r0, sp);
2935cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Printf("sp=%x\n", r0);
2936cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Mrs(r0, APSR);
2937cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // Only keep R/W fields.
2938cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ Mov(r2, 0xf80f0200);
2939cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    __ And(r0, r0, r2);
2940cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  }
294188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
294288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
294388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
294488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
294588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xb00e0000, r0);
294688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0x5678, r1);
294788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(5, r3);
294888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdead4444, r4);
294988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdead5555, r5);
295088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdead6666, r6);
295188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdead7777, r7);
295288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdead8888, r8);
295388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdead9999, r9);
295488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdeadaaaa, r10);
295588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdeadbbbb, r11);
295688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_32(0xdeadcccc, r12);
295788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(1.2345, d0);
295888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(2.9876, d1);
295988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP32(1.3333, s4);
296088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP32(3.21, s5);
296188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(4.444, d4);
296288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(5.555, d5);
296388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(6.666, d6);
296488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(7.777, d7);
296588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(8.888, d8);
296688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(9.999, d9);
296788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(10.000, d10);
296888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(11.111, d11);
296988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(12.222, d12);
297088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(13.333, d13);
297188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(14.444, d14);
297288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(15.555, d15);
297388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(16.666, d16);
297488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(17.777, d17);
297588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(18.888, d18);
297688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(19.999, d19);
297788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(20.000, d20);
297888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(21.111, d21);
297988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(22.222, d22);
298088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(23.333, d23);
298188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(24.444, d24);
298288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(25.555, d25);
298388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(26.666, d26);
298488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(27.777, d27);
298588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(28.888, d28);
298688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(29.999, d29);
298788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(30.000, d30);
298888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  ASSERT_EQUAL_FP64(31.111, d31);
298988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
299088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
299188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
299288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
299388c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisTEST(printf2) {
299488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SETUP();
299588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
299688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  START();
299788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r0, 0x1234);
299888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Mov(r1, 0x5678);
299988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(d0, 1.2345);
300088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Vldr(s2, 2.9876);
300188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  __ Printf("d0=%g d1=%g r0=%x r1=%x\n", d0, s2, r0, r1);
300288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  END();
300388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
300488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  RUN();
300588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
300688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  TEARDOWN();
300788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
300888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
300988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
3010bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloistemplate <typename T>
301110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramleyvoid CheckInstructionSetA32(const T& assm) {
301210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  VIXL_CHECK(assm.IsUsingA32());
301310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  VIXL_CHECK(!assm.IsUsingT32());
301410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  VIXL_CHECK(assm.GetInstructionSetInUse() == A32);
301510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley}
301610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
301710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
3018bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloistemplate <typename T>
301910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramleyvoid CheckInstructionSetT32(const T& assm) {
302010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  VIXL_CHECK(assm.IsUsingT32());
302110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  VIXL_CHECK(!assm.IsUsingA32());
302210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  VIXL_CHECK(assm.GetInstructionSetInUse() == T32);
302310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley}
302410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
302510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
30262ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_NOASM(set_isa_constructors) {
3027919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames  byte buffer[1024];
302810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
30299a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifndef VIXL_INCLUDE_TARGET_T32_ONLY
303010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  // A32 by default.
303110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(Assembler());
303210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(Assembler(1024));
303310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(Assembler(buffer, sizeof(buffer)));
303410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
303510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(MacroAssembler());
303610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(MacroAssembler(1024));
303710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer)));
30389a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#else
30399a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  // T32 by default.
30409a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(Assembler());
30419a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(Assembler(1024));
30429a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(Assembler(buffer, sizeof(buffer)));
30439a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta
30449a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(MacroAssembler());
30459a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(MacroAssembler(1024));
30469a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer)));
30479a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
30489a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta
30499a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_A32
305010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  // Explicit A32.
30519a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetA32(Assembler(A32));
30529a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetA32(Assembler(1024, A32));
30539a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetA32(Assembler(buffer, sizeof(buffer), A32));
30549a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta
305510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(MacroAssembler(A32));
305610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(MacroAssembler(1024, A32));
305710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer), A32));
30589a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
30599a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta
30609a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_T32
306110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  // Explicit T32.
30629a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(Assembler(T32));
30639a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(Assembler(1024, T32));
30649a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  CheckInstructionSetT32(Assembler(buffer, sizeof(buffer), T32));
30659a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta
306610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(MacroAssembler(T32));
306710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(MacroAssembler(1024, T32));
306810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer), T32));
30699a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
307010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley}
307110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
307210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
30732ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_NOASM(set_isa_empty) {
3074bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois// It is possible to change the instruction set if no instructions have yet
3075bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois// been generated. This test only makes sense when both A32 and T32 are
3076bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois// supported.
30779a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_AARCH32
307810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  Assembler assm;
307910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(assm);
308010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  assm.UseT32();
308110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(assm);
308210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  assm.UseA32();
308310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(assm);
308410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  assm.UseInstructionSet(T32);
308510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(assm);
308610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  assm.UseInstructionSet(A32);
308710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(assm);
308810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
308910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  MacroAssembler masm;
309010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(masm);
309110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  masm.UseT32();
309210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(masm);
309310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  masm.UseA32();
309410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(masm);
309510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  masm.UseInstructionSet(T32);
309610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetT32(masm);
309710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  masm.UseInstructionSet(A32);
309810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  CheckInstructionSetA32(masm);
30999a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
310010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley}
310110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
310210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
31032ec4cbaaa5d0c4d50fd207140886e4cbc2d37aa0Rodolph PerfettaTEST_NOASM(set_isa_noop) {
3104bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois// It is possible to call a no-op UseA32/T32 or UseInstructionSet even if
3105bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois// one or more instructions have been generated.
31069a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_A32
310710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  {
310810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    Assembler assm(A32);
310910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetA32(assm);
31108d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
311110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.bx(lr);
311210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    VIXL_ASSERT(assm.GetCursorOffset() > 0);
311310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetA32(assm);
311410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.UseA32();
311510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetA32(assm);
311610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.UseInstructionSet(A32);
311710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetA32(assm);
311810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.FinalizeCode();
311910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  }
312010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  {
31219a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    MacroAssembler masm(A32);
31229a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    CheckInstructionSetA32(masm);
31239a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    masm.Bx(lr);
31249a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    VIXL_ASSERT(masm.GetCursorOffset() > 0);
31259a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    CheckInstructionSetA32(masm);
31269a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    masm.UseA32();
31279a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    CheckInstructionSetA32(masm);
31289a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    masm.UseInstructionSet(A32);
31299a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    CheckInstructionSetA32(masm);
31309a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta    masm.FinalizeCode();
31319a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  }
31329a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
31339a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta
31349a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_T32
31359a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta  {
313610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    Assembler assm(T32);
313710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(assm);
31388d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames    CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
313910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.bx(lr);
314010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    VIXL_ASSERT(assm.GetCursorOffset() > 0);
314110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(assm);
314210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.UseT32();
314310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(assm);
314410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.UseInstructionSet(T32);
314510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(assm);
314610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    assm.FinalizeCode();
314710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  }
314810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  {
314910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    MacroAssembler masm(T32);
315010dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(masm);
315110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    masm.Bx(lr);
315210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    VIXL_ASSERT(masm.GetCursorOffset() > 0);
315310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(masm);
315410dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    masm.UseT32();
315510dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(masm);
315610dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    masm.UseInstructionSet(T32);
315710dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    CheckInstructionSetT32(masm);
315810dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley    masm.FinalizeCode();
315910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley  }
31609a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
316110dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley}
316210dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
316310dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramley
3164628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre RamesTEST(logical_arithmetic_identities) {
3165628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  SETUP();
3166628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3167628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  START();
3168628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3169628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_1;
3170628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_1);
3171628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Add(r0, r0, 0);
3172628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ And(r0, r0, 0xffffffff);
3173628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bic(r0, r0, 0);
3174628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Eor(r0, r0, 0);
3175628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Orn(r0, r0, 0xffffffff);
3176628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Orr(r0, r0, 0);
3177628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Sub(r0, r0, 0);
3178628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_1) == 0);
3179628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3180628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_2;
3181628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_2);
3182628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Adds(r0, r0, 0);
3183628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_2) != 0);
3184628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3185628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_3;
3186628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_3);
3187628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Ands(r0, r0, 0);
3188628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_3) != 0);
3189628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3190628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_4;
3191628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_4);
3192628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bics(r0, r0, 0);
3193628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_4) != 0);
3194628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3195628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_5;
3196628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_5);
3197628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Eors(r0, r0, 0);
3198628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_5) != 0);
3199628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3200628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_6;
3201628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_6);
3202628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Orns(r0, r0, 0);
3203628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_6) != 0);
3204628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3205628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_7;
3206628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_7);
3207628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Orrs(r0, r0, 0);
3208628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_7) != 0);
3209628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3210628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  Label blob_8;
3211628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bind(&blob_8);
3212628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Subs(r0, r0, 0);
3213628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_8) != 0);
3214628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3215628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Mov(r0, 0xbad);
3216628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ And(r1, r0, 0);
3217628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Bic(r2, r0, 0xffffffff);
3218628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Eor(r3, r0, 0xffffffff);
3219628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Orn(r4, r0, 0);
3220628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  __ Orr(r5, r0, 0xffffffff);
3221628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3222628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  END();
3223628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3224628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  RUN();
3225628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3226628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  ASSERT_EQUAL_32(0xbad, r0);
3227628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  ASSERT_EQUAL_32(0, r1);
3228628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  ASSERT_EQUAL_32(0, r2);
3229628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  ASSERT_EQUAL_32(~0xbad, r3);
32308e7b9ae08bf958a99c4130ad15ec4aeedeee1cb2Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r4);
32318e7b9ae08bf958a99c4130ad15ec4aeedeee1cb2Pierre Langlois  ASSERT_EQUAL_32(0xffffffff, r5);
3232628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3233628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames  TEARDOWN();
3234628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames}
3235628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3236628c5263f1ff96c793173770b85b93ebf8bf8d44Alexandre Rames
3237cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob BramleyTEST(scratch_register_checks) {
3238cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  // It is unsafe for users to use registers that the MacroAssembler is also
3239cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  // using as scratch registers. This test checks the MacroAssembler's checking
3240cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  // mechanism itself.
3241cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  SETUP();
32424cb13e841305b38acbd8195b1c511d59c91ec8d9Georgia Kouveli  START();
3243cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  {
3244cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    UseScratchRegisterScope temps(&masm);
3245cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // 'ip' is a scratch register by default.
3246bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_CHECK(masm.GetScratchRegisterList()->GetList() ==
3247bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois               (1u << ip.GetCode()));
3248cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(ip));
3249cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3250cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // Integer registers have no complicated aliasing so
3251cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // masm.AliasesAvailableScratchRegister(reg) == temps.IsAvailable(reg).
3252cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    for (unsigned i = 0; i < kNumberOfRegisters; i++) {
3253cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      Register reg(i);
3254cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      VIXL_CHECK(masm.AliasesAvailableScratchRegister(reg) ==
3255cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley                 temps.IsAvailable(reg));
3256cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    }
3257cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  }
32584cb13e841305b38acbd8195b1c511d59c91ec8d9Georgia Kouveli  END();
3259cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  TEARDOWN();
3260cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley}
3261cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3262cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3263cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob BramleyTEST(scratch_register_checks_v) {
3264cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  // It is unsafe for users to use registers that the MacroAssembler is also
3265cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  // using as scratch registers. This test checks the MacroAssembler's checking
3266cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  // mechanism itself.
3267cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  SETUP();
3268cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  {
3269cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    UseScratchRegisterScope temps(&masm);
3270cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // There is no default floating-point scratch register. Add temps of various
3271cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // sizes to check handling of aliased registers.
3272cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() == 0);
3273cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(q15);
3274cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(d15);
3275cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(s15);
3276cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(d4);
3277cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(d5);
3278cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(s24);
3279cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(s25);
3280cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(s26);
3281cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(s27);
3282cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    temps.Include(q0);
3283cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // See VRegisterList for details of the list encoding.
3284cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() ==
3285cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley               UINT64_C(0xf0000000cf008f0f));
3286cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    //                    |       ||  || |
3287cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    //                   q15    d15|  || q0
3288cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    //                        s24-s27 |d4-d5
3289cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    //                               s15
3290cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3291cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // Simple checks: Included registers are available.
3292cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(q15));
3293cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(d15));
3294cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(s15));
3295cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(d4));
3296cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(d5));
3297cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(s24));
3298cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(s25));
3299cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(s26));
3300cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(s27));
3301cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    VIXL_CHECK(temps.IsAvailable(q0));
3302cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3303cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // Each available S register should mark the corresponding D and Q registers
3304cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // as aliasing an available scratch register.
3305cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    for (unsigned s = 0; s < kNumberOfSRegisters; s++) {
3306cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      if (temps.IsAvailable(SRegister(s))) {
3307cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(masm.AliasesAvailableScratchRegister(SRegister(s)));
3308cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(s / 2)));
3309cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(s / 4)));
3310cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      } else {
3311cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        // AliasesAvailableScratchRegiters == IsAvailable for S registers.
3312cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(!masm.AliasesAvailableScratchRegister(SRegister(s)));
3313cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      }
3314cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    }
3315cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3316cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    // Similar checks for high D registers.
3317cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    unsigned first_high_d_register = kNumberOfSRegisters / 2;
3318cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    for (unsigned d = first_high_d_register; d < kMaxNumberOfDRegisters; d++) {
3319cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      if (temps.IsAvailable(DRegister(d))) {
3320cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(d)));
3321cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(d / 2)));
3322cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      } else {
3323cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        // AliasesAvailableScratchRegiters == IsAvailable for high D registers.
3324cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley        VIXL_CHECK(!masm.AliasesAvailableScratchRegister(DRegister(d)));
3325cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley      }
3326cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley    }
3327cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  }
3328cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley  TEARDOWN();
3329cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley}
3330cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3331cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley
3332a38f9aec7b79989b658790b2492e2de67a64b430Alexandre RamesTEST(nop) {
3333a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  SETUP();
3334a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames
3335a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  Label start;
3336a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  __ Bind(&start);
3337a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  __ Nop();
3338a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  size_t nop_size = (isa == T32) ? k16BitT32InstructionSizeInBytes
3339a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames                                 : kA32InstructionSizeInBytes;
3340a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  // `MacroAssembler::Nop` must generate at least one nop.
3341a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) >= nop_size);
3342a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames
3343a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  masm.FinalizeCode();
3344a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames
3345a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames  TEARDOWN();
3346a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames}
3347a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames
3348a38f9aec7b79989b658790b2492e2de67a64b430Alexandre Rames
33490eb25b040732354c6273c93df709f8d585a140deAlexandre Rames// Check that `GetMarginBeforeLiteralEmission()` is precise.
33500eb25b040732354c6273c93df709f8d585a140deAlexandre RamesTEST(literal_pool_margin) {
33510eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  SETUP();
33520eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33530eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  START();
33540eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33550eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
33560eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
33570eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33580eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // Create a single literal.
33590eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  __ Ldrd(r0, r1, 0x1234567890abcdef);
33600eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33610eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
33620eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33630eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // Generate code to fill all the margin we have before generating the literal
33640eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // pool.
33650eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  int32_t margin = masm.GetMarginBeforeLiteralEmission();
33660eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  int32_t end = masm.GetCursorOffset() + margin;
33670eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  {
33681661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
33690eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // Opening the scope should not have triggered the emission of the literal
33700eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // pool.
33710eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    VIXL_CHECK(!masm.LiteralPoolIsEmpty());
33720eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    while (masm.GetCursorOffset() < end) {
33730eb25b040732354c6273c93df709f8d585a140deAlexandre Rames      __ nop();
33740eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    }
33750eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    VIXL_CHECK(masm.GetCursorOffset() == end);
33760eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  }
33770eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33780eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // There should be no margin left to emit the literal pool.
33790eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
33800eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.GetMarginBeforeLiteralEmission() == 0);
33810eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33820eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // So emitting a single instruction should force emission of the pool.
33830eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  __ Nop();
33840eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
33850eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  END();
33860eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33870eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  RUN();
33880eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33890eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // Check that the literals loaded correctly.
33900eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  ASSERT_EQUAL_32(0x90abcdef, r0);
33910eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  ASSERT_EQUAL_32(0x12345678, r1);
33920eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33930eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  TEARDOWN();
33940eb25b040732354c6273c93df709f8d585a140deAlexandre Rames}
33950eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33960eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
33970eb25b040732354c6273c93df709f8d585a140deAlexandre Rames// Check that `GetMarginBeforeVeneerEmission()` is precise.
33980eb25b040732354c6273c93df709f8d585a140deAlexandre RamesTEST(veneer_pool_margin) {
33990eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  SETUP();
34000eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34010eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  START();
34020eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34030eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
34040eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
34050eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34060eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // Create a single veneer.
34070eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  Label target;
34080eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  __ B(eq, &target);
34090eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34100eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
34110eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34120eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // Generate code to fill all the margin we have before generating the veneer
34130eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // pool.
34140eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  int32_t margin = masm.GetMarginBeforeVeneerEmission();
34150eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  int32_t end = masm.GetCursorOffset() + margin;
34160eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  {
34171661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
34180eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // Opening the scope should not have triggered the emission of the veneer
34190eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // pool.
34200eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    VIXL_CHECK(!masm.VeneerPoolIsEmpty());
34210eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    while (masm.GetCursorOffset() < end) {
34220eb25b040732354c6273c93df709f8d585a140deAlexandre Rames      __ nop();
34230eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    }
34240eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    VIXL_CHECK(masm.GetCursorOffset() == end);
34250eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  }
34260eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // There should be no margin left to emit the veneer pool.
34270eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() == 0);
34280eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34290eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // So emitting a single instruction should force emission of the pool.
34300eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // We cannot simply check that the veneer pool is empty, because the veneer
34310eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // emitted for the CBZ instruction above is itself tracked by the veneer
34320eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // mechanisms. Instead, check that some 'unexpected' code is generated.
34330eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  Label check;
34340eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  __ Bind(&check);
34350eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  {
34361661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
34370eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // Do not actually generate any code.
34380eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  }
34390eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) > 0);
34400eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  __ Bind(&target);
34410eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
34420eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34430eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  END();
34440eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34450eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  RUN();
34460eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34470eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  TEARDOWN();
34480eb25b040732354c6273c93df709f8d585a140deAlexandre Rames}
34490eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
34500eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
3451139307eb64ef70e32e75b4de5ba95da58513e238Martyn CapewellTEST_T32(near_branch_fuzz) {
345267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  SETUP();
345367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  START();
345467b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
345567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  uint16_t seed[3] = {1, 2, 3};
345667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  seed48(seed);
345767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
345867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  const int label_count = 31;
345967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  bool allbound;
346067b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  Label* l;
346167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
346267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  // Use multiple iterations, as each produces a different predictably random
346367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  // sequence.
3464139307eb64ef70e32e75b4de5ba95da58513e238Martyn Capewell  const int iterations = 64;
346567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
346667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  int loop_count = 0;
346767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  __ Mov(r1, 0);
346867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
3469139307eb64ef70e32e75b4de5ba95da58513e238Martyn Capewell  // Initialise the status flags to Z set.
3470139307eb64ef70e32e75b4de5ba95da58513e238Martyn Capewell  __ Cmp(r1, r1);
3471139307eb64ef70e32e75b4de5ba95da58513e238Martyn Capewell
347267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  // Gradually increasing the number of cases effectively increases the
347367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  // probability of nops being emitted in the sequence. The branch-to-bind
347467b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  // ratio in the sequence is fixed at 4:1 by the ratio of cases.
347567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  for (int case_count = 6; case_count < 37; case_count++) {
347667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley    for (int iter = 0; iter < iterations; iter++) {
347767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      // Reset local state.
347867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      allbound = false;
347967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      l = new Label[label_count];
348067b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
348167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      // Set r0 != 0 to force no branches to be taken. Also acts as a marker
348267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      // between each iteration in the disassembly.
348367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      __ Mov(r0, 1);
348467b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
348567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      for (;;) {
348667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        uint32_t inst_case = static_cast<uint32_t>(mrand48()) % case_count;
348767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        uint32_t label_index = static_cast<uint32_t>(mrand48()) % label_count;
348867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
348967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        switch (inst_case) {
3490bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois          case 0:  // Bind.
349167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            if (!l[label_index].IsBound()) {
349267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley              __ Bind(&l[label_index]);
349367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
349467b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley              // We should hit each label exactly once (because the branches are
349567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley              // never taken). Keep a counter to verify this.
349667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley              loop_count++;
349767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley              __ Add(r1, r1, 1);
349867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            }
349967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            break;
3500bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois          case 1:  // Compare and branch if zero (untaken as r0 == 1).
350167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            __ Cbz(r0, &l[label_index]);
350267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            break;
3503bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois          case 2: {  // Compare and branch if not zero.
3504d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            Label past_branch;
3505d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ B(eq, &past_branch, kNear);
3506d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ Cbnz(r0, &l[label_index]);
3507d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ Bind(&past_branch);
3508d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            break;
3509d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois          }
3510bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois          case 3: {  // Unconditional branch preferred near.
3511d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            Label past_branch;
3512d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ B(eq, &past_branch, kNear);
3513d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ B(&l[label_index], kNear);
3514d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ Bind(&past_branch);
3515d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            break;
3516d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois          }
3517bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois          case 4:  // Conditional branch (untaken as Z set) preferred near.
3518d87b1134b5be7b7fb5518180efb3b20b37a7923bPierre Langlois            __ B(ne, &l[label_index], kNear);
3519139307eb64ef70e32e75b4de5ba95da58513e238Martyn Capewell            break;
3520bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois          default:  // Nop.
352167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            __ Nop();
352267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley            break;
352367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        }
352467b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
352567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        // If all labels have been bound, exit the inner loop and finalise the
352667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        // code.
352767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        allbound = true;
352867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        for (int i = 0; i < label_count; i++) {
352967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley          allbound = allbound && l[i].IsBound();
353067b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        }
353167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley        if (allbound) break;
353267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      }
353367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
3534139307eb64ef70e32e75b4de5ba95da58513e238Martyn Capewell      // Ensure that the veneer pools are emitted, to keep each branch/bind test
353567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      // independent.
353667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      masm.FinalizeCode();
353767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley      delete[] l;
353867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley    }
353967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  }
354067b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
354167b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  END();
354267b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  RUN();
354367b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
354467b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  ASSERT_EQUAL_32(loop_count, r1);
354567b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
354667b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley  TEARDOWN();
354767b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley}
354867b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
354967b839b72b77d13cca5363b477facaee33f22bb9Jacob Bramley
35509a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_T32
3551ea90afd4d8e19b3b3f9c051f96c1d7ef98da5c5eJacob BramleyTEST_NOASM(code_buffer_precise_growth) {
35520eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  static const int kBaseBufferSize = 16;
35530eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  MacroAssembler masm(kBaseBufferSize, T32);
35540eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35550eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
35560eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35570eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  {
35580eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    // Fill the buffer with nops.
3559bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm,
3560bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                             kBaseBufferSize,
3561bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                             ExactAssemblyScope::kExactSize);
35620eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    for (int i = 0; i < kBaseBufferSize; i += k16BitT32InstructionSizeInBytes) {
35630eb25b040732354c6273c93df709f8d585a140deAlexandre Rames      __ nop();
35640eb25b040732354c6273c93df709f8d585a140deAlexandre Rames    }
35650eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  }
35660eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35670eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // The buffer should not have grown yet.
35680eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
35690eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35700eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  // Generating a single instruction should force the buffer to grow.
35710eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  __ Nop();
35720eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35730eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  VIXL_CHECK(masm.GetBuffer()->GetCapacity() > kBaseBufferSize);
35740eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35750eb25b040732354c6273c93df709f8d585a140deAlexandre Rames  masm.FinalizeCode();
35760eb25b040732354c6273c93df709f8d585a140deAlexandre Rames}
35779a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
35780eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35790eb25b040732354c6273c93df709f8d585a140deAlexandre Rames
35809a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#ifdef VIXL_INCLUDE_TARGET_T32
3581ea90afd4d8e19b3b3f9c051f96c1d7ef98da5c5eJacob BramleyTEST_NOASM(out_of_space_immediately_before_PerformEnsureEmit) {
35828d191abf32edf41421f68f35585e4fce8da4d50cAlexandre Rames  static const int kBaseBufferSize = 64;
3583740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  MacroAssembler masm(kBaseBufferSize, T32);
3584740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3585740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3586740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3587740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3588740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(masm.LiteralPoolIsEmpty());
3589740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3590740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  // Create a veneer.
3591740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  Label target;
3592740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  __ Cbz(r0, &target);
3593740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3594740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
3595740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3596740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3597740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  uint32_t space = static_cast<uint32_t>(masm.GetBuffer()->GetRemainingBytes());
3598740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  {
3599740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames    // Fill the buffer with nops.
36001661f51a172e7c3dcce6caca55b6fe6d10ebd416Alexandre Rames    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3601740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames    for (uint32_t i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
3602740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames      __ nop();
3603740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames    }
3604740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  }
3605740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3606740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
3607740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3608740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  // The buffer should not have grown yet, and there should be no space left.
3609740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3610740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(masm.GetBuffer()->GetRemainingBytes() == 0);
3611740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3612740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  // Force emission of the veneer, at a point where there is no space available
3613740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  // in the buffer.
3614740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  int32_t past_cbz_range = masm.GetMarginBeforeVeneerEmission() + 1;
3615740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  masm.EnsureEmitFor(past_cbz_range);
3616740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3617740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  __ Bind(&target);
3618740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3619740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3620740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3621740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames  masm.FinalizeCode();
3622740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames}
36239a9331faeba996d6c85e6e2a6355ccfc22c6cab6Rodolph Perfetta#endif
3624740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
3625740da998f1b2677636dfd76a6028e283d6175bf0Alexandre Rames
362652e987eb677af65859f169b20816fa5d293c6cf0Jacob BramleyTEST_T32(distant_literal_references) {
3627f8c2284645ce651f99ba410a512279102851076eJacob Bramley  SETUP();
3628f8c2284645ce651f99ba410a512279102851076eJacob Bramley  START();
3629f8c2284645ce651f99ba410a512279102851076eJacob Bramley
363052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  Literal<uint64_t>* literal =
3631f8c2284645ce651f99ba410a512279102851076eJacob Bramley      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
3632f8c2284645ce651f99ba410a512279102851076eJacob Bramley                            RawLiteral::kPlacedWhenUsed,
3633f8c2284645ce651f99ba410a512279102851076eJacob Bramley                            RawLiteral::kDeletedOnPoolDestruction);
3634f8c2284645ce651f99ba410a512279102851076eJacob Bramley  // Refer to the literal so that it is emitted early.
3635f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldr(r0, literal);
3636f8c2284645ce651f99ba410a512279102851076eJacob Bramley
363752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Add enough nops to exceed the range of all loads.
3638f8c2284645ce651f99ba410a512279102851076eJacob Bramley  int space = 5000;
3639f8c2284645ce651f99ba410a512279102851076eJacob Bramley  {
3640bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
364189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    VIXL_ASSERT(masm.IsUsingT32());
364289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
3643f8c2284645ce651f99ba410a512279102851076eJacob Bramley      __ nop();
3644f8c2284645ce651f99ba410a512279102851076eJacob Bramley    }
3645f8c2284645ce651f99ba410a512279102851076eJacob Bramley  }
3646f8c2284645ce651f99ba410a512279102851076eJacob Bramley
3647bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ENSURE_ALIGNED()                                                      \
3648bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  do {                                                                        \
3649bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
3650bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois            masm.GetCursorOffset())) {                                        \
3651bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope scope(&masm,                                         \
3652bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               k16BitT32InstructionSizeInBytes,               \
3653bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               ExactAssemblyScope::kExactSize);               \
3654bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      __ nop();                                                               \
3655bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                         \
3656bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_ASSERT(                                                              \
3657bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
3658bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  } while (0)
36599c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
3660f8c2284645ce651f99ba410a512279102851076eJacob Bramley  // The literal has already been emitted, and is out of range of all of these
3661f8c2284645ce651f99ba410a512279102851076eJacob Bramley  // instructions. The delegates must generate fix-up code.
36629c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3663f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldr(r1, literal);
36649c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3665f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldrb(r2, literal);
36669c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3667f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldrsb(r3, literal);
36689c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3669f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldrh(r4, literal);
36709c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3671f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldrsh(r5, literal);
36729c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3673f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Ldrd(r6, r7, literal);
36749c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3675f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Vldr(d0, literal);
36769c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_ALIGNED();
3677f8c2284645ce651f99ba410a512279102851076eJacob Bramley  __ Vldr(s3, literal);
3678f8c2284645ce651f99ba410a512279102851076eJacob Bramley
36799c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley#undef ENSURE_ALIGNED
36809c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
36819c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  END();
36829c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  RUN();
36839c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
36849c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  // Check that the literals loaded correctly.
36859c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r0);
36869c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r1);
36879c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0xef, r2);
36889c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0xffffffef, r3);
36899c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0xcdef, r4);
36909c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0xffffcdef, r5);
36919c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r6);
36929c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_32(0x01234567, r7);
36939c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
3694832e97bf00eda271c2abbe3426618e9f8e60850eGeorgia Kouveli  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
36959c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
36969c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  TEARDOWN();
36979c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley}
36989c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
36999c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
370052e987eb677af65859f169b20816fa5d293c6cf0Jacob BramleyTEST_T32(distant_literal_references_unaligned_pc) {
37019c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  SETUP();
37029c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  START();
37039c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
370452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  Literal<uint64_t>* literal =
37059c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
37069c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley                            RawLiteral::kPlacedWhenUsed,
37079c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley                            RawLiteral::kDeletedOnPoolDestruction);
37089c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  // Refer to the literal so that it is emitted early.
37099c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldr(r0, literal);
37109c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
371152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Add enough nops to exceed the range of all loads, leaving the PC aligned
37129c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  // to only a two-byte boundary.
37139c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  int space = 5002;
37149c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  {
3715bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
371689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    VIXL_ASSERT(masm.IsUsingT32());
371789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
37189c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley      __ nop();
37199c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    }
37209c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  }
37219c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
3722bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ENSURE_NOT_ALIGNED()                                                   \
3723bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  do {                                                                         \
3724bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
3725bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope scope(&masm,                                          \
3726bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               k16BitT32InstructionSizeInBytes,                \
3727bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               ExactAssemblyScope::kExactSize);                \
3728bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      __ nop();                                                                \
3729bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                          \
3730bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_ASSERT(                                                               \
3731bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
3732bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  } while (0)
37339c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
37349c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  // The literal has already been emitted, and is out of range of all of these
37359c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  // instructions. The delegates must generate fix-up code.
37369c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_NOT_ALIGNED();
37379c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldr(r1, literal);
37389c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_NOT_ALIGNED();
37399c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldrb(r2, literal);
37409c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_NOT_ALIGNED();
37419c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldrsb(r3, literal);
37429c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_NOT_ALIGNED();
37439c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldrh(r4, literal);
37449c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_NOT_ALIGNED();
37459c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldrsh(r5, literal);
37469c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  ENSURE_NOT_ALIGNED();
37479c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  __ Ldrd(r6, r7, literal);
37489c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  {
37499c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // TODO: We currently require an extra scratch register for these cases
37509c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // because MemOperandComputationHelper isn't able to fit add_sub_offset into
37519c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // a single 'sub' instruction, so 'pc' gets preserved first. The same
37529c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // problem technically exists for the other loads, but vldr is particularly
37539c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // badly affected because vldr cannot set the low bits in its offset mask,
37549c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // so the add/sub operand is likely to be difficult to encode.
37559c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //
37569c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // At the moment, we get this:
37579c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     mov r8, pc
37589c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     mov ip, #5118
37599c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     sub r8, pc
37609c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     vldr d0, [r8, #48]
37619c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //
37629c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    // We should be able to generate something like this:
37639c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     sub ip, pc, #0x1300    // 5118 & 0xff00
37649c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     sub ip, #0xfe          // 5118 & 0x00ff
37659c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    //     vldr d0, [ip, #48]
37669c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    UseScratchRegisterScope temps(&masm);
37679c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    temps.Include(r8);
37689c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    ENSURE_NOT_ALIGNED();
37699c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    __ Vldr(d0, literal);
37709c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    ENSURE_NOT_ALIGNED();
37719c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley    __ Vldr(s3, literal);
37729c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley  }
37739c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
37749c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley#undef ENSURE_NOT_ALIGNED
37759c112d81bf7bc65d6bea5a1d889ef3db7609771dJacob Bramley
3776f8c2284645ce651f99ba410a512279102851076eJacob Bramley  END();
3777f8c2284645ce651f99ba410a512279102851076eJacob Bramley  RUN();
3778f8c2284645ce651f99ba410a512279102851076eJacob Bramley
3779f8c2284645ce651f99ba410a512279102851076eJacob Bramley  // Check that the literals loaded correctly.
3780f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r0);
3781f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r1);
3782f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0xef, r2);
3783f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0xffffffef, r3);
3784f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0xcdef, r4);
3785f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0xffffcdef, r5);
3786f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r6);
3787f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_32(0x01234567, r7);
3788f8c2284645ce651f99ba410a512279102851076eJacob Bramley  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
378927f1339a9fbbe5cb2df532557fd14c499d05a237Georgia Kouveli  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
3790f8c2284645ce651f99ba410a512279102851076eJacob Bramley
3791f8c2284645ce651f99ba410a512279102851076eJacob Bramley  TEARDOWN();
3792f8c2284645ce651f99ba410a512279102851076eJacob Bramley}
3793f8c2284645ce651f99ba410a512279102851076eJacob Bramley
3794f8c2284645ce651f99ba410a512279102851076eJacob Bramley
379552e987eb677af65859f169b20816fa5d293c6cf0Jacob BramleyTEST_T32(distant_literal_references_short_range) {
379652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  SETUP();
379752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  START();
379852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
379952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  Literal<uint64_t>* literal =
380052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
380152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley                            RawLiteral::kPlacedWhenUsed,
380252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley                            RawLiteral::kDeletedOnPoolDestruction);
380352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Refer to the literal so that it is emitted early.
380452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Vldr(s4, literal);
380552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
380652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Add enough nops to exceed the range of the loads, but not the adr that will
380752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // be generated to read the PC.
380852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  int space = 4000;
380952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  {
3810bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
381152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley    VIXL_ASSERT(masm.IsUsingT32());
381252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
381352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley      __ nop();
381452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley    }
381552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  }
381652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
3817bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ENSURE_ALIGNED()                                                      \
3818bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  do {                                                                        \
3819bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
3820bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois            masm.GetCursorOffset())) {                                        \
3821bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope scope(&masm,                                         \
3822bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               k16BitT32InstructionSizeInBytes,               \
3823bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               ExactAssemblyScope::kExactSize);               \
3824bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      __ nop();                                                               \
3825bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                         \
3826bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_ASSERT(                                                              \
3827bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
3828bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  } while (0)
382952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
383052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // The literal has already been emitted, and is out of range of all of these
383152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // instructions. The delegates must generate fix-up code.
383252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
383352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldr(r1, literal);
383452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
383552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrb(r2, literal);
383652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
383752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrsb(r3, literal);
383852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
383952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrh(r4, literal);
384052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
384152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrsh(r5, literal);
384252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
384352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrd(r6, r7, literal);
384452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
384552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Vldr(d0, literal);
384652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_ALIGNED();
384752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Vldr(s3, literal);
384852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
384952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley#undef ENSURE_ALIGNED
385052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
385152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  END();
385252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  RUN();
385352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
385452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Check that the literals loaded correctly.
385552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
385652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r1);
385752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xef, r2);
385852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xffffffef, r3);
385952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xcdef, r4);
386052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xffffcdef, r5);
386152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r6);
386252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0x01234567, r7);
386352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
386452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
386552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
386652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  TEARDOWN();
386752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley}
386852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
386952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
387052e987eb677af65859f169b20816fa5d293c6cf0Jacob BramleyTEST_T32(distant_literal_references_short_range_unaligned_pc) {
387152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  SETUP();
387252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  START();
387352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
387452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  Literal<uint64_t>* literal =
387552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
387652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley                            RawLiteral::kPlacedWhenUsed,
387752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley                            RawLiteral::kDeletedOnPoolDestruction);
387852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Refer to the literal so that it is emitted early.
387952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Vldr(s4, literal);
388052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
388152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Add enough nops to exceed the range of the loads, but not the adr that will
388252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // be generated to read the PC.
388352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  int space = 4000;
388452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  {
3885bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
388652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley    VIXL_ASSERT(masm.IsUsingT32());
388752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley    for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
388852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley      __ nop();
388952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley    }
389052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  }
389152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
3892bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define ENSURE_NOT_ALIGNED()                                                   \
3893bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  do {                                                                         \
3894bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
3895bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope scope(&masm,                                          \
3896bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               k16BitT32InstructionSizeInBytes,                \
3897bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               ExactAssemblyScope::kExactSize);                \
3898bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      __ nop();                                                                \
3899bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                          \
3900bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_ASSERT(                                                               \
3901bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
3902bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  } while (0)
390352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
390452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // The literal has already been emitted, and is out of range of all of these
390552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // instructions. The delegates must generate fix-up code.
390652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
390752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldr(r1, literal);
390852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
390952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrb(r2, literal);
391052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
391152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrsb(r3, literal);
391252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
391352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrh(r4, literal);
391452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
391552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrsh(r5, literal);
391652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
391752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Ldrd(r6, r7, literal);
391852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
391952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Vldr(d0, literal);
392052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ENSURE_NOT_ALIGNED();
392152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  __ Vldr(s3, literal);
392252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
392352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley#undef ENSURE_NOT_ALIGNED
392452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
392552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  END();
392652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  RUN();
392752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
392852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  // Check that the literals loaded correctly.
392952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
393052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r1);
393152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xef, r2);
393252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xffffffef, r3);
393352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xcdef, r4);
393452e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0xffffcdef, r5);
393552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r6);
393652e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_32(0x01234567, r7);
393752e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
393852e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
393952e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
394052e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  TEARDOWN();
394152e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley}
394252e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
394352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley
394489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob BramleyTEST_T32(distant_literal_references_long_range) {
394589d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  SETUP();
394689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  START();
394789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
394889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  Literal<uint64_t>* literal =
394989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
395089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley                            RawLiteral::kPlacedWhenUsed,
395189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley                            RawLiteral::kDeletedOnPoolDestruction);
395289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  // Refer to the literal so that it is emitted early.
395389d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldr(r0, literal);
395489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
3955bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define PAD_WITH_NOPS(space)                                             \
3956bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  do {                                                                   \
3957bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    {                                                                    \
3958bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope scope(&masm,                                    \
3959bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               space,                                    \
3960bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                               CodeBufferCheckScope::kExactSize);        \
3961bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      VIXL_ASSERT(masm.IsUsingT32());                                    \
3962bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) { \
3963bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        __ nop();                                                        \
3964bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      }                                                                  \
3965bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                    \
3966bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  } while (0)
396789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
396889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  // Add enough nops to exceed the range of all loads.
396989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  PAD_WITH_NOPS(5000);
397089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
397189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  // The literal has already been emitted, and is out of range of all of these
397289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  // instructions. The delegates must generate fix-up code.
397389d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldr(r1, literal);
397489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrb(r2, literal);
397589d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrsb(r3, literal);
397689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrh(r4, literal);
397789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrsh(r5, literal);
397889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrd(r6, r7, literal);
397989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Vldr(d0, literal);
398089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Vldr(s3, literal);
398189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
398289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  // Add enough nops to exceed the range of the adr+sub sequence.
398389d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  PAD_WITH_NOPS(0x421000);
398489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
398589d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldr(r1, literal);
398689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrb(r2, literal);
398789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrsb(r3, literal);
398889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrh(r4, literal);
398989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrsh(r5, literal);
399089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  __ Ldrd(r6, r7, literal);
399189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  {
399289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    // TODO: We currently require an extra scratch register for these cases. We
399389d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    // should be able to optimise the code generation to avoid this requirement
399489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    // (and in many cases avoid a 32-bit instruction).
399589d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    UseScratchRegisterScope temps(&masm);
399689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    temps.Include(r8);
399789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    __ Vldr(d0, literal);
399889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley    __ Vldr(s3, literal);
399989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  }
400089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
400189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley#undef PAD_WITH_NOPS
400289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
400389d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  END();
400489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  RUN();
400589d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
400689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  // Check that the literals loaded correctly.
400789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r0);
400889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r1);
400989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0xef, r2);
401089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0xffffffef, r3);
401189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0xcdef, r4);
401289d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0xffffcdef, r5);
401389d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0x89abcdef, r6);
401489d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_32(0x01234567, r7);
401589d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
401689d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
401789d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
401889d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley  TEARDOWN();
401989d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley}
402089d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
402189d2f7702f0dc1751574bd5f9d35b5182fc65facJacob Bramley
4022eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste AfsaTEST(barriers) {
4023eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // Generate all supported barriers, this is just a smoke test
4024eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  SETUP();
4025eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4026eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  START();
4027eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4028eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // DMB
4029eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(SY);
4030eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(ST);
4031eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(ISH);
4032eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(ISHST);
4033eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(NSH);
4034eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(NSHST);
4035eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(OSH);
4036eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dmb(OSHST);
4037eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4038eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // DSB
4039eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(SY);
4040eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(ST);
4041eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(ISH);
4042eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(ISHST);
4043eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(NSH);
4044eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(NSHST);
4045eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(OSH);
4046eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Dsb(OSHST);
4047eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4048eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // ISB
4049eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Isb(SY);
4050eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4051eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  END();
4052eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4053eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  TEARDOWN();
4054eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa}
4055eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4056eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4057eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste AfsaTEST(preloads) {
4058eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // Smoke test for various pld/pli forms.
4059eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  SETUP();
4060eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4061eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  START();
4062eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4063eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLD immediate
4064eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(sp, 0));
4065eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r0, 0));
4066eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r1, 123));
4067eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r2, 1234));
4068eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r3, 4095));
4069eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r4, -123));
4070eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r5, -255));
4071eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4072eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  if (masm.IsUsingA32()) {
4073eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pld(MemOperand(r6, -1234));
4074eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pld(MemOperand(r7, -4095));
4075eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  }
4076eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4077eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4078eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLDW immediate
4079eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(sp, 0));
4080eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r0, 0));
4081eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r1, 123));
4082eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r2, 1234));
4083eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r3, 4095));
4084eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r4, -123));
4085eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r5, -255));
4086eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4087eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  if (masm.IsUsingA32()) {
4088eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pldw(MemOperand(r6, -1234));
4089eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pldw(MemOperand(r7, -4095));
4090eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  }
4091eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4092eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLD register
4093eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r0, r1));
4094eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r0, r1, LSL, 1));
4095eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r0, r1, LSL, 2));
4096eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(MemOperand(r0, r1, LSL, 3));
4097eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4098eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  if (masm.IsUsingA32()) {
4099eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pld(MemOperand(r0, r1, LSL, 4));
4100eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pld(MemOperand(r0, r1, LSL, 20));
4101eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  }
4102eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4103eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLDW register
4104eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r0, r1));
4105eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r0, r1, LSL, 1));
4106eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r0, r1, LSL, 2));
4107eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pldw(MemOperand(r0, r1, LSL, 3));
4108eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4109eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  if (masm.IsUsingA32()) {
4110eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pldw(MemOperand(r0, r1, LSL, 4));
4111eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pldw(MemOperand(r0, r1, LSL, 20));
4112eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  }
4113eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4114eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLD literal
4115eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  Label pld_label;
4116eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pld(&pld_label);
4117eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Bind(&pld_label);
4118eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4119eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLI immediate
4120eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(sp, 0));
4121eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r0, 0));
4122eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r1, 123));
4123eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r2, 1234));
4124eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r3, 4095));
4125eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r4, -123));
4126eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r5, -255));
4127eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4128eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  if (masm.IsUsingA32()) {
4129eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pli(MemOperand(r6, -1234));
4130eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pli(MemOperand(r7, -4095));
4131eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  }
4132eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4133eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLI register
4134eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r0, r1));
4135eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r0, r1, LSL, 1));
4136eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r0, r1, LSL, 2));
4137eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(MemOperand(r0, r1, LSL, 3));
4138eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4139eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  if (masm.IsUsingA32()) {
4140eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pli(MemOperand(r0, r1, LSL, 4));
4141eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa    __ Pli(MemOperand(r0, r1, LSL, 20));
4142eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  }
4143eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4144eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  // PLI literal
4145eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  Label pli_label;
4146eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Pli(&pli_label);
4147eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  __ Bind(&pli_label);
4148eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4149eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  END();
4150eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4151eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa  TEARDOWN();
4152eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa}
4153eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
4154eb11988bb73246cfa10aa817915184cd1c893fb5Baptiste Afsa
415515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent BelliardTEST_T32(veneer_mirrored_branches) {
415615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  SETUP();
415715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
415815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  START();
415915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
416015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  const int kMaxBranchCount = 256;
416115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
416215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  for (int branch_count = 1; branch_count < kMaxBranchCount; branch_count++) {
416315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    Label* targets = new Label[branch_count];
416415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
416515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    for (int i = 0; i < branch_count; i++) {
416615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard      __ Cbz(r0, &targets[i]);
416715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    }
416815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
416915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    for (int i = 0; i < branch_count; i++) {
417015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard      __ Bind(&targets[branch_count - i - 1]);
417115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard      __ Orr(r0, r0, r0);
417215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    }
417315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
417415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    delete[] targets;
417515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  }
417615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
417715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  END();
417815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
417915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  TEARDOWN();
418015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard}
418115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
418215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
418315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent BelliardTEST_T32(branch_fuzz_example) {
418415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  SETUP();
418515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
418615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  START();
418715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
418815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  Label l[64];
418915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
419015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
419115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
419215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
419315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
419415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
419515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
419615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
419715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
419815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[26]);
419915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[29]);
420015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
420115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
420215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
420315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[12]);
420415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[22]);
420515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
420615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
420715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
420815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
420915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
421015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
421115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[7]);
421215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[18]);
421315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[14]);
421415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
421515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[18]);
421615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
421715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
421815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[21]);
421915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
422015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
422115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
422215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
422315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[23]);
422415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
422515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
422615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
422715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[9]);
422815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
422915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
423015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
423115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
423215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[8]);
423315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
423415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
423515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
423615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
423715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[10]);
423815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[8]);
423915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
424015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
424115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[28]);
424215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
424315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
424415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[19]);
424515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[14]);
424615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
424715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[26]);
424815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
424915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
425015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[24]);
425115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
425215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
425315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
425415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
425515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[26]);
425615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
425715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
425815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
425915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[14]);
426015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
426115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[18]);
426215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
426315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
426415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
426515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
426615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[0]);
426715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
426815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
426915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
427015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[8]);
427115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
427215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
427315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
427415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[12]);
427515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[0]);
427615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[23]);
427715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
427815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
427915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
428015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
428115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
428215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
428315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
428415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[23]);
428515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[16]);
428615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
428715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
428815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[12]);
428915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
429015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
429115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
429215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
429315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
429415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[18]);
429515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[4]);
429615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[31]);
429715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
429815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
429915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
430015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
430115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
430215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
430315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
430415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[1]);
430515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
430615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[13]);
430715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
430815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
430915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
431015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
431115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[7]);
431215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
431315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[0]);
431415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[13]);
431515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
431615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
431715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
431815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
431915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
432015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
432115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[31]);
432215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[2]);
432315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
432415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
432515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[27]);
432615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[13]);
432715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[23]);
432815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[7]);
432915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[2]);
433015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
433115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
433215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[15]);
433315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[13]);
433415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
433515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[8]);
433615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
433715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[8]);
433815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
433915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[2]);
434015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[31]);
434115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
434215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
434315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[29]);
434415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[7]);
434515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
434615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[11]);
434715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
434815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
434915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
435015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
435115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
435215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
435315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
435415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[6]);
435515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
435615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
435715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
435815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
435915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[23]);
436015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[12]);
436115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
436215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
436315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
436415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
436515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
436615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
436715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[20]);
436815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
436915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[4]);
437015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
437115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
437215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
437315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[20]);
437415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[29]);
437515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
437615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
437715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
437815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
437915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
438015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[26]);
438115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
438215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
438315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
438415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[17]);
438515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
438615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
438715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
438815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
438915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
439015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
439115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
439215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[26]);
439315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
439415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
439515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[20]);
439615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
439715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
439815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
439915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
440015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
440115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[13]);
440215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
440315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
440415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[8]);
440515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
440615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[23]);
440715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[6]);
440815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
440915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[13]);
441015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[31]);
441115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[14]);
441215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
441315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
441415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
441515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[27]);
441615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[10]);
441715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
441815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[14]);
441915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
442015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[26]);
442115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
442215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[2]);
442315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
442415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
442515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
442615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
442715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
442815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
442915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
443015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
443115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
443215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
443315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[17]);
443415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[12]);
443515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
443615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
443715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
443815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[31]);
443915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
444015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
444115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
444215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[13]);
444315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[14]);
444415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
444515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[5]);
444615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[12]);
444715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
444815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
444915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[11]);
445015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
445115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[20]);
445215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[22]);
445315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
445415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
445515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
445615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
445715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
445815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[0]);
445915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
446015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[16]);
446115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[28]);
446215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[18]);
446315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
446415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
446515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
446615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[8]);
446715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[25]);
446815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
446915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[21]);
447015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[1]);
447115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[29]);
447215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[15]);
447315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
447415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
447515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[3]);
447615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
447715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[9]);
447815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[24]);
447915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
448015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[19]);
448115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ And(r0, r0, r0);
448215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &l[30]);
448315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[25]);
448415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[3]);
448515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[30]);
448615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&l[5]);
448715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
448815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  END();
448915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
449015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  TEARDOWN();
449115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard}
449215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
449315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
449415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard// Generate a "B" and a "Cbz" which have the same checkpoint. Without proper
449515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard// management (i.e. if the veneers were only generated at the shared
449615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard// checkpoint), one one of the branches would be out of range.
449715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent BelliardTEST_T32(veneer_simultaneous) {
449815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  SETUP();
449915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
450015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  START();
450115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
450215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  // `2046` max range - the size of the B.EQ itself.
450315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  static const int kMaxBCondRange = 1048574;
450415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
450515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  Label target_1;
450615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  Label target_2;
450715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
450815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ B(eq, &target_1);
450915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
451015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int target_1_size_1 =
451115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard      kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
451215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int end_1 = masm.GetCursorOffset() + target_1_size_1;
451315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  while (masm.GetCursorOffset() < end_1) {
451415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    __ Nop();
451515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  }
451615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
451715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &target_2);
451815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
451915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
452015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int end_2 = masm.GetCursorOffset() + target_1_size_2;
452115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  while (masm.GetCursorOffset() < end_2) {
452215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    __ Nop();
452315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  }
452415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
452515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Nop();
452615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
452715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&target_1);
452815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&target_2);
452915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
453015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  END();
453115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
453215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  TEARDOWN();
453315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard}
453415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
453515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
453615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard// Generate a "B" and a "Cbz" which have the same checkpoint and the same label.
453715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent BelliardTEST_T32(veneer_simultaneous_one_label) {
453815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  SETUP();
453915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
454015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  START();
454115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
454215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  // `2046` max range - the size of the B.EQ itself.
454315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  static const int kMaxBCondRange = 1048574;
454415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
454515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  Label target;
454615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
454715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ B(eq, &target);
454815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
454915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int target_1_size_1 =
455015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard      kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
455115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int end_1 = masm.GetCursorOffset() + target_1_size_1;
455215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  while (masm.GetCursorOffset() < end_1) {
455315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    __ Nop();
455415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  }
455515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
455615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Cbz(r0, &target);
455715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
455815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
455915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  int end_2 = masm.GetCursorOffset() + target_1_size_2;
456015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  while (masm.GetCursorOffset() < end_2) {
456115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard    __ Nop();
456215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  }
456315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
456415985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Nop();
456515985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
456615985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  __ Bind(&target);
456715985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
456815985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  END();
456915985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
457015985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard  TEARDOWN();
457115985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard}
457215985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
457315985a2fcc72ce0ec5e19c410b444ceec899c11fVincent Belliard
4574bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// The literal pool will be emitted early because we keep a margin to always be
4575bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// able to generate the veneers before the literal.
4576bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent BelliardTEST_T32(veneer_and_literal) {
4577bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  SETUP();
4578bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4579bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  START();
4580bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4581bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_CHECK(masm.VeneerPoolIsEmpty());
4582bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_CHECK(masm.LiteralPoolIsEmpty());
4583bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4584bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const uint32_t ldrd_range = 1020;
4585bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const uint32_t cbz_range = 126;
4586bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const uint32_t kLabelsCount = 20;
4587bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  Label labels[kLabelsCount];
4588bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4589bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Create one literal pool entry.
4590bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Ldrd(r0, r1, 0x1234567890abcdef);
4591bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4592bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Generate some nops.
4593bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  uint32_t i = 0;
4594bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (; i < ldrd_range - cbz_range - 40;
4595bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard       i += k16BitT32InstructionSizeInBytes) {
4596bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4597bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4598bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4599bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // At this point, it remains cbz_range + 40 => 166 bytes before ldrd becomes
4600bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // out of range.
4601bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // We generate kLabelsCount * 4 => 80 bytes. We shouldn't generate the
4602bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // literal pool.
4603bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (uint32_t j = 0; j < kLabelsCount; j++) {
4604bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Cbz(r0, &labels[j]);
4605bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4606bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    i += 2 * k16BitT32InstructionSizeInBytes;
4607bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4608bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4609bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // However as we have pending veneer, the range is shrinken and the literal
4610bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // pool is generated.
4611bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.LiteralPoolIsEmpty());
4612bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // However, we didn't generate the veneer pool.
4613bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() <
4614bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard              static_cast<int32_t>(cbz_range));
4615bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4616bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // We generate a few more instructions.
4617bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (; i < ldrd_range - 4 * kA32InstructionSizeInBytes;
4618bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard       i += k16BitT32InstructionSizeInBytes) {
4619bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4620bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4621bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4622bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // And a veneer pool has been generated.
4623bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() >
4624bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard              static_cast<int32_t>(cbz_range));
4625bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4626bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Bind all the used labels.
4627bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (uint32_t j = 0; j < kLabelsCount; j++) {
4628bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Bind(&labels[j]);
4629bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4630bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4631bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4632bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Now that all the labels have been bound, we have no more veneer.
4633bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_CHECK(masm.VeneerPoolIsEmpty());
4634bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4635bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  END();
4636bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4637bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  RUN();
4638bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4639bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Check that the literals loaded correctly.
4640bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r0);
4641bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r1);
4642bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4643bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  TEARDOWN();
4644bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard}
4645bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4646bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4647bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// The literal pool will be emitted early and, as the emission of the literal
4648bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// pool would have put veneer out of range, the veneers are emitted first.
4649bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent BelliardTEST_T32(veneer_and_literal2) {
4650bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  SETUP();
4651bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4652bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  START();
4653bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4654bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_CHECK(masm.VeneerPoolIsEmpty());
4655bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_CHECK(masm.LiteralPoolIsEmpty());
4656bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4657bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const uint32_t ldrd_range = 1020;
4658bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const uint32_t cbz_range = 126;
4659bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const uint32_t kLabelsCount = 20;
4660bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const int32_t kTypicalMacroInstructionMaxSize =
4661bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      8 * kMaxInstructionSizeInBytes;
4662bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  Label labels[kLabelsCount];
4663bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4664bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Create one literal pool entry.
4665bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Ldrd(r0, r1, 0x1234567890abcdef);
4666bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4667bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (uint32_t i = 0; i < ldrd_range - cbz_range - 4 * kLabelsCount;
4668bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard       i += k16BitT32InstructionSizeInBytes) {
4669bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4670bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4671bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4672bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Add entries to the veneer pool.
4673bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (uint32_t i = 0; i < kLabelsCount; i++) {
4674bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Cbz(r0, &labels[i]);
4675bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4676bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4677bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4678bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Generate nops up to the literal pool limit.
4679bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  while (masm.GetMarginBeforeLiteralEmission() >=
4680bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard         kTypicalMacroInstructionMaxSize) {
4681bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4682bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4683bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4684bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // At this point, no literals and no veneers have been generated.
4685bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(!masm.LiteralPoolIsEmpty());
4686bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() <
4687bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard              static_cast<int32_t>(cbz_range));
4688bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // The literal pool needs to be generated.
4689bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeLiteralEmission() <
4690bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard              kTypicalMacroInstructionMaxSize);
4691bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // But not the veneer pool.
4692bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() >=
4693bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard              kTypicalMacroInstructionMaxSize);
4694bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // However, as the literal emission would put veneers out of range.
4695bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() <
4696bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard              kTypicalMacroInstructionMaxSize +
4697bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                  static_cast<int32_t>(masm.GetLiteralPoolSize()));
4698bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4699bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // This extra Nop will generate the literal pool and before that the veneer
4700bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // pool.
4701bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Nop();
4702bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Now the literal pool has been generated.
4703bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.LiteralPoolIsEmpty());
4704bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // And also the veneer pool.
4705bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() > 1000);
4706bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4707bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Bind all the used labels.
4708bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (uint32_t j = 0; j < kLabelsCount; j++) {
4709bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Bind(&labels[j]);
4710bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4711bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4712bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4713bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Now that all the labels have been bound, we have no more veneer.
4714bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  VIXL_CHECK(masm.VeneerPoolIsEmpty());
4715bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4716bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  END();
4717bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4718bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  RUN();
4719bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4720bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Check that the literals loaded correctly.
4721bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r0);
4722bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r1);
4723bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4724bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  TEARDOWN();
4725bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard}
4726bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4727bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4728bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// Use a literal when we already have a veneer pool potential size greater than
4729bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// the literal range => generate the literal immediately (not optimum but it
4730bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// works).
4731bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent BelliardTEST_T32(veneer_and_literal3) {
4732bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  SETUP();
4733bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4734bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  START();
4735bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4736bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  static const int kLabelsCount = 1000;
4737bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4738bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  Label labels[kLabelsCount];
4739bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4740f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois  // Set the Z flag so that the following branches are not taken.
4741f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois  __ Movs(r0, 0);
4742f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois
4743bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
4744f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois    __ B(ne, &labels[i]);
4745bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4746bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4747bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Create one literal pool entry.
4748bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Ldrd(r0, r1, 0x1234567890abcdef);
4749bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4750bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (int i = 0; i < 10; i++) {
4751bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Nop();
4752bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4753bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4754bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
4755bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Bind(&labels[i]);
4756bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4757bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4758bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  END();
4759bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4760bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  RUN();
4761bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4762bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Check that the literals loaded correctly.
4763bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r0);
4764bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r1);
4765bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4766bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  TEARDOWN();
4767bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard}
4768bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4769bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4770bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// Literal has to be generated sooner than veneers. However, as the literal
4771bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// pool generation would make the veneers out of range, generate the veneers
4772bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// first.
4773bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent BelliardTEST_T32(veneer_and_literal4) {
4774bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  SETUP();
4775bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4776bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  START();
4777bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4778bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  Label end;
4779f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois
4780f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois  // Set the Z flag so that the following branch is not taken.
4781f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois  __ Movs(r0, 0);
4782f86422e92dcbcd2e0a15b26e47c855c29c0132d5Pierre Langlois  __ B(ne, &end);
4783bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4784bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  uint32_t value = 0x1234567;
478552e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  Literal<uint32_t>* literal =
4786bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      new Literal<uint32_t>(value,
4787bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                            RawLiteral::kPlacedWhenUsed,
4788bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                            RawLiteral::kDeletedOnPoolDestruction);
4789bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4790bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Ldr(r11, literal);
4791bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4792bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // The range for ldr is 4095, the range for cbz is 127. Generate nops
4793bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // to have the ldr becomming out of range just before the cbz.
4794bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const int NUM_NOPS = 2044;
4795bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const int NUM_RANGE = 58;
4796bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4797bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  const int NUM1 = NUM_NOPS - NUM_RANGE;
4798bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const int NUM2 = NUM_RANGE;
4799bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4800bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  {
4801bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope aas(&masm, 2 * NUM1, CodeBufferCheckScope::kMaximumSize);
4802bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    for (int i = 0; i < NUM1; i++) {
4803bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      __ nop();
4804bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    }
4805bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4806bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4807bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Cbz(r1, &end);
4808bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4809bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  {
4810bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope aas(&masm, 2 * NUM2, CodeBufferCheckScope::kMaximumSize);
4811bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    for (int i = 0; i < NUM2; i++) {
4812bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      __ nop();
4813bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    }
4814bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4815bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4816bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  {
4817bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
4818bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ add(r1, r1, 3);
4819bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4820bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  __ Bind(&end);
4821bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4822bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  END();
4823bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4824bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  RUN();
4825bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4826bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Check that the literals loaded correctly.
4827bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  ASSERT_EQUAL_32(0x1234567, r11);
4828bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4829bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  TEARDOWN();
4830bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard}
4831bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4832bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4833bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// Literal has to be generated sooner than veneers. However, as the literal
4834bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// pool generation would make the veneers out of range, generate the veneers
4835bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard// first.
4836bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent BelliardTEST_T32(veneer_and_literal5) {
4837bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  SETUP();
4838bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4839bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  START();
4840bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4841bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  static const int kTestCount = 100;
4842bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  Label labels[kTestCount];
4843bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4844bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  int first_test = 2000;
4845bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  // Test on both sizes of the Adr range which is 4095.
4846bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  for (int test = 0; test < kTestCount; test++) {
4847bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    const int string_size = 1000;  // A lot more than the cbz range.
4848bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    std::string test_string(string_size, 'x');
4849bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    StringLiteral big_literal(test_string.c_str());
4850bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4851bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Adr(r11, &big_literal);
4852bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4853bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    {
4854bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      int num_nops = first_test + test;
4855bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      ExactAssemblyScope aas(&masm,
4856bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard                             2 * num_nops,
4857bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard                             CodeBufferCheckScope::kMaximumSize);
4858bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      for (int i = 0; i < num_nops; i++) {
4859bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard        __ nop();
4860bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      }
4861bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    }
4862bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4863bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Cbz(r1, &labels[test]);
4864bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4865bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    {
4866bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
4867bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard      __ add(r1, r1, 3);
4868bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    }
4869bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ Bind(&labels[test]);
4870bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    // Emit the literal pool if it has not beeen emitted (it's the case for
4871bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    // the lower values of test).
4872bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard    __ EmitLiteralPool(MacroAssembler::kBranchRequired);
4873bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  }
4874bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4875bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  END();
4876bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4877bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard  TEARDOWN();
4878bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard}
4879bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4880bd087d8fe70f7db770f37569073b8b9f77a9c372Vincent Belliard
4881c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard// Check that veneer and literals are well generated when they are out of
4882c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard// range at the same time.
4883c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent BelliardTEST_T32(veneer_and_literal6) {
4884c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  SETUP();
4885c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4886c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  START();
4887c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4888c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  Label t1, t2, t3, t4, t5;
4889c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  static const int kLdrdRange = 1020;
4890c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  static const int kSizeForCbz = k16BitT32InstructionSizeInBytes;
4891c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4892c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r0, r1, 0x1111111111111111);
4893c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r2, r3, 0x2222222222222222);
4894c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r4, r5, 0x3333333333333333);
4895c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r6, r7, 0x4444444444444444);
4896c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r8, r9, 0x5555555555555555);
4897c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r10, r11, 0x6666666666666666);
4898c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Ldrd(r10, r11, 0x1234567890abcdef);
4899c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4900c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // Ldrd has a bigger range that cbz. Generate some nops before the cbzs in
4901c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // order to reach the maximum range of ldrd and cbz at the same time.
4902c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  {
4903c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard    int nop_size = kLdrdRange - kCbzCbnzRange - 5 * kSizeForCbz;
4904bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
4905c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard    for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
4906c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard      __ nop();
4907c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard    }
4908c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  }
4909c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4910c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Cbz(r2, &t1);
4911c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Cbz(r2, &t2);
4912c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Cbz(r2, &t3);
4913c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Cbz(r2, &t4);
4914c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Cbz(r2, &t5);
4915c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4916c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // At this point, the ldrds are not out of range. It remains a kCbzCbnzRange
4917c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // margin (minus the size of the veneers).
4918c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4919c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // At this point, the literal and the veneer pools are not emitted.
4920c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  VIXL_CHECK(masm.GetLiteralPoolSize() > 0);
4921c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() < kCbzCbnzRange);
4922c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4923c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // This scope will generate both veneers (they are both out of range).
4924c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  {
4925c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard    int nop_size = kCbzCbnzRange;
4926bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
4927c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard    for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
4928c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard      __ nop();
4929c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard    }
4930c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  }
4931c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4932c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // Check that both veneers have been emitted.
4933c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  VIXL_CHECK(masm.GetLiteralPoolSize() == 0);
4934c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() > kCbzCbnzRange);
4935c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4936c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Bind(&t1);
4937c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Bind(&t2);
4938c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Bind(&t3);
4939c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Bind(&t4);
4940c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  __ Bind(&t5);
4941c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4942c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  END();
4943c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4944c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  RUN();
4945c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4946c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  // Check that the literals loaded correctly.
4947c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x11111111, r0);
4948c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x11111111, r1);
4949c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x22222222, r2);
4950c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x22222222, r3);
4951c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x33333333, r4);
4952c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x33333333, r5);
4953c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x44444444, r6);
4954c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x44444444, r7);
4955c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x55555555, r8);
4956c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x55555555, r9);
4957c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r10);
4958c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r11);
4959c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4960c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard  TEARDOWN();
4961c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard}
4962c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
4963c6d19d5facc0bb99296067ef4a6ca55f83bf4788Vincent Belliard
49641ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard// Check that a label which is just bound during the MacroEmissionCheckScope
49651ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard// can be used.
49661ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent BelliardTEST(ldr_label_bound_during_scope) {
49671ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  SETUP();
49681ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  START();
49691ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49701ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  const int32_t kTypicalMacroInstructionMaxSize =
49711ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard      8 * kMaxInstructionSizeInBytes;
49721ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
497352e987eb677af65859f169b20816fa5d293c6cf0Jacob Bramley  Literal<uint64_t>* literal =
49741ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard      new Literal<uint64_t>(UINT64_C(0x1234567890abcdef),
49751ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard                            RawLiteral::kPlacedWhenUsed,
49761ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard                            RawLiteral::kDeletedOnPoolDestruction);
49771ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  __ Ldrd(r0, r1, literal);
49781ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49791ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  while (masm.GetMarginBeforeLiteralEmission() >=
49801ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard         kTypicalMacroInstructionMaxSize) {
49811ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard    __ Nop();
49821ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  }
49831ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49841ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  VIXL_ASSERT(!masm.LiteralPoolIsEmpty());
49851ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49861ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  // This Ldrd will first generate the pool and then use literal which has just
49871ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  // been bound.
49881ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  __ Ldrd(r2, r3, literal);
49891ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49901ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  VIXL_ASSERT(masm.LiteralPoolIsEmpty());
49911ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49921ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  END();
49931ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49941ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  RUN();
49951ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
49961ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  // Check that the literals loaded correctly.
49971ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r0);
49981ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r1);
49991ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  ASSERT_EQUAL_32(0x90abcdef, r2);
50001ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  ASSERT_EQUAL_32(0x12345678, r3);
50011ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
50021ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard  TEARDOWN();
50031ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard}
50041ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
50051ddc52b438c2f07872e6e715c6b86e8d3b772795Vincent Belliard
5006e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia KouveliTEST_T32(test_it_scope_and_literal_pool) {
5007e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // This test stresses the EnsureEmitFor check inside ITScope to make sure the
5008e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // number of bytes it tries to ensure we can emit is in sync with the
5009e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // MacroEmissionCheckScope that is usually around it.
5010e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  SETUP();
5011e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5012e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  START();
5013e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5014e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // Make sure the pool is empty.
5015e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
5016e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  ASSERT_LITERAL_POOL_SIZE(0);
5017e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5018e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  Literal<uint64_t> l0(0xcafebeefdeadbaba);
5019e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  __ Ldrd(r0, r1, &l0);
5020e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // Leave exactly as many bytes between cursor and pool emission checkpoint as
5021e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // the typical macro instruction needs (and MacroEmissionCheckScope allows
5022e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // for).
5023e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  const int32_t kTypicalMacroInstructionMaxSize =
5024e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli      8 * kMaxInstructionSizeInBytes;
5025bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  int32_t margin =
5026bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      masm.GetMarginBeforeLiteralEmission() - kTypicalMacroInstructionMaxSize;
5027e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  int32_t end = masm.GetCursorOffset() + margin;
5028e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5029e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  {
5030e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
5031e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli    while (masm.GetCursorOffset() < end) {
5032e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli      __ nop();
5033e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli    }
5034e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  }
5035bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  VIXL_CHECK(masm.GetMarginBeforeLiteralEmission() ==
5036bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois             kTypicalMacroInstructionMaxSize);
5037e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5038e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // We cannot use an IT block for this instruction, hence ITScope will
5039e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // generate a branch over it.
5040e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  __ Add(ne, r8, r9, 256);
5041e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5042e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  END();
5043e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5044e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  RUN();
5045e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5046e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  // Check that the literals loaded correctly.
5047e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  ASSERT_EQUAL_32(0xdeadbaba, r0);
5048e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  ASSERT_EQUAL_32(0xcafebeef, r1);
5049e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5050e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli  TEARDOWN();
5051e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli}
5052e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5053e31fda5ecc961cdb78a0a5311d692ae4b15e5933Georgia Kouveli
5054ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa// TODO: Remove this limitation by having a sandboxing mechanism.
5055ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa#if defined(VIXL_HOST_POINTER_32)
5056ead6404d95d7736deeed9ded7595804ea211dc36Baptiste AfsaTEST(ldm_stm_no_writeback) {
5057ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  SETUP();
5058ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5059ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  START();
5060ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5061bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
5062bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5063bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5064ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5065ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r0, reinterpret_cast<uintptr_t>(src));
5066bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Ldm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
5067bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  ;
5068ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
5069ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5070ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r0, reinterpret_cast<uintptr_t>(dst1));
5071bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Stm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
5072bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  ;
5073ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5074ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r0, reinterpret_cast<uintptr_t>(dst2));
5075ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
5076ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5077ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  END();
5078ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5079ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  RUN();
5080ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5081ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r1);
5082ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, r2);
5083ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, r3);
5084ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, r4);
5085ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5086ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r5);
5087ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, r6);
5088ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, r9);
5089ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, r11);
5090ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5091ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, dst1[0]);
5092ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, dst1[1]);
5093ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, dst1[2]);
5094ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, dst1[3]);
5095ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5096ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, dst2[0]);
5097ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, dst2[1]);
5098ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, dst2[2]);
5099ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, dst2[3]);
5100ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5101ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  TEARDOWN();
5102ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa}
5103ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5104ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5105ead6404d95d7736deeed9ded7595804ea211dc36Baptiste AfsaTEST(ldm_stm_writeback) {
5106ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  SETUP();
5107ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5108ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  START();
5109ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5110bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
5111bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  uint32_t dst[8] = {0x00000000,
5112bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000,
5113bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000,
5114bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000,
5115bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000,
5116bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000,
5117bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000,
5118bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                     0x00000000};
5119ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5120ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r0, reinterpret_cast<uintptr_t>(src));
5121bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Ldm(r0, WRITE_BACK, RegisterList(r2, r3));
5122bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  ;
5123bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  __ Ldm(r0, WRITE_BACK, RegisterList(r4, r5));
5124bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  ;
5125ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5126ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r1, reinterpret_cast<uintptr_t>(dst));
5127ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
5128ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
5129ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5130ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  END();
5131ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5132ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  RUN();
5133ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5134ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 4), r0);
5135ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 8), r1);
5136ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5137ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, r2);
5138ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, r3);
5139ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, r4);
5140ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, r5);
5141ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5142ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, dst[0]);
5143ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, dst[1]);
5144ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, dst[2]);
5145ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, dst[3]);
5146ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x12345678, dst[4]);
5147ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x09abcdef, dst[5]);
5148ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xc001c0de, dst[6]);
5149ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0xdeadbeef, dst[7]);
5150ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5151ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  TEARDOWN();
5152ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa}
5153ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5154ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5155ead6404d95d7736deeed9ded7595804ea211dc36Baptiste AfsaTEST_A32(ldm_stm_da_ib) {
5156ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  SETUP();
5157ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5158ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  START();
5159ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5160bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const uint32_t src1[4] = {0x33333333, 0x44444444, 0x11111111, 0x22222222};
5161bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const uint32_t src2[4] = {0x11111111, 0x22222222, 0x33333333, 0x44444444};
5162ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5163bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5164bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5165ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5166ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r11, reinterpret_cast<uintptr_t>(src1 + 3));
5167ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmda(r11, WRITE_BACK, RegisterList(r0, r1));
5168ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3));
5169ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5170ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r10, reinterpret_cast<uintptr_t>(src2 - 1));
5171ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmib(r10, WRITE_BACK, RegisterList(r4, r5));
5172ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmib(r10, NO_WRITE_BACK, RegisterList(r6, r7));
5173ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5174ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r9, reinterpret_cast<uintptr_t>(dst1 + 3));
5175ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmda(r9, WRITE_BACK, RegisterList(r0, r1));
5176ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmda(r9, NO_WRITE_BACK, RegisterList(r2, r3));
5177ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5178ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r8, reinterpret_cast<uintptr_t>(dst2 - 1));
5179ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmib(r8, WRITE_BACK, RegisterList(r4, r5));
5180ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmib(r8, NO_WRITE_BACK, RegisterList(r6, r7));
5181ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5182ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5183ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  END();
5184ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5185ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  RUN();
5186ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5187ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src1 + 1), r11);
5188bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src2 + 1), r10);
5189ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst1 + 1), r9);
5190ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst2 + 1), r8);
5191ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5192ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, r0);
5193ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, r1);
5194ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x33333333, r2);
5195ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x44444444, r3);
5196ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5197ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, r4);
5198ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, r5);
5199ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x33333333, r6);
5200ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x44444444, r7);
5201ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5202ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x33333333, dst1[0]);
5203ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x44444444, dst1[1]);
5204ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, dst1[2]);
5205ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, dst1[3]);
5206ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5207ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, dst2[0]);
5208ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, dst2[1]);
5209ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x33333333, dst2[2]);
5210ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x44444444, dst2[3]);
5211ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5212ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  TEARDOWN();
5213ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa}
5214ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5215ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5216ead6404d95d7736deeed9ded7595804ea211dc36Baptiste AfsaTEST(ldmdb_stmdb) {
5217ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  SETUP();
5218ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5219ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  START();
5220ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5221bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  const uint32_t src[6] =
5222bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      {0x55555555, 0x66666666, 0x33333333, 0x44444444, 0x11111111, 0x22222222};
5223ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5224bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  uint32_t dst[6] =
5225bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
5226ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5227ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r11, reinterpret_cast<uintptr_t>(src + 6));
5228ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmdb(r11, WRITE_BACK, RegisterList(r1, r2));
5229ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmdb(r11, WRITE_BACK, RegisterList(r3, r4));
5230ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Ldmdb(r11, NO_WRITE_BACK, RegisterList(r5, r6));
5231ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5232ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Mov(r10, reinterpret_cast<uintptr_t>(dst + 6));
5233ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmdb(r10, WRITE_BACK, RegisterList(r5, r6));
5234ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmdb(r10, WRITE_BACK, RegisterList(r3, r4));
5235ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  __ Stmdb(r10, NO_WRITE_BACK, RegisterList(r1, r2));
5236ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5237ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  END();
5238ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5239ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  RUN();
5240ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5241ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 2), r11);
5242ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 2), r10);
5243ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5244ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, r1);
5245ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, r2);
5246ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x33333333, r3);
5247ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x44444444, r4);
5248ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x55555555, r5);
5249ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x66666666, r6);
5250ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5251ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, dst[0]);
5252ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, dst[1]);
5253ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x33333333, dst[2]);
5254ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x44444444, dst[3]);
5255ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x55555555, dst[4]);
5256ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  ASSERT_EQUAL_32(0x66666666, dst[5]);
5257ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5258ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa  TEARDOWN();
5259ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa}
5260ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa#endif
5261ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
5262ead6404d95d7736deeed9ded7595804ea211dc36Baptiste Afsa
526318908fb3bb1d433e9c48c715ab95e164839eb390Baptiste AfsaTEST(blx) {
526418908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  SETUP();
526518908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
526618908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  START();
526718908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
526818908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  // TODO(all): Ideally this test should jump back and forth between ARM and
526918908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  // Thumb mode and should also cover BLX immediate. Update this test if we
527018908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  // allow VIXL assembler to change ISA anywhere in the code buffer.
527118908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
527218908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  Label test_start;
527318908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  Label func1;
527418908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  Label func2;
527518908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
527618908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ B(&test_start);
527718908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
527818908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Bind(&func1);
527918908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Mov(r0, 0x11111111);
528018908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Push(lr);
52815c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois  {
52825c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    size_t size_of_generated_code;
52835c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    if (masm.IsUsingA32()) {
52845c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      size_of_generated_code = 7 * kA32InstructionSizeInBytes;
52855c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    } else {
52865c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      size_of_generated_code = 5 * k32BitT32InstructionSizeInBytes +
52875c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois                               3 * k16BitT32InstructionSizeInBytes;
52885c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    }
5289bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    ExactAssemblyScope scope(&masm,
5290bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                             size_of_generated_code,
52915c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois                             ExactAssemblyScope::kExactSize);
52925c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ adr(r11, &func2);
52935c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    if (masm.IsUsingT32()) {
52945c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // The jump target needs to have its least significant bit set to indicate
52955c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      // that we are jumping into thumb mode.
52965c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois      __ orr(r11, r11, 1);
52975c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    }
52985c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ blx(r11);
52995c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ pop(lr);
53005c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bx(lr);
53015c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois
53025c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bind(&func2);
53035c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ movw(r1, 0x2222);
53045c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ movt(r1, 0x2222);
53055c01c410ae559d0a77d68a023957c5bc9de143e0Pierre Langlois    __ bx(lr);
530618908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  }
530718908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
530818908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Bind(&test_start);
530918908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Mov(r0, 0xdeadc0de);
531018908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Mov(r1, 0xdeadc0de);
531118908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  __ Bl(&func1);
531218908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
531318908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  END();
531418908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
531518908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  RUN();
531618908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
531718908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  // Really basic test to check that we reached the different parts of the test.
531818908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  ASSERT_EQUAL_32(0x11111111, r0);
531918908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  ASSERT_EQUAL_32(0x22222222, r1);
532018908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
532118908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa  TEARDOWN();
532218908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa}
532318908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
532418908fb3bb1d433e9c48c715ab95e164839eb390Baptiste Afsa
53254a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// Check that B with a near hint use a narrow branch when it can.
53264a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent BelliardTEST_T32(b_near_hint) {
53274a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  SETUP();
53284a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  START();
53294a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53304a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label start;
53314a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label end;
53324a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53334a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&start);
53344a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Nop();
53354a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53364a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
53374a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be narrow.
53384a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
53394a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k16BitT32InstructionSizeInBytes,
53404a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
53414a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&start, kNear);
53424a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
53434a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
53444a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    ExactAssemblyScope scope(&masm,
53454a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             kBNarrowRange,
53464a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             ExactAssemblyScope::kExactSize);
53474a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    for (int32_t i = 0; i < kBNarrowRange;
53484a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard         i += k16BitT32InstructionSizeInBytes) {
53494a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard      __ nop();
53504a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    }
53514a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
53524a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
53534a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be wide.
53544a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
53554a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k32BitT32InstructionSizeInBytes,
53564a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
53574a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&start, kNear);
53584a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
53594a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
53604a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a forward branch which should be narrow.
53614a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
53624a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k16BitT32InstructionSizeInBytes,
53634a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
53644a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&end, kNear);
53654a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
53664a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53674a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() < kBNarrowRange);
53684a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53694a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
53704a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    ExactAssemblyScope scope(&masm,
53714a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             kBNarrowRange,
53724a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             ExactAssemblyScope::kExactSize);
53734a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    for (int32_t i = 0; i < kBNarrowRange;
53744a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard         i += k16BitT32InstructionSizeInBytes) {
53754a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard      __ nop();
53764a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    }
53774a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
53784a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53794a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  // A veneer should have been generated.
53804a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() > kBNarrowRange);
53814a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53824a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&end);
53834a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53844a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  END();
53854a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53864a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  DISASSEMBLE();
53874a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53884a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  TEARDOWN();
53894a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard}
53904a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53914a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53924a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// Check that B with a far hint use a narrow branch only for a near backward
53934a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// branch.
53944a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent BelliardTEST_T32(b_far_hint) {
53954a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  SETUP();
53964a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  START();
53974a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
53984a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label start;
53994a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label end;
54004a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54014a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&start);
54024a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Nop();
54034a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54044a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54054a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be narrow.
54064a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
54074a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k16BitT32InstructionSizeInBytes,
54084a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
54094a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&start, kFar);
54104a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54114a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54124a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    ExactAssemblyScope scope(&masm,
54134a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             kBNarrowRange,
54144a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             ExactAssemblyScope::kExactSize);
54154a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    for (int32_t i = 0; i < kBNarrowRange;
54164a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard         i += k16BitT32InstructionSizeInBytes) {
54174a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard      __ nop();
54184a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    }
54194a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54204a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54214a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be wide.
54224a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
54234a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k32BitT32InstructionSizeInBytes,
54244a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
54254a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&start, kFar);
54264a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54274a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54284a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a forward branch which should be wide.
54294a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
54304a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k32BitT32InstructionSizeInBytes,
54314a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
54324a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&end, kFar);
54334a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54344a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54354a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&end);
54364a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54374a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  END();
54384a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54394a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  DISASSEMBLE();
54404a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54414a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  TEARDOWN();
54424a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard}
54434a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54444a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54454a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// Check that conditional B with a near hint use a narrow branch when it can.
54464a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent BelliardTEST_T32(b_conditional_near_hint) {
54474a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  SETUP();
54484a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  START();
54494a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54504a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label start;
54514a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label end;
54524a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54534a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&start);
54544a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Nop();
54554a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54564a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be narrow.
54574a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
54584a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k16BitT32InstructionSizeInBytes,
54594a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
54604a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(eq, &start, kNear);
54614a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54624a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54634a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    ExactAssemblyScope scope(&masm,
54644a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             kBConditionalNarrowRange,
54654a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             ExactAssemblyScope::kExactSize);
54664a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    for (int32_t i = 0; i < kBConditionalNarrowRange;
54674a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard         i += k16BitT32InstructionSizeInBytes) {
54684a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard      __ nop();
54694a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    }
54704a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54714a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54724a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be wide.
54734a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
54744a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k32BitT32InstructionSizeInBytes,
54754a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
54764a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(eq, &start, kNear);
54774a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54784a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54794a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a forward branch which should be narrow.
54804a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
54814a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k16BitT32InstructionSizeInBytes,
54824a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
54834a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(eq, &end, kNear);
54844a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54854a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54864a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() < kBConditionalNarrowRange);
54874a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54884a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
54894a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    ExactAssemblyScope scope(&masm,
54904a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             kBConditionalNarrowRange,
54914a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             ExactAssemblyScope::kExactSize);
54924a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    for (int32_t i = 0; i < kBConditionalNarrowRange;
54934a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard         i += k16BitT32InstructionSizeInBytes) {
54944a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard      __ nop();
54954a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    }
54964a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
54974a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
54984a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  // A veneer should have been generated.
54994a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() > kBConditionalNarrowRange);
55004a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55014a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&end);
55024a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55034a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  END();
55044a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55054a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  DISASSEMBLE();
55064a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55074a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  TEARDOWN();
55084a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard}
55094a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55104a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55114a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// Check that conditional B with a far hint use a narrow branch only for a
55124a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// near backward branch.
55134a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent BelliardTEST_T32(b_conditional_far_hint) {
55144a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  SETUP();
55154a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  START();
55164a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55174a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label start;
55184a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label end;
55194a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55204a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&start);
55214a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Nop();
55224a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55234a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
55244a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be narrow.
55254a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
55264a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k16BitT32InstructionSizeInBytes,
55274a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
55284a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(eq, &start, kFar);
55294a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
55304a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
55314a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    ExactAssemblyScope scope(&masm,
55324a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             kBConditionalNarrowRange,
55334a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             ExactAssemblyScope::kExactSize);
55344a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    for (int32_t i = 0; i < kBConditionalNarrowRange;
55354a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard         i += k16BitT32InstructionSizeInBytes) {
55364a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard      __ nop();
55374a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    }
55384a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
55394a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
55404a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a branch which should be wide.
55414a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
55424a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k32BitT32InstructionSizeInBytes,
55434a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
55444a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(eq, &start, kFar);
55454a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
55464a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  {
55474a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    // Generate a forward branch which should be wide.
55484a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    EmissionCheckScope scope(&masm,
55494a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             k32BitT32InstructionSizeInBytes,
55504a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard                             EmissionCheckScope::kExactSize);
55514a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(eq, &end, kFar);
55524a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
55534a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55544a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Bind(&end);
55554a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55564a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  END();
55574a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55584a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  DISASSEMBLE();
55594a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55604a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  TEARDOWN();
55614a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard}
55624a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55634a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55644a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// Check that the veneer pool is correctly emitted even if we do a lot of narrow
55654a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// branches.
55664a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent BelliardTEST_T32(b_narrow_many) {
55674a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  SETUP();
55684a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  START();
55694a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55704a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  static const int kLabelsCount = kBNarrowRange / 2;
55714a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55724a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label labels[kLabelsCount];
55734a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55744a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Mov(r0, 0);
55754a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55764a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
55774a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&labels[i], kNear);
55784a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
55794a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55804a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Mov(r0, 1);
55814a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
55824a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ Bind(&labels[i]);
55834a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
55844a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Nop();
55854a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55864a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  END();
55874a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55884a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  RUN();
55894a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55904a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  ASSERT_EQUAL_32(0, r0);
55914a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55924a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  TEARDOWN();
55934a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard}
55944a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55954a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
55964a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// Check that the veneer pool is correctly emitted even if we do a lot of narrow
55974a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard// branches and cbz.
55984a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent BelliardTEST_T32(b_narrow_and_cbz) {
55994a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  SETUP();
56004a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  START();
56014a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56024a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  static const int kLabelsCount = kBNarrowRange / 4;
56034a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56044a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label b_labels[kLabelsCount];
56054a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  Label cbz_labels[kLabelsCount];
56064a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56074a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Mov(r0, 0);
56084a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56094a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
56104a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ B(&b_labels[i], kNear);
56114a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ Cbz(r0, &cbz_labels[i]);
56124a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
56134a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56144a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Mov(r0, 1);
56154a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
56164a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ Bind(&b_labels[i]);
56174a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
56184a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56194a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Mov(r0, 2);
56204a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  for (int i = 0; i < kLabelsCount; i++) {
56214a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard    __ Bind(&cbz_labels[i]);
56224a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  }
56234a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56244a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  __ Nop();
56254a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56264a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  END();
56274a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56284a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  RUN();
56294a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56304a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  ASSERT_EQUAL_32(2, r0);
56314a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56324a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard  TEARDOWN();
56334a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard}
56344a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
56354a30c5d68ebbc271d6d876d828ffa96db53d8d7cVincent Belliard
5636bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois#define CHECK_SIZE_MATCH(ASM1, ASM2)                                 \
5637bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  {                                                                  \
5638bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    MacroAssembler masm1(BUF_SIZE);                                  \
5639bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm1.UseInstructionSet(isa);                                    \
5640bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_ASSERT(masm1.GetCursorOffset() == 0);                       \
5641bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm1.ASM1;                                                      \
5642bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm1.FinalizeCode();                                            \
5643bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    int size1 = masm1.GetCursorOffset();                             \
5644bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                                                     \
5645bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    MacroAssembler masm2(BUF_SIZE);                                  \
5646bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm2.UseInstructionSet(isa);                                    \
5647bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_ASSERT(masm2.GetCursorOffset() == 0);                       \
5648bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm2.ASM2;                                                      \
5649bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    masm2.FinalizeCode();                                            \
5650bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    int size2 = masm2.GetCursorOffset();                             \
5651bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                                                     \
5652bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    bool disassemble = Test::disassemble();                          \
5653bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    if (size1 != size2) {                                            \
5654bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      printf("Sizes did not match:\n");                              \
5655bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      disassemble = true;                                            \
5656bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                \
5657bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    if (disassemble) {                                               \
5658bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      PrintDisassembler dis(std::cout, 0);                           \
5659bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      printf("// " #ASM1 "\n");                                      \
5660bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      if (masm1.IsUsingT32()) {                                      \
5661bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        dis.DisassembleT32Buffer(masm1.GetBuffer()                   \
5662bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                     ->GetStartAddress<uint16_t*>(), \
5663bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                 size1);                             \
5664bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      } else {                                                       \
5665bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        dis.DisassembleA32Buffer(masm1.GetBuffer()                   \
5666bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                     ->GetStartAddress<uint32_t*>(), \
5667bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                 size1);                             \
5668bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      }                                                              \
5669bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      printf("\n");                                                  \
5670bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                                                     \
5671bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      dis.SetCodeAddress(0);                                         \
5672bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      printf("// " #ASM2 "\n");                                      \
5673bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      if (masm2.IsUsingT32()) {                                      \
5674bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        dis.DisassembleT32Buffer(masm2.GetBuffer()                   \
5675bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                     ->GetStartAddress<uint16_t*>(), \
5676bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                 size2);                             \
5677bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      } else {                                                       \
5678bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois        dis.DisassembleA32Buffer(masm2.GetBuffer()                   \
5679bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                     ->GetStartAddress<uint32_t*>(), \
5680bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois                                 size2);                             \
5681bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      }                                                              \
5682bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois      printf("\n");                                                  \
5683bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    }                                                                \
5684bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois    VIXL_CHECK(size1 == size2);                                      \
568514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  }
568614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
568714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
568814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob BramleyTEST_T32(macro_assembler_commute) {
568914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // Test that the MacroAssembler will commute operands if it means it can use a
569014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // 16-bit instruction with the same effect.
569114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
569214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // TODO: The commented-out tests should pass, but don't. When they are fixed,
569314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // we should update this test.
569414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
569514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Adc(DontCare, r7, r6, r7),
569614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Adc(DontCare, r7, r7, r6));
569714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
569814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Adc(DontCare, eq, r7, r6, r7),
569914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Adc(DontCare, eq, r7, r7, r6));
570014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5701bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Add(DontCare, r1, r2, r7), Add(DontCare, r1, r7, r2));
570214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
570314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  CHECK_SIZE_MATCH(Add(DontCare, lt, r1, r2, r7),
570414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley                   Add(DontCare, lt, r1, r7, r2));
570514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
570614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(DontCare, r4, r4, r10),
570714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(DontCare, r4, r10, r4));
570814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
570914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(DontCare, eq, r4, r4, r10),
571014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(DontCare, eq, r4, r10, r4));
571114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
571214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(DontCare, r7, sp, r7),
571314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(DontCare, r7, r7, sp));
571414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
571514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(DontCare, eq, r7, sp, r7),
571614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(DontCare, eq, r7, r7, sp));
571714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
571814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(DontCare, sp, sp, r10),
571914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(DontCare, sp, r10, sp));
572014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
572114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(DontCare, eq, sp, sp, r10),
572214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(DontCare, eq, sp, r10, sp));
572314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
572414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(And(DontCare, r7, r7, r6),
572514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  And(DontCare, r7, r6, r7));
572614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
572714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(And(DontCare, eq, r7, r7, r6),
572814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  And(DontCare, eq, r7, r6, r7));
572914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
573014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Eor(DontCare, r7, r7, r6),
573114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Eor(DontCare, r7, r6, r7));
573214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
573314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Eor(DontCare, eq, r7, r7, r6),
573414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Eor(DontCare, eq, r7, r6, r7));
573514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
573614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Mul(DontCare, r0, r1, r0),
573714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Mul(DontCare, r0, r0, r1));
573814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
573914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Mul(DontCare, eq, r0, r1, r0),
574014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Mul(DontCare, eq, r0, r0, r1));
574114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
574214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Orr(DontCare, r7, r7, r6),
574314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Orr(DontCare, r7, r6, r7));
574414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
574514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Orr(DontCare, eq, r7, r7, r6),
574614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Orr(DontCare, eq, r7, r6, r7));
574714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
574814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5749bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adc(r7, r6, r7), Adc(r7, r7, r6));
575014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
575114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Adc(eq, r7, r6, r7),
575214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Adc(eq, r7, r7, r6));
575314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5754bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Add(r1, r2, r7), Add(r1, r7, r2));
575514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5756bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Add(lt, r1, r2, r7), Add(lt, r1, r7, r2));
575714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
575814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(r4, r4, r10),
575914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(r4, r10, r4));
576014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
576114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(eq, r4, r4, r10),
576214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(eq, r4, r10, r4));
576314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
576414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(r7, sp, r7),
576514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(r7, r7, sp));
576614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
576714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(eq, r7, sp, r7),
576814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(eq, r7, r7, sp));
576914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
577014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(sp, sp, r10),
577114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(sp, r10, sp));
577214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
577314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Add(eq, sp, sp, r10),
577414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Add(eq, sp, r10, sp));
577514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5776bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(And(r7, r7, r6), And(r7, r6, r7));
577714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
577814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(And(eq, r7, r7, r6),
577914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  And(eq, r7, r6, r7));
578014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5781bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Eor(r7, r7, r6), Eor(r7, r6, r7));
578214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
578314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Eor(eq, r7, r7, r6),
578414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Eor(eq, r7, r6, r7));
578514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5786bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Mul(r0, r1, r0), Mul(r0, r0, r1));
578714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
578814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Mul(eq, r0, r1, r0),
578914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Mul(eq, r0, r0, r1));
579014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5791bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Orr(r7, r7, r6), Orr(r7, r6, r7));
579214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
579314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Orr(eq, r7, r7, r6),
579414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Orr(eq, r7, r6, r7));
579514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
579614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
579714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Adcs(r7, r6, r7),
579814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Adcs(r7, r7, r6));
579914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
580014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Adcs(eq, r7, r6, r7),
580114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Adcs(eq, r7, r7, r6));
580214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5803bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(r1, r2, r7), Adds(r1, r7, r2));
580414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5805bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(lt, r1, r2, r7), Adds(lt, r1, r7, r2));
580614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5807bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(r4, r4, r10), Adds(r4, r10, r4));
580814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5809bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(eq, r4, r4, r10), Adds(eq, r4, r10, r4));
581014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5811bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(r7, sp, r7), Adds(r7, r7, sp));
581214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5813bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(eq, r7, sp, r7), Adds(eq, r7, r7, sp));
581414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5815bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(sp, sp, r10), Adds(sp, r10, sp));
581614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
5817bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois  CHECK_SIZE_MATCH(Adds(eq, sp, sp, r10), Adds(eq, sp, r10, sp));
581814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
581914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Ands(r7, r7, r6),
582014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Ands(r7, r6, r7));
582114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
582214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Ands(eq, r7, r7, r6),
582314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Ands(eq, r7, r6, r7));
582414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
582514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Eors(r7, r7, r6),
582614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Eors(r7, r6, r7));
582714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
582814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Eors(eq, r7, r7, r6),
582914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Eors(eq, r7, r6, r7));
583014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
583114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Muls(r0, r1, r0),
583214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Muls(r0, r0, r1));
583314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
583414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Muls(eq, r0, r1, r0),
583514e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Muls(eq, r0, r0, r1));
583614e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
583714e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Orrs(r7, r7, r6),
583814e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Orrs(r7, r6, r7));
583914e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
584014e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  // CHECK_SIZE_MATCH(Orrs(eq, r7, r7, r6),
584114e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley  //                  Orrs(eq, r7, r6, r7));
584214e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley}
584314e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
584414e3bf1f6fc699edbb5e3a031964cb659bc16f9dJacob Bramley
584588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}  // namespace aarch32
584688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}  // namespace vixl
5847