xref: /aosp_15_r20/external/XNNPACK/test/aarch32-assembler.cc (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2021 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/aarch32-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 <ios>
12*4bdc9457SAndroid Build Coastguard Worker 
13*4bdc9457SAndroid Build Coastguard Worker #include "assembler-helpers.h"
14*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h>
15*4bdc9457SAndroid Build Coastguard Worker 
16*4bdc9457SAndroid Build Coastguard Worker namespace xnnpack {
17*4bdc9457SAndroid Build Coastguard Worker namespace aarch32 {
TEST(AArch32Assembler,InstructionEncoding)18*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, InstructionEncoding) {
19*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
20*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
21*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
22*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
23*4bdc9457SAndroid Build Coastguard Worker 
24*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE086600B, a.add(r6, r11));
25*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE0810002, a.add(r0, r1, r2));
26*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE28A9080, a.add(r9, r10, 128));
27*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE29D5008, a.adds(r5, r13, 8));
28*4bdc9457SAndroid Build Coastguard Worker 
29*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE2025007, a.and_(r5, r2, 7));
30*4bdc9457SAndroid Build Coastguard Worker 
31*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE3CC2003, a.bic(r2, r12, 3));
32*4bdc9457SAndroid Build Coastguard Worker 
33*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE12FFF1E, a.bx(lr));
34*4bdc9457SAndroid Build Coastguard Worker 
35*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE3500002, a.cmp(r0, 2));
36*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE1530007, a.cmp(r3, r7));
37*4bdc9457SAndroid Build Coastguard Worker 
38*4bdc9457SAndroid Build Coastguard Worker   // Offset addressing mode.
39*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE59D7060, a.ldr(r7, mem[sp, 96]));
40*4bdc9457SAndroid Build Coastguard Worker   // Post-indexed addressing mode.
41*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE490B000, a.ldr(r11, mem[r0], 0));
42*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE490B060, a.ldr(r11, mem[r0], 96));
43*4bdc9457SAndroid Build Coastguard Worker   // Offsets out of bounds.
44*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(r7, MemOperand(sp, 4096)));
45*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldr(r7, MemOperand(sp, -4096)));
46*4bdc9457SAndroid Build Coastguard Worker 
47*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE1CD66D8, a.ldrd(r6, r7, mem[sp, 104]));
48*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE0CD66D8, a.ldrd(r6, r7, MemOperand(sp, 104, AddressingMode::kPostIndexed)));
49*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldrd(r6, r8, mem[sp, 104]));
50*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.ldrd(r6, r7, mem[sp, 4096]));
51*4bdc9457SAndroid Build Coastguard Worker 
52*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x01A0C007, a.moveq(r12, r7));
53*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x31A0C003, a.movlo(r12, r3));
54*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x91A0A00C, a.movls(r10, r12));
55*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE1A0A00C, a.mov(r10, r12));
56*4bdc9457SAndroid Build Coastguard Worker 
57*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE320F000, a.nop());
58*4bdc9457SAndroid Build Coastguard Worker 
59*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE8BD0FF0, a.pop({r4, r5, r6, r7, r8, r9, r10, r11}));
60*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.pop({}));
61*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.pop({r1}));
62*4bdc9457SAndroid Build Coastguard Worker 
63*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE92D0FF0, a.push({r4, r5, r6, r7, r8, r9, r10, r11}));
64*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.push({}));
65*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.push({r1}));
66*4bdc9457SAndroid Build Coastguard Worker 
67*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF5D3F000, a.pld(MemOperand(r3, 0)));
68*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF5D3F040, a.pld(MemOperand(r3, 64)));
69*4bdc9457SAndroid Build Coastguard Worker 
70*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE58D5068, a.str(r5, mem[sp, 104]));
71*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(r5, MemOperand(sp, 4096)));
72*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.str(r5, MemOperand(sp, -4096)));
73*4bdc9457SAndroid Build Coastguard Worker 
74*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE0487002, a.sub(r7, r8, r2));
75*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE2425010, a.sub(r5, r2, 16));
76*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE2525010, a.subs(r5, r2, 16));
77*4bdc9457SAndroid Build Coastguard Worker 
78*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xE315000F, a.tst(r5, 15));
79*4bdc9457SAndroid Build Coastguard Worker 
80*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3B9676E, a.vabs_f32(q3, q15));
81*4bdc9457SAndroid Build Coastguard Worker 
82*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF24E2DC2, a.vadd_f32(q9, q15, q1));
83*4bdc9457SAndroid Build Coastguard Worker 
84*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEEB44AC8, a.vcmpe_f32(s8, s16));
85*4bdc9457SAndroid Build Coastguard Worker 
86*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3FBE646, a.vcvt_f32_s32(q15, q3));
87*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3FB6748, a.vcvt_s32_f32(q11, q4));
88*4bdc9457SAndroid Build Coastguard Worker 
89*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3FB6148, a.vcvtn_s32_f32(q11, q4));
90*4bdc9457SAndroid Build Coastguard Worker 
91*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3FF8C4F, a.vdup_8(q12, d15[7]));
92*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vdup_8(q12, d15[8]));
93*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3FE8C4F, a.vdup_16(q12, d15[3]));
94*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vdup_16(q12, d15[4]));
95*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3FC8C4F, a.vdup_32(q12, d15[1]));
96*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vdup_32(q12, d15[2]));
97*4bdc9457SAndroid Build Coastguard Worker 
98*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2BE04C6, a.vext_8(q0, q15, q3, 4));
99*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vext_8(q0, q15, q3, 16));
100*4bdc9457SAndroid Build Coastguard Worker 
101*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF423070F, a.vld1_8({d0}, mem[r3]));
102*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF423070D, a.vld1_8({d0}, mem[r3]++));
103*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4230A0F, a.vld1_8({d0-d1}, mem[r3]));
104*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF423060F, a.vld1_8({d0-d2}, mem[r3]));
105*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF423020F, a.vld1_8({d0-d3}, mem[r3]));
106*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF42A4705, a.vld1_8({d4}, mem[r10], r5));
107*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4294A0D, a.vld1_8({q2}, mem[r9]++));
108*4bdc9457SAndroid Build Coastguard Worker 
109*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF42C178F, a.vld1_32({d1}, mem[r12]));
110*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF42C178D, a.vld1_32({d1}, mem[r12]++));
111*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF42C1A8D, a.vld1_32({d1-d2}, mem[r12]++));
112*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF42C168D, a.vld1_32({d1-d3}, mem[r12]++));
113*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF42C128D, a.vld1_32({d1-d4}, mem[r12]++));
114*4bdc9457SAndroid Build Coastguard Worker 
115*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A8780F, a.vld1_32({d7[0]}, mem[r8]));
116*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A3488D, a.vld1_32({d4[1]}, mem[r3]++));
117*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vld1_32({d0[2]}, mem[r3]));
118*4bdc9457SAndroid Build Coastguard Worker 
119*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4294A8D, a.vld1_32({q2}, mem[r9]++));
120*4bdc9457SAndroid Build Coastguard Worker 
121*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54C8F, a.vld1r_32({d4}, mem[r5]));
122*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54CAF, a.vld1r_32({d4, d5}, mem[r5]));
123*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54CAD, a.vld1r_32({d4, d5}, mem[r5]++));
124*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld1r_32({d4, d5}, mem[r5, 4]));
125*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld1r_32({d4, d6}, mem[r5]));
126*4bdc9457SAndroid Build Coastguard Worker 
127*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54D8F, a.vld2r_32({d4, d5}, mem[r5]));
128*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54DAF, a.vld2r_32({d4, d6}, mem[r5]));
129*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld2r_32({d4, d5}, mem[r5, 4]));
130*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld2r_32({d4, d7}, mem[r5]));
131*4bdc9457SAndroid Build Coastguard Worker 
132*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54E8F, a.vld3r_32({d4, d5, d6}, mem[r5]));
133*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4A54EAF, a.vld3r_32({d4, d6, d8}, mem[r5]));
134*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld3r_32({d4, d5, d6}, mem[r5, 4]));
135*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld3r_32({d4, d5, d7}, mem[r5]));
136*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld3r_32({d4, d6, d7}, mem[r5]));
137*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vld3r_32({d4, d6, d9}, mem[r5]));
138*4bdc9457SAndroid Build Coastguard Worker 
139*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xECD90B08, a.vldm(mem[r9], {d16-d19}));
140*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xECF90B08, a.vldm(mem[r9]++, {d16-d19}));
141*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vldm(mem[r9], {d8-d0}));
142*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vldm(mem[r9], {d0-d16}));
143*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vldm(mem[r9], DRegisterList(d31, 2)));
144*4bdc9457SAndroid Build Coastguard Worker 
145*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEC930A01, a.vldm(mem[r3], {s0}));
146*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xECB30A01, a.vldm(mem[r3]++, {s0}));
147*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vldm(mem[r3], {s4-s0}));
148*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vldm(mem[r3], SRegisterList(s31, 2)));
149*4bdc9457SAndroid Build Coastguard Worker 
150*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEDD97A0E, a.vldr(s15, mem[r9, 56]));
151*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEDD97AFF, a.vldr(s15, mem[r9, 1020]));
152*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED597AFF, a.vldr(s15, mem[r9, -1020]));
153*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(s15, MemOperand(r9, 56, AddressingMode::kPostIndexed)));
154*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(s15, mem[r9, 1024]));
155*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(s15, mem[r9, -1024]));
156*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(s15, mem[r9, 1018]));
157*4bdc9457SAndroid Build Coastguard Worker 
158*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED99FB0E, a.vldr(d15, mem[r9, 56]));
159*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED99FBFF, a.vldr(d15, mem[r9, 1020]));
160*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED19FBFF, a.vldr(d15, mem[r9, -1020]));
161*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(d15, MemOperand(r9, 56, AddressingMode::kPostIndexed)));
162*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(d15, mem[r9, 1024]));
163*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(d15, mem[r9, -1024]));
164*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vldr(d15, mem[r9, 1018]));
165*4bdc9457SAndroid Build Coastguard Worker 
166*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF20E26C6, a.vmax_s8(q1, q15, q3));
167*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF24ECFC4, a.vmax_f32(q14, q15, q2));
168*4bdc9457SAndroid Build Coastguard Worker 
169*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF20E26D6, a.vmin_s8(q1, q15, q3));
170*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF220EFC6, a.vmin_f32(q7, q8, q3));
171*4bdc9457SAndroid Build Coastguard Worker 
172*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEE04AA01, a.vmla_f32(s20, s8, s2));
173*4bdc9457SAndroid Build Coastguard Worker 
174*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3E80140, a.vmla_f32(q8, q4, d0[0]));
175*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3EC0160, a.vmla_f32(q8, q6, d0[1]));
176*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vmla_f32(q8, q4, d0[2]));
177*4bdc9457SAndroid Build Coastguard Worker 
178*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2D9E246, a.vmlal_s16(q15, d9, d6[0]));
179*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2D8424A, a.vmlal_s16(q10, d8, d2[1]));
180*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2D88264, a.vmlal_s16(q12, d8, d4[2]));
181*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2D8626A, a.vmlal_s16(q11, d8, d2[3]));
182*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vmlal_s16(q15, d9, d6[4]));
183*4bdc9457SAndroid Build Coastguard Worker 
184*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2C0E050, a.vmov(q15, 0));
185*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vmov(q15, 1));
186*4bdc9457SAndroid Build Coastguard Worker 
187*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEEB0EA4F, a.vmov(s28, s30));
188*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2245114, a.vmov(d5, d4));
189*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF26101B1, a.vmov(d16, d17));
190*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEC420B1F, a.vmov(d15, r0, r2));
191*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF26041F0, a.vmov(q10, q8));
192*4bdc9457SAndroid Build Coastguard Worker 
193*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEEB08A49, a.vmov_f32(s16, s18));
194*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x5EB08A44, a.vmovpl_f32(s16, s8));
195*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0x4EB08A64, a.vmovmi_f32(s16, s9));
196*4bdc9457SAndroid Build Coastguard Worker 
197*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEEB0AB48, a.vmov_f64(d10, d8));
198*4bdc9457SAndroid Build Coastguard Worker 
199*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF2880A10, a.vmovl_s8(q0, d0));
200*4bdc9457SAndroid Build Coastguard Worker 
201*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEEF1FA10, a.vmrs(APSR_nzcv, FPSCR));
202*4bdc9457SAndroid Build Coastguard Worker 
203*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF34E2DD2, a.vmul_f32(q9, q15, q1));
204*4bdc9457SAndroid Build Coastguard Worker 
205*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3F927EE, a.vneg_f32(q9, q15));
206*4bdc9457SAndroid Build Coastguard Worker 
207*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xECBD8B10, a.vpop({d8-d15}));
208*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpop({d0-d16}));
209*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpop({d4-d0}));
210*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpop(DRegisterList(d31, 2)));
211*4bdc9457SAndroid Build Coastguard Worker 
212*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED2D8B10, a.vpush({d8-d15}));
213*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED6D4B08, a.vpush({d20-d23}));
214*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpush({d8-d7}));
215*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpush({d0-d16}));
216*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpush(DRegisterList(d31, 2)));
217*4bdc9457SAndroid Build Coastguard Worker 
218*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED2D4A08, a.vpush({s8-s15}));
219*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED2DAA04, a.vpush({s20-s23}));
220*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpush({s8-s2}));
221*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vpush(SRegisterList(s31, 2)));
222*4bdc9457SAndroid Build Coastguard Worker 
223*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF25E00D2, a.vqadd_s16(q8, q15, q1));
224*4bdc9457SAndroid Build Coastguard Worker 
225*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3A82CCE, a.vqdmulh_s32(q1, q12, d14[0]));
226*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3A82CEE, a.vqdmulh_s32(q1, q12, d14[1]));
227*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vqdmulh_s32(q1, q12, d14[2]));
228*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vqdmulh_s32(q1, q12, d16[0]));
229*4bdc9457SAndroid Build Coastguard Worker 
230*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3B232A6, a.vqmovn_s16(d3, q11));
231*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF3F602A0, a.vqmovn_s32(d16, q8));
232*4bdc9457SAndroid Build Coastguard Worker 
233*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF22C247E, a.vqshl_s32(q1, q15, q6));
234*4bdc9457SAndroid Build Coastguard Worker 
235*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF264C560, a.vrshl_s32(q14, q8, q2));
236*4bdc9457SAndroid Build Coastguard Worker 
237*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xFE666D41, a.vsdot_s8(q11, q3, d1[0]));
238*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vsdot_s8(q11, q3, d1[2]));
239*4bdc9457SAndroid Build Coastguard Worker 
240*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF40B070F, a.vst1_8({d0}, mem[r11]));
241*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF40B070D, a.vst1_8({d0}, mem[r11]++));
242*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF40B0707, a.vst1_8({d0}, mem[r11], r7));
243*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF48B000F, a.vst1_8({d0[0]}, mem[r11]));
244*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF48B00EF, a.vst1_8({d0[7]}, mem[r11]));
245*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vst1_8(d0[8], mem[r11]));
246*4bdc9457SAndroid Build Coastguard Worker 
247*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF40B074F, a.vst1_16({d0}, mem[r11]));
248*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF40B074D, a.vst1_16({d0}, mem[r11]++));
249*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF40B0747, a.vst1_16({d0}, mem[r11], r7));
250*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF48B040F, a.vst1_16({d0[0]}, mem[r11]));
251*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF48B04CF, a.vst1_16({d0[3]}, mem[r11]));
252*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vst1_16(d0[4], mem[r11]));
253*4bdc9457SAndroid Build Coastguard Worker 
254*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF44B0280, a.vst1_32({d16-d19}, mem[r11], r0));
255*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vst1_32({d0-d4}, mem[r11], r0));
256*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vst1_32({d16-d19}, mem[r11], sp));
257*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vst1_32({d16-d19}, mem[r11], pc));
258*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF404168F, a.vst1_32({d1-d3}, mem[r4]));
259*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF44B0A8D, a.vst1_32({d16-d17}, mem[r11]++));
260*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4CB080F, a.vst1_32({d16[0]}, mem[r11]));
261*4bdc9457SAndroid Build Coastguard Worker   // The surrounding braces are optional, but makes it look closer to native assembly.
262*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4CB080F, a.vst1_32(d16[0], mem[r11]));
263*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4CB088F, a.vst1_32(d16[1], mem[r11]));
264*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidLaneIndex, a.vst1_32(d16[2], mem[r11]));
265*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xF4C6C80D, a.vst1_32({d28[0]}, mem[r6]++));
266*4bdc9457SAndroid Build Coastguard Worker 
267*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xEC868B04, a.vstm(mem[r6], {d8-d9}));
268*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xECA7EB02, a.vstm(mem[r7]++, {d14}));
269*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vstm(mem[r6], {d8-d28}));
270*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidRegisterListLength, a.vstm(mem[r6], DRegisterList(d31, 2)));
271*4bdc9457SAndroid Build Coastguard Worker 
272*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED868A00, a.vstr(s16, mem[r6]));
273*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED868A02, a.vstr(s16, mem[r6, 8]));
274*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED868AFF, a.vstr(s16, mem[r6, 1020]));
275*4bdc9457SAndroid Build Coastguard Worker   CHECK_ENCODING(0xED068AFF, a.vstr(s16, mem[r6, -1020]));
276*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vstr(s16, MemOperand(r6, 8, AddressingMode::kPostIndexed)));
277*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vstr(s16, mem[r6, 1024]));
278*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vstr(s16, mem[r6, -1024]));
279*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.vstr(s16, mem[r6, 1018]));
280*4bdc9457SAndroid Build Coastguard Worker 
281*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
282*4bdc9457SAndroid Build Coastguard Worker }
283*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,Label)284*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, Label) {
285*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
286*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
287*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
288*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
289*4bdc9457SAndroid Build Coastguard Worker 
290*4bdc9457SAndroid Build Coastguard Worker   Label l1;
291*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r0, r0);
292*4bdc9457SAndroid Build Coastguard Worker 
293*4bdc9457SAndroid Build Coastguard Worker   // Branch to unbound label.
294*4bdc9457SAndroid Build Coastguard Worker   auto b1 = a.offset<uint32_t*>();
295*4bdc9457SAndroid Build Coastguard Worker   a.beq(l1);
296*4bdc9457SAndroid Build Coastguard Worker 
297*4bdc9457SAndroid Build Coastguard Worker   a.add(r1, r1, r1);
298*4bdc9457SAndroid Build Coastguard Worker 
299*4bdc9457SAndroid Build Coastguard Worker   auto b2 = a.offset<uint32_t*>();
300*4bdc9457SAndroid Build Coastguard Worker   a.bne(l1);
301*4bdc9457SAndroid Build Coastguard Worker 
302*4bdc9457SAndroid Build Coastguard Worker   a.add(r2, r2, r2);
303*4bdc9457SAndroid Build Coastguard Worker 
304*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
305*4bdc9457SAndroid Build Coastguard Worker 
306*4bdc9457SAndroid Build Coastguard Worker   // Check that b1 and b2 are both patched after binding l1.
307*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x0A000002, *b1);
308*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x1A000000, *b2);
309*4bdc9457SAndroid Build Coastguard Worker 
310*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r1, r2);
311*4bdc9457SAndroid Build Coastguard Worker 
312*4bdc9457SAndroid Build Coastguard Worker   // Branch to bound label.
313*4bdc9457SAndroid Build Coastguard Worker   auto b3 = a.offset<uint32_t*>();
314*4bdc9457SAndroid Build Coastguard Worker   a.bhi(l1);
315*4bdc9457SAndroid Build Coastguard Worker   auto b4 = a.offset<uint32_t*>();
316*4bdc9457SAndroid Build Coastguard Worker   a.bhs(l1);
317*4bdc9457SAndroid Build Coastguard Worker   auto b5 = a.offset<uint32_t*>();
318*4bdc9457SAndroid Build Coastguard Worker   a.blo(l1);
319*4bdc9457SAndroid Build Coastguard Worker   auto b6 = a.offset<uint32_t*>();
320*4bdc9457SAndroid Build Coastguard Worker   a.b(l1);
321*4bdc9457SAndroid Build Coastguard Worker 
322*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x8AFFFFFD, *b3);
323*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x2AFFFFFC, *b4);
324*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0x3AFFFFFB, *b5);
325*4bdc9457SAndroid Build Coastguard Worker   EXPECT_INSTR(0xEAFFFFFA, *b6);
326*4bdc9457SAndroid Build Coastguard Worker 
327*4bdc9457SAndroid Build Coastguard Worker   // Binding a bound label is an error.
328*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
329*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kLabelAlreadyBound, a.bind(l1));
330*4bdc9457SAndroid Build Coastguard Worker 
331*4bdc9457SAndroid Build Coastguard Worker   // Check for bind failure due to too many users of label.
332*4bdc9457SAndroid Build Coastguard Worker   Label lfail;
333*4bdc9457SAndroid Build Coastguard Worker   a.reset();
334*4bdc9457SAndroid Build Coastguard Worker   // Arbitrary high number of users that we probably won't support.
335*4bdc9457SAndroid Build Coastguard Worker   for (int i = 0; i < 1000; i++) {
336*4bdc9457SAndroid Build Coastguard Worker     a.beq(lfail);
337*4bdc9457SAndroid Build Coastguard Worker   }
338*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kLabelHasTooManyUsers, a.error());
339*4bdc9457SAndroid Build Coastguard Worker 
340*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
341*4bdc9457SAndroid Build Coastguard Worker }
342*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,Align)343*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, Align) {
344*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
345*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
346*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
347*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
348*4bdc9457SAndroid Build Coastguard Worker 
349*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r1, r2);
350*4bdc9457SAndroid Build Coastguard Worker   a.align(4);
351*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0x3);
352*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(4, a.code_size_in_bytes());
353*4bdc9457SAndroid Build Coastguard Worker 
354*4bdc9457SAndroid Build Coastguard Worker   a.align(8);
355*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0x7);
356*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(8, a.code_size_in_bytes());
357*4bdc9457SAndroid Build Coastguard Worker 
358*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r1, r2);
359*4bdc9457SAndroid Build Coastguard Worker   a.align(8);
360*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0x7);
361*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(16, a.code_size_in_bytes());
362*4bdc9457SAndroid Build Coastguard Worker 
363*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r1, r2);
364*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(20, a.code_size_in_bytes());
365*4bdc9457SAndroid Build Coastguard Worker 
366*4bdc9457SAndroid Build Coastguard Worker   a.align(16);
367*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0xF);
368*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(32, a.code_size_in_bytes());
369*4bdc9457SAndroid Build Coastguard Worker 
370*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r1, r2);
371*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r1, r2);
372*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(40, a.code_size_in_bytes());
373*4bdc9457SAndroid Build Coastguard Worker 
374*4bdc9457SAndroid Build Coastguard Worker   a.align(16);
375*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0, reinterpret_cast<uintptr_t>(a.offset<uint32_t*>()) & 0xF);
376*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(48, a.code_size_in_bytes());
377*4bdc9457SAndroid Build Coastguard Worker 
378*4bdc9457SAndroid Build Coastguard Worker   // Not power-of-two.
379*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.align(6));
380*4bdc9457SAndroid Build Coastguard Worker   // Is power-of-two but is not a multiple of instruction size.
381*4bdc9457SAndroid Build Coastguard Worker   EXPECT_ERROR(Error::kInvalidOperand, a.align(2));
382*4bdc9457SAndroid Build Coastguard Worker 
383*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
384*4bdc9457SAndroid Build Coastguard Worker }
385*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,CoreRegisterList)386*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, CoreRegisterList) {
387*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0x3, CoreRegisterList({r0, r1}));
388*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(0xFC00, CoreRegisterList({r10, r11, r12, r13, r14, r15}));
389*4bdc9457SAndroid Build Coastguard Worker 
390*4bdc9457SAndroid Build Coastguard Worker   EXPECT_FALSE(CoreRegisterList({}).has_more_than_one_register());
391*4bdc9457SAndroid Build Coastguard Worker   EXPECT_FALSE(CoreRegisterList({r0}).has_more_than_one_register());
392*4bdc9457SAndroid Build Coastguard Worker   EXPECT_FALSE(CoreRegisterList({r1}).has_more_than_one_register());
393*4bdc9457SAndroid Build Coastguard Worker   EXPECT_TRUE(CoreRegisterList({r0, r1}).has_more_than_one_register());
394*4bdc9457SAndroid Build Coastguard Worker }
395*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,ConsecutiveRegisterList)396*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, ConsecutiveRegisterList) {
397*4bdc9457SAndroid Build Coastguard Worker   SRegisterList s_list_1 = SRegisterList(s0, s9);
398*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(s_list_1.start, s0);
399*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(s_list_1.length, 10);
400*4bdc9457SAndroid Build Coastguard Worker 
401*4bdc9457SAndroid Build Coastguard Worker   SRegisterList s_list_2 = {s4 - s11};
402*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(s_list_2.start, s4);
403*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(s_list_2.length, 8);
404*4bdc9457SAndroid Build Coastguard Worker 
405*4bdc9457SAndroid Build Coastguard Worker   DRegisterList d_list_1 = DRegisterList(d4, d5);
406*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_list_1.start, d4);
407*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_list_1.length, 2);
408*4bdc9457SAndroid Build Coastguard Worker 
409*4bdc9457SAndroid Build Coastguard Worker   DRegisterList d_list_2 = {d4 - d11};
410*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_list_2.start, d4);
411*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_list_2.length, 8);
412*4bdc9457SAndroid Build Coastguard Worker 
413*4bdc9457SAndroid Build Coastguard Worker   QRegisterList q_list_1 = {q3-q3};
414*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q_list_1.start, q3);
415*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q_list_1.length, 1);
416*4bdc9457SAndroid Build Coastguard Worker 
417*4bdc9457SAndroid Build Coastguard Worker   DRegisterList d_from_q_1 = static_cast<DRegisterList>(q_list_1);
418*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_from_q_1.start, d6);
419*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_from_q_1.length, 2);
420*4bdc9457SAndroid Build Coastguard Worker 
421*4bdc9457SAndroid Build Coastguard Worker   QRegisterList q_list_2 = {q4-q9};
422*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q_list_2.start, q4);
423*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q_list_2.length, 6);
424*4bdc9457SAndroid Build Coastguard Worker 
425*4bdc9457SAndroid Build Coastguard Worker   DRegisterList d_from_q_2 = static_cast<DRegisterList>(q_list_2);
426*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_from_q_2.start, d8);
427*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(d_from_q_2.length, 12);
428*4bdc9457SAndroid Build Coastguard Worker }
429*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,MemOperand)430*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, MemOperand) {
431*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(MemOperand(r0, 4, AddressingMode::kOffset), (mem[r0, 4]));
432*4bdc9457SAndroid Build Coastguard Worker }
433*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,DRegisterLane)434*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, DRegisterLane) {
435*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ((DRegisterLane{2, 0}), d2[0]);
436*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ((DRegisterLane{2, 1}), d2[1]);
437*4bdc9457SAndroid Build Coastguard Worker }
438*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,QRegister)439*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, QRegister) {
440*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q0.low(), d0);
441*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q0.high(), d1);
442*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q1.low(), d2);
443*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q1.high(), d3);
444*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q15.low(), d30);
445*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(q15.high(), d31);
446*4bdc9457SAndroid Build Coastguard Worker }
447*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,CodeBufferOverflow)448*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, CodeBufferOverflow) {
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   // Requested memory is rounded to page size.
452*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, 4);
453*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
454*4bdc9457SAndroid Build Coastguard Worker   for (int i = 0; i < b.capacity; i += 1 << kInstructionSizeInBytesLog2) {
455*4bdc9457SAndroid Build Coastguard Worker     a.add(r0, r0, 2);
456*4bdc9457SAndroid Build Coastguard Worker   }
457*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kNoError, a.error());
458*4bdc9457SAndroid Build Coastguard Worker 
459*4bdc9457SAndroid Build Coastguard Worker   a.bx(lr);
460*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kOutOfMemory, a.error());
461*4bdc9457SAndroid Build Coastguard Worker 
462*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
463*4bdc9457SAndroid Build Coastguard Worker }
464*4bdc9457SAndroid Build Coastguard Worker 
TEST(AArch32Assembler,BoundOverflow)465*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, BoundOverflow) {
466*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
467*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
468*4bdc9457SAndroid Build Coastguard Worker   // Requested memory is rounded to page size.
469*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, 4);
470*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
471*4bdc9457SAndroid Build Coastguard Worker   Label l1;
472*4bdc9457SAndroid Build Coastguard Worker   for (int i = 0; i < b.capacity; i += 1 << kInstructionSizeInBytesLog2) {
473*4bdc9457SAndroid Build Coastguard Worker     a.add(r0, r0, 2);
474*4bdc9457SAndroid Build Coastguard Worker   }
475*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kNoError, a.error());
476*4bdc9457SAndroid Build Coastguard Worker 
477*4bdc9457SAndroid Build Coastguard Worker   // This is out of bounds, not written.
478*4bdc9457SAndroid Build Coastguard Worker   a.bhi(l1);
479*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(Error::kOutOfMemory, a.error());
480*4bdc9457SAndroid Build Coastguard Worker 
481*4bdc9457SAndroid Build Coastguard Worker   a.bind(l1);
482*4bdc9457SAndroid Build Coastguard Worker   EXPECT_EQ(false, l1.bound);
483*4bdc9457SAndroid Build Coastguard Worker 
484*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
485*4bdc9457SAndroid Build Coastguard Worker }
486*4bdc9457SAndroid Build Coastguard Worker 
487*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM && XNN_PLATFORM_JIT
TEST(AArch32Assembler,JitAllocCodeBuffer)488*4bdc9457SAndroid Build Coastguard Worker TEST(AArch32Assembler, JitAllocCodeBuffer) {
489*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr));
490*4bdc9457SAndroid Build Coastguard Worker   typedef uint32_t (*Func)(uint32_t);
491*4bdc9457SAndroid Build Coastguard Worker 
492*4bdc9457SAndroid Build Coastguard Worker   xnn_code_buffer b;
493*4bdc9457SAndroid Build Coastguard Worker   xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
494*4bdc9457SAndroid Build Coastguard Worker 
495*4bdc9457SAndroid Build Coastguard Worker   Assembler a(&b);
496*4bdc9457SAndroid Build Coastguard Worker   a.add(r0, r0, 2);
497*4bdc9457SAndroid Build Coastguard Worker   a.bx(lr);
498*4bdc9457SAndroid Build Coastguard Worker 
499*4bdc9457SAndroid Build Coastguard Worker   Func fn = reinterpret_cast<Func>(a.finalize());
500*4bdc9457SAndroid Build Coastguard Worker 
501*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(3, fn(1));
502*4bdc9457SAndroid Build Coastguard Worker 
503*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
504*4bdc9457SAndroid Build Coastguard Worker }
505*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_ARM && XNN_PLATFORM_JIT
506*4bdc9457SAndroid Build Coastguard Worker }  // namespace aarch32
507*4bdc9457SAndroid Build Coastguard Worker }  // namespace xnnpack
508