blob: 64d58c60642db67c680152a8f422831600acd8af [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
28 CHECK_ENCODING(0xA9403FEE, a.ldp(x14, x15, mem[sp]));
29 CHECK_ENCODING(0xA8C13FEE, a.ldp(x14, x15, mem[sp], 16));
30 CHECK_ENCODING(0xA9413FEE, a.ldp(x14, x15, mem[sp, 16]));
31 CHECK_ENCODING(0xA9603FEE, a.ldp(x14, x15, mem[sp, -512]));
32 CHECK_ENCODING(0xA95FBFEE, a.ldp(x14, x15, mem[sp, 504]));
33 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], 15));
34 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], -520));
35 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp], 512));
36 EXPECT_ERROR(Error::kInvalidOperand, a.ldp(x14, x15, mem[sp, 16], 16));
37
38 CHECK_ENCODING(0xF9400BE8, a.ldr(x8, mem[sp, 16]));
39 CHECK_ENCODING(0xF97FFFE8, a.ldr(x8, mem[sp, 32760]));
40 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, -8]));
41 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, 7]));
42 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, mem[sp, 32768]));
43 EXPECT_ERROR(Error::kInvalidOperand, a.ldr(x8, MemOperand(sp, 16, AddressingMode::kPostIndex)));
44
Zhi An Ng234d6b42022-01-20 16:31:33 -080045 CHECK_ENCODING(0xF98000A0, a.prfm(PLDL1KEEP, mem[x5]));
46 EXPECT_ERROR(Error::kInvalidOperand, a.prfm(PLDL1KEEP, mem[x5, -8]));
47 EXPECT_ERROR(Error::kInvalidOperand, a.prfm(PLDL1KEEP, mem[x5, 32761]));
48
Zhi An Nge2dc2ec2022-01-20 17:05:33 -080049 CHECK_ENCODING(0xF1008040, a.subs(x0, x2, 32));
50 CHECK_ENCODING(0xF13FFC40, a.subs(x0, x2, 4095));
51 EXPECT_ERROR(Error::kInvalidOperand, a.subs(x0, x2, -32));
52 EXPECT_ERROR(Error::kInvalidOperand, a.subs(x0, x2, 4096));
53
Zhi An Ng65ccb132022-01-20 16:16:47 -080054 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
55}
56
57TEST(AArch64Assembler, SIMDInstructionEncoding) {
Zhi An Ng0ba29e72022-01-20 11:26:01 -080058 xnn_code_buffer b;
59 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
60 Assembler a(&b);
61
Zhi An Ng6e68f542022-01-20 15:18:57 -080062 CHECK_ENCODING(0x0CDF7060, a.ld1({v0.v8b()}, mem[x3], 8));
63 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b()}, mem[x3], 16));
64 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v16b()}, mem[x3], 8));
65
66 CHECK_ENCODING(0x0CDFA060, a.ld1({v0.v8b(), v1.v8b()}, mem[x3], 16));
67 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b(), v1.v8b()}, mem[x3], 32));
68 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v16b(), v1.v16b()}, mem[x3], 16));
69 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v0.v8b(), v2.v8b()}, mem[x3], 16));
70
71 CHECK_ENCODING(0x4CDF61F0, a.ld1({v16.v16b(), v17.v16b(), v18.v16b()}, mem[x15], 48));
72 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v8b(), v17.v16b(), v18.v16b()}, mem[x15], 48));
73 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v16b(), v17.v16b(), v18.v8b()}, mem[x15], 48));
74 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v16b(), v17.v16b(), v18.v16b()}, mem[x15], 24));
75 EXPECT_ERROR(Error::kInvalidOperand, a.ld1({v16.v8b(), v17.v8b(), v18.v8b()}, mem[x15], 48));
76
Zhi An Ng5702efb2022-01-20 14:04:20 -080077 CHECK_ENCODING(0x4D60C902, a.ld2r({v2.v4s(), v3.v4s()}, mem[x8]));
78 EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v3.v4s()}, mem[x8, 16]));
79 EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v4.v4s()}, mem[x8, 16]));
Zhi An Ng6e68f542022-01-20 15:18:57 -080080 EXPECT_ERROR(Error::kInvalidOperand, a.ld2r({v2.v4s(), v3.v8b()}, mem[x8]));
Zhi An Ng5702efb2022-01-20 14:04:20 -080081
Zhi An Ng65ccb132022-01-20 16:16:47 -080082 CHECK_ENCODING(0x4F000405, a.movi(v5.v4s(), 0));
83 CHECK_ENCODING(0x4F008405, a.movi(v5.v8h(), 0));
84 CHECK_ENCODING(0x4F00E405, a.movi(v5.v16b(), 0));
85 EXPECT_ERROR(Error::kUnimplemented, a.movi(v5.v16b(), 0xFF));
Zhi An Ng04cdc412022-01-20 11:37:49 -080086
Zhi An Ng0ba29e72022-01-20 11:26:01 -080087 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
88}
89
Zhi An Ngf67f1be2022-01-21 10:06:54 -080090TEST(AArch64Assembler, Label) {
91 xnn_code_buffer b;
92 xnn_allocate_code_memory(&b, XNN_DEFAULT_CODE_BUFFER_SIZE);
93 Assembler a(&b);
94
95 Label l1;
96 a.movi(v0.v4s(), 0);
97
98 // Branch to unbound label.
99 auto b1 = a.offset<uint32_t*>();
100 a.b_eq(l1);
101
102 a.movi(v1.v4s(), 0);
103
104 auto b2 = a.offset<uint32_t*>();
105 a.b_ne(l1);
106
107 a.movi(v2.v4s(), 0);
108
109 a.bind(l1);
110
111 // Check that b1 and b2 are both patched after binding l1.
112 EXPECT_INSTR(0x54000080, *b1);
113 EXPECT_INSTR(0x54000041, *b2);
114
115 a.movi(v3, 0);
116
117 // Branch to bound label.
118 auto b3 = a.offset<uint32_t*>();
119 a.b_hi(l1);
120 auto b4 = a.offset<uint32_t*>();
121 a.b_hs(l1);
122 auto b5 = a.offset<uint32_t*>();
123 a.b_lo(l1);
124
125 EXPECT_INSTR(0x54FFFFE8, *b3);
126 EXPECT_INSTR(0x54FFFFC2, *b4);
127 EXPECT_INSTR(0x54FFFFA3, *b5);
128
129 // Binding a bound label is an error.
130 a.bind(l1);
131 EXPECT_ERROR(Error::kLabelAlreadyBound, a.bind(l1));
132
133 // Check for bind failure due to too many users of label.
134 Label lfail;
135 a.reset();
136 // Arbitrary high number of users that we probably won't support.
137 for (int i = 0; i < 1000; i++) {
138 a.b_eq(lfail);
139 }
140 EXPECT_EQ(Error::kLabelHasTooManyUsers, a.error());
141
142 ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
143}
144
Zhi An Ng109a5eb2022-01-20 09:35:12 -0800145} // namespace aarch64
146} // namespace xnnpack