1b8021494Sopenharmony_ci// Copyright 2016, VIXL authors
2b8021494Sopenharmony_ci// All rights reserved.
3b8021494Sopenharmony_ci//
4b8021494Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
5b8021494Sopenharmony_ci// modification, are permitted provided that the following conditions are met:
6b8021494Sopenharmony_ci//
7b8021494Sopenharmony_ci//   * Redistributions of source code must retain the above copyright notice,
8b8021494Sopenharmony_ci//     this list of conditions and the following disclaimer.
9b8021494Sopenharmony_ci//   * Redistributions in binary form must reproduce the above copyright notice,
10b8021494Sopenharmony_ci//     this list of conditions and the following disclaimer in the documentation
11b8021494Sopenharmony_ci//     and/or other materials provided with the distribution.
12b8021494Sopenharmony_ci//   * Neither the name of ARM Limited nor the names of its contributors may be
13b8021494Sopenharmony_ci//     used to endorse or promote products derived from this software without
14b8021494Sopenharmony_ci//     specific prior written permission.
15b8021494Sopenharmony_ci//
16b8021494Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17b8021494Sopenharmony_ci// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18b8021494Sopenharmony_ci// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19b8021494Sopenharmony_ci// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20b8021494Sopenharmony_ci// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21b8021494Sopenharmony_ci// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22b8021494Sopenharmony_ci// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23b8021494Sopenharmony_ci// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24b8021494Sopenharmony_ci// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25b8021494Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26b8021494Sopenharmony_ci
27b8021494Sopenharmony_ci
28b8021494Sopenharmony_ci#include "code-buffer-vixl.h"
29b8021494Sopenharmony_ci#include "test-runner.h"
30b8021494Sopenharmony_ci
31b8021494Sopenharmony_cinamespace vixl {
32b8021494Sopenharmony_ci
33b8021494Sopenharmony_ci#define TEST(name) TEST_(CODE_BUFFER_##name)
34b8021494Sopenharmony_ci
35b8021494Sopenharmony_ciTEST(align_grow) {
36b8021494Sopenharmony_ci  CodeBuffer code_buffer(2);
37b8021494Sopenharmony_ci  VIXL_CHECK(code_buffer.GetCapacity() == 2);
38b8021494Sopenharmony_ci  VIXL_CHECK(code_buffer.GetRemainingBytes() == 2);
39b8021494Sopenharmony_ci
40b8021494Sopenharmony_ci  code_buffer.Emit16(0);
41b8021494Sopenharmony_ci  VIXL_CHECK(code_buffer.GetCapacity() == 2);
42b8021494Sopenharmony_ci  VIXL_CHECK(code_buffer.GetRemainingBytes() == 0);
43b8021494Sopenharmony_ci
44b8021494Sopenharmony_ci  // Check that the buffer can automatically grow when aligning the cursor.
45b8021494Sopenharmony_ci  VIXL_CHECK(IsAligned<2>(code_buffer.GetCursorOffset()));
46b8021494Sopenharmony_ci  code_buffer.Align();
47b8021494Sopenharmony_ci  VIXL_CHECK(IsWordAligned(code_buffer.GetCursorOffset()));
48b8021494Sopenharmony_ci  VIXL_CHECK(code_buffer.GetCapacity() > 2);
49b8021494Sopenharmony_ci
50b8021494Sopenharmony_ci  code_buffer.SetClean();
51b8021494Sopenharmony_ci}
52b8021494Sopenharmony_ci
53b8021494Sopenharmony_cistatic void TestDefaultsHelper(const CodeBuffer& buffer) {
54b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetCapacity() == CodeBuffer::kDefaultCapacity);
55b8021494Sopenharmony_ci  VIXL_CHECK(buffer.HasSpaceFor(CodeBuffer::kDefaultCapacity));
56b8021494Sopenharmony_ci  VIXL_CHECK(!buffer.HasSpaceFor(CodeBuffer::kDefaultCapacity + 1));
57b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetCursorOffset() == 0);
58b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetOffsetFrom(0) == 0);
59b8021494Sopenharmony_ci  VIXL_CHECK(buffer.IsManaged());
60b8021494Sopenharmony_ci  VIXL_CHECK(!buffer.IsDirty());
61b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetRemainingBytes() == CodeBuffer::kDefaultCapacity);
62b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetSizeInBytes() == 0);
63b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetEndAddress<uintptr_t>() ==
64b8021494Sopenharmony_ci             buffer.GetStartAddress<uintptr_t>());
65b8021494Sopenharmony_ci}
66b8021494Sopenharmony_ci
67b8021494Sopenharmony_ciTEST(defaults) {
68b8021494Sopenharmony_ci  CodeBuffer buffer;
69b8021494Sopenharmony_ci  TestDefaultsHelper(buffer);
70b8021494Sopenharmony_ci}
71b8021494Sopenharmony_ci
72b8021494Sopenharmony_ciTEST(reset) {
73b8021494Sopenharmony_ci  CodeBuffer buffer;
74b8021494Sopenharmony_ci  // Update the buffer by writing to it.
75b8021494Sopenharmony_ci  buffer.Emit("placeholder data");
76b8021494Sopenharmony_ci  VIXL_CHECK(buffer.IsDirty());
77b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetSizeInBytes() > 0);
78b8021494Sopenharmony_ci  // Calling Reset() should reset it back to its default state. (It does not
79b8021494Sopenharmony_ci  // shrink the capacity, but it should not have grown here.)
80b8021494Sopenharmony_ci  VIXL_ASSERT(buffer.GetCapacity() == CodeBuffer::kDefaultCapacity);
81b8021494Sopenharmony_ci  buffer.Reset();
82b8021494Sopenharmony_ci  TestDefaultsHelper(buffer);
83b8021494Sopenharmony_ci}
84b8021494Sopenharmony_ci
85b8021494Sopenharmony_ciTEST(ensure_space) {
86b8021494Sopenharmony_ci  const size_t initial_capacity = 1234;
87b8021494Sopenharmony_ci  CodeBuffer buffer(initial_capacity);
88b8021494Sopenharmony_ci
89b8021494Sopenharmony_ci  // Requesting less space than we already have should have no effect.
90b8021494Sopenharmony_ci  for (size_t space = 0; space < initial_capacity; space++) {
91b8021494Sopenharmony_ci    buffer.EnsureSpaceFor(space);
92b8021494Sopenharmony_ci    VIXL_CHECK(buffer.GetCapacity() == initial_capacity);
93b8021494Sopenharmony_ci  }
94b8021494Sopenharmony_ci
95b8021494Sopenharmony_ci  // Requesting more memory grows the buffer by an unspecified amount.
96b8021494Sopenharmony_ci  buffer.EnsureSpaceFor(initial_capacity + 1);
97b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetCapacity() > initial_capacity);
98b8021494Sopenharmony_ci}
99b8021494Sopenharmony_ci
100b8021494Sopenharmony_ciTEST(emit) {
101b8021494Sopenharmony_ci  CodeBuffer buffer;
102b8021494Sopenharmony_ci  VIXL_ASSERT(buffer.GetSizeInBytes() == 0);
103b8021494Sopenharmony_ci
104b8021494Sopenharmony_ci  uint64_t base_value = 0x0100001000100101;
105b8021494Sopenharmony_ci  const char* test_string = "test string";
106b8021494Sopenharmony_ci  size_t expected_size = 0;
107b8021494Sopenharmony_ci
108b8021494Sopenharmony_ci  // Simple emissions. This should not align or pad in any way.
109b8021494Sopenharmony_ci  buffer.EmitData(&base_value, 7);
110b8021494Sopenharmony_ci  expected_size += 7;
111b8021494Sopenharmony_ci
112b8021494Sopenharmony_ci  buffer.EmitString(test_string);
113b8021494Sopenharmony_ci  expected_size += strlen(test_string) + 1;  // EmitString() emits the '\0'.
114b8021494Sopenharmony_ci
115b8021494Sopenharmony_ci  buffer.Emit64(static_cast<uint64_t>(base_value * 1));
116b8021494Sopenharmony_ci  buffer.Emit(static_cast<uint64_t>(base_value * 2));
117b8021494Sopenharmony_ci  expected_size += 16;
118b8021494Sopenharmony_ci
119b8021494Sopenharmony_ci  buffer.Emit32(static_cast<uint32_t>(base_value * 3));
120b8021494Sopenharmony_ci  buffer.Emit(static_cast<uint32_t>(base_value * 4));
121b8021494Sopenharmony_ci  expected_size += 8;
122b8021494Sopenharmony_ci
123b8021494Sopenharmony_ci  buffer.Emit16(static_cast<uint16_t>(base_value * 5));
124b8021494Sopenharmony_ci  buffer.Emit(static_cast<uint16_t>(base_value * 6));
125b8021494Sopenharmony_ci  expected_size += 4;
126b8021494Sopenharmony_ci
127b8021494Sopenharmony_ci  buffer.Emit8(static_cast<uint8_t>(base_value * 7));
128b8021494Sopenharmony_ci  buffer.Emit(static_cast<uint8_t>(base_value * 8));
129b8021494Sopenharmony_ci  expected_size += 2;
130b8021494Sopenharmony_ci
131b8021494Sopenharmony_ci  VIXL_CHECK(buffer.GetSizeInBytes() == expected_size);
132b8021494Sopenharmony_ci
133b8021494Sopenharmony_ci  buffer.SetClean();
134b8021494Sopenharmony_ci
135b8021494Sopenharmony_ci  // clang-format off
136b8021494Sopenharmony_ci  uint8_t expected[] = {
137b8021494Sopenharmony_ci    // EmitData
138b8021494Sopenharmony_ci    0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x00,
139b8021494Sopenharmony_ci    // EmitString
140b8021494Sopenharmony_ci    't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0',
141b8021494Sopenharmony_ci    // Emit64
142b8021494Sopenharmony_ci    0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x00, 0x01,
143b8021494Sopenharmony_ci    // Emit<uint64_t>
144b8021494Sopenharmony_ci    0x02, 0x02, 0x20, 0x00, 0x20, 0x00, 0x00, 0x02,
145b8021494Sopenharmony_ci    // Emit32
146b8021494Sopenharmony_ci    0x03, 0x03, 0x30, 0x00,
147b8021494Sopenharmony_ci    // Emit<uint32_t>
148b8021494Sopenharmony_ci    0x04, 0x04, 0x40, 0x00,
149b8021494Sopenharmony_ci    // Emit16
150b8021494Sopenharmony_ci    0x05, 0x05,
151b8021494Sopenharmony_ci    // Emit<uint16_t>
152b8021494Sopenharmony_ci    0x06, 0x06,
153b8021494Sopenharmony_ci    // Emit8
154b8021494Sopenharmony_ci    0x07,
155b8021494Sopenharmony_ci    // Emit<uint8_t>
156b8021494Sopenharmony_ci    0x08
157b8021494Sopenharmony_ci  };
158b8021494Sopenharmony_ci  // clang-format on
159b8021494Sopenharmony_ci
160b8021494Sopenharmony_ci  VIXL_ASSERT(expected_size == sizeof(expected));
161b8021494Sopenharmony_ci  VIXL_CHECK(memcmp(buffer.GetStartAddress<const void*>(),
162b8021494Sopenharmony_ci                    expected,
163b8021494Sopenharmony_ci                    expected_size) == 0);
164b8021494Sopenharmony_ci}
165b8021494Sopenharmony_ci
166b8021494Sopenharmony_ci}  // namespace vixl
167