Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: runtime/vm/assembler_arm_test.cc

Issue 12340006: Adds ARM arm assembler tests. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/os.h" 9 #include "vm/os.h"
10 #include "vm/unit_test.h" 10 #include "vm/unit_test.h"
11 #include "vm/virtual_memory.h" 11 #include "vm/virtual_memory.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 #define __ assembler-> 15 #define __ assembler->
16 16
17 17
18 ASSEMBLER_TEST_GENERATE(Simple, assembler) { 18 ASSEMBLER_TEST_GENERATE(Simple, assembler) {
19 __ mov(R0, ShifterOperand(42)); 19 __ mov(R0, ShifterOperand(42));
20 __ mov(PC, ShifterOperand(LR)); 20 __ mov(PC, ShifterOperand(LR));
21 } 21 }
22 22
23 23
24 ASSEMBLER_TEST_RUN(Simple, test) { 24 ASSEMBLER_TEST_RUN(Simple, test) {
25 typedef int (*SimpleCode)(); 25 typedef int (*SimpleCode)();
26 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry())); 26 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
27 } 27 }
28 28
29
30 ASSEMBLER_TEST_GENERATE(MoveNegated, assembler) {
31 __ mvn(R0, ShifterOperand(42));
32 __ mov(PC, ShifterOperand(LR));
33 }
34
35
36 ASSEMBLER_TEST_RUN(MoveNegated, test) {
37 EXPECT(test != NULL);
38 typedef int (*MoveNegated)();
39 EXPECT_EQ(~42, EXECUTE_TEST_CODE_INT32(MoveNegated, test->entry()));
40 }
41
42
43 ASSEMBLER_TEST_GENERATE(MoveRotImm, assembler) {
44 ShifterOperand shifter_op;
45 EXPECT(ShifterOperand::CanHold(0x00550000, &shifter_op));
46 __ mov(R0, shifter_op);
47 EXPECT(ShifterOperand::CanHold(0x30000003, &shifter_op));
48 __ add(R0, R0, shifter_op);
49 __ mov(PC, ShifterOperand(LR));
50 }
51
52
53 ASSEMBLER_TEST_RUN(MoveRotImm, test) {
54 EXPECT(test != NULL);
55 typedef int (*MoveRotImm)();
56 EXPECT_EQ(0x30550003, EXECUTE_TEST_CODE_INT32(MoveRotImm, test->entry()));
57 }
58
59
60 ASSEMBLER_TEST_GENERATE(MovImm16, assembler) {
61 __ movw(R0, 0x5678);
62 __ movt(R0, 0x1234);
63 __ mov(PC, ShifterOperand(LR));
64 }
65
66
67 ASSEMBLER_TEST_RUN(MovImm16, test) {
68 EXPECT(test != NULL);
69 typedef int (*MovImm16)();
70 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INT32(MovImm16, test->entry()));
71 }
72
73
74 ASSEMBLER_TEST_GENERATE(LoadImmediate, assembler) {
75 __ mov(R0, ShifterOperand(0));
76 __ cmp(R0, ShifterOperand(0));
77 __ LoadImmediate(R0, 0x12345678, EQ);
78 __ LoadImmediate(R0, 0x87654321, NE);
79 __ mov(PC, ShifterOperand(LR));
80 }
81
82
83 ASSEMBLER_TEST_RUN(LoadImmediate, test) {
84 EXPECT(test != NULL);
85 typedef int (*LoadImmediate)();
86 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INT32(LoadImmediate, test->entry()));
87 }
88
89
90 ASSEMBLER_TEST_GENERATE(Vmov, assembler) {
91 __ mov(R3, ShifterOperand(43));
92 __ mov(R1, ShifterOperand(41));
93 __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43
94 __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41
95 __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41
96 __ vmovrs(R3, S5); // R3 = S5, R3 == 41
97 __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41
98 __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41
99 __ vmovsr(S7, R1); // S7 = R1, S6:S7 == 41:43
100 __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43
101 __ sub(R0, R1, ShifterOperand(R0)); // 43-41
102 __ mov(PC, ShifterOperand(LR));
103 }
104
105
106 ASSEMBLER_TEST_RUN(Vmov, test) {
107 EXPECT(test != NULL);
108 typedef int (*Vmov)();
109 EXPECT_EQ(2, EXECUTE_TEST_CODE_INT32(Vmov, test->entry()));
110 }
111
112
113 ASSEMBLER_TEST_GENERATE(SingleVLoadStore, assembler) {
114 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
115 __ mov(R2, ShifterOperand(SP));
116 __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex));
117 __ vldrs(S0, Address(R2, (-kWordSize * 30)));
118 __ vadds(S0, S0, S0);
119 __ vstrs(S0, Address(R2, (-kWordSize * 30)));
120 __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex));
121 __ mov(PC, ShifterOperand(LR));
122 }
123
124
125 ASSEMBLER_TEST_RUN(SingleVLoadStore, test) {
126 EXPECT(test != NULL);
127 typedef float (*SingleVLoadStore)();
128 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
129 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f);
130 }
131
132
133 ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) {
134 int64_t value = bit_cast<int64_t, double>(12.3);
135 __ LoadImmediate(R0, Utils::Low32Bits(value));
136 __ LoadImmediate(R1, Utils::High32Bits(value));
137 __ mov(R2, ShifterOperand(SP));
138 __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex));
139 __ str(R1, Address(R2, (-kWordSize * 29)));
140 __ vldrd(D0, Address(R2, (-kWordSize * 30)));
141 __ vaddd(D0, D0, D0);
142 __ vstrd(D0, Address(R2, (-kWordSize * 30)));
143 __ ldr(R1, Address(R2, (-kWordSize * 29)));
144 __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex));
145 __ mov(PC, ShifterOperand(LR));
146 }
147
148
149 ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) {
150 EXPECT(test != NULL);
151 typedef double (*DoubleVLoadStore)();
152 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry());
153 EXPECT_FLOAT_EQ(2*12.3, res, 0.001);
154 }
155
156
157 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) {
158 __ LoadSImmediate(S0, 12.3f);
159 __ LoadSImmediate(S1, 3.4f);
160 __ vnegs(S0, S0); // -12.3f
161 __ vabss(S0, S0); // 12.3f
162 __ vadds(S0, S0, S1); // 15.7f
163 __ vmuls(S0, S0, S1); // 53.38f
164 __ vsubs(S0, S0, S1); // 49.98f
165 __ vdivs(S0, S0, S1); // 14.7f
166 __ vsqrts(S0, S0); // 3.8340579f
167 __ vmovrs(R0, S0);
168 __ mov(PC, ShifterOperand(LR));
169 }
170
171
172 ASSEMBLER_TEST_RUN(SingleFPOperations, test) {
173 EXPECT(test != NULL);
174 typedef float (*SingleFPOperations)();
175 float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry());
176 EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f);
177 }
178
179
180 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) {
181 __ LoadDImmediate(D0, 12.3, R0);
182 __ LoadDImmediate(D1, 3.4, R0);
183 __ vnegd(D0, D0); // -12.3
184 __ vabsd(D0, D0); // 12.3
185 __ vaddd(D0, D0, D1); // 15.7
186 __ vmuld(D0, D0, D1); // 53.38
187 __ vsubd(D0, D0, D1); // 49.98
188 __ vdivd(D0, D0, D1); // 14.7
189 __ vsqrtd(D0, D0); // 3.8340579
190 __ vmovrrd(R0, R1, D0);
191 __ mov(PC, ShifterOperand(LR));
192 }
193
194
195 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) {
196 EXPECT(test != NULL);
197 typedef double (*DoubleFPOperations)();
198 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry());
199 EXPECT_FLOAT_EQ(3.8340579, res, 0.001);
200 }
201
202
203 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) {
204 __ mov(R3, ShifterOperand(6));
205 __ vmovsr(S3, R3);
206 __ vcvtdi(D1, S3);
207 __ vmovrrd(R0, R1, D1);
208 __ mov(PC, ShifterOperand(LR));
209 }
210
211
212 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) {
213 typedef double (*IntToDoubleConversionCode)();
214 EXPECT(test != NULL);
215 double res = EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode,
216 test->entry());
217 EXPECT_FLOAT_EQ(6.0, res, 0.001);
218 }
219
220
221 ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) {
222 int64_t value = 60000000000LL;
223 __ LoadImmediate(R0, Utils::Low32Bits(value));
224 __ LoadImmediate(R1, Utils::High32Bits(value));
225 __ vmovsr(S0, R0);
226 __ vmovsr(S2, R1);
227 __ vcvtdu(D0, S0);
228 __ vcvtdi(D1, S2);
229 __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0);
230 __ vmlad(D0, D1, D2);
231 __ vmovrrd(R0, R1, D0);
232 __ mov(PC, ShifterOperand(LR));
233 }
234
235
236 ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) {
237 typedef double (*LongToDoubleConversionCode)();
238 EXPECT(test != NULL);
239 double res = EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode,
240 test->entry());
241 EXPECT_FLOAT_EQ(60000000000.0, res, 0.001);
242 }
243
244
245 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) {
246 __ mov(R3, ShifterOperand(6));
247 __ vmovsr(S3, R3);
248 __ vcvtsi(S1, S3);
249 __ vmovrs(R0, S1);
250 __ mov(PC, ShifterOperand(LR));
251 }
252
253
254 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) {
255 typedef float (*IntToFloatConversionCode)();
256 EXPECT(test != NULL);
257 float res = EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, test->entry());
258 EXPECT_FLOAT_EQ(6.0, res, 0.001);
259 }
260
261
262 ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) {
263 __ vmovsr(S1, R0);
264 __ vcvtis(S0, S1);
265 __ vmovrs(R0, S0);
266 __ mov(PC, ShifterOperand(LR));
267 }
268
269
270 ASSEMBLER_TEST_RUN(FloatToIntConversion, test) {
271 typedef int (*FloatToIntConversion)(float arg);
272 EXPECT(test != NULL);
273 EXPECT_EQ(12,
274 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(),
275 12.8f));
276 EXPECT_EQ(INT_MIN,
277 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(),
278 -FLT_MAX));
279 EXPECT_EQ(INT_MAX,
280 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(),
281 FLT_MAX));
282 }
283
284
285 ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) {
286 __ vmovdrr(D1, R0, R1);
287 __ vcvtid(S0, D1);
288 __ vmovrs(R0, S0);
289 __ mov(PC, ShifterOperand(LR));
290 }
291
292
293 ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) {
294 typedef int (*DoubleToIntConversion)(double arg);
295 EXPECT(test != NULL);
296 EXPECT_EQ(12,
297 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(),
298 12.8));
299 EXPECT_EQ(INT_MIN,
300 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(),
301 -DBL_MAX));
302 EXPECT_EQ(INT_MAX,
303 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(),
304 DBL_MAX));
305 }
306
307
308 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) {
309 __ LoadSImmediate(S1, 12.8f);
310 __ vcvtds(D2, S1);
311 __ vmovrrd(R0, R1, D2);
312 __ mov(PC, ShifterOperand(LR));
313 }
314
315
316 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) {
317 typedef double (*FloatToDoubleConversionCode)();
318 EXPECT(test != NULL);
319 double res = EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode,
320 test->entry());
321 EXPECT_FLOAT_EQ(12.8, res, 0.001);
322 }
323
324
325 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) {
326 __ LoadDImmediate(D1, 12.8, R0);
327 __ vcvtsd(S3, D1);
328 __ vmovrs(R0, S3);
329 __ mov(PC, ShifterOperand(LR));
330 }
331
332
333 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) {
334 typedef float (*DoubleToFloatConversionCode)();
335 EXPECT(test != NULL);
336 float res = EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode,
337 test->entry());
338 EXPECT_FLOAT_EQ(12.8, res, 0.001);
339 }
340
341
342 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) {
343 // Test 12.3f vs 12.5f.
344 __ LoadSImmediate(S0, 12.3f);
345 __ LoadSImmediate(S1, 12.5f);
346
347 // Count errors in R0. R0 is zero if no errors found.
348 __ mov(R0, ShifterOperand(0));
349 __ vcmps(S0, S1);
350 __ vmstat();
351 __ add(R0, R0, ShifterOperand(1), VS); // Error if unordered (Nan).
352 __ add(R0, R0, ShifterOperand(2), GT); // Error if greater.
353 __ add(R0, R0, ShifterOperand(4), EQ); // Error if equal.
354 __ add(R0, R0, ShifterOperand(8), PL); // Error if not less.
355
356 // Test NaN.
357 // Create NaN by dividing 0.0f/0.0f.
358 __ LoadSImmediate(S1, 0.0f);
359 __ vdivs(S1, S1, S1);
360 __ vcmps(S1, S1);
361 __ vmstat();
362 __ add(R0, R0, ShifterOperand(16), VC); // Error if not unordered (not Nan).
363
364 // R0 is 0 if all tests passed.
365 __ mov(PC, ShifterOperand(LR));
366 }
367
368
369 ASSEMBLER_TEST_RUN(FloatCompare, test) {
370 EXPECT(test != NULL);
371 typedef int (*FloatCompare)();
372 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(FloatCompare, test->entry()));
373 }
374
375
376 ASSEMBLER_TEST_GENERATE(DoubleCompare, assembler) {
377 // Test 12.3 vs 12.5.
378 __ LoadDImmediate(D0, 12.3, R1);
379 __ LoadDImmediate(D1, 12.5, R1);
380
381 // Count errors in R0. R0 is zero if no errors found.
382 __ mov(R0, ShifterOperand(0));
383 __ vcmpd(D0, D1);
384 __ vmstat();
385 __ add(R0, R0, ShifterOperand(1), VS); // Error if unordered (Nan).
386 __ add(R0, R0, ShifterOperand(2), GT); // Error if greater.
387 __ add(R0, R0, ShifterOperand(4), EQ); // Error if equal.
388 __ add(R0, R0, ShifterOperand(8), PL); // Error if not less.
389
390 // Test NaN.
391 // Create NaN by dividing 0.0/0.0.
392 __ LoadDImmediate(D1, 0.0, R1);
393 __ vdivd(D1, D1, D1);
394 __ vcmpd(D1, D1);
395 __ vmstat();
396 __ add(R0, R0, ShifterOperand(16), VC); // Error if not unordered (not Nan).
397
398 // R0 is 0 if all tests passed.
399 __ mov(PC, ShifterOperand(LR));
400 }
401
402
403 ASSEMBLER_TEST_RUN(DoubleCompare, test) {
404 EXPECT(test != NULL);
405 typedef int (*DoubleCompare)();
406 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(DoubleCompare, test->entry()));
407 }
408
409
410 ASSEMBLER_TEST_GENERATE(Loop, assembler) {
411 Label loop_entry;
412 __ mov(R0, ShifterOperand(1));
413 __ mov(R1, ShifterOperand(2));
414 __ Bind(&loop_entry);
415 __ mov(R0, ShifterOperand(R0, LSL, 1));
416 __ movs(R1, ShifterOperand(R1, LSR, 1));
417 __ b(&loop_entry, NE);
418 __ mov(PC, ShifterOperand(LR));
419 }
420
421
422 ASSEMBLER_TEST_RUN(Loop, test) {
423 EXPECT(test != NULL);
424 typedef int (*Loop)();
425 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Loop, test->entry()));
426 }
427
428
429 ASSEMBLER_TEST_GENERATE(ForwardBranch, assembler) {
430 Label skip;
431 __ mov(R0, ShifterOperand(42));
432 __ b(&skip);
433 __ mov(R0, ShifterOperand(11));
434 __ Bind(&skip);
435 __ mov(PC, ShifterOperand(LR));
436 }
437
438
439 ASSEMBLER_TEST_RUN(ForwardBranch, test) {
440 EXPECT(test != NULL);
441 typedef int (*ForwardBranch)();
442 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(ForwardBranch, test->entry()));
443 }
444
445
446 ASSEMBLER_TEST_GENERATE(LoadStore, assembler) {
447 __ mov(R1, ShifterOperand(123));
448 __ Push(R1);
449 __ Pop(R0);
450 __ mov(PC, ShifterOperand(LR));
451 }
452
453
454 ASSEMBLER_TEST_RUN(LoadStore, test) {
455 EXPECT(test != NULL);
456 typedef int (*LoadStore)();
457 EXPECT_EQ(123, EXECUTE_TEST_CODE_INT32(LoadStore, test->entry()));
458 }
459
460
461 ASSEMBLER_TEST_GENERATE(AddSub, assembler) {
462 __ mov(R1, ShifterOperand(40));
463 __ sub(R1, R1, ShifterOperand(2));
464 __ add(R0, R1, ShifterOperand(4));
465 __ rsbs(R0, R0, ShifterOperand(100));
466 __ rsc(R0, R0, ShifterOperand(100));
467 __ mov(PC, ShifterOperand(LR));
468 }
469
470
471 ASSEMBLER_TEST_RUN(AddSub, test) {
472 EXPECT(test != NULL);
473 typedef int (*AddSub)();
474 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AddSub, test->entry()));
475 }
476
477
478 ASSEMBLER_TEST_GENERATE(Semaphore, assembler) {
479 __ mov(R0, ShifterOperand(40));
480 __ mov(R1, ShifterOperand(42));
481 __ Push(R0);
482 Label retry;
483 __ Bind(&retry);
484 __ ldrex(R0, SP);
485 __ strex(IP, R1, SP); // IP == 0, success
486 __ tst(IP, ShifterOperand(0));
487 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex.
488 __ Pop(R0); // 42
489 __ mov(PC, ShifterOperand(LR));
490 }
491
492
493 ASSEMBLER_TEST_RUN(Semaphore, test) {
494 EXPECT(test != NULL);
495 typedef int (*Semaphore)();
496 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Semaphore, test->entry()));
497 }
498
499
500 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) {
501 __ mov(R0, ShifterOperand(40));
502 __ mov(R1, ShifterOperand(42));
503 __ Push(R0);
504 __ ldrex(R0, SP);
505 __ clrex(); // Simulate a context switch.
506 __ strex(IP, R1, SP); // IP == 1, failure
507 __ Pop(R0); // 40
508 __ add(R0, R0, ShifterOperand(IP));
509 __ mov(PC, ShifterOperand(LR));
510 }
511
512
513 ASSEMBLER_TEST_RUN(FailedSemaphore, test) {
514 EXPECT(test != NULL);
515 typedef int (*FailedSemaphore)();
516 EXPECT_EQ(41, EXECUTE_TEST_CODE_INT32(FailedSemaphore, test->entry()));
517 }
518
519
520 ASSEMBLER_TEST_GENERATE(AndOrr, assembler) {
521 __ mov(R1, ShifterOperand(40));
522 __ mov(R2, ShifterOperand(0));
523 __ and_(R1, R2, ShifterOperand(R1));
524 __ mov(R3, ShifterOperand(42));
525 __ orr(R0, R1, ShifterOperand(R3));
526 __ mov(PC, ShifterOperand(LR));
527 }
528
529
530 ASSEMBLER_TEST_RUN(AndOrr, test) {
531 EXPECT(test != NULL);
532 typedef int (*AndOrr)();
533 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AndOrr, test->entry()));
534 }
535
536
537 ASSEMBLER_TEST_GENERATE(Orrs, assembler) {
538 __ mov(R0, ShifterOperand(0));
539 __ tst(R0, ShifterOperand(R1)); // Set zero-flag.
540 __ orrs(R0, R0, ShifterOperand(1)); // Clear zero-flag.
541 __ mov(PC, ShifterOperand(LR), EQ);
542 __ mov(R0, ShifterOperand(42));
543 __ mov(PC, ShifterOperand(LR), NE); // Only this return should fire.
544 __ mov(R0, ShifterOperand(2));
545 __ mov(PC, ShifterOperand(LR));
546 }
547
548
549 ASSEMBLER_TEST_RUN(Orrs, test) {
550 EXPECT(test != NULL);
551 typedef int (*Orrs)();
552 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Orrs, test->entry()));
553 }
554
555
556 ASSEMBLER_TEST_GENERATE(Multiply, assembler) {
557 __ mov(R1, ShifterOperand(20));
558 __ mov(R2, ShifterOperand(40));
559 __ mul(R3, R2, R1);
560 __ mov(R0, ShifterOperand(R3));
561 __ mov(PC, ShifterOperand(LR));
562 }
563
564
565 ASSEMBLER_TEST_RUN(Multiply, test) {
566 EXPECT(test != NULL);
567 typedef int (*Multiply)();
568 EXPECT_EQ(800, EXECUTE_TEST_CODE_INT32(Multiply, test->entry()));
569 }
570
571
572 ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) {
573 __ vmovsr(S2, R0);
574 __ vmovsr(S4, R2);
575 __ vcvtdi(D1, S2);
576 __ vcvtdi(D2, S4);
577 __ vdivd(D0, D1, D2);
578 __ vcvtid(S0, D0);
579 __ vmovrs(R1, S0); // r1 = r0/r2
580 __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2
581 __ mov(PC, ShifterOperand(LR));
582 }
583
584
585 ASSEMBLER_TEST_RUN(QuotientRemainder, test) {
586 EXPECT(test != NULL);
587 typedef int64_t (*QuotientRemainder)(int64_t dividend, int64_t divisor);
588 EXPECT_EQ(0x1000400000da8LL,
589 EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(),
590 0x12345678, 0x1234));
591 }
592
593
594 ASSEMBLER_TEST_GENERATE(LongMultiply, assembler) {
595 __ Push(R4);
596 __ Mov(IP, R0);
597 __ mul(R4, R2, R1);
598 __ umull(R0, R1, R2, IP);
599 __ mla(R2, IP, R3, R4);
600 __ add(R1, R2, ShifterOperand(R1));
601 __ Pop(R4);
602 __ mov(PC, ShifterOperand(LR));
603 }
604
605
606 ASSEMBLER_TEST_RUN(LongMultiply, test) {
607 EXPECT(test != NULL);
608 typedef int64_t (*LongMultiply)(int64_t operand0, int64_t operand1);
609 EXPECT_EQ(6, EXECUTE_TEST_CODE_INT64_LL(LongMultiply, test->entry(), -3, -2));
610 }
611
612
613 ASSEMBLER_TEST_GENERATE(Clz, assembler) {
614 Label error;
615
616 __ mov(R0, ShifterOperand(0));
617 __ clz(R1, R0);
618 __ cmp(R1, ShifterOperand(32));
619 __ b(&error, NE);
620 __ mov(R2, ShifterOperand(42));
621 __ clz(R2, R2);
622 __ cmp(R2, ShifterOperand(26));
623 __ b(&error, NE);
624 __ mvn(R0, ShifterOperand(0));
625 __ clz(R1, R0);
626 __ cmp(R1, ShifterOperand(0));
627 __ b(&error, NE);
628 __ Lsr(R0, R0, 3);
629 __ clz(R1, R0);
630 __ cmp(R1, ShifterOperand(3));
631 __ b(&error, NE);
632 __ mov(R0, ShifterOperand(0));
633 __ mov(PC, ShifterOperand(LR));
634 __ Bind(&error);
635 __ mov(R0, ShifterOperand(1));
636 __ mov(PC, ShifterOperand(LR));
637 }
638
639
640 ASSEMBLER_TEST_RUN(Clz, test) {
641 EXPECT(test != NULL);
642 typedef int (*Clz)();
643 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Clz, test->entry()));
644 }
645
646
647 ASSEMBLER_TEST_GENERATE(Tst, assembler) {
648 Label skip;
649
650 __ mov(R0, ShifterOperand(42));
651 __ mov(R1, ShifterOperand(40));
652 __ tst(R1, ShifterOperand(0));
653 __ b(&skip, NE);
654 __ mov(R0, ShifterOperand(0));
655 __ Bind(&skip);
656 __ mov(PC, ShifterOperand(LR));
657 }
658
659
660 ASSEMBLER_TEST_RUN(Tst, test) {
661 EXPECT(test != NULL);
662 typedef int (*Tst)();
663 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
664 }
665
666
667 ASSEMBLER_TEST_GENERATE(Lsl, assembler) {
668 Label skip;
669
670 __ mov(R0, ShifterOperand(1));
671 __ mov(R0, ShifterOperand(R0, LSL, 1));
672 __ mov(R1, ShifterOperand(1));
673 __ mov(R0, ShifterOperand(R0, LSL, R1));
674 __ mov(PC, ShifterOperand(LR));
675 }
676
677
678 ASSEMBLER_TEST_RUN(Lsl, test) {
679 EXPECT(test != NULL);
680 typedef int (*Tst)();
681 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
682 }
683
684
685 ASSEMBLER_TEST_GENERATE(Lsr, assembler) {
686 Label skip;
687
688 __ mov(R0, ShifterOperand(4));
689 __ mov(R0, ShifterOperand(R0, LSR, 1));
690 __ mov(R1, ShifterOperand(1));
691 __ mov(R0, ShifterOperand(R0, LSR, R1));
692 __ mov(PC, ShifterOperand(LR));
693 }
694
695
696 ASSEMBLER_TEST_RUN(Lsr, test) {
697 EXPECT(test != NULL);
698 typedef int (*Tst)();
699 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
700 }
701
702
703 ASSEMBLER_TEST_GENERATE(Lsr1, assembler) {
704 Label skip;
705
706 __ mov(R0, ShifterOperand(1));
707 __ Lsl(R0, R0, 31);
708 __ Lsr(R0, R0, 31);
709 __ mov(PC, ShifterOperand(LR));
710 }
711
712
713 ASSEMBLER_TEST_RUN(Lsr1, test) {
714 EXPECT(test != NULL);
715 typedef int (*Tst)();
716 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
717 }
718
719
720 ASSEMBLER_TEST_GENERATE(Asr1, assembler) {
721 Label skip;
722
723 __ mov(R0, ShifterOperand(1));
724 __ Lsl(R0, R0, 31);
725 __ Asr(R0, R0, 31);
726 __ mov(PC, ShifterOperand(LR));
727 }
728
729
730 ASSEMBLER_TEST_RUN(Asr1, test) {
731 EXPECT(test != NULL);
732 typedef int (*Tst)();
733 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
734 }
735
736
737 ASSEMBLER_TEST_GENERATE(Rsb, assembler) {
738 __ mov(R3, ShifterOperand(10));
739 __ rsb(R0, R3, ShifterOperand(42));
740 __ mov(PC, ShifterOperand(LR));
741 }
742
743
744 ASSEMBLER_TEST_RUN(Rsb, test) {
745 EXPECT(test != NULL);
746 typedef int (*Rsb)();
747 EXPECT_EQ(32, EXECUTE_TEST_CODE_INT32(Rsb, test->entry()));
748 }
749
750
751 ASSEMBLER_TEST_GENERATE(Ldrh, assembler) {
752 Label Test1;
753 Label Test2;
754 Label Done;
755
756 __ mov(R1, ShifterOperand(0x11));
757 __ mov(R2, ShifterOperand(SP));
758 __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
759 __ ldrh(R0, Address(R2, (-kWordSize * 30)));
760 __ cmp(R0, ShifterOperand(0x11));
761 __ b(&Test1, EQ);
762 __ mov(R0, ShifterOperand(1));
763 __ b(&Done);
764 __ Bind(&Test1);
765
766 __ mov(R0, ShifterOperand(0));
767 __ strh(R0, Address(R2, (-kWordSize * 30)));
768 __ ldrh(R1, Address(R2, (-kWordSize * 30)));
769 __ cmp(R1, ShifterOperand(0));
770 __ b(&Test2, EQ);
771 __ mov(R0, ShifterOperand(1));
772 __ b(&Done);
773 __ Bind(&Test2);
774
775 __ mov(R0, ShifterOperand(0));
776 __ Bind(&Done);
777 __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
778 __ mov(PC, ShifterOperand(LR));
779 }
780
781
782 ASSEMBLER_TEST_RUN(Ldrh, test) {
783 EXPECT(test != NULL);
784 typedef int (*Tst)();
785 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
786 }
787
788
789 ASSEMBLER_TEST_GENERATE(Ldrsb, assembler) {
790 __ mov(R1, ShifterOperand(0xFF));
791 __ mov(R2, ShifterOperand(SP));
792 __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
793 __ ldrsb(R0, Address(R2, (-kWordSize * 30)));
794 __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
795 __ mov(PC, ShifterOperand(LR));
796 }
797
798
799 ASSEMBLER_TEST_RUN(Ldrsb, test) {
800 EXPECT(test != NULL);
801 typedef int (*Tst)();
802 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
803 }
804
805
806 ASSEMBLER_TEST_GENERATE(Ldrb, assembler) {
807 __ mov(R1, ShifterOperand(0xFF));
808 __ mov(R2, ShifterOperand(SP));
809 __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
810 __ ldrb(R0, Address(R2, (-kWordSize * 30)));
811 __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
812 __ mov(PC, ShifterOperand(LR));
813 }
814
815
816 ASSEMBLER_TEST_RUN(Ldrb, test) {
817 EXPECT(test != NULL);
818 typedef int (*Tst)();
819 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
820 }
821
822
823 ASSEMBLER_TEST_GENERATE(Ldrsh, assembler) {
824 __ mov(R1, ShifterOperand(0xFF));
825 __ mov(R2, ShifterOperand(SP));
826 __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
827 __ ldrsh(R0, Address(R2, (-kWordSize * 30)));
828 __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
829 __ mov(PC, ShifterOperand(LR));
830 }
831
832
833 ASSEMBLER_TEST_RUN(Ldrsh, test) {
834 EXPECT(test != NULL);
835 typedef int (*Tst)();
836 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
837 }
838
839
840 ASSEMBLER_TEST_GENERATE(Ldrh1, assembler) {
841 __ mov(R1, ShifterOperand(0xFF));
842 __ mov(R2, ShifterOperand(SP));
843 __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
844 __ ldrh(R0, Address(R2, (-kWordSize * 30)));
845 __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
846 __ mov(PC, ShifterOperand(LR));
847 }
848
849
850 ASSEMBLER_TEST_RUN(Ldrh1, test) {
851 EXPECT(test != NULL);
852 typedef int (*Tst)();
853 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
854 }
855
856
857 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) {
858 __ Mov(IP, SP);
859 __ strd(R2, Address(SP, (-kWordSize * 30), Address::PreIndex));
860 __ strd(R0, Address(IP, (-kWordSize * 28)));
861 __ ldrd(R2, Address(IP, (-kWordSize * 28)));
862 __ ldrd(R0, Address(SP, (kWordSize * 30), Address::PostIndex));
863 __ sub(R0, R0, ShifterOperand(R2));
864 __ add(R1, R1, ShifterOperand(R3));
865 __ mov(PC, ShifterOperand(LR));
866 }
867
868
869 ASSEMBLER_TEST_RUN(Ldrd, test) {
870 EXPECT(test != NULL);
871 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3);
872 EXPECT_EQ(0x0000444400002222LL, EXECUTE_TEST_CODE_INT64_LL(
873 Tst, test->entry(), 0x0000111100000000LL, 0x0000333300002222LL));
874 }
875
876
877 ASSEMBLER_TEST_GENERATE(Ldm_stm_da, assembler) {
878 __ mov(R0, ShifterOperand(1));
879 __ mov(R1, ShifterOperand(7));
880 __ mov(R2, ShifterOperand(11));
881 __ mov(R3, ShifterOperand(31));
882 __ Push(R5); // We use R5 as accumulator.
883 __ Push(R5);
884 __ Push(R5);
885 __ Push(R5);
886 __ Push(R5);
887 __ Push(R0); // Make room, so we can decrement after.
888 __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
889 __ str(R2, Address(SP)); // Should be a free slot.
890 __ ldr(R5, Address(SP, 1 * kWordSize)); // R0. R5 = +1.
891 __ ldr(IP, Address(SP, 2 * kWordSize)); // R1.
892 __ sub(R5, R5, ShifterOperand(IP)); // -R1. R5 = -6.
893 __ ldr(IP, Address(SP, 3 * kWordSize)); // R2.
894 __ add(R5, R5, ShifterOperand(IP)); // +R2. R5 = +5.
895 __ ldr(IP, Address(SP, 4 * kWordSize)); // R3.
896 __ sub(R5, R5, ShifterOperand(IP)); // -R3. R5 = -26.
897 __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
898 // Same operations again. But this time from the restore registers.
899 __ add(R5, R5, ShifterOperand(R0));
900 __ sub(R5, R5, ShifterOperand(R1));
901 __ add(R5, R5, ShifterOperand(R2));
902 __ sub(R0, R5, ShifterOperand(R3)); // R0 = result = -52.
903 __ Pop(R1); // Remove storage slot.
904 __ Pop(R5); // Restore R5.
905 __ Pop(R5); // Restore R5.
906 __ Pop(R5); // Restore R5.
907 __ Pop(R5); // Restore R5.
908 __ Pop(R5); // Restore R5.
909 __ mov(PC, ShifterOperand(LR));
910 }
911
912
913 ASSEMBLER_TEST_RUN(Ldm_stm_da, test) {
914 EXPECT(test != NULL);
915 typedef int (*Tst)();
916 EXPECT_EQ(-52, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
917 }
918
919
29 } // namespace dart 920 } // namespace dart
30 921
31 #endif // defined TARGET_ARCH_ARM 922 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698