blob: 1065fbde0f0a287fdc937701ad2e98db61bd1867 [file] [log] [blame]
Zhi An Ng109a5eb2022-01-20 09:35:12 -08001// Copyright 2022 Google LLC
2//
3// This source code is licensed under the BSD-style license found in the
4// LICENSE file in the root directory of this source tree.
5
6#include <xnnpack/aarch64-assembler.h>
7#include <xnnpack/allocator.h>
8#include <xnnpack/common.h>
9
Zhi An Ng0ba29e72022-01-20 11:26:01 -080010#include "assembler-helpers.h"
Zhi An Ng109a5eb2022-01-20 09:35:12 -080011#include <gtest/gtest.h>
12
13namespace xnnpack {
14namespace aarch64 {
15
16TEST(AArch64Assembler, Initialization) {
17 xnn_code_buffer b;
18 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
19 Assembler a(&b);
20 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
21}
22
Zhi An Ng65ccb132022-01-20 16:16:47 -080023TEST(AArch64Assembler, BaseInstructionEncoding) {
24 xnn_code_buffer b;
25 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
26 Assembler a(&b);
27
Zhi An Ng49155092022-01-21 16:32:57 -080028 CHECK_ENCODING(0x91008041, a.add(x1, x2, 32));
29 CHECK_ENCODING(0x913FFC41, a.add(x1, x2, 4095));
30 EXPECT_ERROR(Error::kInvalidOperand, a.add(x1, x2, 4096));
31
Zhi An Ng658a67d2022-01-25 10:55:43 -080032 CHECK_ENCODING(0x8B040069, a.add(x9, x3, x4));
33
Zhi An Ng80eac622022-01-25 10:51:12 -080034 CHECK_ENCODING(0xF100081F, a.cmp(x0, 2));
35 EXPECT_ERROR(Error::kInvalidOperand, a.cmp(x0, 4096));
36
Zhi An Ng9e51ad62022-02-03 09:09:59 -080037 CHECK_ENCODING(0xEB0C02DF, a.cmp(x22, x12));
38
Zhi An Ng8709ac92022-01-25 14:52:21 -080039 CHECK_ENCODING(0x9A8F322E, a.csel(x14, x17, x15, kLO));
40
Zhi An Ng65ccb132022-01-20 16:16:47 -080041 CHECK_ENCODING(0xA9403FEE, a.ldp(x14, x15, mem[sp]));
42 CHECK_ENCODING(0xA8C13FEE, a.ldp(x14, x15, mem[sp], 16));
43 CHECK_ENCODING(0xA9413FEE, a.ldp(x14, x15, mem[sp, 16]));
44 CHECK_ENCODING(0xA9603FEE, a.ldp(x14, x15, mem[sp, -512]));
45 CHECK_ENCODING(0xA95FBFEE, a.ldp(x14, x15, mem[sp, 504]));
46 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], 15));
47 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], -520));
48 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], 512));
49 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp, 16], 16));
50
51 CHECK_ENCODING(0xF9400BE8, a.ldr(x8, mem[sp, 16]));
52 CHECK_ENCODING(0xF97FFFE8, a.ldr(x8, mem[sp, 32760]));
53 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, -8]));
54 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, 7]));
55 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, 32768]));
56 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, MemOperand(sp, 16, AddressingMode::kPostIndex)));
57
Zhi An Ng1738f112022-02-03 16:08:31 -080058 CHECK_ENCODING(0xF8408488, a.ldr(x8, mem[x4], 8));
59 CHECK_ENCODING(0xF84FF488, a.ldr(x8, mem[x4], 255));
60 CHECK_ENCODING(0xF8500488, a.ldr(x8, mem[x4], -256));
61 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[x4], 256));
62 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[x4], -257));
63
Zhi An Ng4decc8e2022-02-03 09:32:44 -080064 CHECK_ENCODING(0xAA0303E9, a.mov(x9, x3));
65
Zhi An Ngc2e2da82022-01-25 16:51:58 -080066 CHECK_ENCODING(0xF98000A0, a.prfm(kPLDL1KEEP, mem[x5]));
Zhi An Ngfc67a862022-01-27 09:12:34 -080067 CHECK_ENCODING(0xF98020A0, a.prfm(kPLDL1KEEP, mem[x5, 64]));
Zhi An Ngc2e2da82022-01-25 16:51:58 -080068 EXPECT_ERROR(Error::kInvalidOperand, a.prfm(kPLDL1KEEP, mem[x5, -8]));
69 EXPECT_ERROR(Error::kInvalidOperand, a.prfm(kPLDL1KEEP, mem[x5, 32761]));
Zhi An Ng234d6b42022-01-20 16:31:33 -080070
Zhi An Ngcdfff792022-01-21 15:01:00 -080071 CHECK_ENCODING(0xD65F03C0, a.ret());
72
Zhi An Ng31768682022-01-21 14:52:05 -080073 CHECK_ENCODING(0xCB020083, a.sub(x3, x4, x2));
74
Zhi An Ng8ceeebe2022-02-03 09:20:28 -080075 CHECK_ENCODING(0xA90457F4, a.stp(x20, x21, mem[sp, 64]));
76 CHECK_ENCODING(0xA98457F4, a.stp(x20, x21, mem[sp, 64]++));
77 CHECK_ENCODING(0xA91FD7F4, a.stp(x20, x21, mem[sp, 504]));
78 CHECK_ENCODING(0xA92057F4, a.stp(x20, x21, mem[sp, -512]));
79 EXPECT_ERROR(Error::kInvalidOperand, a.stp(x20, x21, mem[sp, 3]));
80 EXPECT_ERROR(Error::kInvalidOperand, a.stp(x20, x21, mem[sp, 512]));
81 EXPECT_ERROR(Error::kInvalidOperand, a.stp(x20, x21, mem[sp, -520]));
82
Zhi An Nge2dc2ec2022-01-20 17:05:33 -080083 CHECK_ENCODING(0xF1008040, a.subs(x0, x2, 32));
84 CHECK_ENCODING(0xF13FFC40, a.subs(x0, x2, 4095));
85 EXPECT_ERROR(Error::kInvalidOperand, a.subs(x0, x2, -32));
86 EXPECT_ERROR(Error::kInvalidOperand, a.subs(x0, x2, 4096));
87
Zhi An Ng3cec4512022-01-25 15:03:42 -080088 CHECK_ENCODING(0xF240043F, a.tst(x1, 3));
89 CHECK_ENCODING(0xF2400C3F, a.tst(x1, 15));
90 CHECK_ENCODING(0xF240103F, a.tst(x1, 31));
91 EXPECT_ERROR(Error::kUnimplemented, a.tst(x1, 32));
92
Zhi An Ng65ccb132022-01-20 16:16:47 -080093 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
94}
95
96TEST(AArch64Assembler, SIMDInstructionEncoding) {
Zhi An Ng0ba29e72022-01-20 11:26:01 -080097 xnn_code_buffer b;
98 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
99 Assembler a(&b);
100
Zhi An Ng2f24c3e2022-01-21 17:14:03 -0800101 CHECK_ENCODING(0x5E180610, a.dup(d16, v16.d()[1]));
102 EXPECT_ERROR(Error::kInvalidOperand, a.dup(d16, v16.d()[2]));
103 EXPECT_ERROR(Error::kInvalidOperand, a.dup(d16, v16.s()[1]));
104
Zhi An Ngecfb1f02022-01-21 14:14:38 -0800105 CHECK_ENCODING(0x4E25D690, a.fadd(v16.v4s(), v20.v4s(), v5.v4s()));
106 EXPECT_ERROR(Error::kInvalidOperand, a.fadd(v16.v4s(), v20.v4s(), v5.v2s()));
107
Zhi An Ng544d73d2022-01-21 14:21:52 -0800108 CHECK_ENCODING(0x4E30F7E3, a.fmax(v3.v4s(), v31.v4s(), v16.v4s()));
109 EXPECT_ERROR(Error::kInvalidOperand, a.fmax(v3.v8h(), v31.v4s(), v16.v4s()));
110
111 CHECK_ENCODING(0x4EB1F7C2, a.fmin(v2.v4s(), v30.v4s(), v17.v4s()));
112 EXPECT_ERROR(Error::kInvalidOperand, a.fmin(v2.v4s(), v30.v16b(), v17.v4s()));
113
Zhi An Ng6a1151b2022-01-21 13:18:31 -0800114 CHECK_ENCODING(0x4F801290, a.fmla(v16.v4s(), v20.v4s(), v0.s()[0]));
115 EXPECT_ERROR(Error::kInvalidOperand, a.fmla(v16.v4s(), v20.v2s(), v0.s()[0]));
116 EXPECT_ERROR(Error::kInvalidOperand, a.fmla(v16.v2d(), v20.v2d(), v0.s()[0]));
117 EXPECT_ERROR(Error::kInvalidLaneIndex, a.fmla(v16.v4s(), v20.v4s(), v0.s()[4]));
118
Zhi An Ng6e68f542022-01-20 15:18:57 -0800119 CHECK_ENCODING(0x0CDF7060, a.ld1({v0.v8b()}, mem[x3], 8));
120 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b()}, mem[x3], 16));
121 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v16b()}, mem[x3], 8));
122
123 CHECK_ENCODING(0x0CDFA060, a.ld1({v0.v8b(), v1.v8b()}, mem[x3], 16));
124 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b(), v1.v8b()}, mem[x3], 32));
125 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v16b(), v1.v16b()}, mem[x3], 16));
126 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b(), v2.v8b()}, mem[x3], 16));
127
128 CHECK_ENCODING(0x4CDF61F0, a.ld1({v16.v16b(), v17.v16b(), v18.v16b()}, mem[x15], 48));
129 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v8b(), v17.v16b(), v18.v16b()}, mem[x15], 48));
130 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v16b(), v17.v16b(), v18.v8b()}, mem[x15], 48));
131 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v16b(), v17.v16b(), v18.v16b()}, mem[x15], 24));
132 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v8b(), v17.v8b(), v18.v8b()}, mem[x15], 48));
133
Zhi An Ng4a1c6a82022-01-25 16:05:44 -0800134 CHECK_ENCODING(0x6D433FEE, a.ldp(d14, d15, mem[sp, 48]));
135 CHECK_ENCODING(0x6DC33FEE, a.ldp(d14, d15, mem[sp, 48]++));
136 CHECK_ENCODING(0x6CC427E8, a.ldp(d8, d9, mem[sp], 64));
137 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(d14, d15, mem[sp, 7]));
138
Zhi An Ng157b0f42022-01-21 11:30:49 -0800139 CHECK_ENCODING(0xACC154B4, a.ldp(q20, q21, mem[x5], 32));
140 CHECK_ENCODING(0xACE054B4, a.ldp(q20, q21, mem[x5], -1024));
141 CHECK_ENCODING(0xACDFD4B4, a.ldp(q20, q21, mem[x5], 1008));
142 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(q20, q21, mem[x5], 15));
143 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(q20, q21, mem[x5], -1040));
144 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(q20, q21, mem[x5], 1024));
145
Zhi An Ng491e9e02022-01-24 14:52:37 -0800146 CHECK_ENCODING(0xFC408460, a.ldr(d0, mem[x3], 8));
147 CHECK_ENCODING(0xBC404460, a.ldr(s0, mem[x3], 4));
148
Zhi An Ng157b0f42022-01-21 11:30:49 -0800149 CHECK_ENCODING(0x3CC10460, a.ldr(q0, mem[x3], 16));
150 CHECK_ENCODING(0x3CCFF460, a.ldr(q0, mem[x3], 255));
151 CHECK_ENCODING(0x3CD00460, a.ldr(q0, mem[x3], -256));
152 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(q0, mem[x3], -257));
153 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(q0, mem[x3], 256));
154 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(q0, mem[x3, 16], 16));
155
Zhi An Ngeb7256b2022-02-03 16:02:54 -0800156 CHECK_ENCODING(0x4D40C904, a.ld1r({v4.v4s()}, mem[x8]));
157 EXPECT_ERROR(Error::kInvalidOperand, a.ld1r({v4.v4s(), v5.v4s()}, mem[x8]));
158 EXPECT_ERROR(Error::kInvalidOperand, a.ld1r({v4.v4s()}, mem[x8, 16]));
159
Zhi An Ng5702efb2022-01-20 14:04:20 -0800160 CHECK_ENCODING(0x4D60C902, a.ld2r({v2.v4s(), v3.v4s()}, mem[x8]));
161 EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v3.v4s()}, mem[x8, 16]));
162 EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v4.v4s()}, mem[x8, 16]));
Zhi An Ng6e68f542022-01-20 15:18:57 -0800163 EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v3.v8b()}, mem[x8]));
Zhi An Ng5702efb2022-01-20 14:04:20 -0800164
Zhi An Ng5a5c9e12022-01-21 16:47:09 -0800165 CHECK_ENCODING(0x4EB21E50, a.mov(v16.v16b(), v18.v16b()));
166 CHECK_ENCODING(0x0EB21E50, a.mov(v16.v8b(), v18.v8b()));
167 EXPECT_ERROR(Error::kInvalidOperand, a.mov(v16.v16b(), v18.v8b()));
168
Zhi An Ng65ccb132022-01-20 16:16:47 -0800169 CHECK_ENCODING(0x4F000405, a.movi(v5.v4s(), 0));
170 CHECK_ENCODING(0x4F008405, a.movi(v5.v8h(), 0));
171 CHECK_ENCODING(0x4F00E405, a.movi(v5.v16b(), 0));
172 EXPECT_ERROR(Error::kUnimplemented, a.movi(v5.v16b(), 0xFF));
Zhi An Ng04cdc412022-01-20 11:37:49 -0800173
Zhi An Ng3f342992022-01-21 14:27:45 -0800174 CHECK_ENCODING(0x4C82746F, a.st1({v15.v8h()}, mem[x3], x2));
175
176 CHECK_ENCODING(0x4C95AA8F, a.st1({v15.v4s(), v16.v4s()}, mem[x20], x21));
177 EXPECT_ERROR(Error::kInvalidOperand, a.st1({v15.v4s(), v17.v4s()}, mem[x20], x21));
178 EXPECT_ERROR(Error::kInvalidOperand, a.st1({v15.v4s(), v16.v8h()}, mem[x20], x21));
179
180 CHECK_ENCODING(0x4C8E60D0, a.st1({v16.v16b(), v17.v16b(), v18.v16b() }, mem[x6], x14));
181 EXPECT_ERROR(Error::kInvalidOperand, a.st1({v15.v16b(), v17.v16b(), v18.v16b()}, mem[x6], x14));
182 EXPECT_ERROR(Error::kInvalidOperand, a.st1({v16.v16b(), v17.v16b(), v18.v4s()}, mem[x6], x14));
183
184 CHECK_ENCODING(0x4C812FB4, a.st1({v20.v2d(), v21.v2d(), v22.v2d(), v23.v2d()}, mem[x29], x1));
185 EXPECT_ERROR(Error::kInvalidOperand, a.st1({v20.v2d(), v21.v2d(), v22.v2d(), v23.v2s()}, mem[x29], x1));
186 EXPECT_ERROR(Error::kInvalidOperand, a.st1({v20.v2d(), v21.v2d(), v22.v2d(), v27.v2d()}, mem[x29], x1));
187
Zhi An Ng35d8e682022-01-25 11:40:06 -0800188 CHECK_ENCODING(0x6D012FEA, a.stp(d10, d11, mem[sp, 16]));
189 CHECK_ENCODING(0x6D202FEA, a.stp(d10, d11, mem[sp, -512]));
190 CHECK_ENCODING(0x6D1FAFEA, a.stp(d10, d11, mem[sp, 504]));
191 EXPECT_ERROR(Error::kInvalidOperand, a.stp(d10, d11, mem[sp, -520]));
192 EXPECT_ERROR(Error::kInvalidOperand, a.stp(d10, d11, mem[sp, 512]));
193
194 CHECK_ENCODING(0x6D812FEA, a.stp(d10, d11, mem[sp, 16]++));
195
Zhi An Ng048704d2022-01-25 15:14:15 -0800196 CHECK_ENCODING(0xAD0075BC, a.stp(q28, q29, mem[x13]));
197 CHECK_ENCODING(0xAD80F5BC, a.stp(q28, q29, mem[x13, 16]++));
198 EXPECT_ERROR(Error::kInvalidOperand, a.stp(q28, q28, mem[x13, 7]));
199
Zhi An Ng5e313952022-01-21 16:35:36 -0800200 CHECK_ENCODING(0xAC8144D0, a.stp(q16, q17, mem[x6], 32));
201 CHECK_ENCODING(0xAC9FC4D0, a.stp(q16, q17, mem[x6], 1008));
202 CHECK_ENCODING(0xACA044D0, a.stp(q16, q17, mem[x6], -1024));
203 EXPECT_ERROR(Error::kInvalidOperand, a.stp(q16, q17, mem[x6], 34));
204 EXPECT_ERROR(Error::kInvalidOperand, a.stp(q16, q17, mem[x6], 1024));
205 EXPECT_ERROR(Error::kInvalidOperand, a.stp(q16, q17, mem[x6], -1040));
206
Zhi An Ng491e9e02022-01-24 14:52:37 -0800207 CHECK_ENCODING(0xFC0084D0, a.str(d16, mem[x6], 8));
Zhi An Ngf7616322022-01-21 17:06:31 -0800208 CHECK_ENCODING(0x3C8104D0, a.str(q16, mem[x6], 16));
209 CHECK_ENCODING(0x3C8FF4D0, a.str(q16, mem[x6], 255));
210 CHECK_ENCODING(0x3C9004D0, a.str(q16, mem[x6], -256));
211 EXPECT_ERROR(Error::kInvalidOperand, a.str(q16, mem[x6], 256));
212 EXPECT_ERROR(Error::kInvalidOperand, a.str(q16, mem[x6], -257));
213
214 CHECK_ENCODING(0xBD0000D0, a.str(s16, mem[x6]));
215 CHECK_ENCODING(0xBD3FFCD0, a.str(s16, mem[x6, 16380]));
216 EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6, 3]));
217 EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6, -4]));
218 EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6, 16384]));
219
Zhi An Ngf6728512022-02-03 16:19:49 -0800220 CHECK_ENCODING(0xBC0044D0, a.str(s16, mem[x6], 4));
221 CHECK_ENCODING(0xBC0FF4D0, a.str(s16, mem[x6], 255));
222 CHECK_ENCODING(0xBC1004D0, a.str(s16, mem[x6], -256));
223 EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6], 256));
224 EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6], -257));
225
Zhi An Ng0ba29e72022-01-20 11:26:01 -0800226 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
227}
228
Zhi An Ngf67f1be2022-01-21 10:06:54 -0800229TEST(AArch64Assembler, Label) {
230 xnn_code_buffer b;
231 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
232 Assembler a(&b);
233
234 Label l1;
235 a.movi(v0.v4s(), 0);
236
237 // Branch to unbound label.
238 auto b1 = a.offset<uint32_t*>();
239 a.b_eq(l1);
240
241 a.movi(v1.v4s(), 0);
242
243 auto b2 = a.offset<uint32_t*>();
244 a.b_ne(l1);
245
246 a.movi(v2.v4s(), 0);
247
248 a.bind(l1);
249
250 // Check that b1 and b2 are both patched after binding l1.
251 EXPECT_INSTR(0x54000080, *b1);
252 EXPECT_INSTR(0x54000041, *b2);
253
254 a.movi(v3, 0);
255
256 // Branch to bound label.
257 auto b3 = a.offset<uint32_t*>();
258 a.b_hi(l1);
259 auto b4 = a.offset<uint32_t*>();
260 a.b_hs(l1);
261 auto b5 = a.offset<uint32_t*>();
262 a.b_lo(l1);
263
264 EXPECT_INSTR(0x54FFFFE8, *b3);
265 EXPECT_INSTR(0x54FFFFC2, *b4);
266 EXPECT_INSTR(0x54FFFFA3, *b5);
267
268 // Binding a bound label is an error.
269 a.bind(l1);
270 EXPECT_ERROR(Error::kLabelAlreadyBound, a.bind(l1));
271
272 // Check for bind failure due to too many users of label.
273 Label lfail;
274 a.reset();
275 // Arbitrary high number of users that we probably won't support.
276 for (int i = 0; i < 1000; i++) {
277 a.b_eq(lfail);
278 }
279 EXPECT_EQ(Error::kLabelHasTooManyUsers, a.error());
280
281 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
282}
283
Zhi An Ng09810802022-01-21 13:46:39 -0800284TEST(AArch64Assembler, Tbnz) {
285 xnn_code_buffer b;
286 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
287 Assembler a(&b);
288
289 Label l1;
290 a.movi(v0.v4s(), 0);
291
292 // Branch to unbound label.
293 auto b1 = a.offset<uint32_t*>();
294 a.tbnz(x0, 4, l1);
295
296 a.movi(v1.v4s(), 0);
297 a.bind(l1);
298
299 EXPECT_INSTR(0x37200040, *b1);
300
301 a.movi(v2.v4s(), 0);
302
303 // Branch to bound label.
304 auto b2 = a.offset<uint32_t*>();
305 a.tbnz(x1, 6, l1);
306
307 EXPECT_INSTR(0x3737FFE1, *b2);
308
309 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
310}
311
Zhi An Ng56e8b912022-01-21 15:06:20 -0800312TEST(AArch64Assembler, Tbz) {
313 xnn_code_buffer b;
314 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
315 Assembler a(&b);
316
317 Label l1;
318 a.movi(v0.v4s(), 0);
319
320 // Branch to unbound label.
321 auto b1 = a.offset<uint32_t*>();
322 a.tbz(x0, 4, l1);
323
324 a.movi(v1.v4s(), 0);
325 a.bind(l1);
326
327 EXPECT_INSTR(0x36200040, *b1);
328
329 a.movi(v2.v4s(), 0);
330
331 // Branch to bound label.
332 auto b2 = a.offset<uint32_t*>();
333 a.tbz(x1, 6, l1);
334
335 EXPECT_INSTR(0x3637FFE1, *b2);
336
337 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
338}
339
Zhi An Ngb10677e2022-01-21 16:24:26 -0800340TEST(AArch64Assembler, UnconditionalBranch) {
341 xnn_code_buffer b;
342 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
343 Assembler a(&b);
344
345 Label l1;
346 a.movi(v0.v4s(), 0);
347
348 // Branch to unbound label.
349 auto b1 = a.offset<uint32_t*>();
350 a.b(l1);
351
352 a.movi(v1.v4s(), 0);
353 a.bind(l1);
354
355 EXPECT_INSTR(0x14000002, *b1);
356
357 a.movi(v2.v4s(), 0);
358
359 // Branch to bound label.
360 auto b2 = a.offset<uint32_t*>();
361 a.b(l1);
362
363 EXPECT_INSTR(0x17FFFFFF, *b2);
364
365 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
366}
367
Zhi An Ng109a5eb2022-01-20 09:35:12 -0800368} // namespace aarch64
369} // namespace xnnpack