xref: /aosp_15_r20/external/XNNPACK/test/aarch64-assembler.cc (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2022 Google LLC
2*4bdc9457SAndroid Build Coastguard Worker //
3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
5*4bdc9457SAndroid Build Coastguard Worker 
6*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack.h>
7*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/aarch64-assembler.h>
8*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/allocator.h>
9*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/common.h>
10*4bdc9457SAndroid Build Coastguard Worker 
11*4bdc9457SAndroid Build Coastguard Worker #include "assembler-helpers.h"
12*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h>
13*4bdc9457SAndroid Build Coastguard Worker 
14*4bdc9457SAndroid Build Coastguard Worker namespace xnnpack {
15*4bdc9457SAndroid Build Coastguard Worker namespace aarch64 {
16*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,Initialization)17*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, Initialization) {
18*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
19*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
20*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
21*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
22*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
23*4bdc9457SAndroid Build Coastguard Worker }
24*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,BaseInstructionEncoding)25*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, BaseInstructionEncoding) {
26*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
27*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
28*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
29*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
30*4bdc9457SAndroid Build Coastguard Worker 
31*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x91008041, a.add(x1, x2, 32));
32*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x913FFC41, a.add(x1, x2, 4095));
33*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.add(x1, x2, 4096));
34*4bdc9457SAndroid Build Coastguard Worker 
35*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x8B040069, a.add(x9, x3, x4));
36*4bdc9457SAndroid Build Coastguard Worker 
37*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF100081F, a.cmp(x0, 2));
38*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.cmp(x0, 4096));
39*4bdc9457SAndroid Build Coastguard Worker 
40*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEB0C02DF, a.cmp(x22, x12));
41*4bdc9457SAndroid Build Coastguard Worker 
42*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x9A8F322E, a.csel(x14, x17, x15, kLO));
43*4bdc9457SAndroid Build Coastguard Worker 
44*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xD4400000, a.hlt());
45*4bdc9457SAndroid Build Coastguard Worker 
46*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA9403FEE, a.ldp(x14, x15, mem[sp]));
47*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA8C13FEE, a.ldp(x14, x15, mem[sp], 16));
48*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA9413FEE, a.ldp(x14, x15, mem[sp, 16]));
49*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA9603FEE, a.ldp(x14, x15, mem[sp, -512]));
50*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA95FBFEE, a.ldp(x14, x15, mem[sp, 504]));
51*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], 15));
52*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], -520));
53*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], 512));
54*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp, 16], 16));
55*4bdc9457SAndroid Build Coastguard Worker 
56*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF9400BE8, a.ldr(x8, mem[sp, 16]));
57*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF97FFFE8, a.ldr(x8, mem[sp, 32760]));
58*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, -8]));
59*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, 7]));
60*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, 32768]));
61*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, MemOperand(sp, 16, AddressingMode::kPostIndex)));
62*4bdc9457SAndroid Build Coastguard Worker 
63*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF8408488, a.ldr(x8, mem[x4], 8));
64*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF84FF488, a.ldr(x8, mem[x4], 255));
65*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF8500488, a.ldr(x8, mem[x4], -256));
66*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[x4], 256));
67*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[x4], -257));
68*4bdc9457SAndroid Build Coastguard Worker 
69*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xAA0303E9, a.mov(x9, x3));
70*4bdc9457SAndroid Build Coastguard Worker 
71*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xD503201F, a.nop());
72*4bdc9457SAndroid Build Coastguard Worker 
73*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF98000A0, a.prfm(kPLDL1KEEP, mem[x5]));
74*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF98020A0, a.prfm(kPLDL1KEEP, mem[x5, 64]));
75*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.prfm(kPLDL1KEEP, mem[x5, -8]));
76*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.prfm(kPLDL1KEEP, mem[x5, 32761]));
77*4bdc9457SAndroid Build Coastguard Worker 
78*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xD65F03C0, a.ret());
79*4bdc9457SAndroid Build Coastguard Worker 
80*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xCB020083, a.sub(x3, x4, x2));
81*4bdc9457SAndroid Build Coastguard Worker 
82*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA90457F4, a.stp(x20, x21, mem[sp, 64]));
83*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA98457F4, a.stp(x20, x21, mem[sp, 64]++));
84*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA91FD7F4, a.stp(x20, x21, mem[sp, 504]));
85*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xA92057F4, a.stp(x20, x21, mem[sp, -512]));
86*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(x20, x21, mem[sp, 3]));
87*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(x20, x21, mem[sp, 512]));
88*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(x20, x21, mem[sp, -520]));
89*4bdc9457SAndroid Build Coastguard Worker 
90*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF80FFFF4, a.str(x20, mem[sp, 255]++));
91*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF81B0FF4, a.str(x20, mem[sp, -80]++));
92*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF8100FF4, a.str(x20, mem[sp, -256]++));
93*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF90003F4, a.str(x20, mem[sp, 0]));
94*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF93FFFF4, a.str(x20, mem[sp, 32760]));
95*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(sp, mem[sp, -257]++));
96*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(sp, mem[sp, 256]++));
97*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(sp, mem[sp, 3]));
98*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(sp, mem[sp, -1]));
99*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(sp, mem[sp, 32768]));
100*4bdc9457SAndroid Build Coastguard Worker 
101*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF1008040, a.subs(x0, x2, 32));
102*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF13FFC40, a.subs(x0, x2, 4095));
103*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.subs(x0, x2, -32));
104*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.subs(x0, x2, 4096));
105*4bdc9457SAndroid Build Coastguard Worker 
106*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF240043F, a.tst(x1, 3));
107*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2400C3F, a.tst(x1, 15));
108*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF240103F, a.tst(x1, 31));
109*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kUnimplemented, a.tst(x1, 32));
110*4bdc9457SAndroid Build Coastguard Worker 
111*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
112*4bdc9457SAndroid Build Coastguard Worker }
113*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,SIMDInstructionEncoding)114*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, SIMDInstructionEncoding) {
115*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
116*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
117*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
118*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
119*4bdc9457SAndroid Build Coastguard Worker 
120*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x5E180610, a.dup(d16, v16.d()[1]));
121*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.dup(d16, v16.d()[2]));
122*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.dup(d16, v16.s()[1]));
123*4bdc9457SAndroid Build Coastguard Worker 
124*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4EA0F8B0, a.fabs(v16.v4s(), v5.v4s()));
125*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fabs(v16.v4s(), v5.v2s()));
126*4bdc9457SAndroid Build Coastguard Worker 
127*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4E25D690, a.fadd(v16.v4s(), v20.v4s(), v5.v4s()));
128*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fadd(v16.v4s(), v20.v4s(), v5.v2s()));
129*4bdc9457SAndroid Build Coastguard Worker 
130*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4E30F7E3, a.fmax(v3.v4s(), v31.v4s(), v16.v4s()));
131*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fmax(v3.v8h(), v31.v4s(), v16.v4s()));
132*4bdc9457SAndroid Build Coastguard Worker 
133*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4EB1F7C2, a.fmin(v2.v4s(), v30.v4s(), v17.v4s()));
134*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fmin(v2.v4s(), v30.v16b(), v17.v4s()));
135*4bdc9457SAndroid Build Coastguard Worker 
136*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4F801290, a.fmla(v16.v4s(), v20.v4s(), v0.s()[0]));
137*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fmla(v16.v4s(), v20.v2s(), v0.s()[0]));
138*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fmla(v16.v2d(), v20.v2d(), v0.s()[0]));
139*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.fmla(v16.v4s(), v20.v4s(), v0.s()[4]));
140*4bdc9457SAndroid Build Coastguard Worker 
141*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6E29DC61, a.fmul(v1.v4s(), v3.v4s(), v9.v4s()));
142*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fmul(v16.v4s(), v20.v4s(), v5.v2s()));
143*4bdc9457SAndroid Build Coastguard Worker 
144*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6EA0FBC2, a.fneg(v2.v4s(), v30.v4s()));
145*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.fneg(v2.v4s(), v30.v16b()));
146*4bdc9457SAndroid Build Coastguard Worker 
147*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x0CDF7060, a.ld1({v0.v8b()}, mem[x3], 8));
148*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b()}, mem[x3], 16));
149*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v16b()}, mem[x3], 8));
150*4bdc9457SAndroid Build Coastguard Worker 
151*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x0CDFA060, a.ld1({v0.v8b(), v1.v8b()}, mem[x3], 16));
152*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b(), v1.v8b()}, mem[x3], 32));
153*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v16b(), v1.v16b()}, mem[x3], 16));
154*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b(), v2.v8b()}, mem[x3], 16));
155*4bdc9457SAndroid Build Coastguard Worker 
156*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4CDF61F0, a.ld1({v16.v16b(), v17.v16b(), v18.v16b()}, mem[x15], 48));
157*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v8b(), v17.v16b(), v18.v16b()}, mem[x15], 48));
158*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v16b(), v17.v16b(), v18.v8b()}, mem[x15], 48));
159*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v16b(), v17.v16b(), v18.v16b()}, mem[x15], 24));
160*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v8b(), v17.v8b(), v18.v8b()}, mem[x15], 48));
161*4bdc9457SAndroid Build Coastguard Worker 
162*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6D433FEE, a.ldp(d14, d15, mem[sp, 48]));
163*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6DC33FEE, a.ldp(d14, d15, mem[sp, 48]++));
164*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6CC427E8, a.ldp(d8, d9, mem[sp], 64));
165*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(d14, d15, mem[sp, 7]));
166*4bdc9457SAndroid Build Coastguard Worker 
167*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xACC154B4, a.ldp(q20, q21, mem[x5], 32));
168*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xACE054B4, a.ldp(q20, q21, mem[x5], -1024));
169*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xACDFD4B4, a.ldp(q20, q21, mem[x5], 1008));
170*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(q20, q21, mem[x5], 15));
171*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(q20, q21, mem[x5], -1040));
172*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldp(q20, q21, mem[x5], 1024));
173*4bdc9457SAndroid Build Coastguard Worker 
174*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xFC408460, a.ldr(d0, mem[x3], 8));
175*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xBC404460, a.ldr(s0, mem[x3], 4));
176*4bdc9457SAndroid Build Coastguard Worker 
177*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x3CC10460, a.ldr(q0, mem[x3], 16));
178*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x3CCFF460, a.ldr(q0, mem[x3], 255));
179*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x3CD00460, a.ldr(q0, mem[x3], -256));
180*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(q0, mem[x3], -257));
181*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(q0, mem[x3], 256));
182*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(q0, mem[x3, 16], 16));
183*4bdc9457SAndroid Build Coastguard Worker 
184*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4D40C904, a.ld1r({v4.v4s()}, mem[x8]));
185*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1r({v4.v4s(), v5.v4s()}, mem[x8]));
186*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld1r({v4.v4s()}, mem[x8, 16]));
187*4bdc9457SAndroid Build Coastguard Worker 
188*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4D60C902, a.ld2r({v2.v4s(), v3.v4s()}, mem[x8]));
189*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v3.v4s()}, mem[x8, 16]));
190*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v4.v4s()}, mem[x8]));
191*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v3.v8b()}, mem[x8]));
192*4bdc9457SAndroid Build Coastguard Worker 
193*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4D40E906, a.ld3r({v6.v4s(), v7.v4s(), v8.v4s()}, mem[x8]));
194*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld3r({v6.v4s(), v7.v4s(), v8.v4s()}, mem[x8, 16]));
195*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld3r({v6.v4s(), v7.v4s(), v9.v4s()}, mem[x8]));
196*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ld3r({v6.v4s(), v7.v2s(), v8.v4s()}, mem[x8]));
197*4bdc9457SAndroid Build Coastguard Worker 
198*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4EB21E50, a.mov(v16.v16b(), v18.v16b()));
199*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x0EB21E50, a.mov(v16.v8b(), v18.v8b()));
200*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.mov(v16.v16b(), v18.v8b()));
201*4bdc9457SAndroid Build Coastguard Worker 
202*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4F000405, a.movi(v5.v4s(), 0));
203*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4F008405, a.movi(v5.v8h(), 0));
204*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4F00E405, a.movi(v5.v16b(), 0));
205*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kUnimplemented, a.movi(v5.v16b(), 0xFF));
206*4bdc9457SAndroid Build Coastguard Worker 
207*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4C82746F, a.st1({v15.v8h()}, mem[x3], x2));
208*4bdc9457SAndroid Build Coastguard Worker 
209*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4C95AA8F, a.st1({v15.v4s(), v16.v4s()}, mem[x20], x21));
210*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.st1({v15.v4s(), v17.v4s()}, mem[x20], x21));
211*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.st1({v15.v4s(), v16.v8h()}, mem[x20], x21));
212*4bdc9457SAndroid Build Coastguard Worker 
213*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4C8E60D0, a.st1({v16.v16b(), v17.v16b(), v18.v16b() }, mem[x6], x14));
214*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.st1({v15.v16b(), v17.v16b(), v18.v16b()}, mem[x6], x14));
215*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.st1({v16.v16b(), v17.v16b(), v18.v4s()}, mem[x6], x14));
216*4bdc9457SAndroid Build Coastguard Worker 
217*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4C812FB4, a.st1({v20.v2d(), v21.v2d(), v22.v2d(), v23.v2d()}, mem[x29], x1));
218*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.st1({v20.v2d(), v21.v2d(), v22.v2d(), v23.v2s()}, mem[x29], x1));
219*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.st1({v20.v2d(), v21.v2d(), v22.v2d(), v27.v2d()}, mem[x29], x1));
220*4bdc9457SAndroid Build Coastguard Worker 
221*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6D012FEA, a.stp(d10, d11, mem[sp, 16]));
222*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6D202FEA, a.stp(d10, d11, mem[sp, -512]));
223*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6D1FAFEA, a.stp(d10, d11, mem[sp, 504]));
224*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(d10, d11, mem[sp, -520]));
225*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(d10, d11, mem[sp, 512]));
226*4bdc9457SAndroid Build Coastguard Worker 
227*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x6D812FEA, a.stp(d10, d11, mem[sp, 16]++));
228*4bdc9457SAndroid Build Coastguard Worker 
229*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xAD0075BC, a.stp(q28, q29, mem[x13]));
230*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xAD80F5BC, a.stp(q28, q29, mem[x13, 16]++));
231*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(q28, q28, mem[x13, 7]));
232*4bdc9457SAndroid Build Coastguard Worker 
233*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xAC8144D0, a.stp(q16, q17, mem[x6], 32));
234*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xAC9FC4D0, a.stp(q16, q17, mem[x6], 1008));
235*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xACA044D0, a.stp(q16, q17, mem[x6], -1024));
236*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(q16, q17, mem[x6], 34));
237*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(q16, q17, mem[x6], 1024));
238*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.stp(q16, q17, mem[x6], -1040));
239*4bdc9457SAndroid Build Coastguard Worker 
240*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xFC0084D0, a.str(d16, mem[x6], 8));
241*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x3C8104D0, a.str(q16, mem[x6], 16));
242*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x3C8FF4D0, a.str(q16, mem[x6], 255));
243*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x3C9004D0, a.str(q16, mem[x6], -256));
244*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(q16, mem[x6], 256));
245*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(q16, mem[x6], -257));
246*4bdc9457SAndroid Build Coastguard Worker 
247*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xBD0000D0, a.str(s16, mem[x6]));
248*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xBD3FFCD0, a.str(s16, mem[x6, 16380]));
249*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6, 3]));
250*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6, -4]));
251*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6, 16384]));
252*4bdc9457SAndroid Build Coastguard Worker 
253*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xBC0044D0, a.str(s16, mem[x6], 4));
254*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xBC0FF4D0, a.str(s16, mem[x6], 255));
255*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xBC1004D0, a.str(s16, mem[x6], -256));
256*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6], 256));
257*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(s16, mem[x6], -257));
258*4bdc9457SAndroid Build Coastguard Worker 
259*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
260*4bdc9457SAndroid Build Coastguard Worker }
261*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,Label)262*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, Label) {
263*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
264*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
265*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
266*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
267*4bdc9457SAndroid Build Coastguard Worker 
268*4bdc9457SAndroid Build Coastguard Worker   Label l1;
269*4bdc9457SAndroid Build Coastguard Worker   a.movi(v0.v4s(), 0);
270*4bdc9457SAndroid Build Coastguard Worker 
271*4bdc9457SAndroid Build Coastguard Worker   // Branch to unbound label.
272*4bdc9457SAndroid Build Coastguard Worker   auto b1 = a.offset<uint32_t*>();
273*4bdc9457SAndroid Build Coastguard Worker   a.b_eq(l1);
274*4bdc9457SAndroid Build Coastguard Worker 
275*4bdc9457SAndroid Build Coastguard Worker   a.movi(v1.v4s(), 0);
276*4bdc9457SAndroid Build Coastguard Worker 
277*4bdc9457SAndroid Build Coastguard Worker   auto b2 = a.offset<uint32_t*>();
278*4bdc9457SAndroid Build Coastguard Worker   a.b_ne(l1);
279*4bdc9457SAndroid Build Coastguard Worker 
280*4bdc9457SAndroid Build Coastguard Worker   a.movi(v2.v4s(), 0);
281*4bdc9457SAndroid Build Coastguard Worker 
282*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
283*4bdc9457SAndroid Build Coastguard Worker 
284*4bdc9457SAndroid Build Coastguard Worker   // Check that b1 and b2 are both patched after binding l1.
285*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x54000080, *b1);
286*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x54000041, *b2);
287*4bdc9457SAndroid Build Coastguard Worker 
288*4bdc9457SAndroid Build Coastguard Worker   a.movi(v3, 0);
289*4bdc9457SAndroid Build Coastguard Worker 
290*4bdc9457SAndroid Build Coastguard Worker   // Branch to bound label.
291*4bdc9457SAndroid Build Coastguard Worker   auto b3 = a.offset<uint32_t*>();
292*4bdc9457SAndroid Build Coastguard Worker   a.b_hi(l1);
293*4bdc9457SAndroid Build Coastguard Worker   auto b4 = a.offset<uint32_t*>();
294*4bdc9457SAndroid Build Coastguard Worker   a.b_hs(l1);
295*4bdc9457SAndroid Build Coastguard Worker   auto b5 = a.offset<uint32_t*>();
296*4bdc9457SAndroid Build Coastguard Worker   a.b_lo(l1);
297*4bdc9457SAndroid Build Coastguard Worker 
298*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x54FFFFE8, *b3);
299*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x54FFFFC2, *b4);
300*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x54FFFFA3, *b5);
301*4bdc9457SAndroid Build Coastguard Worker 
302*4bdc9457SAndroid Build Coastguard Worker   // Binding a bound label is an error.
303*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
304*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kLabelAlreadyBound, a.bind(l1));
305*4bdc9457SAndroid Build Coastguard Worker 
306*4bdc9457SAndroid Build Coastguard Worker   // Check for bind failure due to too many users of label.
307*4bdc9457SAndroid Build Coastguard Worker   Label lfail;
308*4bdc9457SAndroid Build Coastguard Worker   a.reset();
309*4bdc9457SAndroid Build Coastguard Worker   // Arbitrary high number of users that we probably won't support.
310*4bdc9457SAndroid Build Coastguard Worker   for (int i = 0; i < 1000; i++) {
311*4bdc9457SAndroid Build Coastguard Worker     a.b_eq(lfail);
312*4bdc9457SAndroid Build Coastguard Worker   }
313*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kLabelHasTooManyUsers, a.error());
314*4bdc9457SAndroid Build Coastguard Worker 
315*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
316*4bdc9457SAndroid Build Coastguard Worker }
317*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,Tbnz)318*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, Tbnz) {
319*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
320*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
321*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
322*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
323*4bdc9457SAndroid Build Coastguard Worker 
324*4bdc9457SAndroid Build Coastguard Worker   Label l1;
325*4bdc9457SAndroid Build Coastguard Worker   a.movi(v0.v4s(), 0);
326*4bdc9457SAndroid Build Coastguard Worker 
327*4bdc9457SAndroid Build Coastguard Worker   // Branch to unbound label.
328*4bdc9457SAndroid Build Coastguard Worker   auto b1 = a.offset<uint32_t*>();
329*4bdc9457SAndroid Build Coastguard Worker   a.tbnz(x0, 4, l1);
330*4bdc9457SAndroid Build Coastguard Worker 
331*4bdc9457SAndroid Build Coastguard Worker   a.movi(v1.v4s(), 0);
332*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
333*4bdc9457SAndroid Build Coastguard Worker 
334*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x37200040, *b1);
335*4bdc9457SAndroid Build Coastguard Worker 
336*4bdc9457SAndroid Build Coastguard Worker   a.movi(v2.v4s(), 0);
337*4bdc9457SAndroid Build Coastguard Worker 
338*4bdc9457SAndroid Build Coastguard Worker   // Branch to bound label.
339*4bdc9457SAndroid Build Coastguard Worker   auto b2 = a.offset<uint32_t*>();
340*4bdc9457SAndroid Build Coastguard Worker   a.tbnz(x1, 6, l1);
341*4bdc9457SAndroid Build Coastguard Worker 
342*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x3737FFE1, *b2);
343*4bdc9457SAndroid Build Coastguard Worker 
344*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
345*4bdc9457SAndroid Build Coastguard Worker }
346*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,Tbz)347*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, Tbz) {
348*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
349*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
350*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
351*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
352*4bdc9457SAndroid Build Coastguard Worker 
353*4bdc9457SAndroid Build Coastguard Worker   Label l1;
354*4bdc9457SAndroid Build Coastguard Worker   a.movi(v0.v4s(), 0);
355*4bdc9457SAndroid Build Coastguard Worker 
356*4bdc9457SAndroid Build Coastguard Worker   // Branch to unbound label.
357*4bdc9457SAndroid Build Coastguard Worker   auto b1 = a.offset<uint32_t*>();
358*4bdc9457SAndroid Build Coastguard Worker   a.tbz(x0, 4, l1);
359*4bdc9457SAndroid Build Coastguard Worker 
360*4bdc9457SAndroid Build Coastguard Worker   a.movi(v1.v4s(), 0);
361*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
362*4bdc9457SAndroid Build Coastguard Worker 
363*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x36200040, *b1);
364*4bdc9457SAndroid Build Coastguard Worker 
365*4bdc9457SAndroid Build Coastguard Worker   a.movi(v2.v4s(), 0);
366*4bdc9457SAndroid Build Coastguard Worker 
367*4bdc9457SAndroid Build Coastguard Worker   // Branch to bound label.
368*4bdc9457SAndroid Build Coastguard Worker   auto b2 = a.offset<uint32_t*>();
369*4bdc9457SAndroid Build Coastguard Worker   a.tbz(x1, 6, l1);
370*4bdc9457SAndroid Build Coastguard Worker 
371*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x3637FFE1, *b2);
372*4bdc9457SAndroid Build Coastguard Worker 
373*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
374*4bdc9457SAndroid Build Coastguard Worker }
375*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,UnconditionalBranch)376*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, UnconditionalBranch) {
377*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
378*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
379*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
380*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
381*4bdc9457SAndroid Build Coastguard Worker 
382*4bdc9457SAndroid Build Coastguard Worker   Label l1;
383*4bdc9457SAndroid Build Coastguard Worker   a.movi(v0.v4s(), 0);
384*4bdc9457SAndroid Build Coastguard Worker 
385*4bdc9457SAndroid Build Coastguard Worker   // Branch to unbound label.
386*4bdc9457SAndroid Build Coastguard Worker   auto b1 = a.offset<uint32_t*>();
387*4bdc9457SAndroid Build Coastguard Worker   a.b(l1);
388*4bdc9457SAndroid Build Coastguard Worker 
389*4bdc9457SAndroid Build Coastguard Worker   a.movi(v1.v4s(), 0);
390*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
391*4bdc9457SAndroid Build Coastguard Worker 
392*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x14000002, *b1);
393*4bdc9457SAndroid Build Coastguard Worker 
394*4bdc9457SAndroid Build Coastguard Worker   a.movi(v2.v4s(), 0);
395*4bdc9457SAndroid Build Coastguard Worker 
396*4bdc9457SAndroid Build Coastguard Worker   // Branch to bound label.
397*4bdc9457SAndroid Build Coastguard Worker   auto b2 = a.offset<uint32_t*>();
398*4bdc9457SAndroid Build Coastguard Worker   a.b(l1);
399*4bdc9457SAndroid Build Coastguard Worker 
400*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x17FFFFFF, *b2);
401*4bdc9457SAndroid Build Coastguard Worker 
402*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
403*4bdc9457SAndroid Build Coastguard Worker }
404*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,Align)405*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, Align) {
406*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
407*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
408*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
409*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
410*4bdc9457SAndroid Build Coastguard Worker 
411*4bdc9457SAndroid Build Coastguard Worker   a.add(x0, x1, x2);
412*4bdc9457SAndroid Build Coastguard Worker   a.align(4);
413*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0x3);
414*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(4, a.code_size_in_bytes());
415*4bdc9457SAndroid Build Coastguard Worker 
416*4bdc9457SAndroid Build Coastguard Worker   a.align(8);
417*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0x7);
418*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(8, a.code_size_in_bytes());
419*4bdc9457SAndroid Build Coastguard Worker 
420*4bdc9457SAndroid Build Coastguard Worker   a.add(x0, x1, x2);
421*4bdc9457SAndroid Build Coastguard Worker   a.align(8);
422*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0x7);
423*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(16, a.code_size_in_bytes());
424*4bdc9457SAndroid Build Coastguard Worker 
425*4bdc9457SAndroid Build Coastguard Worker   a.add(x0, x1, x2);
426*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(20, a.code_size_in_bytes());
427*4bdc9457SAndroid Build Coastguard Worker 
428*4bdc9457SAndroid Build Coastguard Worker   a.align(16);
429*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0xF);
430*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(32, a.code_size_in_bytes());
431*4bdc9457SAndroid Build Coastguard Worker 
432*4bdc9457SAndroid Build Coastguard Worker   a.add(x0, x1, x2);
433*4bdc9457SAndroid Build Coastguard Worker   a.add(x0, x1, x2);
434*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(40, a.code_size_in_bytes());
435*4bdc9457SAndroid Build Coastguard Worker 
436*4bdc9457SAndroid Build Coastguard Worker   a.align(16);
437*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0xF);
438*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(48, a.code_size_in_bytes());
439*4bdc9457SAndroid Build Coastguard Worker 
440*4bdc9457SAndroid Build Coastguard Worker   // Not power-of-two.
441*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.align(6));
442*4bdc9457SAndroid Build Coastguard Worker   // Is power-of-two but is not a multiple of instruction size.
443*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.align(2));
444*4bdc9457SAndroid Build Coastguard Worker 
445*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
446*4bdc9457SAndroid Build Coastguard Worker }
447*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,AssembleToEndOfBuffer)448*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, AssembleToEndOfBuffer) {
449*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
450*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
451*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
452*4bdc9457SAndroid Build Coastguard Worker 
453*4bdc9457SAndroid Build Coastguard Worker   Assembler a1(&b);
454*4bdc9457SAndroid Build Coastguard Worker   a1.emit32(1);
455*4bdc9457SAndroid Build Coastguard Worker   a1.finalize();
456*4bdc9457SAndroid Build Coastguard Worker 
457*4bdc9457SAndroid Build Coastguard Worker   // Different assembler, but same code buffer.
458*4bdc9457SAndroid Build Coastguard Worker   Assembler a2(&b);
459*4bdc9457SAndroid Build Coastguard Worker   a2.emit32(2);
460*4bdc9457SAndroid Build Coastguard Worker   a2.finalize();
461*4bdc9457SAndroid Build Coastguard Worker 
462*4bdc9457SAndroid Build Coastguard Worker   // Check that we wrote to end of buffer and did not overwrite.
463*4bdc9457SAndroid Build Coastguard Worker   uint32_t* p = (uint32_t*) b.start;
464*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(1, *p);
465*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(2, *(p+1));
466*4bdc9457SAndroid Build Coastguard Worker 
467*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(8, b.size);
468*4bdc9457SAndroid Build Coastguard Worker 
469*4bdc9457SAndroid Build Coastguard Worker   a2.reset();
470*4bdc9457SAndroid Build Coastguard Worker 
471*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(4, b.size);
472*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ((byte*)b.start + 4, a2.offset());
473*4bdc9457SAndroid Build Coastguard Worker 
474*4bdc9457SAndroid Build Coastguard Worker   a2.emit32(3);
475*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(3, *(p+1));
476*4bdc9457SAndroid Build Coastguard Worker 
477*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
478*4bdc9457SAndroid Build Coastguard Worker }
479*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,FinalizeWithError)480*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, FinalizeWithError) {
481*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
482*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
483*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
484*4bdc9457SAndroid Build Coastguard Worker 
485*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
486*4bdc9457SAndroid Build Coastguard Worker   // Write a valid instruction.
487*4bdc9457SAndroid Build Coastguard Worker   a.add(x1, x2, 32);
488*4bdc9457SAndroid Build Coastguard Worker   // Then write an invalid instruction.
489*4bdc9457SAndroid Build Coastguard Worker   a.ldp(x14, x15, mem[sp], 15);
490*4bdc9457SAndroid Build Coastguard Worker   // Since we have an error, size should not be updated.
491*4bdc9457SAndroid Build Coastguard Worker   a.finalize();
492*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(0, b.size);
493*4bdc9457SAndroid Build Coastguard Worker 
494*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
495*4bdc9457SAndroid Build Coastguard Worker }
496*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch64Assembler,BindOverflow)497*4bdc9457SAndroid Build Coastguard Worker TEST(AArch64Assembler, BindOverflow) {
498*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
499*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
500*4bdc9457SAndroid Build Coastguard Worker   // Requested memory is rounded to page size.
501*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, 4);
502*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
503*4bdc9457SAndroid Build Coastguard Worker   Label l1;
504*4bdc9457SAndroid Build Coastguard Worker   for (int i = 0; i < b.capacity; i += 1 << kInstructionSizeInBytesLog2) {
505*4bdc9457SAndroid Build Coastguard Worker     a.add(x0, x0, 2);
506*4bdc9457SAndroid Build Coastguard Worker   }
507*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kNoError, a.error());
508*4bdc9457SAndroid Build Coastguard Worker 
509*4bdc9457SAndroid Build Coastguard Worker   // This is out of bounds, not written.
510*4bdc9457SAndroid Build Coastguard Worker   a.tbz(x1, 1, l1);
511*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kOutOfMemory, a.error());
512*4bdc9457SAndroid Build Coastguard Worker 
513*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
514*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(false, l1.bound);
515*4bdc9457SAndroid Build Coastguard Worker 
516*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
517*4bdc9457SAndroid Build Coastguard Worker }
518*4bdc9457SAndroid Build Coastguard Worker 
519*4bdc9457SAndroid Build Coastguard Worker }  // namespace aarch64
520*4bdc9457SAndroid Build Coastguard Worker }  // namespace xnnpack
521