1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "gtest/gtest.h"
18
19 #include <link.h>
20
21 #include <cstdint>
22 #include <cstdio>
23
24 // Dummy function for LinkerExidx test.
arm_tests()25 int arm_tests() {
26 return 0;
27 }
28
read_exidx_func(int32_t * entry)29 uintptr_t read_exidx_func(int32_t* entry) {
30 int32_t offset = *entry;
31 // sign-extend from int31 to int32.
32 if ((offset & 0x40000000) != 0) {
33 offset += -0x7fffffff - 1;
34 }
35 return reinterpret_cast<uintptr_t>(entry) + offset;
36 }
37
TEST(ARM,LinkerExidx)38 TEST(ARM, LinkerExidx) {
39 int count;
40 int32_t* entries;
41 entries = reinterpret_cast<int32_t*>(
42 dl_unwind_find_exidx(reinterpret_cast<uintptr_t>(read_exidx_func), &count));
43 ASSERT_TRUE(entries);
44 ASSERT_GT(count, 0);
45 // Sanity checks
46 uintptr_t func = reinterpret_cast<uintptr_t>(arm_tests);
47 bool found = false;
48 for (int i = 0; i < count; i++) {
49 // Entries must have 31 bit set to zero.
50 ASSERT_GE(entries[2 * i], 0);
51 uintptr_t exidx_func = read_exidx_func(&entries[2 * i]);
52 // If our function is compiled to thumb, exception table contains our
53 // address - 1.
54 if (func == exidx_func || func == exidx_func + 1) {
55 found = true;
56 }
57 // Entries must be sorted. Some addresses may appear twice if function
58 // is compiled to arm.
59 if (i > 0) {
60 ASSERT_GE(exidx_func, read_exidx_func(&entries[2 * (i - 1)]));
61 }
62 }
63 ASSERT_TRUE(found);
64 }
65
TEST(ARM,LSL0)66 TEST(ARM, LSL0) {
67 int result;
68
69 asm volatile(
70 "mov %0, #-2\n"
71 "mov r1, #0\n"
72 "lsl %0, r1\n"
73 : "=r"(result)::"r1");
74 EXPECT_EQ(result, -2);
75
76 asm volatile(
77 "mov r1, #-2\n"
78 "mov r2, #0\n"
79 "lsl %0, r1, r2\n"
80 : "=r"(result)::"r1", "r2");
81 EXPECT_EQ(result, -2);
82
83 asm volatile(
84 "mov r1, #-2\n"
85 "lsl %0, r1, #0\n"
86 : "=r"(result)::"r1");
87 EXPECT_EQ(result, -2);
88 }
89
TEST(ARM,LSL32)90 TEST(ARM, LSL32) {
91 int result;
92 int flag;
93
94 asm volatile(
95 "mov %0, #-1\n"
96 "mov r1, #32\n"
97 "lsls %0, r1\n"
98 "sbc %1, r1, r1\n"
99 : "=r"(result), "=r"(flag)::"r1");
100 EXPECT_EQ(result, 0);
101 EXPECT_EQ(flag, 0);
102
103 asm volatile(
104 "mov r1, #-1\n"
105 "mov r2, #32\n"
106 "lsls %0, r1, r2\n"
107 "sbc %1, r1, r1\n"
108 : "=r"(result), "=r"(flag)::"r1", "r2");
109 EXPECT_EQ(result, 0);
110 EXPECT_EQ(flag, 0);
111 }
112
TEST(ARM,LSL33)113 TEST(ARM, LSL33) {
114 int result;
115 int flag;
116
117 asm volatile(
118 "mov %0, #-1\n"
119 "mov r1, #33\n"
120 "lsls %0, r1\n"
121 "sbc %1, r1, r1\n"
122 : "=r"(result), "=r"(flag)::"r1");
123 EXPECT_EQ(result, 0);
124 EXPECT_EQ(flag, -1);
125
126 asm volatile(
127 "mov r1, #-1\n"
128 "mov r2, #33\n"
129 "lsls %0, r1, r2\n"
130 "sbc %1, r1, r1\n"
131 : "=r"(result), "=r"(flag)::"r1", "r2");
132 EXPECT_EQ(result, 0);
133 EXPECT_EQ(flag, -1);
134 }
135
TEST(ARM,LSL256)136 TEST(ARM, LSL256) {
137 int result;
138
139 asm volatile(
140 "mov %0, #-2\n"
141 "mov r1, #256\n"
142 "lsl %0, r1\n"
143 : "=r"(result)::"r1");
144 EXPECT_EQ(result, -2);
145
146 asm volatile(
147 "mov r1, #-2\n"
148 "mov r2, #256\n"
149 "lsl %0, r1, r2\n"
150 : "=r"(result)::"r1", "r2");
151 EXPECT_EQ(result, -2);
152 }
153
TEST(ARM,LSR0)154 TEST(ARM, LSR0) {
155 int result;
156
157 asm volatile(
158 "mov %0, #-2\n"
159 "mov r1, #0\n"
160 "lsr %0, r1\n"
161 : "=r"(result)::"r1");
162 EXPECT_EQ(result, -2);
163
164 asm volatile(
165 "mov r1, #-2\n"
166 "mov r2, #0\n"
167 "lsr %0, r1, r2\n"
168 : "=r"(result)::"r1", "r2");
169 EXPECT_EQ(result, -2);
170 }
171
TEST(ARM,LSR32)172 TEST(ARM, LSR32) {
173 int result;
174 int flag;
175
176 asm volatile(
177 "mov %0, #-1\n"
178 "mov r1, #32\n"
179 "lsrs %0, r1\n"
180 "sbc %1, r1, r1\n"
181 : "=r"(result), "=r"(flag)::"r1");
182 EXPECT_EQ(result, 0);
183 EXPECT_EQ(flag, 0);
184
185 asm volatile(
186 "mov r1, #-1\n"
187 "mov r2, #32\n"
188 "lsrs %0, r1, r2\n"
189 "sbc %1, r1, r1\n"
190 : "=r"(result), "=r"(flag)::"r1", "r2");
191 EXPECT_EQ(result, 0);
192 EXPECT_EQ(flag, 0);
193
194 asm volatile(
195 "mov r1, #-1\n"
196 "lsrs %0, r1, #32\n"
197 "sbc %1, r1, r1\n"
198 : "=r"(result), "=r"(flag)::"r1");
199 EXPECT_EQ(result, 0);
200 EXPECT_EQ(flag, 0);
201 }
202
TEST(ARM,LSR33)203 TEST(ARM, LSR33) {
204 int result;
205 int flag;
206
207 asm volatile(
208 "mov %0, #-1\n"
209 "mov r1, #33\n"
210 "lsrs %0, r1\n"
211 "sbc %1, r1, r1\n"
212 : "=r"(result), "=r"(flag)::"r1");
213 EXPECT_EQ(result, 0);
214 EXPECT_EQ(flag, -1);
215
216 asm volatile(
217 "mov r1, #-1\n"
218 "mov r2, #33\n"
219 "lsrs %0, r1, r2\n"
220 "sbc %1, r1, r1\n"
221 : "=r"(result), "=r"(flag)::"r1", "r2");
222 EXPECT_EQ(result, 0);
223 EXPECT_EQ(flag, -1);
224 }
225
TEST(ARM,LSR256)226 TEST(ARM, LSR256) {
227 int result;
228
229 asm volatile(
230 "mov %0, #-2\n"
231 "mov r1, #256\n"
232 "lsr %0, r1\n"
233 : "=r"(result)::"r1");
234 EXPECT_EQ(result, -2);
235
236 asm volatile(
237 "mov r1, #-2\n"
238 "mov r2, #256\n"
239 "lsr %0, r1, r2\n"
240 : "=r"(result)::"r1", "r2");
241 EXPECT_EQ(result, -2);
242 }
243
TEST(ARM,ASR0)244 TEST(ARM, ASR0) {
245 int result;
246
247 asm volatile(
248 "mov %0, #-2\n"
249 "mov r1, #0\n"
250 "asr %0, r1\n"
251 : "=r"(result)::"r1");
252 EXPECT_EQ(result, -2);
253
254 asm volatile(
255 "mov r1, #-2\n"
256 "mov r2, #0\n"
257 "asr %0, r1, r2\n"
258 : "=r"(result)::"r1", "r2");
259 EXPECT_EQ(result, -2);
260 }
261
TEST(ARM,ASR32)262 TEST(ARM, ASR32) {
263 int result;
264 int flag;
265
266 asm volatile(
267 "mov %0, #-1\n"
268 "mov r1, #32\n"
269 "asrs %0, r1\n"
270 "sbc %1, r1, r1\n"
271 : "=r"(result), "=r"(flag)::"r1");
272 EXPECT_EQ(result, -1);
273 EXPECT_EQ(flag, 0);
274
275 asm volatile(
276 "mov r1, #-1\n"
277 "mov r2, #32\n"
278 "asrs %0, r1, r2\n"
279 "sbc %1, r1, r1\n"
280 : "=r"(result), "=r"(flag)::"r1", "r2");
281 EXPECT_EQ(result, -1);
282 EXPECT_EQ(flag, 0);
283
284 asm volatile(
285 "mov r1, #-1\n"
286 "asrs %0, r1, #32\n"
287 "sbc %1, r1, r1\n"
288 : "=r"(result), "=r"(flag)::"r1");
289 EXPECT_EQ(result, -1);
290 EXPECT_EQ(flag, 0);
291 }
292
TEST(ARM,ASR33)293 TEST(ARM, ASR33) {
294 int result;
295 int flag;
296
297 asm volatile(
298 "mov %0, #-1\n"
299 "mov r1, #33\n"
300 "asrs %0, r1\n"
301 "sbc %1, r1, r1\n"
302 : "=r"(result), "=r"(flag)::"r1");
303 EXPECT_EQ(result, -1);
304 EXPECT_EQ(flag, 0);
305
306 asm volatile(
307 "mov r1, #-1\n"
308 "mov r2, #33\n"
309 "asrs %0, r1, r2\n"
310 "sbc %1, r1, r1\n"
311 : "=r"(result), "=r"(flag)::"r1", "r2");
312 EXPECT_EQ(result, -1);
313 EXPECT_EQ(flag, 0);
314 }
315
TEST(ARM,ASR256)316 TEST(ARM, ASR256) {
317 int result;
318
319 asm volatile(
320 "mov %0, #-2\n"
321 "mov r1, #256\n"
322 "asr %0, r1\n"
323 : "=r"(result)::"r1");
324 EXPECT_EQ(result, -2);
325
326 asm volatile(
327 "mov r1, #-2\n"
328 "mov r2, #256\n"
329 "asr %0, r1, r2\n"
330 : "=r"(result)::"r1", "r2");
331 EXPECT_EQ(result, -2);
332 }
333