Flutter Engine
The Flutter Engine
assembler_riscv_test.cc
Go to the documentation of this file.
1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
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.
4
5#include "vm/globals.h"
6#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
7
10#include "vm/cpu.h"
11#include "vm/os.h"
12#include "vm/unit_test.h"
13#include "vm/virtual_memory.h"
14
15namespace dart {
16namespace compiler {
17#define __ assembler->
18
19#if defined(PRODUCT)
20#define EXPECT_DISASSEMBLY(expected)
21#else
22#define EXPECT_DISASSEMBLY(expected) \
23 EXPECT_STREQ(expected, test->RelativeDisassembly())
24#endif
25
26// Called from assembler_test.cc.
27// RA: return address.
28// A0: value.
29// A1: growable array.
30// A2: current thread.
31ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
32 __ PushRegister(RA);
33 __ PushNativeCalleeSavedRegisters();
34
35 __ mv(THR, A2);
36 __ RestorePinnedRegisters(); // Setup WRITE_BARRIER_STATE.
37
38 __ StoreIntoObject(A1, FieldAddress(A1, GrowableObjectArray::data_offset()),
39 A0);
40
41 __ PopNativeCalleeSavedRegisters();
42 __ PopRegister(RA);
43 __ ret();
44}
45
46static intx_t Call(intx_t entry,
47 intx_t arg0 = 0,
48 intx_t arg1 = 0,
49 intx_t arg2 = 0,
50 intx_t arg3 = 0) {
51#if defined(USING_SIMULATOR)
52 return Simulator::Current()->Call(entry, arg0, arg1, arg2, arg3);
53#else
54 typedef intx_t (*F)(intx_t, intx_t, intx_t, intx_t);
55 return reinterpret_cast<F>(entry)(arg0, arg1, arg2, arg3);
56#endif
57}
58static float CallF(intx_t entry, intx_t arg0) {
59#if defined(USING_SIMULATOR)
60 return Simulator::Current()->CallF(entry, arg0);
61#else
62 typedef float (*F)(intx_t);
63 return reinterpret_cast<F>(entry)(arg0);
64#endif
65}
66static float CallF(intx_t entry, intx_t arg0, float arg1) {
67#if defined(USING_SIMULATOR)
68 return Simulator::Current()->CallF(entry, arg0, arg1);
69#else
70 typedef float (*F)(intx_t, float);
71 return reinterpret_cast<F>(entry)(arg0, arg1);
72#endif
73}
74static float CallF(intx_t entry, double arg0) {
75#if defined(USING_SIMULATOR)
76 return Simulator::Current()->CallF(entry, arg0);
77#else
78 typedef float (*F)(double);
79 return reinterpret_cast<F>(entry)(arg0);
80#endif
81}
82static float CallF(intx_t entry, float arg0) {
83#if defined(USING_SIMULATOR)
84 return Simulator::Current()->CallF(entry, arg0);
85#else
86 typedef float (*F)(float);
87 return reinterpret_cast<F>(entry)(arg0);
88#endif
89}
90static float CallF(intx_t entry, float arg0, float arg1) {
91#if defined(USING_SIMULATOR)
92 return Simulator::Current()->CallF(entry, arg0, arg1);
93#else
94 typedef float (*F)(float, float);
95 return reinterpret_cast<F>(entry)(arg0, arg1);
96#endif
97}
98static float CallF(intx_t entry, float arg0, float arg1, float arg2) {
99#if defined(USING_SIMULATOR)
100 return Simulator::Current()->CallF(entry, arg0, arg1, arg2);
101#else
102 typedef float (*F)(float, float, float);
103 return reinterpret_cast<F>(entry)(arg0, arg1, arg2);
104#endif
105}
106static intx_t CallI(intx_t entry, float arg0) {
107#if defined(USING_SIMULATOR)
108 return Simulator::Current()->CallI(entry, arg0);
109#else
110 typedef intx_t (*F)(float);
111 return reinterpret_cast<F>(entry)(arg0);
112#endif
113}
114static intx_t CallI(intx_t entry, float arg0, float arg1) {
115#if defined(USING_SIMULATOR)
116 return Simulator::Current()->CallI(entry, arg0, arg1);
117#else
118 typedef intx_t (*F)(float, float);
119 return reinterpret_cast<F>(entry)(arg0, arg1);
120#endif
121}
122static double CallD(intx_t entry, intx_t arg0) {
123#if defined(USING_SIMULATOR)
124 return Simulator::Current()->CallD(entry, arg0);
125#else
126 typedef double (*F)(intx_t);
127 return reinterpret_cast<F>(entry)(arg0);
128#endif
129}
130static double CallD(intx_t entry, intx_t arg0, double arg1) {
131#if defined(USING_SIMULATOR)
132 return Simulator::Current()->CallD(entry, arg0, arg1);
133#else
134 typedef double (*F)(intx_t, double);
135 return reinterpret_cast<F>(entry)(arg0, arg1);
136#endif
137}
138static double CallD(intx_t entry, float arg0) {
139#if defined(USING_SIMULATOR)
140 return Simulator::Current()->CallD(entry, arg0);
141#else
142 typedef double (*F)(float);
143 return reinterpret_cast<F>(entry)(arg0);
144#endif
145}
146static double CallD(intx_t entry, double arg0) {
147#if defined(USING_SIMULATOR)
148 return Simulator::Current()->CallD(entry, arg0);
149#else
150 typedef double (*F)(double);
151 return reinterpret_cast<F>(entry)(arg0);
152#endif
153}
154static double CallD(intx_t entry, double arg0, double arg1) {
155#if defined(USING_SIMULATOR)
156 return Simulator::Current()->CallD(entry, arg0, arg1);
157#else
158 typedef double (*F)(double, double);
159 return reinterpret_cast<F>(entry)(arg0, arg1);
160#endif
161}
162static double CallD(intx_t entry, double arg0, double arg1, double arg2) {
163#if defined(USING_SIMULATOR)
164 return Simulator::Current()->CallD(entry, arg0, arg1, arg2);
165#else
166 typedef double (*F)(double, double, double);
167 return reinterpret_cast<F>(entry)(arg0, arg1, arg2);
168#endif
169}
170static intx_t CallI(intx_t entry, double arg0) {
171#if defined(USING_SIMULATOR)
172 return Simulator::Current()->CallI(entry, arg0);
173#else
174 typedef intx_t (*F)(double);
175 return reinterpret_cast<F>(entry)(arg0);
176#endif
177}
178static intx_t CallI(intx_t entry, double arg0, double arg1) {
179#if defined(USING_SIMULATOR)
180 return Simulator::Current()->CallI(entry, arg0, arg1);
181#else
182 typedef intx_t (*F)(double, double);
183 return reinterpret_cast<F>(entry)(arg0, arg1);
184#endif
185}
186
187ASSEMBLER_TEST_GENERATE(LoadUpperImmediate, assembler) {
188 FLAG_use_compressed_instructions = false;
189 __ SetExtensions(RV_G);
190
191 __ lui(A0, 42 << 16);
192 __ ret();
193}
194ASSEMBLER_TEST_RUN(LoadUpperImmediate, test) {
195 EXPECT_DISASSEMBLY(
196 "002a0537 lui a0, 2752512\n"
197 "00008067 ret\n");
198 EXPECT_EQ(42 << 16, Call(test->entry()));
199}
200
201ASSEMBLER_TEST_GENERATE(AddUpperImmediatePC, assembler) {
202 FLAG_use_compressed_instructions = false;
203 __ SetExtensions(RV_G);
204
205 __ auipc(A0, 0);
206 __ ret();
207}
208ASSEMBLER_TEST_RUN(AddUpperImmediatePC, test) {
209 EXPECT_DISASSEMBLY(
210 "00000517 auipc a0, 0\n"
211 "00008067 ret\n");
212 EXPECT_EQ(test->entry(), static_cast<uintx_t>(Call(test->entry())));
213}
214
215ASSEMBLER_TEST_GENERATE(JumpAndLink, assembler) {
216 FLAG_use_compressed_instructions = false;
217 __ SetExtensions(RV_G);
218
219 Label label1, label2;
220 __ jal(T4, &label1); // Forward.
221 __ sub(A0, T0, T1);
222 __ ret();
223 __ trap();
224
225 __ Bind(&label2);
226 __ li(T1, 7);
227 __ jalr(ZR, T5);
228 __ trap();
229
230 __ Bind(&label1);
231 __ li(T0, 4);
232 __ jal(T5, &label2); // Backward.
233 __ jalr(ZR, T4);
234 __ trap();
235}
236ASSEMBLER_TEST_RUN(JumpAndLink, test) {
237 EXPECT_DISASSEMBLY(
238 "01c00eef jal t4, +28\n"
239 "40628533 sub a0, t0, t1\n"
240 "00008067 ret\n"
241 "00000000 trap\n"
242 "00700313 li t1, 7\n"
243 "000f0067 jr t5\n"
244 "00000000 trap\n"
245 "00400293 li t0, 4\n"
246 "ff1fff6f jal t5, -16\n"
247 "000e8067 jr t4\n"
248 "00000000 trap\n");
249 EXPECT_EQ(-3, Call(test->entry()));
250}
251
252ASSEMBLER_TEST_GENERATE(Jump, assembler) {
253 FLAG_use_compressed_instructions = false;
254 __ SetExtensions(RV_G);
255
256 Label label1, label2;
257 __ j(&label1); // Forward.
258 __ trap();
259 __ Bind(&label2);
260 __ li(T1, 7);
261 __ sub(A0, T0, T1);
262 __ ret();
263 __ Bind(&label1);
264 __ li(T0, 4);
265 __ j(&label2); // Backward.
266 __ trap();
267}
269 EXPECT_DISASSEMBLY(
270 "0140006f j +20\n"
271 "00000000 trap\n"
272 "00700313 li t1, 7\n"
273 "40628533 sub a0, t0, t1\n"
274 "00008067 ret\n"
275 "00400293 li t0, 4\n"
276 "ff1ff06f j -16\n"
277 "00000000 trap\n");
278 EXPECT_EQ(-3, Call(test->entry()));
279}
280
281ASSEMBLER_TEST_GENERATE(JumpAndLinkRegister, assembler) {
282 FLAG_use_compressed_instructions = false;
283 __ SetExtensions(RV_G);
284
285 /* 00 */ __ jalr(T4, A1, 28); // Forward.
286 /* 04 */ __ sub(A0, T0, T1);
287 /* 08 */ __ ret();
288 /* 12 */ __ trap();
289
290 /* 16 */ __ li(T1, 7);
291 /* 20 */ __ jalr(ZR, T5);
292 /* 24 */ __ trap();
293
294 /* 28 */ __ li(T0, 4);
295 /* 32 */ __ jalr(T5, A1, 16); // Backward.
296 /* 36 */ __ jalr(ZR, T4);
297 /* 40 */ __ trap();
298}
299ASSEMBLER_TEST_RUN(JumpAndLinkRegister, test) {
300 EXPECT_DISASSEMBLY(
301 "01c58ee7 jalr t4, 28(a1)\n"
302 "40628533 sub a0, t0, t1\n"
303 "00008067 ret\n"
304 "00000000 trap\n"
305 "00700313 li t1, 7\n"
306 "000f0067 jr t5\n"
307 "00000000 trap\n"
308 "00400293 li t0, 4\n"
309 "01058f67 jalr t5, 16(a1)\n"
310 "000e8067 jr t4\n"
311 "00000000 trap\n");
312 EXPECT_EQ(-3, Call(test->entry(), 0, test->entry()));
313}
314
315ASSEMBLER_TEST_GENERATE(JumpRegister, assembler) {
316 FLAG_use_compressed_instructions = false;
317 __ SetExtensions(RV_G);
318
319 /* 00 */ __ jr(A1, 20); // Forward.
320 /* 04 */ __ trap();
321 /* 08 */ __ li(T1, 7);
322 /* 12 */ __ sub(A0, T0, T1);
323 /* 16 */ __ ret();
324 /* 20 */ __ li(T0, 4);
325 /* 24 */ __ jr(A1, 8); // Backward.
326 /* 28 */ __ trap();
327}
328ASSEMBLER_TEST_RUN(JumpRegister, test) {
329 EXPECT_DISASSEMBLY(
330 "01458067 jr 20(a1)\n"
331 "00000000 trap\n"
332 "00700313 li t1, 7\n"
333 "40628533 sub a0, t0, t1\n"
334 "00008067 ret\n"
335 "00400293 li t0, 4\n"
336 "00858067 jr 8(a1)\n"
337 "00000000 trap\n");
338 EXPECT_EQ(-3, Call(test->entry(), 0, test->entry()));
339}
340
341ASSEMBLER_TEST_GENERATE(BranchEqualForward, assembler) {
342 FLAG_use_compressed_instructions = false;
343 __ SetExtensions(RV_G);
344
345 Label label;
346 __ beq(A0, A1, &label);
347 __ li(A0, 3);
348 __ ret();
349 __ Bind(&label);
350 __ li(A0, 4);
351 __ ret();
352}
353ASSEMBLER_TEST_RUN(BranchEqualForward, test) {
354 EXPECT_DISASSEMBLY(
355 "00b50663 beq a0, a1, +12\n"
356 "00300513 li a0, 3\n"
357 "00008067 ret\n"
358 "00400513 li a0, 4\n"
359 "00008067 ret\n");
360 EXPECT_EQ(4, Call(test->entry(), 1, 1));
361 EXPECT_EQ(3, Call(test->entry(), 1, 0));
362 EXPECT_EQ(3, Call(test->entry(), 1, -1));
363 EXPECT_EQ(3, Call(test->entry(), 0, 1));
364 EXPECT_EQ(4, Call(test->entry(), 0, 0));
365 EXPECT_EQ(3, Call(test->entry(), 0, -1));
366 EXPECT_EQ(3, Call(test->entry(), -1, 1));
367 EXPECT_EQ(3, Call(test->entry(), -1, 0));
368 EXPECT_EQ(4, Call(test->entry(), -1, -1));
369}
370
371ASSEMBLER_TEST_GENERATE(BranchEqualForwardFar, assembler) {
372 FLAG_use_compressed_instructions = false;
373 __ SetExtensions(RV_G);
374
375 Label label;
376 __ beq(A0, A1, &label);
377 __ li(A0, 3);
378 __ ret();
379 for (intptr_t i = 0; i < (1 << 13); i++) {
380 __ ebreak();
381 }
382 __ Bind(&label);
383 __ li(A0, 4);
384 __ ret();
385}
386ASSEMBLER_TEST_RUN(BranchEqualForwardFar, test) {
387 // EXPECT_DISASSEMBLY(constant too big);
388 EXPECT_EQ(4, Call(test->entry(), 1, 1));
389 EXPECT_EQ(3, Call(test->entry(), 1, 0));
390 EXPECT_EQ(3, Call(test->entry(), 1, -1));
391 EXPECT_EQ(3, Call(test->entry(), 0, 1));
392 EXPECT_EQ(4, Call(test->entry(), 0, 0));
393 EXPECT_EQ(3, Call(test->entry(), 0, -1));
394 EXPECT_EQ(3, Call(test->entry(), -1, 1));
395 EXPECT_EQ(3, Call(test->entry(), -1, 0));
396 EXPECT_EQ(4, Call(test->entry(), -1, -1));
397}
398
399ASSEMBLER_TEST_GENERATE(BranchNotEqualForward, assembler) {
400 FLAG_use_compressed_instructions = false;
401 __ SetExtensions(RV_G);
402
403 Label label;
404 __ bne(A0, A1, &label);
405 __ li(A0, 3);
406 __ ret();
407 __ Bind(&label);
408 __ li(A0, 4);
409 __ ret();
410}
411ASSEMBLER_TEST_RUN(BranchNotEqualForward, test) {
412 EXPECT_DISASSEMBLY(
413 "00b51663 bne a0, a1, +12\n"
414 "00300513 li a0, 3\n"
415 "00008067 ret\n"
416 "00400513 li a0, 4\n"
417 "00008067 ret\n");
418 EXPECT_EQ(3, Call(test->entry(), 1, 1));
419 EXPECT_EQ(4, Call(test->entry(), 1, 0));
420 EXPECT_EQ(4, Call(test->entry(), 1, -1));
421 EXPECT_EQ(4, Call(test->entry(), 0, 1));
422 EXPECT_EQ(3, Call(test->entry(), 0, 0));
423 EXPECT_EQ(4, Call(test->entry(), 0, -1));
424 EXPECT_EQ(4, Call(test->entry(), -1, 1));
425 EXPECT_EQ(4, Call(test->entry(), -1, 0));
426 EXPECT_EQ(3, Call(test->entry(), -1, -1));
427}
428
429ASSEMBLER_TEST_GENERATE(BranchNotEqualForwardFar, assembler) {
430 FLAG_use_compressed_instructions = false;
431 __ SetExtensions(RV_G);
432
433 Label label;
434 __ bne(A0, A1, &label);
435 __ li(A0, 3);
436 __ ret();
437 for (intptr_t i = 0; i < (1 << 13); i++) {
438 __ ebreak();
439 }
440 __ Bind(&label);
441 __ li(A0, 4);
442 __ ret();
443}
444ASSEMBLER_TEST_RUN(BranchNotEqualForwardFar, test) {
445 // EXPECT_DISASSEMBLY(constant too big);
446 EXPECT_EQ(3, Call(test->entry(), 1, 1));
447 EXPECT_EQ(4, Call(test->entry(), 1, 0));
448 EXPECT_EQ(4, Call(test->entry(), 1, -1));
449 EXPECT_EQ(4, Call(test->entry(), 0, 1));
450 EXPECT_EQ(3, Call(test->entry(), 0, 0));
451 EXPECT_EQ(4, Call(test->entry(), 0, -1));
452 EXPECT_EQ(4, Call(test->entry(), -1, 1));
453 EXPECT_EQ(4, Call(test->entry(), -1, 0));
454 EXPECT_EQ(3, Call(test->entry(), -1, -1));
455}
456
457ASSEMBLER_TEST_GENERATE(BranchLessThanForward, assembler) {
458 FLAG_use_compressed_instructions = false;
459 __ SetExtensions(RV_G);
460
461 Label label;
462 __ blt(A0, A1, &label);
463 __ li(A0, 3);
464 __ ret();
465 __ Bind(&label);
466 __ li(A0, 4);
467 __ ret();
468}
469ASSEMBLER_TEST_RUN(BranchLessThanForward, test) {
470 EXPECT_DISASSEMBLY(
471 "00b54663 blt a0, a1, +12\n"
472 "00300513 li a0, 3\n"
473 "00008067 ret\n"
474 "00400513 li a0, 4\n"
475 "00008067 ret\n");
476 EXPECT_EQ(3, Call(test->entry(), 1, 1));
477 EXPECT_EQ(3, Call(test->entry(), 1, 0));
478 EXPECT_EQ(3, Call(test->entry(), 1, -1));
479 EXPECT_EQ(4, Call(test->entry(), 0, 1));
480 EXPECT_EQ(3, Call(test->entry(), 0, 0));
481 EXPECT_EQ(3, Call(test->entry(), 0, -1));
482 EXPECT_EQ(4, Call(test->entry(), -1, 1));
483 EXPECT_EQ(4, Call(test->entry(), -1, 0));
484 EXPECT_EQ(3, Call(test->entry(), -1, -1));
485}
486
487ASSEMBLER_TEST_GENERATE(BranchLessThanForwardFar, assembler) {
488 FLAG_use_compressed_instructions = false;
489 __ SetExtensions(RV_G);
490
491 Label label;
492 __ blt(A0, A1, &label);
493 __ li(A0, 3);
494 __ ret();
495 for (intptr_t i = 0; i < (1 << 13); i++) {
496 __ ebreak();
497 }
498 __ Bind(&label);
499 __ li(A0, 4);
500 __ ret();
501}
502ASSEMBLER_TEST_RUN(BranchLessThanForwardFar, test) {
503 // EXPECT_DISASSEMBLY(constant too big);
504 EXPECT_EQ(3, Call(test->entry(), 1, 1));
505 EXPECT_EQ(3, Call(test->entry(), 1, 0));
506 EXPECT_EQ(3, Call(test->entry(), 1, -1));
507 EXPECT_EQ(4, Call(test->entry(), 0, 1));
508 EXPECT_EQ(3, Call(test->entry(), 0, 0));
509 EXPECT_EQ(3, Call(test->entry(), 0, -1));
510 EXPECT_EQ(4, Call(test->entry(), -1, 1));
511 EXPECT_EQ(4, Call(test->entry(), -1, 0));
512 EXPECT_EQ(3, Call(test->entry(), -1, -1));
513}
514
515ASSEMBLER_TEST_GENERATE(BranchLessOrEqualForward, assembler) {
516 FLAG_use_compressed_instructions = false;
517 __ SetExtensions(RV_G);
518
519 Label label;
520 __ ble(A0, A1, &label);
521 __ li(A0, 3);
522 __ ret();
523 __ Bind(&label);
524 __ li(A0, 4);
525 __ ret();
526}
527ASSEMBLER_TEST_RUN(BranchLessOrEqualForward, test) {
528 EXPECT_DISASSEMBLY(
529 "00a5d663 ble a0, a1, +12\n"
530 "00300513 li a0, 3\n"
531 "00008067 ret\n"
532 "00400513 li a0, 4\n"
533 "00008067 ret\n");
534 EXPECT_EQ(4, Call(test->entry(), 1, 1));
535 EXPECT_EQ(3, Call(test->entry(), 1, 0));
536 EXPECT_EQ(3, Call(test->entry(), 1, -1));
537 EXPECT_EQ(4, Call(test->entry(), 0, 1));
538 EXPECT_EQ(4, Call(test->entry(), 0, 0));
539 EXPECT_EQ(3, Call(test->entry(), 0, -1));
540 EXPECT_EQ(4, Call(test->entry(), -1, 1));
541 EXPECT_EQ(4, Call(test->entry(), -1, 0));
542 EXPECT_EQ(4, Call(test->entry(), -1, -1));
543}
544
545ASSEMBLER_TEST_GENERATE(BranchLessOrEqualForwardFar, assembler) {
546 FLAG_use_compressed_instructions = false;
547 __ SetExtensions(RV_G);
548
549 Label label;
550 __ ble(A0, A1, &label);
551 __ li(A0, 3);
552 __ ret();
553 for (intptr_t i = 0; i < (1 << 13); i++) {
554 __ ebreak();
555 }
556 __ Bind(&label);
557 __ li(A0, 4);
558 __ ret();
559}
560ASSEMBLER_TEST_RUN(BranchLessOrEqualForwardFar, test) {
561 // EXPECT_DISASSEMBLY(constant too big);
562 EXPECT_EQ(4, Call(test->entry(), 1, 1));
563 EXPECT_EQ(3, Call(test->entry(), 1, 0));
564 EXPECT_EQ(3, Call(test->entry(), 1, -1));
565 EXPECT_EQ(4, Call(test->entry(), 0, 1));
566 EXPECT_EQ(4, Call(test->entry(), 0, 0));
567 EXPECT_EQ(3, Call(test->entry(), 0, -1));
568 EXPECT_EQ(4, Call(test->entry(), -1, 1));
569 EXPECT_EQ(4, Call(test->entry(), -1, 0));
570 EXPECT_EQ(4, Call(test->entry(), -1, -1));
571}
572
573ASSEMBLER_TEST_GENERATE(BranchGreaterThanForward, assembler) {
574 FLAG_use_compressed_instructions = false;
575 __ SetExtensions(RV_G);
576
577 Label label;
578 __ bgt(A0, A1, &label);
579 __ li(A0, 3);
580 __ ret();
581 __ Bind(&label);
582 __ li(A0, 4);
583 __ ret();
584}
585ASSEMBLER_TEST_RUN(BranchGreaterThanForward, test) {
586 EXPECT_DISASSEMBLY(
587 "00a5c663 blt a1, a0, +12\n"
588 "00300513 li a0, 3\n"
589 "00008067 ret\n"
590 "00400513 li a0, 4\n"
591 "00008067 ret\n");
592 EXPECT_EQ(3, Call(test->entry(), 1, 1));
593 EXPECT_EQ(4, Call(test->entry(), 1, 0));
594 EXPECT_EQ(4, Call(test->entry(), 1, -1));
595 EXPECT_EQ(3, Call(test->entry(), 0, 1));
596 EXPECT_EQ(3, Call(test->entry(), 0, 0));
597 EXPECT_EQ(4, Call(test->entry(), 0, -1));
598 EXPECT_EQ(3, Call(test->entry(), -1, 1));
599 EXPECT_EQ(3, Call(test->entry(), -1, 0));
600 EXPECT_EQ(3, Call(test->entry(), -1, -1));
601}
602
603ASSEMBLER_TEST_GENERATE(BranchGreaterOrEqualForward, assembler) {
604 FLAG_use_compressed_instructions = false;
605 __ SetExtensions(RV_G);
606
607 Label label;
608 __ bge(A0, A1, &label);
609 __ li(A0, 3);
610 __ ret();
611 __ Bind(&label);
612 __ li(A0, 4);
613 __ ret();
614}
615ASSEMBLER_TEST_RUN(BranchGreaterOrEqualForward, test) {
616 EXPECT_DISASSEMBLY(
617 "00b55663 ble a1, a0, +12\n"
618 "00300513 li a0, 3\n"
619 "00008067 ret\n"
620 "00400513 li a0, 4\n"
621 "00008067 ret\n");
622 EXPECT_EQ(4, Call(test->entry(), 1, 1));
623 EXPECT_EQ(4, Call(test->entry(), 1, 0));
624 EXPECT_EQ(4, Call(test->entry(), 1, -1));
625 EXPECT_EQ(3, Call(test->entry(), 0, 1));
626 EXPECT_EQ(4, Call(test->entry(), 0, 0));
627 EXPECT_EQ(4, Call(test->entry(), 0, -1));
628 EXPECT_EQ(3, Call(test->entry(), -1, 1));
629 EXPECT_EQ(3, Call(test->entry(), -1, 0));
630 EXPECT_EQ(4, Call(test->entry(), -1, -1));
631}
632
633ASSEMBLER_TEST_GENERATE(BranchLessThanUnsignedForward, assembler) {
634 FLAG_use_compressed_instructions = false;
635 __ SetExtensions(RV_G);
636
637 Label label;
638 __ bltu(A0, A1, &label);
639 __ li(A0, 3);
640 __ ret();
641 __ Bind(&label);
642 __ li(A0, 4);
643 __ ret();
644}
645ASSEMBLER_TEST_RUN(BranchLessThanUnsignedForward, test) {
646 EXPECT_DISASSEMBLY(
647 "00b56663 bltu a0, a1, +12\n"
648 "00300513 li a0, 3\n"
649 "00008067 ret\n"
650 "00400513 li a0, 4\n"
651 "00008067 ret\n");
652 EXPECT_EQ(3, Call(test->entry(), 1, 1));
653 EXPECT_EQ(3, Call(test->entry(), 1, 0));
654 EXPECT_EQ(4, Call(test->entry(), 1, -1));
655 EXPECT_EQ(4, Call(test->entry(), 0, 1));
656 EXPECT_EQ(3, Call(test->entry(), 0, 0));
657 EXPECT_EQ(4, Call(test->entry(), 0, -1));
658 EXPECT_EQ(3, Call(test->entry(), -1, 1));
659 EXPECT_EQ(3, Call(test->entry(), -1, 0));
660 EXPECT_EQ(3, Call(test->entry(), -1, -1));
661}
662
663ASSEMBLER_TEST_GENERATE(BranchLessOrEqualUnsignedForward, assembler) {
664 FLAG_use_compressed_instructions = false;
665 __ SetExtensions(RV_G);
666
667 Label label;
668 __ bleu(A0, A1, &label);
669 __ li(A0, 3);
670 __ ret();
671 __ Bind(&label);
672 __ li(A0, 4);
673 __ ret();
674}
675ASSEMBLER_TEST_RUN(BranchLessOrEqualUnsignedForward, test) {
676 EXPECT_DISASSEMBLY(
677 "00a5f663 bleu a0, a1, +12\n"
678 "00300513 li a0, 3\n"
679 "00008067 ret\n"
680 "00400513 li a0, 4\n"
681 "00008067 ret\n");
682 EXPECT_EQ(4, Call(test->entry(), 1, 1));
683 EXPECT_EQ(3, Call(test->entry(), 1, 0));
684 EXPECT_EQ(4, Call(test->entry(), 1, -1));
685 EXPECT_EQ(4, Call(test->entry(), 0, 1));
686 EXPECT_EQ(4, Call(test->entry(), 0, 0));
687 EXPECT_EQ(4, Call(test->entry(), 0, -1));
688 EXPECT_EQ(3, Call(test->entry(), -1, 1));
689 EXPECT_EQ(3, Call(test->entry(), -1, 0));
690 EXPECT_EQ(4, Call(test->entry(), -1, -1));
691}
692
693ASSEMBLER_TEST_GENERATE(BranchGreaterThanUnsignedForward, assembler) {
694 FLAG_use_compressed_instructions = false;
695 __ SetExtensions(RV_G);
696
697 Label label;
698 __ bgtu(A0, A1, &label);
699 __ li(A0, 3);
700 __ ret();
701 __ Bind(&label);
702 __ li(A0, 4);
703 __ ret();
704}
705ASSEMBLER_TEST_RUN(BranchGreaterThanUnsignedForward, test) {
706 EXPECT_DISASSEMBLY(
707 "00a5e663 bltu a1, a0, +12\n"
708 "00300513 li a0, 3\n"
709 "00008067 ret\n"
710 "00400513 li a0, 4\n"
711 "00008067 ret\n");
712 EXPECT_EQ(3, Call(test->entry(), 1, 1));
713 EXPECT_EQ(4, Call(test->entry(), 1, 0));
714 EXPECT_EQ(3, Call(test->entry(), 1, -1));
715 EXPECT_EQ(3, Call(test->entry(), 0, 1));
716 EXPECT_EQ(3, Call(test->entry(), 0, 0));
717 EXPECT_EQ(3, Call(test->entry(), 0, -1));
718 EXPECT_EQ(4, Call(test->entry(), -1, 1));
719 EXPECT_EQ(4, Call(test->entry(), -1, 0));
720 EXPECT_EQ(3, Call(test->entry(), -1, -1));
721}
722
723ASSEMBLER_TEST_GENERATE(BranchGreaterOrEqualUnsignedForward, assembler) {
724 FLAG_use_compressed_instructions = false;
725 __ SetExtensions(RV_G);
726
727 Label label;
728 __ bgeu(A0, A1, &label);
729 __ li(A0, 3);
730 __ ret();
731 __ Bind(&label);
732 __ li(A0, 4);
733 __ ret();
734}
735ASSEMBLER_TEST_RUN(BranchGreaterOrEqualUnsignedForward, test) {
736 EXPECT_DISASSEMBLY(
737 "00b57663 bleu a1, a0, +12\n"
738 "00300513 li a0, 3\n"
739 "00008067 ret\n"
740 "00400513 li a0, 4\n"
741 "00008067 ret\n");
742 EXPECT_EQ(4, Call(test->entry(), 1, 1));
743 EXPECT_EQ(4, Call(test->entry(), 1, 0));
744 EXPECT_EQ(3, Call(test->entry(), 1, -1));
745 EXPECT_EQ(3, Call(test->entry(), 0, 1));
746 EXPECT_EQ(4, Call(test->entry(), 0, 0));
747 EXPECT_EQ(3, Call(test->entry(), 0, -1));
748 EXPECT_EQ(4, Call(test->entry(), -1, 1));
749 EXPECT_EQ(4, Call(test->entry(), -1, 0));
750 EXPECT_EQ(4, Call(test->entry(), -1, -1));
751}
752
753ASSEMBLER_TEST_GENERATE(LoadByte_0, assembler) {
754 FLAG_use_compressed_instructions = false;
755 __ SetExtensions(RV_G);
756 __ lb(A0, Address(A0, 0));
757 __ ret();
758}
759ASSEMBLER_TEST_RUN(LoadByte_0, test) {
760 EXPECT_DISASSEMBLY(
761 "00050503 lb a0, 0(a0)\n"
762 "00008067 ret\n");
763
764 uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
765 values[0] = 0xAB;
766 values[1] = 0xCD;
767 values[2] = 0xEF;
768 EXPECT_EQ(-51, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
769 free(values);
770}
771
772ASSEMBLER_TEST_GENERATE(LoadByte_Pos, assembler) {
773 FLAG_use_compressed_instructions = false;
774 __ SetExtensions(RV_G);
775 __ lb(A0, Address(A0, 1));
776 __ ret();
777}
778ASSEMBLER_TEST_RUN(LoadByte_Pos, test) {
779 EXPECT_DISASSEMBLY(
780 "00150503 lb a0, 1(a0)\n"
781 "00008067 ret\n");
782
783 uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
784 values[0] = 0xAB;
785 values[1] = 0xCD;
786 values[2] = 0xEF;
787
788 EXPECT_EQ(-17, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
789 free(values);
790}
791
792ASSEMBLER_TEST_GENERATE(LoadByte_Neg, assembler) {
793 FLAG_use_compressed_instructions = false;
794 __ SetExtensions(RV_G);
795 __ lb(A0, Address(A0, -1));
796 __ ret();
797}
798ASSEMBLER_TEST_RUN(LoadByte_Neg, test) {
799 EXPECT_DISASSEMBLY(
800 "fff50503 lb a0, -1(a0)\n"
801 "00008067 ret\n");
802
803 uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
804 values[0] = 0xAB;
805 values[1] = 0xCD;
806 values[2] = 0xEF;
807
808 EXPECT_EQ(-85, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
809 free(values);
810}
811
812ASSEMBLER_TEST_GENERATE(LoadByteUnsigned_0, assembler) {
813 FLAG_use_compressed_instructions = false;
814 __ SetExtensions(RV_G);
815 __ lbu(A0, Address(A0, 0));
816 __ ret();
817}
818ASSEMBLER_TEST_RUN(LoadByteUnsigned_0, test) {
819 EXPECT_DISASSEMBLY(
820 "00054503 lbu a0, 0(a0)\n"
821 "00008067 ret\n");
822
823 uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
824 values[0] = 0xAB;
825 values[1] = 0xCD;
826 values[2] = 0xEF;
827
828 EXPECT_EQ(0xCD, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
829 free(values);
830}
831
832ASSEMBLER_TEST_GENERATE(LoadByteUnsigned_Pos, assembler) {
833 FLAG_use_compressed_instructions = false;
834 __ SetExtensions(RV_G);
835 __ lbu(A0, Address(A0, 1));
836 __ ret();
837}
838ASSEMBLER_TEST_RUN(LoadByteUnsigned_Pos, test) {
839 EXPECT_DISASSEMBLY(
840 "00154503 lbu a0, 1(a0)\n"
841 "00008067 ret\n");
842
843 uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
844 values[0] = 0xAB;
845 values[1] = 0xCD;
846 values[2] = 0xEF;
847
848 EXPECT_EQ(0xEF, Call(test->entry(), reinterpret_cast<intx_t>((&values[1]))));
849 free(values);
850}
851
852ASSEMBLER_TEST_GENERATE(LoadByteUnsigned_Neg, assembler) {
853 FLAG_use_compressed_instructions = false;
854 __ SetExtensions(RV_G);
855 __ lbu(A0, Address(A0, -1));
856 __ ret();
857}
858ASSEMBLER_TEST_RUN(LoadByteUnsigned_Neg, test) {
859 EXPECT_DISASSEMBLY(
860 "fff54503 lbu a0, -1(a0)\n"
861 "00008067 ret\n");
862
863 uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
864 values[0] = 0xAB;
865 values[1] = 0xCD;
866 values[2] = 0xEF;
867
868 EXPECT_EQ(0xAB, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
869}
870
871ASSEMBLER_TEST_GENERATE(LoadHalfword_0, assembler) {
872 FLAG_use_compressed_instructions = false;
873 __ SetExtensions(RV_G);
874 __ lh(A0, Address(A0, 0));
875 __ ret();
876}
877ASSEMBLER_TEST_RUN(LoadHalfword_0, test) {
878 EXPECT_DISASSEMBLY(
879 "00051503 lh a0, 0(a0)\n"
880 "00008067 ret\n");
881
882 uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
883 values[0] = 0xAB01;
884 values[1] = 0xCD02;
885 values[2] = 0xEF03;
886
887 EXPECT_EQ(-13054, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
888}
889ASSEMBLER_TEST_GENERATE(LoadHalfword_Pos, assembler) {
890 FLAG_use_compressed_instructions = false;
891 __ SetExtensions(RV_G);
892 __ lh(A0, Address(A0, 2));
893 __ ret();
894}
895ASSEMBLER_TEST_RUN(LoadHalfword_Pos, test) {
896 EXPECT_DISASSEMBLY(
897 "00251503 lh a0, 2(a0)\n"
898 "00008067 ret\n");
899
900 uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
901 values[0] = 0xAB01;
902 values[1] = 0xCD02;
903 values[2] = 0xEF03;
904
905 EXPECT_EQ(-4349, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
906}
907ASSEMBLER_TEST_GENERATE(LoadHalfword_Neg, assembler) {
908 FLAG_use_compressed_instructions = false;
909 __ SetExtensions(RV_G);
910 __ lh(A0, Address(A0, -2));
911 __ ret();
912}
913ASSEMBLER_TEST_RUN(LoadHalfword_Neg, test) {
914 EXPECT_DISASSEMBLY(
915 "ffe51503 lh a0, -2(a0)\n"
916 "00008067 ret\n");
917
918 uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
919 values[0] = 0xAB01;
920 values[1] = 0xCD02;
921 values[2] = 0xEF03;
922
923 EXPECT_EQ(-21759, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
924}
925
926ASSEMBLER_TEST_GENERATE(LoadHalfwordUnsigned_0, assembler) {
927 FLAG_use_compressed_instructions = false;
928 __ SetExtensions(RV_G);
929 __ lhu(A0, Address(A0, 0));
930 __ ret();
931}
932ASSEMBLER_TEST_RUN(LoadHalfwordUnsigned_0, test) {
933 EXPECT_DISASSEMBLY(
934 "00055503 lhu a0, 0(a0)\n"
935 "00008067 ret\n");
936
937 uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
938 values[0] = 0xAB01;
939 values[1] = 0xCD02;
940 values[2] = 0xEF03;
941
942 EXPECT_EQ(0xCD02, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
943}
944
945ASSEMBLER_TEST_GENERATE(LoadHalfwordUnsigned_Pos, assembler) {
946 FLAG_use_compressed_instructions = false;
947 __ SetExtensions(RV_G);
948 __ lhu(A0, Address(A0, 2));
949 __ ret();
950}
951ASSEMBLER_TEST_RUN(LoadHalfwordUnsigned_Pos, test) {
952 EXPECT_DISASSEMBLY(
953 "00255503 lhu a0, 2(a0)\n"
954 "00008067 ret\n");
955
956 uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
957 values[0] = 0xAB01;
958 values[1] = 0xCD02;
959 values[2] = 0xEF03;
960
961 EXPECT_EQ(0xEF03, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
962}
963ASSEMBLER_TEST_GENERATE(LoadHalfwordUnsigned_Neg, assembler) {
964 FLAG_use_compressed_instructions = false;
965 __ SetExtensions(RV_G);
966 __ lhu(A0, Address(A0, -2));
967 __ ret();
968}
969ASSEMBLER_TEST_RUN(LoadHalfwordUnsigned_Neg, test) {
970 EXPECT_DISASSEMBLY(
971 "ffe55503 lhu a0, -2(a0)\n"
972 "00008067 ret\n");
973
974 uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
975 values[0] = 0xAB01;
976 values[1] = 0xCD02;
977 values[2] = 0xEF03;
978
979 EXPECT_EQ(0xAB01, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
980}
981
982ASSEMBLER_TEST_GENERATE(LoadWord_0, assembler) {
983 FLAG_use_compressed_instructions = false;
984 __ SetExtensions(RV_G);
985 __ lw(A0, Address(A0, 0));
986 __ ret();
987}
988ASSEMBLER_TEST_RUN(LoadWord_0, test) {
989 EXPECT_DISASSEMBLY(
990 "00052503 lw a0, 0(a0)\n"
991 "00008067 ret\n");
992
993 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
994 values[0] = 0xAB010203;
995 values[1] = 0xCD020405;
996 values[2] = 0xEF030607;
997
998 EXPECT_EQ(-855505915,
999 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1000}
1001ASSEMBLER_TEST_GENERATE(LoadWord_Pos, assembler) {
1002 FLAG_use_compressed_instructions = false;
1003 __ SetExtensions(RV_G);
1004 __ lw(A0, Address(A0, 4));
1005 __ ret();
1006}
1007ASSEMBLER_TEST_RUN(LoadWord_Pos, test) {
1008 EXPECT_DISASSEMBLY(
1009 "00452503 lw a0, 4(a0)\n"
1010 "00008067 ret\n");
1011
1012 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1013 values[0] = 0xAB010203;
1014 values[1] = 0xCD020405;
1015 values[2] = 0xEF030607;
1016
1017 EXPECT_EQ(-285014521,
1018 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1019}
1020ASSEMBLER_TEST_GENERATE(LoadWord_Neg, assembler) {
1021 FLAG_use_compressed_instructions = false;
1022 __ SetExtensions(RV_G);
1023 __ lw(A0, Address(A0, -4));
1024 __ ret();
1025}
1026ASSEMBLER_TEST_RUN(LoadWord_Neg, test) {
1027 EXPECT_DISASSEMBLY(
1028 "ffc52503 lw a0, -4(a0)\n"
1029 "00008067 ret\n");
1030
1031 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1032 values[0] = 0xAB010203;
1033 values[1] = 0xCD020405;
1034 values[2] = 0xEF030607;
1035
1036 EXPECT_EQ(-1425997309,
1037 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1038}
1039
1040ASSEMBLER_TEST_GENERATE(StoreWord_0, assembler) {
1041 FLAG_use_compressed_instructions = false;
1042 __ SetExtensions(RV_G);
1043 __ sw(A1, Address(A0, 0));
1044 __ ret();
1045}
1046ASSEMBLER_TEST_RUN(StoreWord_0, test) {
1047 EXPECT_DISASSEMBLY(
1048 "00b52023 sw a1, 0(a0)\n"
1049 "00008067 ret\n");
1050
1051 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1052 values[0] = 0;
1053 values[1] = 0;
1054 values[2] = 0;
1055
1056 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD020405);
1057 EXPECT_EQ(0u, values[0]);
1058 EXPECT_EQ(0xCD020405, values[1]);
1059 EXPECT_EQ(0u, values[2]);
1060}
1061ASSEMBLER_TEST_GENERATE(StoreWord_Pos, assembler) {
1062 FLAG_use_compressed_instructions = false;
1063 __ SetExtensions(RV_G);
1064 __ sw(A1, Address(A0, 4));
1065 __ ret();
1066}
1067ASSEMBLER_TEST_RUN(StoreWord_Pos, test) {
1068 EXPECT_DISASSEMBLY(
1069 "00b52223 sw a1, 4(a0)\n"
1070 "00008067 ret\n");
1071
1072 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1073 values[0] = 0;
1074 values[1] = 0;
1075 values[2] = 0;
1076
1077 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF030607);
1078 EXPECT_EQ(0u, values[0]);
1079 EXPECT_EQ(0u, values[1]);
1080 EXPECT_EQ(0xEF030607, values[2]);
1081}
1082ASSEMBLER_TEST_GENERATE(StoreWord_Neg, assembler) {
1083 FLAG_use_compressed_instructions = false;
1084 __ SetExtensions(RV_G);
1085 __ sw(A1, Address(A0, -4));
1086 __ ret();
1087}
1088ASSEMBLER_TEST_RUN(StoreWord_Neg, test) {
1089 EXPECT_DISASSEMBLY(
1090 "feb52e23 sw a1, -4(a0)\n"
1091 "00008067 ret\n");
1092
1093 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1094 values[0] = 0;
1095 values[1] = 0;
1096 values[2] = 0;
1097
1098 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xAB010203);
1099 EXPECT_EQ(0xAB010203, values[0]);
1100 EXPECT_EQ(0u, values[1]);
1101 EXPECT_EQ(0u, values[2]);
1102}
1103
1104#if XLEN >= 64
1105ASSEMBLER_TEST_GENERATE(LoadWordUnsigned_0, assembler) {
1106 FLAG_use_compressed_instructions = false;
1107 __ SetExtensions(RV_G);
1108 __ lwu(A0, Address(A0, 0));
1109 __ ret();
1110}
1111ASSEMBLER_TEST_RUN(LoadWordUnsigned_0, test) {
1112 EXPECT_DISASSEMBLY(
1113 "00056503 lwu a0, 0(a0)\n"
1114 "00008067 ret\n");
1115
1116 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1117 values[0] = 0xAB010203;
1118 values[1] = 0xCD020405;
1119 values[2] = 0xEF030607;
1120
1121 EXPECT_EQ(0xCD020405,
1122 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1123}
1124ASSEMBLER_TEST_GENERATE(LoadWordUnsigned_Pos, assembler) {
1125 FLAG_use_compressed_instructions = false;
1126 __ SetExtensions(RV_G);
1127 __ lwu(A0, Address(A0, 4));
1128 __ ret();
1129}
1130ASSEMBLER_TEST_RUN(LoadWordUnsigned_Pos, test) {
1131 EXPECT_DISASSEMBLY(
1132 "00456503 lwu a0, 4(a0)\n"
1133 "00008067 ret\n");
1134
1135 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1136 values[0] = 0xAB010203;
1137 values[1] = 0xCD020405;
1138 values[2] = 0xEF030607;
1139
1140 EXPECT_EQ(0xEF030607,
1141 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1142}
1143ASSEMBLER_TEST_GENERATE(LoadWordUnsigned_Neg, assembler) {
1144 FLAG_use_compressed_instructions = false;
1145 __ SetExtensions(RV_G);
1146 __ lwu(A0, Address(A0, -4));
1147 __ ret();
1148}
1149ASSEMBLER_TEST_RUN(LoadWordUnsigned_Neg, test) {
1150 EXPECT_DISASSEMBLY(
1151 "ffc56503 lwu a0, -4(a0)\n"
1152 "00008067 ret\n");
1153
1154 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
1155 values[0] = 0xAB010203;
1156 values[1] = 0xCD020405;
1157 values[2] = 0xEF030607;
1158
1159 EXPECT_EQ(0xAB010203,
1160 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1161}
1162
1163ASSEMBLER_TEST_GENERATE(LoadDoubleWord_0, assembler) {
1164 FLAG_use_compressed_instructions = false;
1165 __ SetExtensions(RV_G);
1166 __ ld(A0, Address(A0, 0));
1167 __ ret();
1168}
1169ASSEMBLER_TEST_RUN(LoadDoubleWord_0, test) {
1170 EXPECT_DISASSEMBLY(
1171 "00053503 ld a0, 0(a0)\n"
1172 "00008067 ret\n");
1173
1174 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
1175 values[0] = 0xAB01020304050607;
1176 values[1] = 0xCD02040505060708;
1177 values[2] = 0xEF03060708090A0B;
1178
1179 EXPECT_EQ(-3674369926375274744,
1180 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1181}
1182ASSEMBLER_TEST_GENERATE(LoadDoubleWord_Pos, assembler) {
1183 FLAG_use_compressed_instructions = false;
1184 __ SetExtensions(RV_G);
1185 __ ld(A0, Address(A0, 8));
1186 __ ret();
1187}
1188ASSEMBLER_TEST_RUN(LoadDoubleWord_Pos, test) {
1189 EXPECT_DISASSEMBLY(
1190 "00853503 ld a0, 8(a0)\n"
1191 "00008067 ret\n");
1192
1193 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
1194 values[0] = 0xAB01020304050607;
1195 values[1] = 0xCD02040505060708;
1196 values[2] = 0xEF03060708090A0B;
1197
1198 EXPECT_EQ(-1224128046445295093,
1199 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1200}
1201ASSEMBLER_TEST_GENERATE(LoadDoubleWord_Neg, assembler) {
1202 FLAG_use_compressed_instructions = false;
1203 __ SetExtensions(RV_G);
1204 __ ld(A0, Address(A0, -8));
1205 __ ret();
1206}
1207ASSEMBLER_TEST_RUN(LoadDoubleWord_Neg, test) {
1208 EXPECT_DISASSEMBLY(
1209 "ff853503 ld a0, -8(a0)\n"
1210 "00008067 ret\n");
1211
1212 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
1213 values[0] = 0xAB01020304050607;
1214 values[1] = 0xCD02040505060708;
1215 values[2] = 0xEF03060708090A0B;
1216
1217 EXPECT_EQ(-6124611806271568377,
1218 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
1219}
1220
1221ASSEMBLER_TEST_GENERATE(StoreDoubleWord_0, assembler) {
1222 FLAG_use_compressed_instructions = false;
1223 __ SetExtensions(RV_G);
1224 __ sd(A1, Address(A0, 0));
1225 __ ret();
1226}
1227ASSEMBLER_TEST_RUN(StoreDoubleWord_0, test) {
1228 EXPECT_DISASSEMBLY(
1229 "00b53023 sd a1, 0(a0)\n"
1230 "00008067 ret\n");
1231
1232 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
1233 values[0] = 0;
1234 values[1] = 0;
1235 values[2] = 0;
1236
1237 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD02040505060708);
1238 EXPECT_EQ(0u, values[0]);
1239 EXPECT_EQ(0xCD02040505060708, values[1]);
1240 EXPECT_EQ(0u, values[2]);
1241}
1242ASSEMBLER_TEST_GENERATE(StoreDoubleWord_Pos, assembler) {
1243 FLAG_use_compressed_instructions = false;
1244 __ SetExtensions(RV_G);
1245 __ sd(A1, Address(A0, 8));
1246 __ ret();
1247}
1248ASSEMBLER_TEST_RUN(StoreDoubleWord_Pos, test) {
1249 EXPECT_DISASSEMBLY(
1250 "00b53423 sd a1, 8(a0)\n"
1251 "00008067 ret\n");
1252
1253 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
1254 values[0] = 0;
1255 values[1] = 0;
1256 values[2] = 0;
1257
1258 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF03060708090A0B);
1259 EXPECT_EQ(0u, values[0]);
1260 EXPECT_EQ(0u, values[1]);
1261 EXPECT_EQ(0xEF03060708090A0B, values[2]);
1262}
1263ASSEMBLER_TEST_GENERATE(StoreDoubleWord_Neg, assembler) {
1264 FLAG_use_compressed_instructions = false;
1265 __ SetExtensions(RV_G);
1266 __ sd(A1, Address(A0, -8));
1267 __ ret();
1268}
1269ASSEMBLER_TEST_RUN(StoreDoubleWord_Neg, test) {
1270 EXPECT_DISASSEMBLY(
1271 "feb53c23 sd a1, -8(a0)\n"
1272 "00008067 ret\n");
1273
1274 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
1275 values[0] = 0;
1276 values[1] = 0;
1277 values[2] = 0;
1278
1279 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xAB01020304050607);
1280 EXPECT_EQ(0xAB01020304050607, values[0]);
1281 EXPECT_EQ(0u, values[1]);
1282 EXPECT_EQ(0u, values[2]);
1283}
1284#endif
1285
1286ASSEMBLER_TEST_GENERATE(AddImmediate1, assembler) {
1287 FLAG_use_compressed_instructions = false;
1288 __ SetExtensions(RV_G);
1289 __ addi(A0, A0, 42);
1290 __ ret();
1291}
1292ASSEMBLER_TEST_RUN(AddImmediate1, test) {
1293 EXPECT_DISASSEMBLY(
1294 "02a50513 addi a0, a0, 42\n"
1295 "00008067 ret\n");
1296 EXPECT_EQ(42, Call(test->entry(), 0));
1297 EXPECT_EQ(40, Call(test->entry(), -2));
1298 EXPECT_EQ(0, Call(test->entry(), -42));
1299}
1300
1301ASSEMBLER_TEST_GENERATE(AddImmediate2, assembler) {
1302 FLAG_use_compressed_instructions = false;
1303 __ SetExtensions(RV_G);
1304 __ addi(A0, A0, -42);
1305 __ ret();
1306}
1307ASSEMBLER_TEST_RUN(AddImmediate2, test) {
1308 EXPECT_DISASSEMBLY(
1309 "fd650513 addi a0, a0, -42\n"
1310 "00008067 ret\n");
1311 EXPECT_EQ(-42, Call(test->entry(), 0));
1312 EXPECT_EQ(-44, Call(test->entry(), -2));
1313 EXPECT_EQ(38, Call(test->entry(), 80));
1314}
1315
1316ASSEMBLER_TEST_GENERATE(SetLessThanImmediate1, assembler) {
1317 FLAG_use_compressed_instructions = false;
1318 __ SetExtensions(RV_G);
1319 __ slti(A0, A0, 7);
1320 __ ret();
1321}
1322ASSEMBLER_TEST_RUN(SetLessThanImmediate1, test) {
1323 EXPECT_DISASSEMBLY(
1324 "00752513 slti a0, a0, 7\n"
1325 "00008067 ret\n");
1326 EXPECT_EQ(1, Call(test->entry(), 6));
1327 EXPECT_EQ(0, Call(test->entry(), 7));
1328 EXPECT_EQ(0, Call(test->entry(), 8));
1329 EXPECT_EQ(1, Call(test->entry(), -6));
1330 EXPECT_EQ(1, Call(test->entry(), -7));
1331 EXPECT_EQ(1, Call(test->entry(), -8));
1332}
1333
1334ASSEMBLER_TEST_GENERATE(SetLessThanImmediate2, assembler) {
1335 FLAG_use_compressed_instructions = false;
1336 __ SetExtensions(RV_G);
1337 __ slti(A0, A0, -7);
1338 __ ret();
1339}
1340ASSEMBLER_TEST_RUN(SetLessThanImmediate2, test) {
1341 EXPECT_DISASSEMBLY(
1342 "ff952513 slti a0, a0, -7\n"
1343 "00008067 ret\n");
1344 EXPECT_EQ(0, Call(test->entry(), 6));
1345 EXPECT_EQ(0, Call(test->entry(), 7));
1346 EXPECT_EQ(0, Call(test->entry(), 8));
1347 EXPECT_EQ(0, Call(test->entry(), -6));
1348 EXPECT_EQ(0, Call(test->entry(), -7));
1349 EXPECT_EQ(1, Call(test->entry(), -8));
1350}
1351
1352ASSEMBLER_TEST_GENERATE(SetLessThanImmediateUnsigned1, assembler) {
1353 FLAG_use_compressed_instructions = false;
1354 __ SetExtensions(RV_G);
1355 __ sltiu(A0, A0, 7);
1356 __ ret();
1357}
1358ASSEMBLER_TEST_RUN(SetLessThanImmediateUnsigned1, test) {
1359 EXPECT_DISASSEMBLY(
1360 "00753513 sltiu a0, a0, 7\n"
1361 "00008067 ret\n");
1362 EXPECT_EQ(1, Call(test->entry(), 6));
1363 EXPECT_EQ(0, Call(test->entry(), 7));
1364 EXPECT_EQ(0, Call(test->entry(), 8));
1365 EXPECT_EQ(0, Call(test->entry(), -6));
1366 EXPECT_EQ(0, Call(test->entry(), -7));
1367 EXPECT_EQ(0, Call(test->entry(), -8));
1368}
1369
1370ASSEMBLER_TEST_GENERATE(SetLessThanImmediateUnsigned2, assembler) {
1371 FLAG_use_compressed_instructions = false;
1372 __ SetExtensions(RV_G);
1373 __ sltiu(A0, A0, -7);
1374 __ ret();
1375}
1376ASSEMBLER_TEST_RUN(SetLessThanImmediateUnsigned2, test) {
1377 EXPECT_DISASSEMBLY(
1378 "ff953513 sltiu a0, a0, -7\n"
1379 "00008067 ret\n");
1380 EXPECT_EQ(1, Call(test->entry(), 6));
1381 EXPECT_EQ(1, Call(test->entry(), 7));
1382 EXPECT_EQ(1, Call(test->entry(), 8));
1383 EXPECT_EQ(0, Call(test->entry(), -6));
1384 EXPECT_EQ(0, Call(test->entry(), -7));
1385 EXPECT_EQ(1, Call(test->entry(), -8));
1386}
1387
1388ASSEMBLER_TEST_GENERATE(XorImmediate1, assembler) {
1389 FLAG_use_compressed_instructions = false;
1390 __ SetExtensions(RV_G);
1391 __ xori(A0, A0, 42);
1392 __ ret();
1393}
1394ASSEMBLER_TEST_RUN(XorImmediate1, test) {
1395 EXPECT_DISASSEMBLY(
1396 "02a54513 xori a0, a0, 42\n"
1397 "00008067 ret\n");
1398 EXPECT_EQ(42, Call(test->entry(), 0));
1399 EXPECT_EQ(43, Call(test->entry(), 1));
1400 EXPECT_EQ(32, Call(test->entry(), 10));
1401 EXPECT_EQ(-43, Call(test->entry(), -1));
1402 EXPECT_EQ(-36, Call(test->entry(), -10));
1403}
1404
1405ASSEMBLER_TEST_GENERATE(XorImmediate2, assembler) {
1406 FLAG_use_compressed_instructions = false;
1407 __ SetExtensions(RV_G);
1408 __ xori(A0, A0, -42);
1409 __ ret();
1410}
1411ASSEMBLER_TEST_RUN(XorImmediate2, test) {
1412 EXPECT_DISASSEMBLY(
1413 "fd654513 xori a0, a0, -42\n"
1414 "00008067 ret\n");
1415 EXPECT_EQ(-42, Call(test->entry(), 0));
1416 EXPECT_EQ(-41, Call(test->entry(), 1));
1417 EXPECT_EQ(-36, Call(test->entry(), 10));
1418 EXPECT_EQ(41, Call(test->entry(), -1));
1419 EXPECT_EQ(32, Call(test->entry(), -10));
1420}
1421
1422ASSEMBLER_TEST_GENERATE(OrImmediate1, assembler) {
1423 FLAG_use_compressed_instructions = false;
1424 __ SetExtensions(RV_G);
1425 __ ori(A0, A0, -6);
1426 __ ret();
1427}
1428ASSEMBLER_TEST_RUN(OrImmediate1, test) {
1429 EXPECT_DISASSEMBLY(
1430 "ffa56513 ori a0, a0, -6\n"
1431 "00008067 ret\n");
1432 EXPECT_EQ(-6, Call(test->entry(), 0));
1433 EXPECT_EQ(-5, Call(test->entry(), 1));
1434 EXPECT_EQ(-5, Call(test->entry(), 11));
1435 EXPECT_EQ(-1, Call(test->entry(), -1));
1436 EXPECT_EQ(-1, Call(test->entry(), -11));
1437}
1438
1439ASSEMBLER_TEST_GENERATE(OrImmediate2, assembler) {
1440 FLAG_use_compressed_instructions = false;
1441 __ SetExtensions(RV_G);
1442 __ ori(A0, A0, 6);
1443 __ ret();
1444}
1445ASSEMBLER_TEST_RUN(OrImmediate2, test) {
1446 EXPECT_DISASSEMBLY(
1447 "00656513 ori a0, a0, 6\n"
1448 "00008067 ret\n");
1449 EXPECT_EQ(6, Call(test->entry(), 0));
1450 EXPECT_EQ(7, Call(test->entry(), 1));
1451 EXPECT_EQ(15, Call(test->entry(), 11));
1452 EXPECT_EQ(-1, Call(test->entry(), -1));
1453 EXPECT_EQ(-9, Call(test->entry(), -11));
1454}
1455
1456ASSEMBLER_TEST_GENERATE(AndImmediate1, assembler) {
1457 FLAG_use_compressed_instructions = false;
1458 __ SetExtensions(RV_G);
1459 __ andi(A0, A0, -6);
1460 __ ret();
1461}
1462ASSEMBLER_TEST_RUN(AndImmediate1, test) {
1463 EXPECT_DISASSEMBLY(
1464 "ffa57513 andi a0, a0, -6\n"
1465 "00008067 ret\n");
1466 EXPECT_EQ(0, Call(test->entry(), 0));
1467 EXPECT_EQ(0, Call(test->entry(), 1));
1468 EXPECT_EQ(10, Call(test->entry(), 11));
1469 EXPECT_EQ(-6, Call(test->entry(), -1));
1470 EXPECT_EQ(-16, Call(test->entry(), -11));
1471}
1472
1473ASSEMBLER_TEST_GENERATE(AndImmediate2, assembler) {
1474 FLAG_use_compressed_instructions = false;
1475 __ SetExtensions(RV_G);
1476 __ andi(A0, A0, 6);
1477 __ ret();
1478}
1479ASSEMBLER_TEST_RUN(AndImmediate2, test) {
1480 EXPECT_DISASSEMBLY(
1481 "00657513 andi a0, a0, 6\n"
1482 "00008067 ret\n");
1483 EXPECT_EQ(0, Call(test->entry(), 0));
1484 EXPECT_EQ(0, Call(test->entry(), 1));
1485 EXPECT_EQ(2, Call(test->entry(), 11));
1486 EXPECT_EQ(6, Call(test->entry(), -1));
1487 EXPECT_EQ(4, Call(test->entry(), -11));
1488}
1489
1490ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediate, assembler) {
1491 FLAG_use_compressed_instructions = false;
1492 __ SetExtensions(RV_G);
1493 __ slli(A0, A0, 2);
1494 __ ret();
1495}
1496ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediate, test) {
1497 EXPECT_DISASSEMBLY(
1498 "00251513 slli a0, a0, 0x2\n"
1499 "00008067 ret\n");
1500 EXPECT_EQ(84, Call(test->entry(), 21));
1501 EXPECT_EQ(4, Call(test->entry(), 1));
1502 EXPECT_EQ(0, Call(test->entry(), 0));
1503 EXPECT_EQ(-4, Call(test->entry(), -1));
1504 EXPECT_EQ(-84, Call(test->entry(), -21));
1505}
1506
1507ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediate2, assembler) {
1508 FLAG_use_compressed_instructions = false;
1509 __ SetExtensions(RV_G);
1510 __ slli(A0, A0, XLEN - 1);
1511 __ ret();
1512}
1513ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediate2, test) {
1514#if XLEN == 32
1515 EXPECT_DISASSEMBLY(
1516 "01f51513 slli a0, a0, 0x1f\n"
1517 "00008067 ret\n");
1518#elif XLEN == 64
1519 EXPECT_DISASSEMBLY(
1520 "03f51513 slli a0, a0, 0x3f\n"
1521 "00008067 ret\n");
1522#endif
1523 EXPECT_EQ(0, Call(test->entry(), 2));
1524 EXPECT_EQ(kMinIntX, Call(test->entry(), 1));
1525 EXPECT_EQ(0, Call(test->entry(), 0));
1526 EXPECT_EQ(kMinIntX, Call(test->entry(), -1));
1527 EXPECT_EQ(0, Call(test->entry(), -2));
1528}
1529
1530ASSEMBLER_TEST_GENERATE(ShiftRightLogicalImmediate, assembler) {
1531 FLAG_use_compressed_instructions = false;
1532 __ SetExtensions(RV_G);
1533 __ srli(A0, A0, 2);
1534 __ ret();
1535}
1536ASSEMBLER_TEST_RUN(ShiftRightLogicalImmediate, test) {
1537 EXPECT_DISASSEMBLY(
1538 "00255513 srli a0, a0, 0x2\n"
1539 "00008067 ret\n");
1540 EXPECT_EQ(5, Call(test->entry(), 21));
1541 EXPECT_EQ(0, Call(test->entry(), 1));
1542 EXPECT_EQ(0, Call(test->entry(), 0));
1543 EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-1) >> 2),
1544 Call(test->entry(), -1));
1545 EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-21) >> 2),
1546 Call(test->entry(), -21));
1547}
1548
1549ASSEMBLER_TEST_GENERATE(ShiftRightLogicalImmediate2, assembler) {
1550 FLAG_use_compressed_instructions = false;
1551 __ SetExtensions(RV_G);
1552 __ srli(A0, A0, XLEN - 1);
1553 __ ret();
1554}
1555ASSEMBLER_TEST_RUN(ShiftRightLogicalImmediate2, test) {
1556#if XLEN == 32
1557 EXPECT_DISASSEMBLY(
1558 "01f55513 srli a0, a0, 0x1f\n"
1559 "00008067 ret\n");
1560#elif XLEN == 64
1561 EXPECT_DISASSEMBLY(
1562 "03f55513 srli a0, a0, 0x3f\n"
1563 "00008067 ret\n");
1564#endif
1565 EXPECT_EQ(0, Call(test->entry(), 21));
1566 EXPECT_EQ(0, Call(test->entry(), 1));
1567 EXPECT_EQ(0, Call(test->entry(), 0));
1568 EXPECT_EQ(1, Call(test->entry(), -1));
1569 EXPECT_EQ(1, Call(test->entry(), -21));
1570}
1571
1572ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticImmediate, assembler) {
1573 FLAG_use_compressed_instructions = false;
1574 __ SetExtensions(RV_G);
1575 __ srai(A0, A0, 2);
1576 __ ret();
1577}
1578ASSEMBLER_TEST_RUN(ShiftRightArithmeticImmediate, test) {
1579 EXPECT_DISASSEMBLY(
1580 "40255513 srai a0, a0, 0x2\n"
1581 "00008067 ret\n");
1582 EXPECT_EQ(5, Call(test->entry(), 21));
1583 EXPECT_EQ(0, Call(test->entry(), 1));
1584 EXPECT_EQ(0, Call(test->entry(), 0));
1585 EXPECT_EQ(-1, Call(test->entry(), -1));
1586 EXPECT_EQ(-6, Call(test->entry(), -21));
1587}
1588
1589ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticImmediate2, assembler) {
1590 FLAG_use_compressed_instructions = false;
1591 __ SetExtensions(RV_G);
1592 __ srai(A0, A0, XLEN - 1);
1593 __ ret();
1594}
1595ASSEMBLER_TEST_RUN(ShiftRightArithmeticImmediate2, test) {
1596#if XLEN == 32
1597 EXPECT_DISASSEMBLY(
1598 "41f55513 srai a0, a0, 0x1f\n" // CHECK
1599 "00008067 ret\n");
1600#elif XLEN == 64
1601 EXPECT_DISASSEMBLY(
1602 "43f55513 srai a0, a0, 0x3f\n" // CHECK
1603 "00008067 ret\n");
1604#endif
1605 EXPECT_EQ(0, Call(test->entry(), 21));
1606 EXPECT_EQ(0, Call(test->entry(), 1));
1607 EXPECT_EQ(0, Call(test->entry(), 0));
1608 EXPECT_EQ(-1, Call(test->entry(), -1));
1609 EXPECT_EQ(-1, Call(test->entry(), -21));
1610}
1611
1612ASSEMBLER_TEST_GENERATE(Add, assembler) {
1613 FLAG_use_compressed_instructions = false;
1614 __ SetExtensions(RV_G);
1615 __ add(A0, A0, A1);
1616 __ ret();
1617}
1619 EXPECT_DISASSEMBLY(
1620 "00b50533 add a0, a0, a1\n"
1621 "00008067 ret\n");
1622 EXPECT_EQ(24, Call(test->entry(), 7, 17));
1623 EXPECT_EQ(-10, Call(test->entry(), 7, -17));
1624 EXPECT_EQ(10, Call(test->entry(), -7, 17));
1625 EXPECT_EQ(-24, Call(test->entry(), -7, -17));
1626 EXPECT_EQ(24, Call(test->entry(), 17, 7));
1627 EXPECT_EQ(10, Call(test->entry(), 17, -7));
1628 EXPECT_EQ(-10, Call(test->entry(), -17, 7));
1629 EXPECT_EQ(-24, Call(test->entry(), -17, -7));
1630}
1631
1632ASSEMBLER_TEST_GENERATE(Subtract, assembler) {
1633 FLAG_use_compressed_instructions = false;
1634 __ SetExtensions(RV_G);
1635 __ sub(A0, A0, A1);
1636 __ ret();
1637}
1638ASSEMBLER_TEST_RUN(Subtract, test) {
1639 EXPECT_DISASSEMBLY(
1640 "40b50533 sub a0, a0, a1\n"
1641 "00008067 ret\n");
1642 EXPECT_EQ(-10, Call(test->entry(), 7, 17));
1643 EXPECT_EQ(24, Call(test->entry(), 7, -17));
1644 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
1645 EXPECT_EQ(10, Call(test->entry(), -7, -17));
1646 EXPECT_EQ(10, Call(test->entry(), 17, 7));
1647 EXPECT_EQ(24, Call(test->entry(), 17, -7));
1648 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
1649 EXPECT_EQ(-10, Call(test->entry(), -17, -7));
1650}
1651
1652ASSEMBLER_TEST_GENERATE(ShiftLeftLogical, assembler) {
1653 FLAG_use_compressed_instructions = false;
1654 __ SetExtensions(RV_G);
1655 __ sll(A0, A0, A1);
1656 __ ret();
1657}
1658ASSEMBLER_TEST_RUN(ShiftLeftLogical, test) {
1659 EXPECT_DISASSEMBLY(
1660 "00b51533 sll a0, a0, a1\n"
1661 "00008067 ret\n");
1662 EXPECT_EQ(2176, Call(test->entry(), 17, 7));
1663 EXPECT_EQ(-2176, Call(test->entry(), -17, 7));
1664 EXPECT_EQ(34, Call(test->entry(), 17, 1));
1665 EXPECT_EQ(-34, Call(test->entry(), -17, 1));
1666 EXPECT_EQ(17, Call(test->entry(), 17, 0));
1667 EXPECT_EQ(-17, Call(test->entry(), -17, 0));
1668}
1669
1670ASSEMBLER_TEST_GENERATE(SetLessThan, assembler) {
1671 FLAG_use_compressed_instructions = false;
1672 __ SetExtensions(RV_G);
1673 __ slt(A0, A0, A1);
1674 __ ret();
1675}
1676ASSEMBLER_TEST_RUN(SetLessThan, test) {
1677 EXPECT_DISASSEMBLY(
1678 "00b52533 slt a0, a0, a1\n"
1679 "00008067 ret\n");
1680 EXPECT_EQ(0, Call(test->entry(), 7, 7));
1681 EXPECT_EQ(0, Call(test->entry(), -7, -7));
1682 EXPECT_EQ(1, Call(test->entry(), 7, 17));
1683 EXPECT_EQ(0, Call(test->entry(), 7, -17));
1684 EXPECT_EQ(1, Call(test->entry(), -7, 17));
1685 EXPECT_EQ(0, Call(test->entry(), -7, -17));
1686 EXPECT_EQ(0, Call(test->entry(), 17, 7));
1687 EXPECT_EQ(0, Call(test->entry(), 17, -7));
1688 EXPECT_EQ(1, Call(test->entry(), -17, 7));
1689 EXPECT_EQ(1, Call(test->entry(), -17, -7));
1690}
1691
1692ASSEMBLER_TEST_GENERATE(SetLessThanUnsigned, assembler) {
1693 FLAG_use_compressed_instructions = false;
1694 __ SetExtensions(RV_G);
1695 __ sltu(A0, A0, A1);
1696 __ ret();
1697}
1698ASSEMBLER_TEST_RUN(SetLessThanUnsigned, test) {
1699 EXPECT_DISASSEMBLY(
1700 "00b53533 sltu a0, a0, a1\n"
1701 "00008067 ret\n");
1702 EXPECT_EQ(0, Call(test->entry(), 7, 7));
1703 EXPECT_EQ(0, Call(test->entry(), -7, -7));
1704 EXPECT_EQ(1, Call(test->entry(), 7, 17));
1705 EXPECT_EQ(1, Call(test->entry(), 7, -17));
1706 EXPECT_EQ(0, Call(test->entry(), -7, 17));
1707 EXPECT_EQ(0, Call(test->entry(), -7, -17));
1708 EXPECT_EQ(0, Call(test->entry(), 17, 7));
1709 EXPECT_EQ(1, Call(test->entry(), 17, -7));
1710 EXPECT_EQ(0, Call(test->entry(), -17, 7));
1711 EXPECT_EQ(1, Call(test->entry(), -17, -7));
1712}
1713
1714ASSEMBLER_TEST_GENERATE(Xor, assembler) {
1715 FLAG_use_compressed_instructions = false;
1716 __ SetExtensions(RV_G);
1717 __ xor_(A0, A0, A1);
1718 __ ret();
1719}
1721 EXPECT_DISASSEMBLY(
1722 "00b54533 xor a0, a0, a1\n"
1723 "00008067 ret\n");
1724 EXPECT_EQ(22, Call(test->entry(), 7, 17));
1725 EXPECT_EQ(-24, Call(test->entry(), 7, -17));
1726 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
1727 EXPECT_EQ(22, Call(test->entry(), -7, -17));
1728 EXPECT_EQ(22, Call(test->entry(), 17, 7));
1729 EXPECT_EQ(-24, Call(test->entry(), 17, -7));
1730 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
1731 EXPECT_EQ(22, Call(test->entry(), -17, -7));
1732}
1733
1734ASSEMBLER_TEST_GENERATE(ShiftRightLogical, assembler) {
1735 FLAG_use_compressed_instructions = false;
1736 __ SetExtensions(RV_G);
1737 __ srl(A0, A0, A1);
1738 __ ret();
1739}
1740ASSEMBLER_TEST_RUN(ShiftRightLogical, test) {
1741 EXPECT_DISASSEMBLY(
1742 "00b55533 srl a0, a0, a1\n"
1743 "00008067 ret\n");
1744 EXPECT_EQ(0, Call(test->entry(), 17, 7));
1745 EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-17) >> 7),
1746 Call(test->entry(), -17, 7));
1747 EXPECT_EQ(8, Call(test->entry(), 17, 1));
1748 EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-17) >> 1),
1749 Call(test->entry(), -17, 1));
1750 EXPECT_EQ(17, Call(test->entry(), 17, 0));
1751 EXPECT_EQ(-17, Call(test->entry(), -17, 0));
1752}
1753
1754ASSEMBLER_TEST_GENERATE(ShiftRightArithmetic, assembler) {
1755 FLAG_use_compressed_instructions = false;
1756 __ SetExtensions(RV_G);
1757 __ sra(A0, A0, A1);
1758 __ ret();
1759}
1760ASSEMBLER_TEST_RUN(ShiftRightArithmetic, test) {
1761 EXPECT_DISASSEMBLY(
1762 "40b55533 sra a0, a0, a1\n"
1763 "00008067 ret\n");
1764 EXPECT_EQ(0, Call(test->entry(), 17, 7));
1765 EXPECT_EQ(-1, Call(test->entry(), -17, 7));
1766 EXPECT_EQ(8, Call(test->entry(), 17, 1));
1767 EXPECT_EQ(-9, Call(test->entry(), -17, 1));
1768 EXPECT_EQ(17, Call(test->entry(), 17, 0));
1769 EXPECT_EQ(-17, Call(test->entry(), -17, 0));
1770}
1771
1772ASSEMBLER_TEST_GENERATE(Or, assembler) {
1773 FLAG_use_compressed_instructions = false;
1774 __ SetExtensions(RV_G);
1775 __ or_(A0, A0, A1);
1776 __ ret();
1777}
1779 EXPECT_DISASSEMBLY(
1780 "00b56533 or a0, a0, a1\n"
1781 "00008067 ret\n");
1782 EXPECT_EQ(23, Call(test->entry(), 7, 17));
1783 EXPECT_EQ(-17, Call(test->entry(), 7, -17));
1784 EXPECT_EQ(-7, Call(test->entry(), -7, 17));
1785 EXPECT_EQ(-1, Call(test->entry(), -7, -17));
1786 EXPECT_EQ(23, Call(test->entry(), 17, 7));
1787 EXPECT_EQ(-7, Call(test->entry(), 17, -7));
1788 EXPECT_EQ(-17, Call(test->entry(), -17, 7));
1789 EXPECT_EQ(-1, Call(test->entry(), -17, -7));
1790}
1791
1792ASSEMBLER_TEST_GENERATE(And, assembler) {
1793 FLAG_use_compressed_instructions = false;
1794 __ SetExtensions(RV_G);
1795 __ and_(A0, A0, A1);
1796 __ ret();
1797}
1799 EXPECT_DISASSEMBLY(
1800 "00b57533 and a0, a0, a1\n"
1801 "00008067 ret\n");
1802 EXPECT_EQ(1, Call(test->entry(), 7, 17));
1803 EXPECT_EQ(7, Call(test->entry(), 7, -17));
1804 EXPECT_EQ(17, Call(test->entry(), -7, 17));
1805 EXPECT_EQ(-23, Call(test->entry(), -7, -17));
1806 EXPECT_EQ(1, Call(test->entry(), 17, 7));
1807 EXPECT_EQ(17, Call(test->entry(), 17, -7));
1808 EXPECT_EQ(7, Call(test->entry(), -17, 7));
1809 EXPECT_EQ(-23, Call(test->entry(), -17, -7));
1810}
1811
1812ASSEMBLER_TEST_GENERATE(Fence, assembler) {
1813 FLAG_use_compressed_instructions = false;
1814 __ SetExtensions(RV_G);
1815 __ fence();
1816 __ fence(kRead, kWrite);
1817 __ fence(kInput, kOutput);
1818 __ fence(kMemory, kMemory);
1819 __ fence(kAll, kAll);
1820 __ ret();
1821}
1822ASSEMBLER_TEST_RUN(Fence, test) {
1823 EXPECT_DISASSEMBLY(
1824 "0ff0000f fence\n"
1825 "0210000f fence r,w\n"
1826 "0840000f fence i,o\n"
1827 "0330000f fence rw,rw\n"
1828 "0ff0000f fence\n"
1829 "00008067 ret\n");
1830 Call(test->entry());
1831}
1832
1833ASSEMBLER_TEST_GENERATE(InstructionFence, assembler) {
1834 FLAG_use_compressed_instructions = false;
1835 __ SetExtensions(RV_G);
1836 __ fencei();
1837 __ ret();
1838}
1839ASSEMBLER_TEST_RUN(InstructionFence, test) {
1840 EXPECT_DISASSEMBLY(
1841 "0000100f fence.i\n"
1842 "00008067 ret\n");
1843 Call(test->entry());
1844}
1845
1846ASSEMBLER_TEST_GENERATE(EnvironmentCall, assembler) {
1847 FLAG_use_compressed_instructions = false;
1848 __ SetExtensions(RV_G);
1849 __ ecall();
1850 __ ret();
1851}
1852ASSEMBLER_TEST_RUN(EnvironmentCall, test) {
1853 EXPECT_DISASSEMBLY(
1854 "00000073 ecall\n"
1855 "00008067 ret\n");
1856
1857 // Not running: would trap.
1858}
1859
1860ASSEMBLER_TEST_GENERATE(EnvironmentBreak, assembler) {
1861 FLAG_use_compressed_instructions = false;
1862 __ SetExtensions(RV_G);
1863 __ ebreak();
1864 __ ret();
1865}
1866ASSEMBLER_TEST_RUN(EnvironmentBreak, test) {
1867 EXPECT_DISASSEMBLY(
1868 "00100073 ebreak\n"
1869 "00008067 ret\n");
1870
1871 // Not running: would trap.
1872}
1873
1874ASSEMBLER_TEST_GENERATE(ControlStatusRegisters, assembler) {
1875 FLAG_use_compressed_instructions = false;
1876 __ SetExtensions(RV_G);
1877 __ csrrw(T0, 0x123, S1);
1878 __ csrrs(T1, 0x123, S2);
1879 __ csrrc(T2, 0x123, S3);
1880 __ csrr(T3, 0x123);
1881 __ csrw(0x123, S4);
1882 __ csrs(0x123, S5);
1883 __ csrc(0x123, S6);
1884 __ csrrwi(T1, 0x123, 1);
1885 __ csrrsi(T2, 0x123, 2);
1886 __ csrrci(T3, 0x123, 3);
1887 __ csrwi(0x123, 4);
1888 __ csrsi(0x123, 5);
1889 __ csrci(0x123, 6);
1890 __ ret();
1891}
1892ASSEMBLER_TEST_RUN(ControlStatusRegisters, test) {
1893 EXPECT_DISASSEMBLY(
1894 "123492f3 csrrw t0, 0x123, thr\n"
1895 "12392373 csrrs t1, 0x123, s2\n"
1896 "1239b3f3 csrrc t2, 0x123, s3\n"
1897 "12302e73 csrr t3, 0x123\n"
1898 "123a1073 csrw 0x123, s4\n"
1899 "123aa073 csrs 0x123, s5\n"
1900 "123b3073 csrc 0x123, s6\n"
1901 "1230d373 csrrwi t1, 0x123, 1\n"
1902 "123163f3 csrrsi t2, 0x123, 2\n"
1903 "1231fe73 csrrci t3, 0x123, 3\n"
1904 "12325073 csrwi 0x123, 4\n"
1905 "1232e073 csrsi 0x123, 5\n"
1906 "12337073 csrci 0x123, 6\n"
1907 "00008067 ret\n");
1908
1909 // Not running: would trap.
1910}
1911
1912ASSEMBLER_TEST_GENERATE(Nop, assembler) {
1913 FLAG_use_compressed_instructions = false;
1914 __ SetExtensions(RV_G);
1915 __ nop();
1916 __ ret();
1917}
1919 EXPECT_DISASSEMBLY(
1920 "00000013 nop\n"
1921 "00008067 ret\n");
1922 EXPECT_EQ(123, Call(test->entry(), 123));
1923}
1924
1925ASSEMBLER_TEST_GENERATE(Move, assembler) {
1926 FLAG_use_compressed_instructions = false;
1927 __ SetExtensions(RV_G);
1928 __ mv(A0, A1);
1929 __ ret();
1930}
1931ASSEMBLER_TEST_RUN(Move, test) {
1932 EXPECT_DISASSEMBLY(
1933 "00058513 mv a0, a1\n"
1934 "00008067 ret\n");
1935 EXPECT_EQ(36, Call(test->entry(), 42, 36));
1936}
1937
1938ASSEMBLER_TEST_GENERATE(Not, assembler) {
1939 FLAG_use_compressed_instructions = false;
1940 __ SetExtensions(RV_G);
1941 __ not_(A0, A0);
1942 __ ret();
1943}
1945 EXPECT_DISASSEMBLY(
1946 "fff54513 not a0, a0\n"
1947 "00008067 ret\n");
1948 EXPECT_EQ(~42, Call(test->entry(), 42));
1949 EXPECT_EQ(~-42, Call(test->entry(), -42));
1950}
1951
1952ASSEMBLER_TEST_GENERATE(Negate, assembler) {
1953 FLAG_use_compressed_instructions = false;
1954 __ SetExtensions(RV_G);
1955 __ neg(A0, A0);
1956 __ ret();
1957}
1958ASSEMBLER_TEST_RUN(Negate, test) {
1959 EXPECT_DISASSEMBLY(
1960 "40a00533 neg a0, a0\n"
1961 "00008067 ret\n");
1962 EXPECT_EQ(-42, Call(test->entry(), 42));
1963 EXPECT_EQ(42, Call(test->entry(), -42));
1964}
1965
1966ASSEMBLER_TEST_GENERATE(SetNotEqualToZero, assembler) {
1967 FLAG_use_compressed_instructions = false;
1968 __ SetExtensions(RV_G);
1969 __ snez(A0, A0);
1970 __ ret();
1971}
1972ASSEMBLER_TEST_RUN(SetNotEqualToZero, test) {
1973 EXPECT_DISASSEMBLY(
1974 "00a03533 snez a0, a0\n"
1975 "00008067 ret\n");
1976 EXPECT_EQ(1, Call(test->entry(), -42));
1977 EXPECT_EQ(0, Call(test->entry(), 0));
1978 EXPECT_EQ(1, Call(test->entry(), 42));
1979}
1980
1981ASSEMBLER_TEST_GENERATE(SetEqualToZero, assembler) {
1982 FLAG_use_compressed_instructions = false;
1983 __ SetExtensions(RV_G);
1984 __ seqz(A0, A0);
1985 __ ret();
1986}
1987ASSEMBLER_TEST_RUN(SetEqualToZero, test) {
1988 EXPECT_DISASSEMBLY(
1989 "00153513 seqz a0, a0\n"
1990 "00008067 ret\n");
1991 EXPECT_EQ(0, Call(test->entry(), -42));
1992 EXPECT_EQ(1, Call(test->entry(), 0));
1993 EXPECT_EQ(0, Call(test->entry(), 42));
1994}
1995
1996ASSEMBLER_TEST_GENERATE(SetLessThanZero, assembler) {
1997 FLAG_use_compressed_instructions = false;
1998 __ SetExtensions(RV_G);
1999 __ sltz(A0, A0);
2000 __ ret();
2001}
2002ASSEMBLER_TEST_RUN(SetLessThanZero, test) {
2003 EXPECT_DISASSEMBLY(
2004 "00052533 sltz a0, a0\n"
2005 "00008067 ret\n");
2006 EXPECT_EQ(1, Call(test->entry(), -42));
2007 EXPECT_EQ(0, Call(test->entry(), 0));
2008 EXPECT_EQ(0, Call(test->entry(), 42));
2009}
2010
2011ASSEMBLER_TEST_GENERATE(SetGreaterThanZero, assembler) {
2012 FLAG_use_compressed_instructions = false;
2013 __ SetExtensions(RV_G);
2014 __ sgtz(A0, A0);
2015 __ ret();
2016}
2017ASSEMBLER_TEST_RUN(SetGreaterThanZero, test) {
2018 EXPECT_DISASSEMBLY(
2019 "00a02533 sgtz a0, a0\n"
2020 "00008067 ret\n");
2021 EXPECT_EQ(0, Call(test->entry(), -42));
2022 EXPECT_EQ(0, Call(test->entry(), 0));
2023 EXPECT_EQ(1, Call(test->entry(), 42));
2024}
2025
2026ASSEMBLER_TEST_GENERATE(BranchEqualZero, assembler) {
2027 FLAG_use_compressed_instructions = false;
2028 __ SetExtensions(RV_G);
2029 Label label;
2030 __ beqz(A0, &label);
2031 __ li(A0, 3);
2032 __ ret();
2033 __ Bind(&label);
2034 __ li(A0, 4);
2035 __ ret();
2036}
2037ASSEMBLER_TEST_RUN(BranchEqualZero, test) {
2038 EXPECT_DISASSEMBLY(
2039 "00050663 beqz a0, +12\n"
2040 "00300513 li a0, 3\n"
2041 "00008067 ret\n"
2042 "00400513 li a0, 4\n"
2043 "00008067 ret\n");
2044 EXPECT_EQ(3, Call(test->entry(), -42));
2045 EXPECT_EQ(4, Call(test->entry(), 0));
2046 EXPECT_EQ(3, Call(test->entry(), 42));
2047}
2048
2049ASSEMBLER_TEST_GENERATE(BranchNotEqualZero, assembler) {
2050 FLAG_use_compressed_instructions = false;
2051 __ SetExtensions(RV_G);
2052 Label label;
2053 __ bnez(A0, &label);
2054 __ li(A0, 3);
2055 __ ret();
2056 __ Bind(&label);
2057 __ li(A0, 4);
2058 __ ret();
2059}
2060ASSEMBLER_TEST_RUN(BranchNotEqualZero, test) {
2061 EXPECT_DISASSEMBLY(
2062 "00051663 bnez a0, +12\n"
2063 "00300513 li a0, 3\n"
2064 "00008067 ret\n"
2065 "00400513 li a0, 4\n"
2066 "00008067 ret\n");
2067 EXPECT_EQ(4, Call(test->entry(), -42));
2068 EXPECT_EQ(3, Call(test->entry(), 0));
2069 EXPECT_EQ(4, Call(test->entry(), 42));
2070}
2071
2072ASSEMBLER_TEST_GENERATE(BranchLessOrEqualZero, assembler) {
2073 FLAG_use_compressed_instructions = false;
2074 __ SetExtensions(RV_G);
2075 Label label;
2076 __ blez(A0, &label);
2077 __ li(A0, 3);
2078 __ ret();
2079 __ Bind(&label);
2080 __ li(A0, 4);
2081 __ ret();
2082}
2083ASSEMBLER_TEST_RUN(BranchLessOrEqualZero, test) {
2084 EXPECT_DISASSEMBLY(
2085 "00a05663 blez a0, +12\n"
2086 "00300513 li a0, 3\n"
2087 "00008067 ret\n"
2088 "00400513 li a0, 4\n"
2089 "00008067 ret\n");
2090 EXPECT_EQ(4, Call(test->entry(), -42));
2091 EXPECT_EQ(4, Call(test->entry(), 0));
2092 EXPECT_EQ(3, Call(test->entry(), 42));
2093}
2094
2095ASSEMBLER_TEST_GENERATE(BranchGreaterOrEqualZero, assembler) {
2096 FLAG_use_compressed_instructions = false;
2097 __ SetExtensions(RV_G);
2098 Label label;
2099 __ bgez(A0, &label);
2100 __ li(A0, 3);
2101 __ ret();
2102 __ Bind(&label);
2103 __ li(A0, 4);
2104 __ ret();
2105}
2106ASSEMBLER_TEST_RUN(BranchGreaterOrEqualZero, test) {
2107 EXPECT_DISASSEMBLY(
2108 "00055663 bgez a0, +12\n"
2109 "00300513 li a0, 3\n"
2110 "00008067 ret\n"
2111 "00400513 li a0, 4\n"
2112 "00008067 ret\n");
2113 EXPECT_EQ(3, Call(test->entry(), -42));
2114 EXPECT_EQ(4, Call(test->entry(), 0));
2115 EXPECT_EQ(4, Call(test->entry(), 42));
2116}
2117
2118ASSEMBLER_TEST_GENERATE(BranchLessThanZero, assembler) {
2119 FLAG_use_compressed_instructions = false;
2120 __ SetExtensions(RV_G);
2121 Label label;
2122 __ bltz(A0, &label);
2123 __ li(A0, 3);
2124 __ ret();
2125 __ Bind(&label);
2126 __ li(A0, 4);
2127 __ ret();
2128}
2129ASSEMBLER_TEST_RUN(BranchLessThanZero, test) {
2130 EXPECT_DISASSEMBLY(
2131 "00054663 bltz a0, +12\n"
2132 "00300513 li a0, 3\n"
2133 "00008067 ret\n"
2134 "00400513 li a0, 4\n"
2135 "00008067 ret\n");
2136 EXPECT_EQ(4, Call(test->entry(), -42));
2137 EXPECT_EQ(3, Call(test->entry(), 0));
2138 EXPECT_EQ(3, Call(test->entry(), 42));
2139}
2140
2141ASSEMBLER_TEST_GENERATE(BranchGreaterThanZero, assembler) {
2142 FLAG_use_compressed_instructions = false;
2143 __ SetExtensions(RV_G);
2144 Label label;
2145 __ bgtz(A0, &label);
2146 __ li(A0, 3);
2147 __ ret();
2148 __ Bind(&label);
2149 __ li(A0, 4);
2150 __ ret();
2151}
2152ASSEMBLER_TEST_RUN(BranchGreaterThanZero, test) {
2153 EXPECT_DISASSEMBLY(
2154 "00a04663 bgtz a0, +12\n"
2155 "00300513 li a0, 3\n"
2156 "00008067 ret\n"
2157 "00400513 li a0, 4\n"
2158 "00008067 ret\n");
2159 EXPECT_EQ(3, Call(test->entry(), -42));
2160 EXPECT_EQ(3, Call(test->entry(), 0));
2161 EXPECT_EQ(4, Call(test->entry(), 42));
2162}
2163
2164#if XLEN >= 64
2165ASSEMBLER_TEST_GENERATE(AddImmediateWord1, assembler) {
2166 FLAG_use_compressed_instructions = false;
2167 __ SetExtensions(RV_G);
2168 __ addiw(A0, A0, 42);
2169 __ ret();
2170}
2171ASSEMBLER_TEST_RUN(AddImmediateWord1, test) {
2172 EXPECT_DISASSEMBLY(
2173 "02a5051b addiw a0, a0, 42\n"
2174 "00008067 ret\n");
2175 EXPECT_EQ(42, Call(test->entry(), 0));
2176 EXPECT_EQ(40, Call(test->entry(), -2));
2177 EXPECT_EQ(0, Call(test->entry(), -42));
2178}
2179
2180ASSEMBLER_TEST_GENERATE(AddImmediateWord2, assembler) {
2181 FLAG_use_compressed_instructions = false;
2182 __ SetExtensions(RV_G);
2183 __ addiw(A0, A0, -42);
2184 __ ret();
2185}
2186ASSEMBLER_TEST_RUN(AddImmediateWord2, test) {
2187 EXPECT_DISASSEMBLY(
2188 "fd65051b addiw a0, a0, -42\n"
2189 "00008067 ret\n");
2190 EXPECT_EQ(-42, Call(test->entry(), 0));
2191 EXPECT_EQ(-44, Call(test->entry(), -2));
2192 EXPECT_EQ(38, Call(test->entry(), 80));
2193}
2194
2195ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediateWord, assembler) {
2196 FLAG_use_compressed_instructions = false;
2197 __ SetExtensions(RV_G);
2198 __ slliw(A0, A0, 2);
2199 __ ret();
2200}
2201ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediateWord, test) {
2202 EXPECT_DISASSEMBLY(
2203 "0025151b slliw a0, a0, 0x2\n"
2204 "00008067 ret\n");
2205 EXPECT_EQ(84, Call(test->entry(), 21));
2206 EXPECT_EQ(4, Call(test->entry(), 1));
2207 EXPECT_EQ(0, Call(test->entry(), 0));
2208 EXPECT_EQ(-4, Call(test->entry(), -1));
2209 EXPECT_EQ(-84, Call(test->entry(), -21));
2210}
2211
2212ASSEMBLER_TEST_GENERATE(ShiftRightLogicalImmediateWord, assembler) {
2213 FLAG_use_compressed_instructions = false;
2214 __ SetExtensions(RV_G);
2215 __ srliw(A0, A0, 2);
2216 __ ret();
2217}
2218ASSEMBLER_TEST_RUN(ShiftRightLogicalImmediateWord, test) {
2219 EXPECT_DISASSEMBLY(
2220 "0025551b srliw a0, a0, 0x2\n"
2221 "00008067 ret\n");
2222 EXPECT_EQ(5, Call(test->entry(), 21));
2223 EXPECT_EQ(0, Call(test->entry(), 1));
2224 EXPECT_EQ(0, Call(test->entry(), 0));
2225 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-1) >> 2),
2226 Call(test->entry(), -1));
2227 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-21) >> 2),
2228 Call(test->entry(), -21));
2229}
2230
2231ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticImmediateWord, assembler) {
2232 FLAG_use_compressed_instructions = false;
2233 __ SetExtensions(RV_G);
2234 __ sraiw(A0, A0, 2);
2235 __ ret();
2236}
2237ASSEMBLER_TEST_RUN(ShiftRightArithmeticImmediateWord, test) {
2238 EXPECT_DISASSEMBLY(
2239 "4025551b sraiw a0, a0, 0x2\n"
2240 "00008067 ret\n");
2241 EXPECT_EQ(5, Call(test->entry(), 21));
2242 EXPECT_EQ(0, Call(test->entry(), 1));
2243 EXPECT_EQ(0, Call(test->entry(), 0));
2244 EXPECT_EQ(-1, Call(test->entry(), -1));
2245 EXPECT_EQ(-6, Call(test->entry(), -21));
2246}
2247
2248ASSEMBLER_TEST_GENERATE(AddWord, assembler) {
2249 FLAG_use_compressed_instructions = false;
2250 __ SetExtensions(RV_G);
2251 __ addw(A0, A0, A1);
2252 __ ret();
2253}
2254ASSEMBLER_TEST_RUN(AddWord, test) {
2255 EXPECT_DISASSEMBLY(
2256 "00b5053b addw a0, a0, a1\n"
2257 "00008067 ret\n");
2258 EXPECT_EQ(24, Call(test->entry(), 7, 17));
2259 EXPECT_EQ(-10, Call(test->entry(), 7, -17));
2260 EXPECT_EQ(10, Call(test->entry(), -7, 17));
2261 EXPECT_EQ(-24, Call(test->entry(), -7, -17));
2262 EXPECT_EQ(24, Call(test->entry(), 17, 7));
2263 EXPECT_EQ(10, Call(test->entry(), 17, -7));
2264 EXPECT_EQ(-10, Call(test->entry(), -17, 7));
2265 EXPECT_EQ(-24, Call(test->entry(), -17, -7));
2266 EXPECT_EQ(3, Call(test->entry(), 0x200000002, 0x100000001));
2267}
2268
2269ASSEMBLER_TEST_GENERATE(SubtractWord, assembler) {
2270 FLAG_use_compressed_instructions = false;
2271 __ SetExtensions(RV_G);
2272 __ subw(A0, A0, A1);
2273 __ ret();
2274}
2275ASSEMBLER_TEST_RUN(SubtractWord, test) {
2276 EXPECT_DISASSEMBLY(
2277 "40b5053b subw a0, a0, a1\n"
2278 "00008067 ret\n");
2279 EXPECT_EQ(-10, Call(test->entry(), 7, 17));
2280 EXPECT_EQ(24, Call(test->entry(), 7, -17));
2281 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
2282 EXPECT_EQ(10, Call(test->entry(), -7, -17));
2283 EXPECT_EQ(10, Call(test->entry(), 17, 7));
2284 EXPECT_EQ(24, Call(test->entry(), 17, -7));
2285 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
2286 EXPECT_EQ(-10, Call(test->entry(), -17, -7));
2287 EXPECT_EQ(1, Call(test->entry(), 0x200000002, 0x100000001));
2288}
2289
2290ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalWord, assembler) {
2291 FLAG_use_compressed_instructions = false;
2292 __ SetExtensions(RV_G);
2293 __ sllw(A0, A0, A1);
2294 __ ret();
2295}
2296ASSEMBLER_TEST_RUN(ShiftLeftLogicalWord, test) {
2297 EXPECT_DISASSEMBLY(
2298 "00b5153b sllw a0, a0, a1\n"
2299 "00008067 ret\n");
2300 EXPECT_EQ(2176, Call(test->entry(), 17, 7));
2301 EXPECT_EQ(-2176, Call(test->entry(), -17, 7));
2302 EXPECT_EQ(34, Call(test->entry(), 17, 1));
2303 EXPECT_EQ(-34, Call(test->entry(), -17, 1));
2304 EXPECT_EQ(17, Call(test->entry(), 17, 0));
2305 EXPECT_EQ(-17, Call(test->entry(), -17, 0));
2306 EXPECT_EQ(0x10, Call(test->entry(), 0x10000001, 4));
2307}
2308
2309ASSEMBLER_TEST_GENERATE(ShiftRightLogicalWord, assembler) {
2310 FLAG_use_compressed_instructions = false;
2311 __ SetExtensions(RV_G);
2312 __ srlw(A0, A0, A1);
2313 __ ret();
2314}
2315ASSEMBLER_TEST_RUN(ShiftRightLogicalWord, test) {
2316 EXPECT_DISASSEMBLY(
2317 "00b5553b srlw a0, a0, a1\n"
2318 "00008067 ret\n");
2319 EXPECT_EQ(0, Call(test->entry(), 17, 7));
2320 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-17) >> 7),
2321 Call(test->entry(), -17, 7));
2322 EXPECT_EQ(8, Call(test->entry(), 17, 1));
2323 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-17) >> 1),
2324 Call(test->entry(), -17, 1));
2325 EXPECT_EQ(17, Call(test->entry(), 17, 0));
2326 EXPECT_EQ(-17, Call(test->entry(), -17, 0));
2327}
2328
2329ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticWord, assembler) {
2330 FLAG_use_compressed_instructions = false;
2331 __ SetExtensions(RV_G);
2332 __ sraw(A0, A0, A1);
2333 __ ret();
2334}
2335ASSEMBLER_TEST_RUN(ShiftRightArithmeticWord, test) {
2336 EXPECT_DISASSEMBLY(
2337 "40b5553b sraw a0, a0, a1\n"
2338 "00008067 ret\n");
2339 EXPECT_EQ(0, Call(test->entry(), 17, 7));
2340 EXPECT_EQ(-1, Call(test->entry(), -17, 7));
2341 EXPECT_EQ(8, Call(test->entry(), 17, 1));
2342 EXPECT_EQ(-9, Call(test->entry(), -17, 1));
2343 EXPECT_EQ(17, Call(test->entry(), 17, 0));
2344 EXPECT_EQ(-17, Call(test->entry(), -17, 0));
2345}
2346
2347ASSEMBLER_TEST_GENERATE(NegateWord, assembler) {
2348 FLAG_use_compressed_instructions = false;
2349 __ SetExtensions(RV_G);
2350 __ negw(A0, A0);
2351 __ ret();
2352}
2353ASSEMBLER_TEST_RUN(NegateWord, test) {
2354 EXPECT_DISASSEMBLY(
2355 "40a0053b negw a0, a0\n"
2356 "00008067 ret\n");
2357 EXPECT_EQ(0, Call(test->entry(), 0));
2358 EXPECT_EQ(-42, Call(test->entry(), 42));
2359 EXPECT_EQ(42, Call(test->entry(), -42));
2360 EXPECT_EQ(1, Call(test->entry(), 0x10FFFFFFFF));
2361}
2362
2363ASSEMBLER_TEST_GENERATE(SignExtendWord, assembler) {
2364 FLAG_use_compressed_instructions = false;
2365 __ SetExtensions(RV_G);
2366 __ sextw(A0, A0);
2367 __ ret();
2368}
2369ASSEMBLER_TEST_RUN(SignExtendWord, test) {
2370 EXPECT_DISASSEMBLY(
2371 "0005051b sext.w a0, a0\n"
2372 "00008067 ret\n");
2373 EXPECT_EQ(0, Call(test->entry(), 0));
2374 EXPECT_EQ(42, Call(test->entry(), 42));
2375 EXPECT_EQ(-42, Call(test->entry(), -42));
2376 EXPECT_EQ(-1, Call(test->entry(), 0x10FFFFFFFF));
2377}
2378#endif // XLEN >= 64
2379
2380ASSEMBLER_TEST_GENERATE(Multiply, assembler) {
2381 FLAG_use_compressed_instructions = false;
2382 __ SetExtensions(RV_G);
2383 __ mul(A0, A0, A1);
2384 __ ret();
2385}
2386ASSEMBLER_TEST_RUN(Multiply, test) {
2387 EXPECT_DISASSEMBLY(
2388 "02b50533 mul a0, a0, a1\n"
2389 "00008067 ret\n");
2390 EXPECT_EQ(68, Call(test->entry(), 4, 17));
2391 EXPECT_EQ(-68, Call(test->entry(), -4, 17));
2392 EXPECT_EQ(-68, Call(test->entry(), 4, -17));
2393 EXPECT_EQ(68, Call(test->entry(), -4, -17));
2394 EXPECT_EQ(68, Call(test->entry(), 17, 4));
2395 EXPECT_EQ(-68, Call(test->entry(), -17, 4));
2396 EXPECT_EQ(-68, Call(test->entry(), 17, -4));
2397 EXPECT_EQ(68, Call(test->entry(), -17, -4));
2398}
2399
2400ASSEMBLER_TEST_GENERATE(MultiplyHigh, assembler) {
2401 FLAG_use_compressed_instructions = false;
2402 __ SetExtensions(RV_G);
2403 __ mulh(A0, A0, A1);
2404 __ ret();
2405}
2406ASSEMBLER_TEST_RUN(MultiplyHigh, test) {
2407 EXPECT_DISASSEMBLY(
2408 "02b51533 mulh a0, a0, a1\n"
2409 "00008067 ret\n");
2410 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2411 EXPECT_EQ(-1, Call(test->entry(), -4, 17));
2412 EXPECT_EQ(-1, Call(test->entry(), 4, -17));
2413 EXPECT_EQ(0, Call(test->entry(), -4, -17));
2414 EXPECT_EQ(0, Call(test->entry(), 17, 4));
2415 EXPECT_EQ(-1, Call(test->entry(), -17, 4));
2416 EXPECT_EQ(-1, Call(test->entry(), 17, -4));
2417 EXPECT_EQ(0, Call(test->entry(), -17, -4));
2418}
2419
2420ASSEMBLER_TEST_GENERATE(MultiplyHighSignedUnsigned, assembler) {
2421 FLAG_use_compressed_instructions = false;
2422 __ SetExtensions(RV_G);
2423 __ mulhsu(A0, A0, A1);
2424 __ ret();
2425}
2426ASSEMBLER_TEST_RUN(MultiplyHighSignedUnsigned, test) {
2427 EXPECT_DISASSEMBLY(
2428 "02b52533 mulhsu a0, a0, a1\n"
2429 "00008067 ret\n");
2430 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2431 EXPECT_EQ(-1, Call(test->entry(), -4, 17));
2432 EXPECT_EQ(3, Call(test->entry(), 4, -17));
2433 EXPECT_EQ(-4, Call(test->entry(), -4, -17));
2434 EXPECT_EQ(0, Call(test->entry(), 17, 4));
2435 EXPECT_EQ(-1, Call(test->entry(), -17, 4));
2436 EXPECT_EQ(16, Call(test->entry(), 17, -4));
2437 EXPECT_EQ(-17, Call(test->entry(), -17, -4));
2438}
2439
2440ASSEMBLER_TEST_GENERATE(MultiplyHighUnsigned, assembler) {
2441 FLAG_use_compressed_instructions = false;
2442 __ SetExtensions(RV_G);
2443 __ mulhu(A0, A0, A1);
2444 __ ret();
2445}
2446ASSEMBLER_TEST_RUN(MultiplyHighUnsigned, test) {
2447 EXPECT_DISASSEMBLY(
2448 "02b53533 mulhu a0, a0, a1\n"
2449 "00008067 ret\n");
2450 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2451 EXPECT_EQ(16, Call(test->entry(), -4, 17));
2452 EXPECT_EQ(3, Call(test->entry(), 4, -17));
2453 EXPECT_EQ(-21, Call(test->entry(), -4, -17));
2454 EXPECT_EQ(0, Call(test->entry(), 17, 4));
2455 EXPECT_EQ(3, Call(test->entry(), -17, 4));
2456 EXPECT_EQ(16, Call(test->entry(), 17, -4));
2457 EXPECT_EQ(-21, Call(test->entry(), -17, -4));
2458}
2459
2460ASSEMBLER_TEST_GENERATE(Divide, assembler) {
2461 FLAG_use_compressed_instructions = false;
2462 __ SetExtensions(RV_G);
2463 __ div(A0, A0, A1);
2464 __ ret();
2465}
2466ASSEMBLER_TEST_RUN(Divide, test) {
2467 EXPECT_DISASSEMBLY(
2468 "02b54533 div a0, a0, a1\n"
2469 "00008067 ret\n");
2470 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2471 EXPECT_EQ(0, Call(test->entry(), -4, 17));
2472 EXPECT_EQ(0, Call(test->entry(), 4, -17));
2473 EXPECT_EQ(0, Call(test->entry(), -4, -17));
2474 EXPECT_EQ(4, Call(test->entry(), 17, 4));
2475 EXPECT_EQ(-4, Call(test->entry(), -17, 4));
2476 EXPECT_EQ(-4, Call(test->entry(), 17, -4));
2477 EXPECT_EQ(4, Call(test->entry(), -17, -4));
2478}
2479
2480ASSEMBLER_TEST_GENERATE(DivideUnsigned, assembler) {
2481 FLAG_use_compressed_instructions = false;
2482 __ SetExtensions(RV_G);
2483 __ divu(A0, A0, A1);
2484 __ ret();
2485}
2486ASSEMBLER_TEST_RUN(DivideUnsigned, test) {
2487 EXPECT_DISASSEMBLY(
2488 "02b55533 divu a0, a0, a1\n"
2489 "00008067 ret\n");
2490 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2491#if XLEN == 32
2492 EXPECT_EQ(252645134, Call(test->entry(), -4, 17));
2493#else
2494 EXPECT_EQ(1085102592571150094, Call(test->entry(), -4, 17));
2495#endif
2496 EXPECT_EQ(0, Call(test->entry(), 4, -17));
2497 EXPECT_EQ(1, Call(test->entry(), -4, -17));
2498 EXPECT_EQ(4, Call(test->entry(), 17, 4));
2499#if XLEN == 32
2500 EXPECT_EQ(1073741819, Call(test->entry(), -17, 4));
2501#else
2502 EXPECT_EQ(4611686018427387899, Call(test->entry(), -17, 4));
2503#endif
2504 EXPECT_EQ(0, Call(test->entry(), 17, -4));
2505 EXPECT_EQ(0, Call(test->entry(), -17, -4));
2506}
2507
2508ASSEMBLER_TEST_GENERATE(Remainder, assembler) {
2509 FLAG_use_compressed_instructions = false;
2510 __ SetExtensions(RV_G);
2511 __ rem(A0, A0, A1);
2512 __ ret();
2513}
2514ASSEMBLER_TEST_RUN(Remainder, test) {
2515 EXPECT_DISASSEMBLY(
2516 "02b56533 rem a0, a0, a1\n"
2517 "00008067 ret\n");
2518 EXPECT_EQ(4, Call(test->entry(), 4, 17));
2519 EXPECT_EQ(-4, Call(test->entry(), -4, 17));
2520 EXPECT_EQ(4, Call(test->entry(), 4, -17));
2521 EXPECT_EQ(-4, Call(test->entry(), -4, -17));
2522 EXPECT_EQ(1, Call(test->entry(), 17, 4));
2523 EXPECT_EQ(-1, Call(test->entry(), -17, 4));
2524 EXPECT_EQ(1, Call(test->entry(), 17, -4));
2525 EXPECT_EQ(-1, Call(test->entry(), -17, -4));
2526}
2527
2528ASSEMBLER_TEST_GENERATE(RemainderUnsigned, assembler) {
2529 FLAG_use_compressed_instructions = false;
2530 __ SetExtensions(RV_G);
2531 __ remu(A0, A0, A1);
2532 __ ret();
2533}
2534ASSEMBLER_TEST_RUN(RemainderUnsigned, test) {
2535 EXPECT_DISASSEMBLY(
2536 "02b57533 remu a0, a0, a1\n"
2537 "00008067 ret\n");
2538 EXPECT_EQ(4, Call(test->entry(), 4, 17));
2539 EXPECT_EQ(14, Call(test->entry(), -4, 17));
2540 EXPECT_EQ(4, Call(test->entry(), 4, -17));
2541 EXPECT_EQ(13, Call(test->entry(), -4, -17));
2542 EXPECT_EQ(1, Call(test->entry(), 17, 4));
2543 EXPECT_EQ(3, Call(test->entry(), -17, 4));
2544 EXPECT_EQ(17, Call(test->entry(), 17, -4));
2545 EXPECT_EQ(-17, Call(test->entry(), -17, -4));
2546}
2547
2548#if XLEN >= 64
2549ASSEMBLER_TEST_GENERATE(MultiplyWord, assembler) {
2550 FLAG_use_compressed_instructions = false;
2551 __ SetExtensions(RV_G);
2552 __ mulw(A0, A0, A1);
2553 __ ret();
2554}
2555ASSEMBLER_TEST_RUN(MultiplyWord, test) {
2556 EXPECT_DISASSEMBLY(
2557 "02b5053b mulw a0, a0, a1\n"
2558 "00008067 ret\n");
2559 EXPECT_EQ(68, Call(test->entry(), 4, 17));
2560 EXPECT_EQ(-68, Call(test->entry(), -4, 17));
2561 EXPECT_EQ(-68, Call(test->entry(), 4, -17));
2562 EXPECT_EQ(68, Call(test->entry(), -4, -17));
2563 EXPECT_EQ(68, Call(test->entry(), 17, 4));
2564 EXPECT_EQ(-68, Call(test->entry(), -17, 4));
2565 EXPECT_EQ(-68, Call(test->entry(), 17, -4));
2566 EXPECT_EQ(68, Call(test->entry(), -17, -4));
2567}
2568
2569ASSEMBLER_TEST_GENERATE(DivideWord, assembler) {
2570 FLAG_use_compressed_instructions = false;
2571 __ SetExtensions(RV_G);
2572 __ divw(A0, A0, A1);
2573 __ ret();
2574}
2575ASSEMBLER_TEST_RUN(DivideWord, test) {
2576 EXPECT_DISASSEMBLY(
2577 "02b5453b divw a0, a0, a1\n"
2578 "00008067 ret\n");
2579 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2580 EXPECT_EQ(0, Call(test->entry(), -4, 17));
2581 EXPECT_EQ(0, Call(test->entry(), 4, -17));
2582 EXPECT_EQ(0, Call(test->entry(), -4, -17));
2583 EXPECT_EQ(4, Call(test->entry(), 17, 4));
2584 EXPECT_EQ(-4, Call(test->entry(), -17, 4));
2585 EXPECT_EQ(-4, Call(test->entry(), 17, -4));
2586 EXPECT_EQ(4, Call(test->entry(), -17, -4));
2587}
2588
2589ASSEMBLER_TEST_GENERATE(DivideUnsignedWord, assembler) {
2590 FLAG_use_compressed_instructions = false;
2591 __ SetExtensions(RV_G);
2592 __ divuw(A0, A0, A1);
2593 __ ret();
2594}
2595ASSEMBLER_TEST_RUN(DivideUnsignedWord, test) {
2596 EXPECT_DISASSEMBLY(
2597 "02b5553b divuw a0, a0, a1\n"
2598 "00008067 ret\n");
2599 EXPECT_EQ(0, Call(test->entry(), 4, 17));
2600 EXPECT_EQ(252645134, Call(test->entry(), -4, 17));
2601 EXPECT_EQ(0, Call(test->entry(), 4, -17));
2602 EXPECT_EQ(1, Call(test->entry(), -4, -17));
2603 EXPECT_EQ(4, Call(test->entry(), 17, 4));
2604 EXPECT_EQ(1073741819, Call(test->entry(), -17, 4));
2605 EXPECT_EQ(0, Call(test->entry(), 17, -4));
2606 EXPECT_EQ(0, Call(test->entry(), -17, -4));
2607}
2608
2609ASSEMBLER_TEST_GENERATE(RemainderWord, assembler) {
2610 FLAG_use_compressed_instructions = false;
2611 __ SetExtensions(RV_G);
2612 __ remw(A0, A0, A1);
2613 __ ret();
2614}
2615ASSEMBLER_TEST_RUN(RemainderWord, test) {
2616 EXPECT_DISASSEMBLY(
2617 "02b5653b remw a0, a0, a1\n"
2618 "00008067 ret\n");
2619 EXPECT_EQ(4, Call(test->entry(), 4, 17));
2620 EXPECT_EQ(-4, Call(test->entry(), -4, 17));
2621 EXPECT_EQ(4, Call(test->entry(), 4, -17));
2622 EXPECT_EQ(-4, Call(test->entry(), -4, -17));
2623 EXPECT_EQ(1, Call(test->entry(), 17, 4));
2624 EXPECT_EQ(-1, Call(test->entry(), -17, 4));
2625 EXPECT_EQ(1, Call(test->entry(), 17, -4));
2626 EXPECT_EQ(-1, Call(test->entry(), -17, -4));
2627}
2628
2629ASSEMBLER_TEST_GENERATE(RemainderUnsignedWord, assembler) {
2630 FLAG_use_compressed_instructions = false;
2631 __ SetExtensions(RV_G);
2632 __ remuw(A0, A0, A1);
2633 __ ret();
2634}
2635ASSEMBLER_TEST_RUN(RemainderUnsignedWord, test) {
2636 EXPECT_DISASSEMBLY(
2637 "02b5753b remuw a0, a0, a1\n"
2638 "00008067 ret\n");
2639 EXPECT_EQ(4, Call(test->entry(), 4, 17));
2640 EXPECT_EQ(14, Call(test->entry(), -4, 17));
2641 EXPECT_EQ(4, Call(test->entry(), 4, -17));
2642 EXPECT_EQ(13, Call(test->entry(), -4, -17));
2643 EXPECT_EQ(1, Call(test->entry(), 17, 4));
2644 EXPECT_EQ(3, Call(test->entry(), -17, 4));
2645 EXPECT_EQ(17, Call(test->entry(), 17, -4));
2646 EXPECT_EQ(-17, Call(test->entry(), -17, -4));
2647}
2648#endif
2649
2650ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalWord_Success, assembler) {
2651 FLAG_use_compressed_instructions = false;
2652 __ SetExtensions(RV_G);
2653 __ lrw(T0, Address(A0));
2654 __ addi(T0, T0, 1);
2655 __ scw(A0, T0, Address(A0));
2656 __ ret();
2657}
2658ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalWord_Success, test) {
2659 EXPECT_DISASSEMBLY(
2660 "100522af lr.w t0, (a0)\n"
2661 "00128293 addi t0, t0, 1\n"
2662 "1855252f sc.w a0, t0, (a0)\n"
2663 "00008067 ret\n");
2664
2665 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2666 *value = 0b1100;
2667 EXPECT_EQ(0, Call(test->entry(), reinterpret_cast<intx_t>(value)));
2668 EXPECT_EQ(0b1101, *value);
2669}
2670
2671ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalWord_Failure, assembler) {
2672 FLAG_use_compressed_instructions = false;
2673 __ SetExtensions(RV_G);
2674 __ li(T0, 42);
2675 __ scw(A0, T0, Address(A0));
2676 __ ret();
2677}
2678ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalWord_Failure, test) {
2679 EXPECT_DISASSEMBLY(
2680 "02a00293 li t0, 42\n"
2681 "1855252f sc.w a0, t0, (a0)\n"
2682 "00008067 ret\n");
2683
2684 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2685 *value = 0b1100;
2686 EXPECT_EQ(false, 0 == Call(test->entry(), reinterpret_cast<intx_t>(value)));
2687 EXPECT_EQ(0b1100, *value);
2688}
2689
2690ASSEMBLER_TEST_GENERATE(AmoSwapWord, assembler) {
2691 FLAG_use_compressed_instructions = false;
2692 __ SetExtensions(RV_G);
2693 __ amoswapw(A0, A1, Address(A0));
2694 __ ret();
2695}
2696ASSEMBLER_TEST_RUN(AmoSwapWord, test) {
2697 EXPECT_DISASSEMBLY(
2698 "08b5252f amoswap.w a0, a1, (a0)\n"
2699 "00008067 ret\n");
2700
2701 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2702 *value = 0b1100;
2703 EXPECT_EQ(0b1100,
2704 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2705 EXPECT_EQ(0b1010, *value);
2706}
2707
2708ASSEMBLER_TEST_GENERATE(AmoAddWord, assembler) {
2709 FLAG_use_compressed_instructions = false;
2710 __ SetExtensions(RV_G);
2711 __ amoaddw(A0, A1, Address(A0));
2712 __ ret();
2713}
2714ASSEMBLER_TEST_RUN(AmoAddWord, test) {
2715 EXPECT_DISASSEMBLY(
2716 "00b5252f amoadd.w a0, a1, (a0)\n"
2717 "00008067 ret\n");
2718
2719 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2720 *value = 42;
2721 EXPECT_EQ(42, Call(test->entry(), reinterpret_cast<intx_t>(value), 10));
2722 EXPECT_EQ(52, *value);
2723}
2724
2725ASSEMBLER_TEST_GENERATE(AmoXorWord, assembler) {
2726 FLAG_use_compressed_instructions = false;
2727 __ SetExtensions(RV_G);
2728 __ amoxorw(A0, A1, Address(A0));
2729 __ ret();
2730}
2731ASSEMBLER_TEST_RUN(AmoXorWord, test) {
2732 EXPECT_DISASSEMBLY(
2733 "20b5252f amoxor.w a0, a1, (a0)\n"
2734 "00008067 ret\n");
2735
2736 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2737 *value = 0b1100;
2738 EXPECT_EQ(0b1100,
2739 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2740 EXPECT_EQ(0b0110, *value);
2741}
2742
2743ASSEMBLER_TEST_GENERATE(AmoAndWord, assembler) {
2744 FLAG_use_compressed_instructions = false;
2745 __ SetExtensions(RV_G);
2746 __ amoandw(A0, A1, Address(A0));
2747 __ ret();
2748}
2749ASSEMBLER_TEST_RUN(AmoAndWord, test) {
2750 EXPECT_DISASSEMBLY(
2751 "60b5252f amoand.w a0, a1, (a0)\n"
2752 "00008067 ret\n");
2753
2754 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2755 *value = 0b1100;
2756 EXPECT_EQ(0b1100,
2757 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2758 EXPECT_EQ(0b1000, *value);
2759}
2760
2761ASSEMBLER_TEST_GENERATE(AmoOrWord, assembler) {
2762 FLAG_use_compressed_instructions = false;
2763 __ SetExtensions(RV_G);
2764 __ amoorw(A0, A1, Address(A0));
2765 __ ret();
2766}
2767ASSEMBLER_TEST_RUN(AmoOrWord, test) {
2768 EXPECT_DISASSEMBLY(
2769 "40b5252f amoor.w a0, a1, (a0)\n"
2770 "00008067 ret\n");
2771
2772 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2773 *value = 0b1100;
2774 EXPECT_EQ(0b1100,
2775 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2776 EXPECT_EQ(0b1110, *value);
2777}
2778
2779ASSEMBLER_TEST_GENERATE(AmoMinWord, assembler) {
2780 FLAG_use_compressed_instructions = false;
2781 __ SetExtensions(RV_G);
2782 __ amominw(A0, A1, Address(A0));
2783 __ ret();
2784}
2785ASSEMBLER_TEST_RUN(AmoMinWord, test) {
2786 EXPECT_DISASSEMBLY(
2787 "80b5252f amomin.w a0, a1, (a0)\n"
2788 "00008067 ret\n");
2789
2790 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2791 *value = -7;
2792 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
2793 EXPECT_EQ(-7, *value);
2794 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
2795 EXPECT_EQ(-7, *value);
2796 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
2797 EXPECT_EQ(-11, *value);
2798}
2799
2800ASSEMBLER_TEST_GENERATE(AmoMaxWord, assembler) {
2801 FLAG_use_compressed_instructions = false;
2802 __ SetExtensions(RV_G);
2803 __ amomaxw(A0, A1, Address(A0));
2804 __ ret();
2805}
2806ASSEMBLER_TEST_RUN(AmoMaxWord, test) {
2807 EXPECT_DISASSEMBLY(
2808 "a0b5252f amomax.w a0, a1, (a0)\n"
2809 "00008067 ret\n");
2810
2811 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2812 *value = -7;
2813 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
2814 EXPECT_EQ(-7, *value);
2815 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
2816 EXPECT_EQ(-7, *value);
2817 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
2818 EXPECT_EQ(-4, *value);
2819}
2820
2821ASSEMBLER_TEST_GENERATE(AmoMinUnsignedWord, assembler) {
2822 FLAG_use_compressed_instructions = false;
2823 __ SetExtensions(RV_G);
2824 __ amominuw(A0, A1, Address(A0));
2825 __ ret();
2826}
2827ASSEMBLER_TEST_RUN(AmoMinUnsignedWord, test) {
2828 EXPECT_DISASSEMBLY(
2829 "c0b5252f amominu.w a0, a1, (a0)\n"
2830 "00008067 ret\n");
2831
2832 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2833 *value = -7;
2834 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
2835 Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
2836 EXPECT_EQ(-7, *value);
2837 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
2838 Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
2839 EXPECT_EQ(-7, *value);
2840 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
2841 Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
2842 EXPECT_EQ(-11, *value);
2843}
2844
2845ASSEMBLER_TEST_GENERATE(AmoMaxUnsignedWord, assembler) {
2846 FLAG_use_compressed_instructions = false;
2847 __ SetExtensions(RV_G);
2848 __ amomaxuw(A0, A1, Address(A0));
2849 __ ret();
2850}
2851ASSEMBLER_TEST_RUN(AmoMaxUnsignedWord, test) {
2852 EXPECT_DISASSEMBLY(
2853 "e0b5252f amomaxu.w a0, a1, (a0)\n"
2854 "00008067 ret\n");
2855
2856 int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
2857 *value = -7;
2858 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
2859 Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
2860 EXPECT_EQ(-7, *value);
2861 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
2862 Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
2863 EXPECT_EQ(-7, *value);
2864 EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
2865 Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
2866 EXPECT_EQ(-4, *value);
2867}
2868
2869#if XLEN >= 64
2870ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalDoubleWord_Success,
2871 assembler) {
2872 FLAG_use_compressed_instructions = false;
2873 __ SetExtensions(RV_G);
2874 __ lrd(T0, Address(A0));
2875 __ addi(T0, T0, 1);
2876 __ scd(A0, T0, Address(A0));
2877 __ ret();
2878}
2879ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalDoubleWord_Success, test) {
2880 EXPECT_DISASSEMBLY(
2881 "100532af lr.d t0, (a0)\n"
2882 "00128293 addi t0, t0, 1\n"
2883 "1855352f sc.d a0, t0, (a0)\n"
2884 "00008067 ret\n");
2885
2886 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2887 *value = 0b1100;
2888 EXPECT_EQ(0, Call(test->entry(), reinterpret_cast<intx_t>(value)));
2889 EXPECT_EQ(0b1101, *value);
2890}
2891
2892ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalDoubleWord_Failure,
2893 assembler) {
2894 FLAG_use_compressed_instructions = false;
2895 __ SetExtensions(RV_G);
2896 __ li(T0, 42);
2897 __ scd(A0, T0, Address(A0));
2898 __ ret();
2899}
2900ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalDoubleWord_Failure, test) {
2901 EXPECT_DISASSEMBLY(
2902 "02a00293 li t0, 42\n"
2903 "1855352f sc.d a0, t0, (a0)\n"
2904 "00008067 ret\n");
2905
2906 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2907 *value = 0b1100;
2908 EXPECT_EQ(false, 0 == Call(test->entry(), reinterpret_cast<intx_t>(value)));
2909 EXPECT_EQ(0b1100, *value);
2910}
2911
2912ASSEMBLER_TEST_GENERATE(AmoSwapDoubleWord, assembler) {
2913 FLAG_use_compressed_instructions = false;
2914 __ SetExtensions(RV_G);
2915 __ amoswapd(A0, A1, Address(A0));
2916 __ ret();
2917}
2918ASSEMBLER_TEST_RUN(AmoSwapDoubleWord, test) {
2919 EXPECT_DISASSEMBLY(
2920 "08b5352f amoswap.d a0, a1, (a0)\n"
2921 "00008067 ret\n");
2922
2923 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2924 *value = 0b1100;
2925 EXPECT_EQ(0b1100,
2926 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2927 EXPECT_EQ(0b1010, *value);
2928}
2929
2930ASSEMBLER_TEST_GENERATE(AmoAddDoubleWord, assembler) {
2931 FLAG_use_compressed_instructions = false;
2932 __ SetExtensions(RV_G);
2933 __ amoaddd(A0, A1, Address(A0));
2934 __ ret();
2935}
2936ASSEMBLER_TEST_RUN(AmoAddDoubleWord, test) {
2937 EXPECT_DISASSEMBLY(
2938 "00b5352f amoadd.d a0, a1, (a0)\n"
2939 "00008067 ret\n");
2940
2941 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2942 *value = 42;
2943 EXPECT_EQ(42, Call(test->entry(), reinterpret_cast<intx_t>(value), 10));
2944 EXPECT_EQ(52, *value);
2945}
2946
2947ASSEMBLER_TEST_GENERATE(AmoXorDoubleWord, assembler) {
2948 FLAG_use_compressed_instructions = false;
2949 __ SetExtensions(RV_G);
2950 __ amoxord(A0, A1, Address(A0));
2951 __ ret();
2952}
2953ASSEMBLER_TEST_RUN(AmoXorDoubleWord, test) {
2954 EXPECT_DISASSEMBLY(
2955 "20b5352f amoxor.d a0, a1, (a0)\n"
2956 "00008067 ret\n");
2957
2958 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2959 *value = 0b1100;
2960 EXPECT_EQ(0b1100,
2961 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2962 EXPECT_EQ(0b0110, *value);
2963}
2964
2965ASSEMBLER_TEST_GENERATE(AmoAndDoubleWord, assembler) {
2966 FLAG_use_compressed_instructions = false;
2967 __ SetExtensions(RV_G);
2968 __ amoandd(A0, A1, Address(A0));
2969 __ ret();
2970}
2971ASSEMBLER_TEST_RUN(AmoAndDoubleWord, test) {
2972 EXPECT_DISASSEMBLY(
2973 "60b5352f amoand.d a0, a1, (a0)\n"
2974 "00008067 ret\n");
2975
2976 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2977 *value = 0b1100;
2978 EXPECT_EQ(0b1100,
2979 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2980 EXPECT_EQ(0b1000, *value);
2981}
2982
2983ASSEMBLER_TEST_GENERATE(AmoOrDoubleWord, assembler) {
2984 FLAG_use_compressed_instructions = false;
2985 __ SetExtensions(RV_G);
2986 __ amoord(A0, A1, Address(A0));
2987 __ ret();
2988}
2989ASSEMBLER_TEST_RUN(AmoOrDoubleWord, test) {
2990 EXPECT_DISASSEMBLY(
2991 "40b5352f amoor.d a0, a1, (a0)\n"
2992 "00008067 ret\n");
2993
2994 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
2995 *value = 0b1100;
2996 EXPECT_EQ(0b1100,
2997 Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
2998 EXPECT_EQ(0b1110, *value);
2999}
3000
3001ASSEMBLER_TEST_GENERATE(AmoMinDoubleWord, assembler) {
3002 FLAG_use_compressed_instructions = false;
3003 __ SetExtensions(RV_G);
3004 __ amomind(A0, A1, Address(A0));
3005 __ ret();
3006}
3007ASSEMBLER_TEST_RUN(AmoMinDoubleWord, test) {
3008 EXPECT_DISASSEMBLY(
3009 "80b5352f amomin.d a0, a1, (a0)\n"
3010 "00008067 ret\n");
3011
3012 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
3013 *value = -7;
3014 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
3015 EXPECT_EQ(-7, *value);
3016 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
3017 EXPECT_EQ(-7, *value);
3018 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
3019 EXPECT_EQ(-11, *value);
3020}
3021
3022ASSEMBLER_TEST_GENERATE(AmoMaxDoubleWord, assembler) {
3023 FLAG_use_compressed_instructions = false;
3024 __ SetExtensions(RV_G);
3025 __ amomaxd(A0, A1, Address(A0));
3026 __ ret();
3027}
3028ASSEMBLER_TEST_RUN(AmoMaxDoubleWord, test) {
3029 EXPECT_DISASSEMBLY(
3030 "a0b5352f amomax.d a0, a1, (a0)\n"
3031 "00008067 ret\n");
3032
3033 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
3034 *value = -7;
3035 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
3036 EXPECT_EQ(-7, *value);
3037 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
3038 EXPECT_EQ(-7, *value);
3039 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
3040 EXPECT_EQ(-4, *value);
3041}
3042
3043ASSEMBLER_TEST_GENERATE(AmoMinUnsignedDoubleWord, assembler) {
3044 FLAG_use_compressed_instructions = false;
3045 __ SetExtensions(RV_G);
3046 __ amominud(A0, A1, Address(A0));
3047 __ ret();
3048}
3049ASSEMBLER_TEST_RUN(AmoMinUnsignedDoubleWord, test) {
3050 EXPECT_DISASSEMBLY(
3051 "c0b5352f amominu.d a0, a1, (a0)\n"
3052 "00008067 ret\n");
3053
3054 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
3055 *value = -7;
3056 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
3057 EXPECT_EQ(-7, *value);
3058 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
3059 EXPECT_EQ(-7, *value);
3060 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
3061 EXPECT_EQ(-11, *value);
3062}
3063
3064ASSEMBLER_TEST_GENERATE(AmoMaxUnsignedDoubleWord, assembler) {
3065 FLAG_use_compressed_instructions = false;
3066 __ SetExtensions(RV_G);
3067 __ amomaxud(A0, A1, Address(A0));
3068 __ ret();
3069}
3070ASSEMBLER_TEST_RUN(AmoMaxUnsignedDoubleWord, test) {
3071 EXPECT_DISASSEMBLY(
3072 "e0b5352f amomaxu.d a0, a1, (a0)\n"
3073 "00008067 ret\n");
3074
3075 int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
3076 *value = -7;
3077 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
3078 EXPECT_EQ(-7, *value);
3079 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
3080 EXPECT_EQ(-7, *value);
3081 EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
3082 EXPECT_EQ(-4, *value);
3083}
3084#endif
3085
3086ASSEMBLER_TEST_GENERATE(LoadSingleFloat, assembler) {
3087 FLAG_use_compressed_instructions = false;
3088 __ SetExtensions(RV_G);
3089 __ flw(FA0, Address(A0, 1 * sizeof(float)));
3090 __ ret();
3091}
3092ASSEMBLER_TEST_RUN(LoadSingleFloat, test) {
3093 EXPECT_DISASSEMBLY(
3094 "00452507 flw fa0, 4(a0)\n"
3095 "00008067 ret\n");
3096
3097 float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
3098 data[0] = 1.7f;
3099 data[1] = 2.8f;
3100 data[2] = 3.9f;
3101 EXPECT_EQ(data[1], CallF(test->entry(), reinterpret_cast<intx_t>(data)));
3102}
3103
3104ASSEMBLER_TEST_GENERATE(StoreSingleFloat, assembler) {
3105 FLAG_use_compressed_instructions = false;
3106 __ SetExtensions(RV_G);
3107 __ fsw(FA0, Address(A0, 1 * sizeof(float)));
3108 __ ret();
3109}
3110ASSEMBLER_TEST_RUN(StoreSingleFloat, test) {
3111 EXPECT_DISASSEMBLY(
3112 "00a52227 fsw fa0, 4(a0)\n"
3113 "00008067 ret\n");
3114
3115 float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
3116 data[0] = 1.7f;
3117 data[1] = 2.8f;
3118 data[2] = 3.9f;
3119 CallF(test->entry(), reinterpret_cast<intx_t>(data), 4.2f);
3120 EXPECT_EQ(4.2f, data[1]);
3121}
3122
3123ASSEMBLER_TEST_GENERATE(SingleMultiplyAdd, assembler) {
3124 FLAG_use_compressed_instructions = false;
3125 __ SetExtensions(RV_G);
3126 __ fmadds(FA0, FA0, FA1, FA2);
3127 __ ret();
3128}
3129ASSEMBLER_TEST_RUN(SingleMultiplyAdd, test) {
3130 EXPECT_DISASSEMBLY(
3131 "60b50543 fmadd.s fa0, fa0, fa1, fa2\n"
3132 "00008067 ret\n");
3133 EXPECT_EQ(22.0, CallF(test->entry(), 3.0, 5.0, 7.0));
3134 EXPECT_EQ(-8.0, CallF(test->entry(), -3.0, 5.0, 7.0));
3135 EXPECT_EQ(-8.0, CallF(test->entry(), 3.0, -5.0, 7.0));
3136 EXPECT_EQ(8.0, CallF(test->entry(), 3.0, 5.0, -7.0));
3137
3138 EXPECT_EQ(26.0, CallF(test->entry(), 7.0, 3.0, 5.0));
3139 EXPECT_EQ(-16.0, CallF(test->entry(), -7.0, 3.0, 5.0));
3140 EXPECT_EQ(-16.0, CallF(test->entry(), 7.0, -3.0, 5.0));
3141 EXPECT_EQ(16.0, CallF(test->entry(), 7.0, 3.0, -5.0));
3142}
3143
3144ASSEMBLER_TEST_GENERATE(SingleMultiplySubtract, assembler) {
3145 FLAG_use_compressed_instructions = false;
3146 __ SetExtensions(RV_G);
3147 __ fmsubs(FA0, FA0, FA1, FA2);
3148 __ ret();
3149}
3150ASSEMBLER_TEST_RUN(SingleMultiplySubtract, test) {
3151 EXPECT_DISASSEMBLY(
3152 "60b50547 fmsub.s fa0, fa0, fa1, fa2\n"
3153 "00008067 ret\n");
3154 EXPECT_EQ(8.0, CallF(test->entry(), 3.0, 5.0, 7.0));
3155 EXPECT_EQ(-22.0, CallF(test->entry(), -3.0, 5.0, 7.0));
3156 EXPECT_EQ(-22.0, CallF(test->entry(), 3.0, -5.0, 7.0));
3157 EXPECT_EQ(22.0, CallF(test->entry(), 3.0, 5.0, -7.0));
3158
3159 EXPECT_EQ(16.0, CallF(test->entry(), 7.0, 3.0, 5.0));
3160 EXPECT_EQ(-26.0, CallF(test->entry(), -7.0, 3.0, 5.0));
3161 EXPECT_EQ(-26.0, CallF(test->entry(), 7.0, -3.0, 5.0));
3162 EXPECT_EQ(26.0, CallF(test->entry(), 7.0, 3.0, -5.0));
3163}
3164
3165ASSEMBLER_TEST_GENERATE(SingleNegateMultiplySubtract, assembler) {
3166 FLAG_use_compressed_instructions = false;
3167 __ SetExtensions(RV_G);
3168 __ fnmsubs(FA0, FA0, FA1, FA2);
3169 __ ret();
3170}
3171ASSEMBLER_TEST_RUN(SingleNegateMultiplySubtract, test) {
3172 EXPECT_DISASSEMBLY(
3173 "60b5054b fnmsub.s fa0, fa0, fa1, fa2\n"
3174 "00008067 ret\n");
3175 EXPECT_EQ(-8.0, CallF(test->entry(), 3.0, 5.0, 7.0));
3176 EXPECT_EQ(22.0, CallF(test->entry(), -3.0, 5.0, 7.0));
3177 EXPECT_EQ(22.0, CallF(test->entry(), 3.0, -5.0, 7.0));
3178 EXPECT_EQ(-22.0, CallF(test->entry(), 3.0, 5.0, -7.0));
3179
3180 EXPECT_EQ(-16.0, CallF(test->entry(), 7.0, 3.0, 5.0));
3181 EXPECT_EQ(26.0, CallF(test->entry(), -7.0, 3.0, 5.0));
3182 EXPECT_EQ(26.0, CallF(test->entry(), 7.0, -3.0, 5.0));
3183 EXPECT_EQ(-26.0, CallF(test->entry(), 7.0, 3.0, -5.0));
3184}
3185
3186ASSEMBLER_TEST_GENERATE(SingleNegateMultiplyAdd, assembler) {
3187 FLAG_use_compressed_instructions = false;
3188 __ SetExtensions(RV_G);
3189 __ fnmadds(FA0, FA0, FA1, FA2);
3190 __ ret();
3191}
3192ASSEMBLER_TEST_RUN(SingleNegateMultiplyAdd, test) {
3193 EXPECT_DISASSEMBLY(
3194 "60b5054f fnmadd.s fa0, fa0, fa1, fa2\n"
3195 "00008067 ret\n");
3196 EXPECT_EQ(-22.0, CallF(test->entry(), 3.0, 5.0, 7.0));
3197 EXPECT_EQ(8.0, CallF(test->entry(), -3.0, 5.0, 7.0));
3198 EXPECT_EQ(8.0, CallF(test->entry(), 3.0, -5.0, 7.0));
3199 EXPECT_EQ(-8.0, CallF(test->entry(), 3.0, 5.0, -7.0));
3200
3201 EXPECT_EQ(-26.0, CallF(test->entry(), 7.0, 3.0, 5.0));
3202 EXPECT_EQ(16.0, CallF(test->entry(), -7.0, 3.0, 5.0));
3203 EXPECT_EQ(16.0, CallF(test->entry(), 7.0, -3.0, 5.0));
3204 EXPECT_EQ(-16.0, CallF(test->entry(), 7.0, 3.0, -5.0));
3205}
3206
3207ASSEMBLER_TEST_GENERATE(SingleAdd, assembler) {
3208 FLAG_use_compressed_instructions = false;
3209 __ SetExtensions(RV_G);
3210 __ fadds(FA0, FA0, FA1);
3211 __ ret();
3212}
3213ASSEMBLER_TEST_RUN(SingleAdd, test) {
3214 EXPECT_DISASSEMBLY(
3215 "00b50553 fadd.s fa0, fa0, fa1\n"
3216 "00008067 ret\n");
3217 EXPECT_EQ(8.0f, CallF(test->entry(), 3.0f, 5.0f));
3218 EXPECT_EQ(2.0f, CallF(test->entry(), -3.0f, 5.0f));
3219 EXPECT_EQ(-2.0f, CallF(test->entry(), 3.0f, -5.0f));
3220 EXPECT_EQ(-8.0f, CallF(test->entry(), -3.0f, -5.0f));
3221
3222 EXPECT_EQ(10.0f, CallF(test->entry(), 7.0f, 3.0f));
3223 EXPECT_EQ(-4.0f, CallF(test->entry(), -7.0f, 3.0f));
3224 EXPECT_EQ(4.0f, CallF(test->entry(), 7.0f, -3.0f));
3225 EXPECT_EQ(-10.0f, CallF(test->entry(), -7.0f, -3.0f));
3226}
3227
3228ASSEMBLER_TEST_GENERATE(SingleSubtract, assembler) {
3229 FLAG_use_compressed_instructions = false;
3230 __ SetExtensions(RV_G);
3231 __ fsubs(FA0, FA0, FA1);
3232 __ ret();
3233}
3234ASSEMBLER_TEST_RUN(SingleSubtract, test) {
3235 EXPECT_DISASSEMBLY(
3236 "08b50553 fsub.s fa0, fa0, fa1\n"
3237 "00008067 ret\n");
3238 EXPECT_EQ(-2.0f, CallF(test->entry(), 3.0f, 5.0f));
3239 EXPECT_EQ(-8.0f, CallF(test->entry(), -3.0f, 5.0f));
3240 EXPECT_EQ(8.0f, CallF(test->entry(), 3.0f, -5.0f));
3241 EXPECT_EQ(2.0f, CallF(test->entry(), -3.0f, -5.0f));
3242
3243 EXPECT_EQ(4.0f, CallF(test->entry(), 7.0f, 3.0f));
3244 EXPECT_EQ(-10.0f, CallF(test->entry(), -7.0f, 3.0f));
3245 EXPECT_EQ(10.0f, CallF(test->entry(), 7.0f, -3.0f));
3246 EXPECT_EQ(-4.0f, CallF(test->entry(), -7.0f, -3.0f));
3247}
3248
3249ASSEMBLER_TEST_GENERATE(SingleMultiply, assembler) {
3250 FLAG_use_compressed_instructions = false;
3251 __ SetExtensions(RV_G);
3252 __ fmuls(FA0, FA0, FA1);
3253 __ ret();
3254}
3255ASSEMBLER_TEST_RUN(SingleMultiply, test) {
3256 EXPECT_DISASSEMBLY(
3257 "10b50553 fmul.s fa0, fa0, fa1\n"
3258 "00008067 ret\n");
3259 EXPECT_EQ(15.0f, CallF(test->entry(), 3.0f, 5.0f));
3260 EXPECT_EQ(-15.0f, CallF(test->entry(), -3.0f, 5.0f));
3261 EXPECT_EQ(-15.0f, CallF(test->entry(), 3.0f, -5.0f));
3262 EXPECT_EQ(15.0f, CallF(test->entry(), -3.0f, -5.0f));
3263
3264 EXPECT_EQ(21.0f, CallF(test->entry(), 7.0f, 3.0f));
3265 EXPECT_EQ(-21.0f, CallF(test->entry(), -7.0f, 3.0f));
3266 EXPECT_EQ(-21.0f, CallF(test->entry(), 7.0f, -3.0f));
3267 EXPECT_EQ(21.0f, CallF(test->entry(), -7.0f, -3.0f));
3268}
3269
3270ASSEMBLER_TEST_GENERATE(SingleDivide, assembler) {
3271 FLAG_use_compressed_instructions = false;
3272 __ SetExtensions(RV_G);
3273 __ fdivs(FA0, FA0, FA1);
3274 __ ret();
3275}
3276ASSEMBLER_TEST_RUN(SingleDivide, test) {
3277 EXPECT_DISASSEMBLY(
3278 "18b50553 fdiv.s fa0, fa0, fa1\n"
3279 "00008067 ret\n");
3280 EXPECT_EQ(2.0f, CallF(test->entry(), 10.0f, 5.0f));
3281 EXPECT_EQ(-2.0f, CallF(test->entry(), -10.0f, 5.0f));
3282 EXPECT_EQ(-2.0f, CallF(test->entry(), 10.0f, -5.0f));
3283 EXPECT_EQ(2.0f, CallF(test->entry(), -10.0f, -5.0f));
3284}
3285
3286ASSEMBLER_TEST_GENERATE(SingleSquareRoot, assembler) {
3287 FLAG_use_compressed_instructions = false;
3288 __ SetExtensions(RV_G);
3289 __ fsqrts(FA0, FA0);
3290 __ ret();
3291}
3292ASSEMBLER_TEST_RUN(SingleSquareRoot, test) {
3293 EXPECT_DISASSEMBLY(
3294 "58050553 fsqrt.s fa0, fa0\n"
3295 "00008067 ret\n");
3296 EXPECT_EQ(0.0f, CallF(test->entry(), 0.0f));
3297 EXPECT_EQ(1.0f, CallF(test->entry(), 1.0f));
3298 EXPECT_EQ(2.0f, CallF(test->entry(), 4.0f));
3299 EXPECT_EQ(3.0f, CallF(test->entry(), 9.0f));
3300}
3301
3302ASSEMBLER_TEST_GENERATE(SingleSignInject, assembler) {
3303 FLAG_use_compressed_instructions = false;
3304 __ SetExtensions(RV_G);
3305 __ fsgnjs(FA0, FA0, FA1);
3306 __ ret();
3307}
3308ASSEMBLER_TEST_RUN(SingleSignInject, test) {
3309 EXPECT_DISASSEMBLY(
3310 "20b50553 fsgnj.s fa0, fa0, fa1\n"
3311 "00008067 ret\n");
3312 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 5.0f));
3313 EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, 5.0f));
3314 EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, -5.0f));
3315 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -5.0f));
3316}
3317
3318ASSEMBLER_TEST_GENERATE(SingleNegatedSignInject, assembler) {
3319 FLAG_use_compressed_instructions = false;
3320 __ SetExtensions(RV_G);
3321 __ fsgnjns(FA0, FA0, FA1);
3322 __ ret();
3323}
3324ASSEMBLER_TEST_RUN(SingleNegatedSignInject, test) {
3325 EXPECT_DISASSEMBLY(
3326 "20b51553 fsgnjn.s fa0, fa0, fa1\n"
3327 "00008067 ret\n");
3328 EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, 5.0f));
3329 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 5.0f));
3330 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -5.0f));
3331 EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, -5.0f));
3332}
3333
3334ASSEMBLER_TEST_GENERATE(SingleXorSignInject, assembler) {
3335 FLAG_use_compressed_instructions = false;
3336 __ SetExtensions(RV_G);
3337 __ fsgnjxs(FA0, FA0, FA1);
3338 __ ret();
3339}
3340ASSEMBLER_TEST_RUN(SingleXorSignInject, test) {
3341 EXPECT_DISASSEMBLY(
3342 "20b52553 fsgnjx.s fa0, fa0, fa1\n"
3343 "00008067 ret\n");
3344 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 5.0f));
3345 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 5.0f));
3346 EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, -5.0f));
3347 EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, -5.0f));
3348}
3349
3350ASSEMBLER_TEST_GENERATE(SingleMin, assembler) {
3351 FLAG_use_compressed_instructions = false;
3352 __ SetExtensions(RV_G);
3353 __ fmins(FA0, FA0, FA1);
3354 __ ret();
3355}
3356ASSEMBLER_TEST_RUN(SingleMin, test) {
3357 EXPECT_DISASSEMBLY(
3358 "28b50553 fmin.s fa0, fa0, fa1\n"
3359 "00008067 ret\n");
3360 EXPECT_EQ(1.0f, CallF(test->entry(), 3.0f, 1.0f));
3361 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 3.0f));
3362 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 5.0f));
3363 EXPECT_EQ(-1.0f, CallF(test->entry(), 3.0f, -1.0f));
3364 EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, -3.0f));
3365 EXPECT_EQ(-5.0f, CallF(test->entry(), 3.0f, -5.0f));
3366 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 1.0f));
3367 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 3.0f));
3368 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 5.0f));
3369 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -1.0f));
3370 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -3.0f));
3371 EXPECT_EQ(-5.0f, CallF(test->entry(), -3.0f, -5.0f));
3372
3373 EXPECT_EQ(bit_cast<uint32_t>(-0.0f),
3374 bit_cast<uint32_t>(CallF(test->entry(), 0.0f, -0.0f)));
3375 EXPECT_EQ(bit_cast<uint32_t>(-0.0f),
3376 bit_cast<uint32_t>(CallF(test->entry(), -0.0f, 0.0f)));
3377
3378 float qNAN = std::numeric_limits<float>::quiet_NaN();
3379 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, qNAN));
3380 EXPECT_EQ(3.0f, CallF(test->entry(), qNAN, 3.0f));
3381 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, qNAN));
3382 EXPECT_EQ(-3.0f, CallF(test->entry(), qNAN, -3.0f));
3383
3384 float sNAN = std::numeric_limits<float>::signaling_NaN();
3385 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, sNAN));
3386 EXPECT_EQ(3.0f, CallF(test->entry(), sNAN, 3.0f));
3387 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, sNAN));
3388 EXPECT_EQ(-3.0f, CallF(test->entry(), sNAN, -3.0f));
3389
3390 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3391 bit_cast<uint32_t>(CallF(test->entry(), qNAN, qNAN)));
3392 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3393 bit_cast<uint32_t>(CallF(test->entry(), sNAN, sNAN)));
3394 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3395 bit_cast<uint32_t>(CallF(test->entry(), qNAN, sNAN)));
3396 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3397 bit_cast<uint32_t>(CallF(test->entry(), sNAN, qNAN)));
3398}
3399
3400ASSEMBLER_TEST_GENERATE(SingleMax, assembler) {
3401 FLAG_use_compressed_instructions = false;
3402 __ SetExtensions(RV_G);
3403 __ fmaxs(FA0, FA0, FA1);
3404 __ ret();
3405}
3406ASSEMBLER_TEST_RUN(SingleMax, test) {
3407 EXPECT_DISASSEMBLY(
3408 "28b51553 fmax.s fa0, fa0, fa1\n"
3409 "00008067 ret\n");
3410 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 1.0f));
3411 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 3.0f));
3412 EXPECT_EQ(5.0f, CallF(test->entry(), 3.0f, 5.0f));
3413 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -1.0f));
3414 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -3.0f));
3415 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -5.0f));
3416 EXPECT_EQ(1.0f, CallF(test->entry(), -3.0f, 1.0f));
3417 EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, 3.0f));
3418 EXPECT_EQ(5.0f, CallF(test->entry(), -3.0f, 5.0f));
3419 EXPECT_EQ(-1.0f, CallF(test->entry(), -3.0f, -1.0f));
3420 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -3.0f));
3421 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -5.0f));
3422
3423 EXPECT_EQ(bit_cast<uint32_t>(0.0f),
3424 bit_cast<uint32_t>(CallF(test->entry(), 0.0f, -0.0f)));
3425 EXPECT_EQ(bit_cast<uint32_t>(0.0f),
3426 bit_cast<uint32_t>(CallF(test->entry(), -0.0f, 0.0f)));
3427
3428 float qNAN = std::numeric_limits<float>::quiet_NaN();
3429 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, qNAN));
3430 EXPECT_EQ(3.0f, CallF(test->entry(), qNAN, 3.0f));
3431 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, qNAN));
3432 EXPECT_EQ(-3.0f, CallF(test->entry(), qNAN, -3.0f));
3433
3434 float sNAN = std::numeric_limits<float>::signaling_NaN();
3435 EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, sNAN));
3436 EXPECT_EQ(3.0f, CallF(test->entry(), sNAN, 3.0f));
3437 EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, sNAN));
3438 EXPECT_EQ(-3.0f, CallF(test->entry(), sNAN, -3.0f));
3439
3440 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3441 bit_cast<uint32_t>(CallF(test->entry(), qNAN, qNAN)));
3442 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3443 bit_cast<uint32_t>(CallF(test->entry(), sNAN, sNAN)));
3444 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3445 bit_cast<uint32_t>(CallF(test->entry(), qNAN, sNAN)));
3446 EXPECT_EQ(bit_cast<uint32_t>(qNAN),
3447 bit_cast<uint32_t>(CallF(test->entry(), sNAN, qNAN)));
3448}
3449
3450ASSEMBLER_TEST_GENERATE(SingleEqual, assembler) {
3451 FLAG_use_compressed_instructions = false;
3452 __ SetExtensions(RV_G);
3453 __ feqs(A0, FA0, FA1);
3454 __ ret();
3455}
3456ASSEMBLER_TEST_RUN(SingleEqual, test) {
3457 EXPECT_DISASSEMBLY(
3458 "a0b52553 feq.s a0, fa0, fa1\n"
3459 "00008067 ret\n");
3460 EXPECT_EQ(0, CallI(test->entry(), 3.0f, 1.0f));
3461 EXPECT_EQ(1, CallI(test->entry(), 3.0f, 3.0f));
3462 EXPECT_EQ(0, CallI(test->entry(), 3.0f, 5.0f));
3463 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -1.0f));
3464 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -3.0f));
3465 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -5.0f));
3466 EXPECT_EQ(0, CallI(test->entry(), -3.0f, 1.0f));
3467 EXPECT_EQ(0, CallI(test->entry(), -3.0f, 3.0f));
3468 EXPECT_EQ(0, CallI(test->entry(), -3.0f, 5.0f));
3469 EXPECT_EQ(0, CallI(test->entry(), -3.0f, -1.0f));
3470 EXPECT_EQ(1, CallI(test->entry(), -3.0f, -3.0f));
3471 EXPECT_EQ(0, CallI(test->entry(), -3.0f, -5.0f));
3472
3473 float qNAN = std::numeric_limits<float>::quiet_NaN();
3474 EXPECT_EQ(0, CallI(test->entry(), 3.0f, qNAN));
3475 EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0f));
3476 EXPECT_EQ(0, CallI(test->entry(), -3.0f, qNAN));
3477 EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0f));
3478}
3479
3480ASSEMBLER_TEST_GENERATE(SingleLessThan, assembler) {
3481 FLAG_use_compressed_instructions = false;
3482 __ SetExtensions(RV_G);
3483 __ flts(A0, FA0, FA1);
3484 __ ret();
3485}
3486ASSEMBLER_TEST_RUN(SingleLessThan, test) {
3487 EXPECT_DISASSEMBLY(
3488 "a0b51553 flt.s a0, fa0, fa1\n"
3489 "00008067 ret\n");
3490 EXPECT_EQ(0, CallI(test->entry(), 3.0f, 1.0f));
3491 EXPECT_EQ(0, CallI(test->entry(), 3.0f, 3.0f));
3492 EXPECT_EQ(1, CallI(test->entry(), 3.0f, 5.0f));
3493 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -1.0f));
3494 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -3.0f));
3495 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -5.0f));
3496 EXPECT_EQ(1, CallI(test->entry(), -3.0f, 1.0f));
3497 EXPECT_EQ(1, CallI(test->entry(), -3.0f, 3.0f));
3498 EXPECT_EQ(1, CallI(test->entry(), -3.0f, 5.0f));
3499 EXPECT_EQ(1, CallI(test->entry(), -3.0f, -1.0f));
3500 EXPECT_EQ(0, CallI(test->entry(), -3.0f, -3.0f));
3501 EXPECT_EQ(0, CallI(test->entry(), -3.0f, -5.0f));
3502
3503 float qNAN = std::numeric_limits<float>::quiet_NaN();
3504 EXPECT_EQ(0, CallI(test->entry(), 3.0f, qNAN));
3505 EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0f));
3506 EXPECT_EQ(0, CallI(test->entry(), -3.0f, qNAN));
3507 EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0f));
3508}
3509
3510ASSEMBLER_TEST_GENERATE(SingleLessOrEqual, assembler) {
3511 FLAG_use_compressed_instructions = false;
3512 __ SetExtensions(RV_G);
3513 __ fles(A0, FA0, FA1);
3514 __ ret();
3515}
3516ASSEMBLER_TEST_RUN(SingleLessOrEqual, test) {
3517 EXPECT_DISASSEMBLY(
3518 "a0b50553 fle.s a0, fa0, fa1\n"
3519 "00008067 ret\n");
3520 EXPECT_EQ(0, CallI(test->entry(), 3.0f, 1.0f));
3521 EXPECT_EQ(1, CallI(test->entry(), 3.0f, 3.0f));
3522 EXPECT_EQ(1, CallI(test->entry(), 3.0f, 5.0f));
3523 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -1.0f));
3524 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -3.0f));
3525 EXPECT_EQ(0, CallI(test->entry(), 3.0f, -5.0f));
3526 EXPECT_EQ(1, CallI(test->entry(), -3.0f, 1.0f));
3527 EXPECT_EQ(1, CallI(test->entry(), -3.0f, 3.0f));
3528 EXPECT_EQ(1, CallI(test->entry(), -3.0f, 5.0f));
3529 EXPECT_EQ(1, CallI(test->entry(), -3.0f, -1.0f));
3530 EXPECT_EQ(1, CallI(test->entry(), -3.0f, -3.0f));
3531 EXPECT_EQ(0, CallI(test->entry(), -3.0f, -5.0f));
3532
3533 float qNAN = std::numeric_limits<float>::quiet_NaN();
3534 EXPECT_EQ(0, CallI(test->entry(), 3.0f, qNAN));
3535 EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0f));
3536 EXPECT_EQ(0, CallI(test->entry(), -3.0f, qNAN));
3537 EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0f));
3538}
3539
3540ASSEMBLER_TEST_GENERATE(SingleClassify, assembler) {
3541 FLAG_use_compressed_instructions = false;
3542 __ SetExtensions(RV_G);
3543 __ fclasss(A0, FA0);
3544 __ ret();
3545}
3546ASSEMBLER_TEST_RUN(SingleClassify, test) {
3547 EXPECT_DISASSEMBLY(
3548 "e0051553 fclass.s a0, fa0\n"
3549 "00008067 ret\n");
3550 // Neg infinity
3551 EXPECT_EQ(1 << 0,
3552 CallI(test->entry(), -std::numeric_limits<float>::infinity()));
3553 // Neg normal
3554 EXPECT_EQ(1 << 1, CallI(test->entry(), -1.0f));
3555 // Neg subnormal
3556 EXPECT_EQ(1 << 2,
3557 CallI(test->entry(), -std::numeric_limits<float>::min() / 2.0f));
3558 // Neg zero
3559 EXPECT_EQ(1 << 3, CallI(test->entry(), -0.0f));
3560 // Pos zero
3561 EXPECT_EQ(1 << 4, CallI(test->entry(), 0.0f));
3562 // Pos subnormal
3563 EXPECT_EQ(1 << 5,
3564 CallI(test->entry(), std::numeric_limits<float>::min() / 2.0f));
3565 // Pos normal
3566 EXPECT_EQ(1 << 6, CallI(test->entry(), 1.0f));
3567 // Pos infinity
3568 EXPECT_EQ(1 << 7,
3569 CallI(test->entry(), std::numeric_limits<float>::infinity()));
3570 // Signaling NaN
3571 EXPECT_EQ(1 << 8,
3572 CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
3573 // Queit NaN
3574 EXPECT_EQ(1 << 9,
3575 CallI(test->entry(), std::numeric_limits<float>::quiet_NaN()));
3576}
3577
3578ASSEMBLER_TEST_GENERATE(ConvertSingleToWord, assembler) {
3579 FLAG_use_compressed_instructions = false;
3580 __ SetExtensions(RV_G);
3581 __ fcvtws(A0, FA0);
3582 __ ret();
3583}
3584ASSEMBLER_TEST_RUN(ConvertSingleToWord, test) {
3585 EXPECT_DISASSEMBLY(
3586 "c0050553 fcvt.w.s a0, fa0\n"
3587 "00008067 ret\n");
3588 EXPECT_EQ(-42, CallI(test->entry(), static_cast<float>(-42)));
3589 EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
3590 EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
3591 EXPECT_EQ(sign_extend(kMinInt32),
3592 CallI(test->entry(), static_cast<float>(kMinInt32)));
3593 EXPECT_EQ(sign_extend(kMaxInt32),
3594 CallI(test->entry(), static_cast<float>(kMaxInt32)));
3595 EXPECT_EQ(sign_extend(kMaxInt32),
3596 CallI(test->entry(), static_cast<float>(kMaxUint32)));
3597 EXPECT_EQ(sign_extend(kMinInt32),
3598 CallI(test->entry(), static_cast<float>(kMinInt64)));
3599 EXPECT_EQ(sign_extend(kMaxInt32),
3600 CallI(test->entry(), static_cast<float>(kMaxInt64)));
3601 EXPECT_EQ(sign_extend(kMaxInt32),
3602 CallI(test->entry(), static_cast<float>(kMaxUint64)));
3603 EXPECT_EQ(sign_extend(kMinInt32),
3604 CallI(test->entry(), -std::numeric_limits<float>::infinity()));
3605 EXPECT_EQ(sign_extend(kMaxInt32),
3606 CallI(test->entry(), std::numeric_limits<float>::infinity()));
3607 EXPECT_EQ(sign_extend(kMaxInt32),
3608 CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
3609}
3610
3611ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RNE, assembler) {
3612 FLAG_use_compressed_instructions = false;
3613 __ SetExtensions(RV_G);
3614 __ fcvtws(A0, FA0, RNE);
3615 __ ret();
3616}
3617ASSEMBLER_TEST_RUN(ConvertSingleToWord_RNE, test) {
3618 EXPECT_DISASSEMBLY(
3619 "c0050553 fcvt.w.s a0, fa0\n"
3620 "00008067 ret\n");
3621 EXPECT_EQ(-44, CallI(test->entry(), -43.6f));
3622 EXPECT_EQ(-44, CallI(test->entry(), -43.5f));
3623 EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
3624 EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
3625 EXPECT_EQ(-43, CallI(test->entry(), -42.6f));
3626 EXPECT_EQ(-42, CallI(test->entry(), -42.5f));
3627 EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
3628 EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
3629 EXPECT_EQ(0, CallI(test->entry(), -0.0f));
3630 EXPECT_EQ(0, CallI(test->entry(), +0.0f));
3631 EXPECT_EQ(42, CallI(test->entry(), 42.0f));
3632 EXPECT_EQ(42, CallI(test->entry(), 42.4f));
3633 EXPECT_EQ(42, CallI(test->entry(), 42.5f));
3634 EXPECT_EQ(43, CallI(test->entry(), 42.6f));
3635 EXPECT_EQ(43, CallI(test->entry(), 43.0f));
3636 EXPECT_EQ(43, CallI(test->entry(), 43.4f));
3637 EXPECT_EQ(44, CallI(test->entry(), 43.5f));
3638 EXPECT_EQ(44, CallI(test->entry(), 43.6f));
3639}
3640
3641ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RTZ, assembler) {
3642 FLAG_use_compressed_instructions = false;
3643 __ SetExtensions(RV_G);
3644 __ fcvtws(A0, FA0, RTZ);
3645 __ ret();
3646}
3647ASSEMBLER_TEST_RUN(ConvertSingleToWord_RTZ, test) {
3648 EXPECT_DISASSEMBLY(
3649 "c0051553 fcvt.w.s a0, fa0, rtz\n"
3650 "00008067 ret\n");
3651 EXPECT_EQ(-43, CallI(test->entry(), -43.6f));
3652 EXPECT_EQ(-43, CallI(test->entry(), -43.5f));
3653 EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
3654 EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
3655 EXPECT_EQ(-42, CallI(test->entry(), -42.6f));
3656 EXPECT_EQ(-42, CallI(test->entry(), -42.5f));
3657 EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
3658 EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
3659 EXPECT_EQ(0, CallI(test->entry(), -0.0f));
3660 EXPECT_EQ(0, CallI(test->entry(), +0.0f));
3661 EXPECT_EQ(42, CallI(test->entry(), 42.0f));
3662 EXPECT_EQ(42, CallI(test->entry(), 42.4f));
3663 EXPECT_EQ(42, CallI(test->entry(), 42.5f));
3664 EXPECT_EQ(42, CallI(test->entry(), 42.6f));
3665 EXPECT_EQ(43, CallI(test->entry(), 43.0f));
3666 EXPECT_EQ(43, CallI(test->entry(), 43.4f));
3667 EXPECT_EQ(43, CallI(test->entry(), 43.5f));
3668 EXPECT_EQ(43, CallI(test->entry(), 43.6f));
3669}
3670
3671ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RDN, assembler) {
3672 FLAG_use_compressed_instructions = false;
3673 __ SetExtensions(RV_G);
3674 __ fcvtws(A0, FA0, RDN);
3675 __ ret();
3676}
3677ASSEMBLER_TEST_RUN(ConvertSingleToWord_RDN, test) {
3678 EXPECT_DISASSEMBLY(
3679 "c0052553 fcvt.w.s a0, fa0, rdn\n"
3680 "00008067 ret\n");
3681 EXPECT_EQ(-44, CallI(test->entry(), -43.6f));
3682 EXPECT_EQ(-44, CallI(test->entry(), -43.5f));
3683 EXPECT_EQ(-44, CallI(test->entry(), -43.4f));
3684 EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
3685 EXPECT_EQ(-43, CallI(test->entry(), -42.6f));
3686 EXPECT_EQ(-43, CallI(test->entry(), -42.5f));
3687 EXPECT_EQ(-43, CallI(test->entry(), -42.4f));
3688 EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
3689 EXPECT_EQ(0, CallI(test->entry(), -0.0f));
3690 EXPECT_EQ(0, CallI(test->entry(), +0.0f));
3691 EXPECT_EQ(42, CallI(test->entry(), 42.0f));
3692 EXPECT_EQ(42, CallI(test->entry(), 42.4f));
3693 EXPECT_EQ(42, CallI(test->entry(), 42.5f));
3694 EXPECT_EQ(42, CallI(test->entry(), 42.6f));
3695 EXPECT_EQ(43, CallI(test->entry(), 43.0f));
3696 EXPECT_EQ(43, CallI(test->entry(), 43.4f));
3697 EXPECT_EQ(43, CallI(test->entry(), 43.5f));
3698 EXPECT_EQ(43, CallI(test->entry(), 43.6f));
3699}
3700
3701ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RUP, assembler) {
3702 FLAG_use_compressed_instructions = false;
3703 __ SetExtensions(RV_G);
3704 __ fcvtws(A0, FA0, RUP);
3705 __ ret();
3706}
3707ASSEMBLER_TEST_RUN(ConvertSingleToWord_RUP, test) {
3708 EXPECT_DISASSEMBLY(
3709 "c0053553 fcvt.w.s a0, fa0, rup\n"
3710 "00008067 ret\n");
3711 EXPECT_EQ(-43, CallI(test->entry(), -43.6f));
3712 EXPECT_EQ(-43, CallI(test->entry(), -43.5f));
3713 EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
3714 EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
3715 EXPECT_EQ(-42, CallI(test->entry(), -42.6f));
3716 EXPECT_EQ(-42, CallI(test->entry(), -42.5f));
3717 EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
3718 EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
3719 EXPECT_EQ(0, CallI(test->entry(), -0.0f));
3720 EXPECT_EQ(0, CallI(test->entry(), +0.0f));
3721 EXPECT_EQ(42, CallI(test->entry(), 42.0f));
3722 EXPECT_EQ(43, CallI(test->entry(), 42.4f));
3723 EXPECT_EQ(43, CallI(test->entry(), 42.5f));
3724 EXPECT_EQ(43, CallI(test->entry(), 42.6f));
3725 EXPECT_EQ(43, CallI(test->entry(), 43.0f));
3726 EXPECT_EQ(44, CallI(test->entry(), 43.5f));
3727 EXPECT_EQ(44, CallI(test->entry(), 43.5f));
3728 EXPECT_EQ(44, CallI(test->entry(), 43.6f));
3729}
3730
3731ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RMM, assembler) {
3732 FLAG_use_compressed_instructions = false;
3733 __ SetExtensions(RV_G);
3734 __ fcvtws(A0, FA0, RMM);
3735 __ ret();
3736}
3737ASSEMBLER_TEST_RUN(ConvertSingleToWord_RMM, test) {
3738 EXPECT_DISASSEMBLY(
3739 "c0054553 fcvt.w.s a0, fa0, rmm\n"
3740 "00008067 ret\n");
3741 EXPECT_EQ(-44, CallI(test->entry(), -43.6f));
3742 EXPECT_EQ(-44, CallI(test->entry(), -43.5f));
3743 EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
3744 EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
3745 EXPECT_EQ(-43, CallI(test->entry(), -42.6f));
3746 EXPECT_EQ(-43, CallI(test->entry(), -42.5f));
3747 EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
3748 EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
3749 EXPECT_EQ(0, CallI(test->entry(), -0.0f));
3750 EXPECT_EQ(0, CallI(test->entry(), +0.0f));
3751 EXPECT_EQ(42, CallI(test->entry(), 42.0f));
3752 EXPECT_EQ(42, CallI(test->entry(), 42.4f));
3753 EXPECT_EQ(43, CallI(test->entry(), 42.5f));
3754 EXPECT_EQ(43, CallI(test->entry(), 42.6f));
3755 EXPECT_EQ(43, CallI(test->entry(), 43.0f));
3756 EXPECT_EQ(43, CallI(test->entry(), 43.4f));
3757 EXPECT_EQ(44, CallI(test->entry(), 43.5f));
3758 EXPECT_EQ(44, CallI(test->entry(), 43.6f));
3759}
3760
3761ASSEMBLER_TEST_GENERATE(ConvertSingleToUnsignedWord, assembler) {
3762 FLAG_use_compressed_instructions = false;
3763 __ SetExtensions(RV_G);
3764 __ fcvtwus(A0, FA0);
3765 __ ret();
3766}
3767ASSEMBLER_TEST_RUN(ConvertSingleToUnsignedWord, test) {
3768 EXPECT_DISASSEMBLY(
3769 "c0150553 fcvt.wu.s a0, fa0\n"
3770 "00008067 ret\n");
3771 EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(-42)));
3772 EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
3773 EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
3774 EXPECT_EQ(sign_extend(0),
3775 CallI(test->entry(), static_cast<float>(kMinInt32)));
3776 // float loss of precision
3777 EXPECT_EQ(-2147483648, CallI(test->entry(), static_cast<float>(kMaxInt32)));
3778 EXPECT_EQ(sign_extend(kMaxUint32),
3779 CallI(test->entry(), static_cast<float>(kMaxUint32)));
3780 EXPECT_EQ(sign_extend(0),
3781 CallI(test->entry(), static_cast<float>(kMinInt64)));
3782 EXPECT_EQ(sign_extend(kMaxUint32),
3783 CallI(test->entry(), static_cast<float>(kMaxInt64)));
3784 EXPECT_EQ(sign_extend(kMaxUint32),
3785 CallI(test->entry(), static_cast<float>(kMaxUint64)));
3786 EXPECT_EQ(sign_extend(0),
3787 CallI(test->entry(), -std::numeric_limits<float>::infinity()));
3788 EXPECT_EQ(sign_extend(kMaxUint32),
3789 CallI(test->entry(), std::numeric_limits<float>::infinity()));
3790 EXPECT_EQ(sign_extend(kMaxUint32),
3791 CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
3792}
3793
3794ASSEMBLER_TEST_GENERATE(ConvertWordToSingle, assembler) {
3795 FLAG_use_compressed_instructions = false;
3796 __ SetExtensions(RV_G);
3797 __ fcvtsw(FA0, A0);
3798 __ ret();
3799}
3800ASSEMBLER_TEST_RUN(ConvertWordToSingle, test) {
3801 EXPECT_DISASSEMBLY(
3802 "d0050553 fcvt.s.w fa0, a0\n"
3803 "00008067 ret\n");
3804 EXPECT_EQ(-42.0f, CallF(test->entry(), sign_extend(-42)));
3805 EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
3806 EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
3807 EXPECT_EQ(static_cast<float>(kMinInt32),
3808 CallF(test->entry(), sign_extend(kMinInt32)));
3809 EXPECT_EQ(static_cast<float>(kMaxInt32),
3810 CallF(test->entry(), sign_extend(kMaxInt32)));
3811 EXPECT_EQ(-1.0f, CallF(test->entry(), sign_extend(kMaxUint32)));
3812}
3813
3814ASSEMBLER_TEST_GENERATE(ConvertUnsignedWordToSingle, assembler) {
3815 FLAG_use_compressed_instructions = false;
3816 __ SetExtensions(RV_G);
3817 __ fcvtswu(FA0, A0);
3818 __ ret();
3819}
3820ASSEMBLER_TEST_RUN(ConvertUnsignedWordToSingle, test) {
3821 EXPECT_DISASSEMBLY(
3822 "d0150553 fcvt.s.wu fa0, a0\n"
3823 "00008067 ret\n");
3824 EXPECT_EQ(
3825 static_cast<float>(static_cast<uint32_t>(static_cast<int32_t>(-42))),
3826 CallF(test->entry(), sign_extend(-42)));
3827 EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
3828 EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
3829 EXPECT_EQ(static_cast<float>(static_cast<uint32_t>(kMinInt32)),
3830 CallF(test->entry(), sign_extend(kMinInt32)));
3831 EXPECT_EQ(static_cast<float>(kMaxInt32),
3832 CallF(test->entry(), sign_extend(kMaxInt32)));
3833 EXPECT_EQ(static_cast<float>(kMaxUint32),
3834 CallF(test->entry(), sign_extend(kMaxUint32)));
3835}
3836
3837ASSEMBLER_TEST_GENERATE(SingleMove, assembler) {
3838 FLAG_use_compressed_instructions = false;
3839 __ SetExtensions(RV_G);
3840 __ fmvs(FA0, FA1);
3841 __ ret();
3842}
3843ASSEMBLER_TEST_RUN(SingleMove, test) {
3844 EXPECT_DISASSEMBLY(
3845 "20b58553 fmv.s fa0, fa1\n"
3846 "00008067 ret\n");
3847 EXPECT_EQ(36.0f, CallF(test->entry(), 42.0f, 36.0f));
3848 EXPECT_EQ(std::numeric_limits<float>::infinity(),
3849 CallF(test->entry(), -std::numeric_limits<float>::infinity(),
3850 std::numeric_limits<float>::infinity()));
3851}
3852
3853ASSEMBLER_TEST_GENERATE(SingleAbsoluteValue, assembler) {
3854 FLAG_use_compressed_instructions = false;
3855 __ SetExtensions(RV_G);
3856 __ fabss(FA0, FA0);
3857 __ ret();
3858}
3859ASSEMBLER_TEST_RUN(SingleAbsoluteValue, test) {
3860 EXPECT_DISASSEMBLY(
3861 "20a52553 fabs.s fa0, fa0\n"
3862 "00008067 ret\n");
3863 EXPECT_EQ(0.0f, CallF(test->entry(), 0.0f));
3864 EXPECT_EQ(0.0f, CallF(test->entry(), -0.0f));
3865 EXPECT_EQ(42.0f, CallF(test->entry(), 42.0f));
3866 EXPECT_EQ(42.0f, CallF(test->entry(), -42.0f));
3867 EXPECT_EQ(std::numeric_limits<float>::infinity(),
3868 CallF(test->entry(), std::numeric_limits<float>::infinity()));
3869 EXPECT_EQ(std::numeric_limits<float>::infinity(),
3870 CallF(test->entry(), -std::numeric_limits<float>::infinity()));
3871}
3872
3873ASSEMBLER_TEST_GENERATE(SingleNegate, assembler) {
3874 FLAG_use_compressed_instructions = false;
3875 __ SetExtensions(RV_G);
3876 __ fnegs(FA0, FA0);
3877 __ ret();
3878}
3879ASSEMBLER_TEST_RUN(SingleNegate, test) {
3880 EXPECT_DISASSEMBLY(
3881 "20a51553 fneg.s fa0, fa0\n"
3882 "00008067 ret\n");
3883 EXPECT_EQ(-0.0f, CallF(test->entry(), 0.0f));
3884 EXPECT_EQ(0.0f, CallF(test->entry(), -0.0f));
3885 EXPECT_EQ(-42.0f, CallF(test->entry(), 42.0f));
3886 EXPECT_EQ(42.0f, CallF(test->entry(), -42.0f));
3887 EXPECT_EQ(-std::numeric_limits<float>::infinity(),
3888 CallF(test->entry(), std::numeric_limits<float>::infinity()));
3889 EXPECT_EQ(std::numeric_limits<float>::infinity(),
3890 CallF(test->entry(), -std::numeric_limits<float>::infinity()));
3891}
3892
3893ASSEMBLER_TEST_GENERATE(BitCastSingleToInteger, assembler) {
3894 FLAG_use_compressed_instructions = false;
3895 __ SetExtensions(RV_G);
3896 __ fmvxw(A0, FA0);
3897 __ ret();
3898}
3899ASSEMBLER_TEST_RUN(BitCastSingleToInteger, test) {
3900 EXPECT_DISASSEMBLY(
3901 "e0050553 fmv.x.w a0, fa0\n"
3902 "00008067 ret\n");
3903 EXPECT_EQ(bit_cast<int32_t>(0.0f), CallI(test->entry(), 0.0f));
3904 EXPECT_EQ(bit_cast<int32_t>(-0.0f), CallI(test->entry(), -0.0f));
3905 EXPECT_EQ(bit_cast<int32_t>(42.0f), CallI(test->entry(), 42.0f));
3906 EXPECT_EQ(bit_cast<int32_t>(-42.0f), CallI(test->entry(), -42.0f));
3907 EXPECT_EQ(bit_cast<int32_t>(std::numeric_limits<float>::quiet_NaN()),
3908 CallI(test->entry(), std::numeric_limits<float>::quiet_NaN()));
3909 EXPECT_EQ(bit_cast<int32_t>(std::numeric_limits<float>::signaling_NaN()),
3910 CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
3911 EXPECT_EQ(bit_cast<int32_t>(std::numeric_limits<float>::infinity()),
3912 CallI(test->entry(), std::numeric_limits<float>::infinity()));
3913 EXPECT_EQ(bit_cast<int32_t>(-std::numeric_limits<float>::infinity()),
3914 CallI(test->entry(), -std::numeric_limits<float>::infinity()));
3915}
3916
3917ASSEMBLER_TEST_GENERATE(BitCastIntegerToSingle, assembler) {
3918 FLAG_use_compressed_instructions = false;
3919 __ SetExtensions(RV_G);
3920 __ fmvwx(FA0, A0);
3921 __ ret();
3922}
3923ASSEMBLER_TEST_RUN(BitCastIntegerToSingle, test) {
3924 EXPECT_DISASSEMBLY(
3925 "f0050553 fmv.w.x fa0, a0\n"
3926 "00008067 ret\n");
3927 EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(bit_cast<int32_t>(0.0f))));
3928 EXPECT_EQ(-0.0f, CallF(test->entry(), sign_extend(bit_cast<int32_t>(-0.0f))));
3929 EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(bit_cast<int32_t>(42.0f))));
3930 EXPECT_EQ(-42.0f,
3931 CallF(test->entry(), sign_extend(bit_cast<int32_t>(-42.0f))));
3932 EXPECT_EQ(true, isnan(CallF(test->entry(),
3933 sign_extend(bit_cast<int32_t>(
3934 std::numeric_limits<float>::quiet_NaN())))));
3935 EXPECT_EQ(true,
3936 isnan(CallF(test->entry(),
3937 sign_extend(bit_cast<int32_t>(
3938 std::numeric_limits<float>::signaling_NaN())))));
3939 EXPECT_EQ(std::numeric_limits<float>::infinity(),
3940 CallF(test->entry(), sign_extend(bit_cast<int32_t>(
3941 std::numeric_limits<float>::infinity()))));
3942 EXPECT_EQ(
3943 -std::numeric_limits<float>::infinity(),
3944 CallF(test->entry(), sign_extend(bit_cast<int32_t>(
3945 -std::numeric_limits<float>::infinity()))));
3946}
3947
3948#if XLEN >= 64
3949ASSEMBLER_TEST_GENERATE(ConvertSingleToDoubleWord, assembler) {
3950 FLAG_use_compressed_instructions = false;
3951 __ SetExtensions(RV_G);
3952 __ fcvtls(A0, FA0);
3953 __ ret();
3954}
3955ASSEMBLER_TEST_RUN(ConvertSingleToDoubleWord, test) {
3956 EXPECT_DISASSEMBLY(
3957 "c0250553 fcvt.l.s a0, fa0\n"
3958 "00008067 ret\n");
3959 EXPECT_EQ(-42, CallI(test->entry(), static_cast<float>(-42)));
3960 EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
3961 EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
3962 EXPECT_EQ(static_cast<int64_t>(kMinInt32),
3963 CallI(test->entry(), static_cast<float>(kMinInt32)));
3964 // float loses precision:
3965 EXPECT_EQ(static_cast<int64_t>(kMaxInt32) + 1,
3966 CallI(test->entry(), static_cast<float>(kMaxInt32)));
3967 EXPECT_EQ(static_cast<int64_t>(kMaxUint32) + 1,
3968 CallI(test->entry(), static_cast<float>(kMaxUint32)));
3969 EXPECT_EQ(kMinInt64, CallI(test->entry(), static_cast<float>(kMinInt64)));
3970 EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<float>(kMaxInt64)));
3971 EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<float>(kMaxUint64)));
3972 EXPECT_EQ(kMinInt64,
3973 CallI(test->entry(), -std::numeric_limits<float>::infinity()));
3974 EXPECT_EQ(kMaxInt64,
3975 CallI(test->entry(), std::numeric_limits<float>::infinity()));
3976 EXPECT_EQ(kMaxInt64,
3977 CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
3978}
3979
3980ASSEMBLER_TEST_GENERATE(ConvertSingleToUnsignedDoubleWord, assembler) {
3981 FLAG_use_compressed_instructions = false;
3982 __ SetExtensions(RV_G);
3983 __ fcvtlus(A0, FA0);
3984 __ ret();
3985}
3986ASSEMBLER_TEST_RUN(ConvertSingleToUnsignedDoubleWord, test) {
3987 EXPECT_DISASSEMBLY(
3988 "c0350553 fcvt.lu.s a0, fa0\n"
3989 "00008067 ret\n");
3990 EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(-42)));
3991 EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
3992 EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
3993 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
3994 CallI(test->entry(), static_cast<float>(kMinInt32)));
3995 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt32) + 1),
3996 CallI(test->entry(), static_cast<float>(kMaxInt32)));
3997 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint32) + 1),
3998 CallI(test->entry(), static_cast<float>(kMaxUint32)));
3999 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
4000 CallI(test->entry(), static_cast<float>(kMinInt64)));
4001 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt64) + 1),
4002 CallI(test->entry(), static_cast<float>(kMaxInt64)));
4003 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
4004 CallI(test->entry(), static_cast<float>(kMaxUint64)));
4005 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
4006 CallI(test->entry(), -std::numeric_limits<float>::infinity()));
4007 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
4008 CallI(test->entry(), std::numeric_limits<float>::infinity()));
4009 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
4010 CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
4011}
4012
4013ASSEMBLER_TEST_GENERATE(ConvertDoubleWordToSingle, assembler) {
4014 FLAG_use_compressed_instructions = false;
4015 __ SetExtensions(RV_G);
4016 __ fcvtsl(FA0, A0);
4017 __ ret();
4018}
4019ASSEMBLER_TEST_RUN(ConvertDoubleWordToSingle, test) {
4020 EXPECT_DISASSEMBLY(
4021 "d0250553 fcvt.s.l fa0, a0\n"
4022 "00008067 ret\n");
4023 EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
4024 EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
4025 EXPECT_EQ(-42.0f, CallF(test->entry(), sign_extend(-42)));
4026 EXPECT_EQ(static_cast<float>(kMinInt32),
4027 CallF(test->entry(), sign_extend(kMinInt32)));
4028 EXPECT_EQ(static_cast<float>(kMaxInt32),
4029 CallF(test->entry(), sign_extend(kMaxInt32)));
4030 EXPECT_EQ(static_cast<float>(sign_extend(kMaxUint32)),
4031 CallF(test->entry(), sign_extend(kMaxUint32)));
4032 EXPECT_EQ(static_cast<float>(kMinInt64),
4033 CallF(test->entry(), sign_extend(kMinInt64)));
4034 EXPECT_EQ(static_cast<float>(kMaxInt64),
4035 CallF(test->entry(), sign_extend(kMaxInt64)));
4036 EXPECT_EQ(static_cast<float>(sign_extend(kMaxUint64)),
4037 CallF(test->entry(), sign_extend(kMaxUint64)));
4038}
4039
4040ASSEMBLER_TEST_GENERATE(ConvertUnsignedDoubleWordToSingle, assembler) {
4041 FLAG_use_compressed_instructions = false;
4042 __ SetExtensions(RV_G);
4043 __ fcvtslu(FA0, A0);
4044 __ ret();
4045}
4046ASSEMBLER_TEST_RUN(ConvertUnsignedDoubleWordToSingle, test) {
4047 EXPECT_DISASSEMBLY(
4048 "d0350553 fcvt.s.lu fa0, a0\n"
4049 "00008067 ret\n");
4050 EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
4051 EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
4052 EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(-42))),
4053 CallF(test->entry(), sign_extend(-42)));
4054 EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMinInt32))),
4055 CallF(test->entry(), sign_extend(kMinInt32)));
4056 EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMaxInt32))),
4057 CallF(test->entry(), sign_extend(kMaxInt32)));
4058 EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMaxUint32))),
4059 CallF(test->entry(), sign_extend(kMaxUint32)));
4060 EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMinInt64))),
4061 CallF(test->entry(), sign_extend(kMinInt64)));
4062 EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMaxInt64))),
4063 CallF(test->entry(), sign_extend(kMaxInt64)));
4064 EXPECT_EQ(static_cast<float>(kMaxUint64),
4065 CallF(test->entry(), sign_extend(kMaxUint64)));
4066}
4067#endif
4068
4069ASSEMBLER_TEST_GENERATE(LoadDoubleFloat, assembler) {
4070 FLAG_use_compressed_instructions = false;
4071 __ SetExtensions(RV_G);
4072 __ fld(FA0, Address(A0, 1 * sizeof(double)));
4073 __ ret();
4074}
4075ASSEMBLER_TEST_RUN(LoadDoubleFloat, test) {
4076 EXPECT_DISASSEMBLY(
4077 "00853507 fld fa0, 8(a0)\n"
4078 "00008067 ret\n");
4079
4080 double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
4081 data[0] = 1.7;
4082 data[1] = 2.8;
4083 data[2] = 3.9;
4084 EXPECT_EQ(data[1], CallD(test->entry(), reinterpret_cast<intx_t>(data)));
4085}
4086
4087ASSEMBLER_TEST_GENERATE(StoreDoubleFloat, assembler) {
4088 FLAG_use_compressed_instructions = false;
4089 __ SetExtensions(RV_G);
4090 __ fsd(FA0, Address(A0, 1 * sizeof(double)));
4091 __ ret();
4092}
4093ASSEMBLER_TEST_RUN(StoreDoubleFloat, test) {
4094 EXPECT_DISASSEMBLY(
4095 "00a53427 fsd fa0, 8(a0)\n"
4096 "00008067 ret\n");
4097
4098 double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
4099 data[0] = 1.7;
4100 data[1] = 2.8;
4101 data[2] = 3.9;
4102 CallD(test->entry(), reinterpret_cast<intx_t>(data), 4.2);
4103 EXPECT_EQ(4.2, data[1]);
4104}
4105
4106ASSEMBLER_TEST_GENERATE(DoubleMultiplyAdd, assembler) {
4107 FLAG_use_compressed_instructions = false;
4108 __ SetExtensions(RV_G);
4109 __ fmaddd(FA0, FA0, FA1, FA2);
4110 __ ret();
4111}
4112ASSEMBLER_TEST_RUN(DoubleMultiplyAdd, test) {
4113 EXPECT_DISASSEMBLY(
4114 "62b50543 fmadd.d fa0, fa0, fa1, fa2\n"
4115 "00008067 ret\n");
4116 EXPECT_EQ(22.0, CallD(test->entry(), 3.0, 5.0, 7.0));
4117 EXPECT_EQ(-8.0, CallD(test->entry(), -3.0, 5.0, 7.0));
4118 EXPECT_EQ(-8.0, CallD(test->entry(), 3.0, -5.0, 7.0));
4119 EXPECT_EQ(8.0, CallD(test->entry(), 3.0, 5.0, -7.0));
4120
4121 EXPECT_EQ(26.0, CallD(test->entry(), 7.0, 3.0, 5.0));
4122 EXPECT_EQ(-16.0, CallD(test->entry(), -7.0, 3.0, 5.0));
4123 EXPECT_EQ(-16.0, CallD(test->entry(), 7.0, -3.0, 5.0));
4124 EXPECT_EQ(16.0, CallD(test->entry(), 7.0, 3.0, -5.0));
4125}
4126
4127ASSEMBLER_TEST_GENERATE(DoubleMultiplySubtract, assembler) {
4128 FLAG_use_compressed_instructions = false;
4129 __ SetExtensions(RV_G);
4130 __ fmsubd(FA0, FA0, FA1, FA2);
4131 __ ret();
4132}
4133ASSEMBLER_TEST_RUN(DoubleMultiplySubtract, test) {
4134 EXPECT_DISASSEMBLY(
4135 "62b50547 fmsub.d fa0, fa0, fa1, fa2\n"
4136 "00008067 ret\n");
4137 EXPECT_EQ(8.0, CallD(test->entry(), 3.0, 5.0, 7.0));
4138 EXPECT_EQ(-22.0, CallD(test->entry(), -3.0, 5.0, 7.0));
4139 EXPECT_EQ(-22.0, CallD(test->entry(), 3.0, -5.0, 7.0));
4140 EXPECT_EQ(22.0, CallD(test->entry(), 3.0, 5.0, -7.0));
4141
4142 EXPECT_EQ(16.0, CallD(test->entry(), 7.0, 3.0, 5.0));
4143 EXPECT_EQ(-26.0, CallD(test->entry(), -7.0, 3.0, 5.0));
4144 EXPECT_EQ(-26.0, CallD(test->entry(), 7.0, -3.0, 5.0));
4145 EXPECT_EQ(26.0, CallD(test->entry(), 7.0, 3.0, -5.0));
4146}
4147
4148ASSEMBLER_TEST_GENERATE(DoubleNegateMultiplySubtract, assembler) {
4149 FLAG_use_compressed_instructions = false;
4150 __ SetExtensions(RV_G);
4151 __ fnmsubd(FA0, FA0, FA1, FA2);
4152 __ ret();
4153}
4154ASSEMBLER_TEST_RUN(DoubleNegateMultiplySubtract, test) {
4155 EXPECT_DISASSEMBLY(
4156 "62b5054b fnmsub.d fa0, fa0, fa1, fa2\n"
4157 "00008067 ret\n");
4158 EXPECT_EQ(-8.0, CallD(test->entry(), 3.0, 5.0, 7.0));
4159 EXPECT_EQ(22.0, CallD(test->entry(), -3.0, 5.0, 7.0));
4160 EXPECT_EQ(22.0, CallD(test->entry(), 3.0, -5.0, 7.0));
4161 EXPECT_EQ(-22.0, CallD(test->entry(), 3.0, 5.0, -7.0));
4162
4163 EXPECT_EQ(-16.0, CallD(test->entry(), 7.0, 3.0, 5.0));
4164 EXPECT_EQ(26.0, CallD(test->entry(), -7.0, 3.0, 5.0));
4165 EXPECT_EQ(26.0, CallD(test->entry(), 7.0, -3.0, 5.0));
4166 EXPECT_EQ(-26.0, CallD(test->entry(), 7.0, 3.0, -5.0));
4167}
4168
4169ASSEMBLER_TEST_GENERATE(DoubleNegateMultiplyAdd, assembler) {
4170 FLAG_use_compressed_instructions = false;
4171 __ SetExtensions(RV_G);
4172 __ fnmaddd(FA0, FA0, FA1, FA2);
4173 __ ret();
4174}
4175ASSEMBLER_TEST_RUN(DoubleNegateMultiplyAdd, test) {
4176 EXPECT_DISASSEMBLY(
4177 "62b5054f fnmadd.d fa0, fa0, fa1, fa2\n"
4178 "00008067 ret\n");
4179 EXPECT_EQ(-22.0, CallD(test->entry(), 3.0, 5.0, 7.0));
4180 EXPECT_EQ(8.0, CallD(test->entry(), -3.0, 5.0, 7.0));
4181 EXPECT_EQ(8.0, CallD(test->entry(), 3.0, -5.0, 7.0));
4182 EXPECT_EQ(-8.0, CallD(test->entry(), 3.0, 5.0, -7.0));
4183
4184 EXPECT_EQ(-26.0, CallD(test->entry(), 7.0, 3.0, 5.0));
4185 EXPECT_EQ(16.0, CallD(test->entry(), -7.0, 3.0, 5.0));
4186 EXPECT_EQ(16.0, CallD(test->entry(), 7.0, -3.0, 5.0));
4187 EXPECT_EQ(-16.0, CallD(test->entry(), 7.0, 3.0, -5.0));
4188}
4189
4190ASSEMBLER_TEST_GENERATE(DoubleAdd, assembler) {
4191 FLAG_use_compressed_instructions = false;
4192 __ SetExtensions(RV_G);
4193 __ faddd(FA0, FA0, FA1);
4194 __ ret();
4195}
4196ASSEMBLER_TEST_RUN(DoubleAdd, test) {
4197 EXPECT_DISASSEMBLY(
4198 "02b50553 fadd.d fa0, fa0, fa1\n"
4199 "00008067 ret\n");
4200 EXPECT_EQ(8.0, CallD(test->entry(), 3.0, 5.0));
4201 EXPECT_EQ(2.0, CallD(test->entry(), -3.0, 5.0));
4202 EXPECT_EQ(-2.0, CallD(test->entry(), 3.0, -5.0));
4203 EXPECT_EQ(-8.0, CallD(test->entry(), -3.0, -5.0));
4204
4205 EXPECT_EQ(10.0, CallD(test->entry(), 7.0, 3.0));
4206 EXPECT_EQ(-4.0, CallD(test->entry(), -7.0, 3.0));
4207 EXPECT_EQ(4.0, CallD(test->entry(), 7.0, -3.0));
4208 EXPECT_EQ(-10.0, CallD(test->entry(), -7.0, -3.0));
4209}
4210
4211ASSEMBLER_TEST_GENERATE(DoubleSubtract, assembler) {
4212 FLAG_use_compressed_instructions = false;
4213 __ SetExtensions(RV_G);
4214 __ fsubd(FA0, FA0, FA1);
4215 __ ret();
4216}
4217ASSEMBLER_TEST_RUN(DoubleSubtract, test) {
4218 EXPECT_DISASSEMBLY(
4219 "0ab50553 fsub.d fa0, fa0, fa1\n"
4220 "00008067 ret\n");
4221 EXPECT_EQ(-2.0, CallD(test->entry(), 3.0, 5.0));
4222 EXPECT_EQ(-8.0, CallD(test->entry(), -3.0, 5.0));
4223 EXPECT_EQ(8.0, CallD(test->entry(), 3.0, -5.0));
4224 EXPECT_EQ(2.0, CallD(test->entry(), -3.0, -5.0));
4225
4226 EXPECT_EQ(4.0, CallD(test->entry(), 7.0, 3.0));
4227 EXPECT_EQ(-10.0, CallD(test->entry(), -7.0, 3.0));
4228 EXPECT_EQ(10.0, CallD(test->entry(), 7.0, -3.0));
4229 EXPECT_EQ(-4.0, CallD(test->entry(), -7.0, -3.0));
4230}
4231
4232ASSEMBLER_TEST_GENERATE(DoubleMultiply, assembler) {
4233 FLAG_use_compressed_instructions = false;
4234 __ SetExtensions(RV_G);
4235 __ fmuld(FA0, FA0, FA1);
4236 __ ret();
4237}
4238ASSEMBLER_TEST_RUN(DoubleMultiply, test) {
4239 EXPECT_DISASSEMBLY(
4240 "12b50553 fmul.d fa0, fa0, fa1\n"
4241 "00008067 ret\n");
4242 EXPECT_EQ(15.0, CallD(test->entry(), 3.0, 5.0));
4243 EXPECT_EQ(-15.0, CallD(test->entry(), -3.0, 5.0));
4244 EXPECT_EQ(-15.0, CallD(test->entry(), 3.0, -5.0));
4245 EXPECT_EQ(15.0, CallD(test->entry(), -3.0, -5.0));
4246
4247 EXPECT_EQ(21.0, CallD(test->entry(), 7.0, 3.0));
4248 EXPECT_EQ(-21.0, CallD(test->entry(), -7.0, 3.0));
4249 EXPECT_EQ(-21.0, CallD(test->entry(), 7.0, -3.0));
4250 EXPECT_EQ(21.0, CallD(test->entry(), -7.0, -3.0));
4251}
4252
4253ASSEMBLER_TEST_GENERATE(DoubleDivide, assembler) {
4254 FLAG_use_compressed_instructions = false;
4255 __ SetExtensions(RV_G);
4256 __ fdivd(FA0, FA0, FA1);
4257 __ ret();
4258}
4259ASSEMBLER_TEST_RUN(DoubleDivide, test) {
4260 EXPECT_DISASSEMBLY(
4261 "1ab50553 fdiv.d fa0, fa0, fa1\n"
4262 "00008067 ret\n");
4263 EXPECT_EQ(2.0, CallD(test->entry(), 10.0, 5.0));
4264 EXPECT_EQ(-2.0, CallD(test->entry(), -10.0, 5.0));
4265 EXPECT_EQ(-2.0, CallD(test->entry(), 10.0, -5.0));
4266 EXPECT_EQ(2.0, CallD(test->entry(), -10.0, -5.0));
4267}
4268
4269ASSEMBLER_TEST_GENERATE(DoubleSquareRoot, assembler) {
4270 FLAG_use_compressed_instructions = false;
4271 __ SetExtensions(RV_G);
4272 __ fsqrtd(FA0, FA0);
4273 __ ret();
4274}
4275ASSEMBLER_TEST_RUN(DoubleSquareRoot, test) {
4276 EXPECT_DISASSEMBLY(
4277 "5a050553 fsqrt.d fa0, fa0\n"
4278 "00008067 ret\n");
4279 EXPECT_EQ(0.0, CallD(test->entry(), 0.0));
4280 EXPECT_EQ(1.0, CallD(test->entry(), 1.0));
4281 EXPECT_EQ(2.0, CallD(test->entry(), 4.0));
4282 EXPECT_EQ(3.0, CallD(test->entry(), 9.0));
4283}
4284
4285ASSEMBLER_TEST_GENERATE(DoubleSignInject, assembler) {
4286 FLAG_use_compressed_instructions = false;
4287 __ SetExtensions(RV_G);
4288 __ fsgnjd(FA0, FA0, FA1);
4289 __ ret();
4290}
4291ASSEMBLER_TEST_RUN(DoubleSignInject, test) {
4292 EXPECT_DISASSEMBLY(
4293 "22b50553 fsgnj.d fa0, fa0, fa1\n"
4294 "00008067 ret\n");
4295 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 5.0));
4296 EXPECT_EQ(3.0, CallD(test->entry(), -3.0, 5.0));
4297 EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, -5.0));
4298 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -5.0));
4299}
4300
4301ASSEMBLER_TEST_GENERATE(DoubleNegatedSignInject, assembler) {
4302 FLAG_use_compressed_instructions = false;
4303 __ SetExtensions(RV_G);
4304 __ fsgnjnd(FA0, FA0, FA1);
4305 __ ret();
4306}
4307ASSEMBLER_TEST_RUN(DoubleNegatedSignInject, test) {
4308 EXPECT_DISASSEMBLY(
4309 "22b51553 fsgnjn.d fa0, fa0, fa1\n"
4310 "00008067 ret\n");
4311 EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, 5.0));
4312 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 5.0));
4313 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -5.0));
4314 EXPECT_EQ(3.0, CallD(test->entry(), -3.0, -5.0));
4315}
4316
4317ASSEMBLER_TEST_GENERATE(DoubleXorSignInject, assembler) {
4318 FLAG_use_compressed_instructions = false;
4319 __ SetExtensions(RV_G);
4320 __ fsgnjxd(FA0, FA0, FA1);
4321 __ ret();
4322}
4323ASSEMBLER_TEST_RUN(DoubleXorSignInject, test) {
4324 EXPECT_DISASSEMBLY(
4325 "22b52553 fsgnjx.d fa0, fa0, fa1\n"
4326 "00008067 ret\n");
4327 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 5.0));
4328 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 5.0));
4329 EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, -5.0));
4330 EXPECT_EQ(3.0, CallD(test->entry(), -3.0, -5.0));
4331}
4332
4333ASSEMBLER_TEST_GENERATE(DoubleMin, assembler) {
4334 FLAG_use_compressed_instructions = false;
4335 __ SetExtensions(RV_G);
4336 __ fmind(FA0, FA0, FA1);
4337 __ ret();
4338}
4339ASSEMBLER_TEST_RUN(DoubleMin, test) {
4340 EXPECT_DISASSEMBLY(
4341 "2ab50553 fmin.d fa0, fa0, fa1\n"
4342 "00008067 ret\n");
4343 EXPECT_EQ(1.0, CallD(test->entry(), 3.0, 1.0));
4344 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 3.0));
4345 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 5.0));
4346 EXPECT_EQ(-1.0, CallD(test->entry(), 3.0, -1.0));
4347 EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, -3.0));
4348 EXPECT_EQ(-5.0, CallD(test->entry(), 3.0, -5.0));
4349 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 1.0));
4350 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 3.0));
4351 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 5.0));
4352 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -1.0));
4353 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -3.0));
4354 EXPECT_EQ(-5.0, CallD(test->entry(), -3.0, -5.0));
4355
4356 EXPECT_EQ(bit_cast<uint64_t>(-0.0),
4357 bit_cast<uint64_t>(CallD(test->entry(), 0.0, -0.0)));
4358 EXPECT_EQ(bit_cast<uint64_t>(-0.0),
4359 bit_cast<uint64_t>(CallD(test->entry(), -0.0, 0.0)));
4360
4361 double qNAN = std::numeric_limits<double>::quiet_NaN();
4362 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, qNAN));
4363 EXPECT_EQ(3.0, CallD(test->entry(), qNAN, 3.0));
4364 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, qNAN));
4365 EXPECT_EQ(-3.0, CallD(test->entry(), qNAN, -3.0));
4366
4367 double sNAN = std::numeric_limits<double>::signaling_NaN();
4368 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, sNAN));
4369 EXPECT_EQ(3.0, CallD(test->entry(), sNAN, 3.0));
4370 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, sNAN));
4371 EXPECT_EQ(-3.0, CallD(test->entry(), sNAN, -3.0));
4372
4373 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4374 bit_cast<uint64_t>(CallD(test->entry(), sNAN, sNAN)));
4375 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4376 bit_cast<uint64_t>(CallD(test->entry(), qNAN, qNAN)));
4377 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4378 bit_cast<uint64_t>(CallD(test->entry(), qNAN, sNAN)));
4379 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4380 bit_cast<uint64_t>(CallD(test->entry(), sNAN, qNAN)));
4381}
4382
4383ASSEMBLER_TEST_GENERATE(DoubleMax, assembler) {
4384 FLAG_use_compressed_instructions = false;
4385 __ SetExtensions(RV_G);
4386 __ fmaxd(FA0, FA0, FA1);
4387 __ ret();
4388}
4389ASSEMBLER_TEST_RUN(DoubleMax, test) {
4390 EXPECT_DISASSEMBLY(
4391 "2ab51553 fmax.d fa0, fa0, fa1\n"
4392 "00008067 ret\n");
4393 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 1.0));
4394 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 3.0));
4395 EXPECT_EQ(5.0, CallD(test->entry(), 3.0, 5.0));
4396 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -1.0));
4397 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -3.0));
4398 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -5.0));
4399 EXPECT_EQ(1.0, CallD(test->entry(), -3.0, 1.0));
4400 EXPECT_EQ(3.0, CallD(test->entry(), -3.0, 3.0));
4401 EXPECT_EQ(5.0, CallD(test->entry(), -3.0, 5.0));
4402 EXPECT_EQ(-1.0, CallD(test->entry(), -3.0, -1.0));
4403 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -3.0));
4404 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -5.0));
4405
4406 EXPECT_EQ(bit_cast<uint64_t>(0.0),
4407 bit_cast<uint64_t>(CallD(test->entry(), 0.0, -0.0)));
4408 EXPECT_EQ(bit_cast<uint64_t>(0.0),
4409 bit_cast<uint64_t>(CallD(test->entry(), -0.0, 0.0)));
4410
4411 double qNAN = std::numeric_limits<double>::quiet_NaN();
4412 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, qNAN));
4413 EXPECT_EQ(3.0, CallD(test->entry(), qNAN, 3.0));
4414 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, qNAN));
4415 EXPECT_EQ(-3.0, CallD(test->entry(), qNAN, -3.0));
4416
4417 double sNAN = std::numeric_limits<double>::signaling_NaN();
4418 EXPECT_EQ(3.0, CallD(test->entry(), 3.0, sNAN));
4419 EXPECT_EQ(3.0, CallD(test->entry(), sNAN, 3.0));
4420 EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, sNAN));
4421 EXPECT_EQ(-3.0, CallD(test->entry(), sNAN, -3.0));
4422
4423 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4424 bit_cast<uint64_t>(CallD(test->entry(), sNAN, sNAN)));
4425 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4426 bit_cast<uint64_t>(CallD(test->entry(), qNAN, qNAN)));
4427 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4428 bit_cast<uint64_t>(CallD(test->entry(), qNAN, sNAN)));
4429 EXPECT_EQ(bit_cast<uint64_t>(qNAN),
4430 bit_cast<uint64_t>(CallD(test->entry(), sNAN, qNAN)));
4431}
4432
4433ASSEMBLER_TEST_GENERATE(DoubleToSingle, assembler) {
4434 FLAG_use_compressed_instructions = false;
4435 __ SetExtensions(RV_G);
4436 __ fcvtsd(FA0, FA0);
4437 __ ret();
4438}
4439ASSEMBLER_TEST_RUN(DoubleToSingle, test) {
4440 EXPECT_DISASSEMBLY(
4441 "40150553 fcvt.s.d fa0, fa0\n"
4442 "00008067 ret\n");
4443 EXPECT_EQ(0.0f, CallF(test->entry(), 0.0));
4444 EXPECT_EQ(42.0f, CallF(test->entry(), 42.0));
4445 EXPECT_EQ(-42.0f, CallF(test->entry(), -42.0));
4446 EXPECT_EQ(true, isnan(CallF(test->entry(),
4447 std::numeric_limits<double>::quiet_NaN())));
4448 EXPECT_EQ(true, isnan(CallF(test->entry(),
4449 std::numeric_limits<double>::signaling_NaN())));
4450 EXPECT_EQ(std::numeric_limits<float>::infinity(),
4451 CallF(test->entry(), std::numeric_limits<double>::infinity()));
4452 EXPECT_EQ(-std::numeric_limits<float>::infinity(),
4453 CallF(test->entry(), -std::numeric_limits<double>::infinity()));
4454}
4455
4456ASSEMBLER_TEST_GENERATE(SingleToDouble, assembler) {
4457 FLAG_use_compressed_instructions = false;
4458 __ SetExtensions(RV_G);
4459 __ fcvtds(FA0, FA0);
4460 __ ret();
4461}
4462ASSEMBLER_TEST_RUN(SingleToDouble, test) {
4463 EXPECT_DISASSEMBLY(
4464 "42050553 fcvt.d.s fa0, fa0\n"
4465 "00008067 ret\n");
4466 EXPECT_EQ(0.0, CallD(test->entry(), 0.0f));
4467 EXPECT_EQ(42.0, CallD(test->entry(), 42.0f));
4468 EXPECT_EQ(-42.0, CallD(test->entry(), -42.0f));
4469 EXPECT_EQ(true, isnan(CallD(test->entry(),
4470 std::numeric_limits<float>::quiet_NaN())));
4471 EXPECT_EQ(true, isnan(CallD(test->entry(),
4472 std::numeric_limits<float>::signaling_NaN())));
4473 EXPECT_EQ(std::numeric_limits<double>::infinity(),
4474 CallD(test->entry(), std::numeric_limits<float>::infinity()));
4475 EXPECT_EQ(-std::numeric_limits<double>::infinity(),
4476 CallD(test->entry(), -std::numeric_limits<float>::infinity()));
4477}
4478
4479ASSEMBLER_TEST_GENERATE(NaNBoxing, assembler) {
4480 FLAG_use_compressed_instructions = false;
4481 __ SetExtensions(RV_G);
4482 __ ret();
4483}
4484ASSEMBLER_TEST_RUN(NaNBoxing, test) {
4485 EXPECT_DISASSEMBLY("00008067 ret\n");
4486 EXPECT_EQ(true, isnan(CallD(test->entry(), 42.0f)));
4487}
4488
4489ASSEMBLER_TEST_GENERATE(DoubleEqual, assembler) {
4490 FLAG_use_compressed_instructions = false;
4491 __ SetExtensions(RV_G);
4492 __ feqd(A0, FA0, FA1);
4493 __ ret();
4494}
4495ASSEMBLER_TEST_RUN(DoubleEqual, test) {
4496 EXPECT_DISASSEMBLY(
4497 "a2b52553 feq.d a0, fa0, fa1\n"
4498 "00008067 ret\n");
4499 EXPECT_EQ(0, CallI(test->entry(), 3.0, 1.0));
4500 EXPECT_EQ(1, CallI(test->entry(), 3.0, 3.0));
4501 EXPECT_EQ(0, CallI(test->entry(), 3.0, 5.0));
4502 EXPECT_EQ(0, CallI(test->entry(), 3.0, -1.0));
4503 EXPECT_EQ(0, CallI(test->entry(), 3.0, -3.0));
4504 EXPECT_EQ(0, CallI(test->entry(), 3.0, -5.0));
4505 EXPECT_EQ(0, CallI(test->entry(), -3.0, 1.0));
4506 EXPECT_EQ(0, CallI(test->entry(), -3.0, 3.0));
4507 EXPECT_EQ(0, CallI(test->entry(), -3.0, 5.0));
4508 EXPECT_EQ(0, CallI(test->entry(), -3.0, -1.0));
4509 EXPECT_EQ(1, CallI(test->entry(), -3.0, -3.0));
4510 EXPECT_EQ(0, CallI(test->entry(), -3.0, -5.0));
4511
4512 double qNAN = std::numeric_limits<double>::quiet_NaN();
4513 EXPECT_EQ(0, CallI(test->entry(), 3.0, qNAN));
4514 EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0));
4515 EXPECT_EQ(0, CallI(test->entry(), -3.0, qNAN));
4516 EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0));
4517}
4518
4519ASSEMBLER_TEST_GENERATE(DoubleLessThan, assembler) {
4520 FLAG_use_compressed_instructions = false;
4521 __ SetExtensions(RV_G);
4522 __ fltd(A0, FA0, FA1);
4523 __ ret();
4524}
4525ASSEMBLER_TEST_RUN(DoubleLessThan, test) {
4526 EXPECT_DISASSEMBLY(
4527 "a2b51553 flt.d a0, fa0, fa1\n"
4528 "00008067 ret\n");
4529 EXPECT_EQ(0, CallI(test->entry(), 3.0, 1.0));
4530 EXPECT_EQ(0, CallI(test->entry(), 3.0, 3.0));
4531 EXPECT_EQ(1, CallI(test->entry(), 3.0, 5.0));
4532 EXPECT_EQ(0, CallI(test->entry(), 3.0, -1.0));
4533 EXPECT_EQ(0, CallI(test->entry(), 3.0, -3.0));
4534 EXPECT_EQ(0, CallI(test->entry(), 3.0, -5.0));
4535 EXPECT_EQ(1, CallI(test->entry(), -3.0, 1.0));
4536 EXPECT_EQ(1, CallI(test->entry(), -3.0, 3.0));
4537 EXPECT_EQ(1, CallI(test->entry(), -3.0, 5.0));
4538 EXPECT_EQ(1, CallI(test->entry(), -3.0, -1.0));
4539 EXPECT_EQ(0, CallI(test->entry(), -3.0, -3.0));
4540 EXPECT_EQ(0, CallI(test->entry(), -3.0, -5.0));
4541
4542 double qNAN = std::numeric_limits<double>::quiet_NaN();
4543 EXPECT_EQ(0, CallI(test->entry(), 3.0, qNAN));
4544 EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0));
4545 EXPECT_EQ(0, CallI(test->entry(), -3.0, qNAN));
4546 EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0));
4547}
4548
4549ASSEMBLER_TEST_GENERATE(DoubleLessOrEqual, assembler) {
4550 FLAG_use_compressed_instructions = false;
4551 __ SetExtensions(RV_G);
4552 __ fled(A0, FA0, FA1);
4553 __ ret();
4554}
4555ASSEMBLER_TEST_RUN(DoubleLessOrEqual, test) {
4556 EXPECT_DISASSEMBLY(
4557 "a2b50553 fle.d a0, fa0, fa1\n"
4558 "00008067 ret\n");
4559 EXPECT_EQ(0, CallI(test->entry(), 3.0, 1.0));
4560 EXPECT_EQ(1, CallI(test->entry(), 3.0, 3.0));
4561 EXPECT_EQ(1, CallI(test->entry(), 3.0, 5.0));
4562 EXPECT_EQ(0, CallI(test->entry(), 3.0, -1.0));
4563 EXPECT_EQ(0, CallI(test->entry(), 3.0, -3.0));
4564 EXPECT_EQ(0, CallI(test->entry(), 3.0, -5.0));
4565 EXPECT_EQ(1, CallI(test->entry(), -3.0, 1.0));
4566 EXPECT_EQ(1, CallI(test->entry(), -3.0, 3.0));
4567 EXPECT_EQ(1, CallI(test->entry(), -3.0, 5.0));
4568 EXPECT_EQ(1, CallI(test->entry(), -3.0, -1.0));
4569 EXPECT_EQ(1, CallI(test->entry(), -3.0, -3.0));
4570 EXPECT_EQ(0, CallI(test->entry(), -3.0, -5.0));
4571
4572 double qNAN = std::numeric_limits<double>::quiet_NaN();
4573 EXPECT_EQ(0, CallI(test->entry(), 3.0, qNAN));
4574 EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0));
4575 EXPECT_EQ(0, CallI(test->entry(), -3.0, qNAN));
4576 EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0));
4577}
4578
4579ASSEMBLER_TEST_GENERATE(DoubleClassify, assembler) {
4580 FLAG_use_compressed_instructions = false;
4581 __ SetExtensions(RV_G);
4582 __ fclassd(A0, FA0);
4583 __ ret();
4584}
4585ASSEMBLER_TEST_RUN(DoubleClassify, test) {
4586 EXPECT_DISASSEMBLY(
4587 "e2051553 fclass.d a0, fa0\n"
4588 "00008067 ret\n");
4589 // Neg infinity
4590 EXPECT_EQ(1 << 0,
4591 CallI(test->entry(), -std::numeric_limits<double>::infinity()));
4592 // Neg normal
4593 EXPECT_EQ(1 << 1, CallI(test->entry(), -1.0));
4594 // Neg subnormal
4595 EXPECT_EQ(1 << 2,
4596 CallI(test->entry(), -std::numeric_limits<double>::min() / 2.0));
4597 // Neg zero
4598 EXPECT_EQ(1 << 3, CallI(test->entry(), -0.0));
4599 // Pos zero
4600 EXPECT_EQ(1 << 4, CallI(test->entry(), 0.0));
4601 // Pos subnormal
4602 EXPECT_EQ(1 << 5,
4603 CallI(test->entry(), std::numeric_limits<double>::min() / 2.0));
4604 // Pos normal
4605 EXPECT_EQ(1 << 6, CallI(test->entry(), 1.0));
4606 // Pos infinity
4607 EXPECT_EQ(1 << 7,
4608 CallI(test->entry(), std::numeric_limits<double>::infinity()));
4609 // Signaling NaN
4610 EXPECT_EQ(1 << 8,
4611 CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
4612 // Queit NaN
4613 EXPECT_EQ(1 << 9,
4614 CallI(test->entry(), std::numeric_limits<double>::quiet_NaN()));
4615}
4616
4617ASSEMBLER_TEST_GENERATE(ConvertDoubleToWord, assembler) {
4618 FLAG_use_compressed_instructions = false;
4619 __ SetExtensions(RV_G);
4620 __ fcvtwd(A0, FA0);
4621 __ ret();
4622}
4623ASSEMBLER_TEST_RUN(ConvertDoubleToWord, test) {
4624 EXPECT_DISASSEMBLY(
4625 "c2050553 fcvt.w.d a0, fa0\n"
4626 "00008067 ret\n");
4627 EXPECT_EQ(-42, CallI(test->entry(), static_cast<double>(-42)));
4628 EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
4629 EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
4630 EXPECT_EQ(sign_extend(kMinInt32),
4631 CallI(test->entry(), static_cast<double>(kMinInt32)));
4632 EXPECT_EQ(sign_extend(kMaxInt32),
4633 CallI(test->entry(), static_cast<double>(kMaxInt32)));
4634 EXPECT_EQ(sign_extend(kMaxInt32),
4635 CallI(test->entry(), static_cast<double>(kMaxUint32)));
4636 EXPECT_EQ(sign_extend(kMinInt32),
4637 CallI(test->entry(), static_cast<double>(kMinInt64)));
4638 EXPECT_EQ(sign_extend(kMaxInt32),
4639 CallI(test->entry(), static_cast<double>(kMaxInt64)));
4640 EXPECT_EQ(sign_extend(kMaxInt32),
4641 CallI(test->entry(), static_cast<double>(kMaxUint64)));
4642 EXPECT_EQ(sign_extend(kMinInt32),
4643 CallI(test->entry(), -std::numeric_limits<double>::infinity()));
4644 EXPECT_EQ(sign_extend(kMaxInt32),
4645 CallI(test->entry(), std::numeric_limits<double>::infinity()));
4646 EXPECT_EQ(sign_extend(kMaxInt32),
4647 CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
4648}
4649
4650ASSEMBLER_TEST_GENERATE(ConvertDoubleToUnsignedWord, assembler) {
4651 FLAG_use_compressed_instructions = false;
4652 __ SetExtensions(RV_G);
4653 __ fcvtwud(A0, FA0);
4654 __ ret();
4655}
4656ASSEMBLER_TEST_RUN(ConvertDoubleToUnsignedWord, test) {
4657 EXPECT_DISASSEMBLY(
4658 "c2150553 fcvt.wu.d a0, fa0\n"
4659 "00008067 ret\n");
4660 EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(-42)));
4661 EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
4662 EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
4663 EXPECT_EQ(sign_extend(0),
4664 CallI(test->entry(), static_cast<double>(kMinInt32)));
4665 EXPECT_EQ(sign_extend(kMaxInt32),
4666 CallI(test->entry(), static_cast<double>(kMaxInt32)));
4667 EXPECT_EQ(sign_extend(kMaxUint32),
4668 CallI(test->entry(), static_cast<double>(kMaxUint32)));
4669 EXPECT_EQ(sign_extend(0),
4670 CallI(test->entry(), static_cast<double>(kMinInt64)));
4671 EXPECT_EQ(sign_extend(kMaxUint32),
4672 CallI(test->entry(), static_cast<double>(kMaxInt64)));
4673 EXPECT_EQ(sign_extend(kMaxUint32),
4674 CallI(test->entry(), static_cast<double>(kMaxUint64)));
4675 EXPECT_EQ(sign_extend(0),
4676 CallI(test->entry(), -std::numeric_limits<double>::infinity()));
4677 EXPECT_EQ(sign_extend(kMaxUint32),
4678 CallI(test->entry(), std::numeric_limits<double>::infinity()));
4679 EXPECT_EQ(sign_extend(kMaxUint32),
4680 CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
4681}
4682
4683ASSEMBLER_TEST_GENERATE(ConvertWordToDouble, assembler) {
4684 FLAG_use_compressed_instructions = false;
4685 __ SetExtensions(RV_G);
4686 __ fcvtdw(FA0, A0);
4687 __ ret();
4688}
4689ASSEMBLER_TEST_RUN(ConvertWordToDouble, test) {
4690 EXPECT_DISASSEMBLY(
4691 "d2050553 fcvt.d.w fa0, a0\n"
4692 "00008067 ret\n");
4693 EXPECT_EQ(-42.0, CallD(test->entry(), sign_extend(-42)));
4694 EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
4695 EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
4696 EXPECT_EQ(static_cast<double>(kMinInt32),
4697 CallD(test->entry(), sign_extend(kMinInt32)));
4698 EXPECT_EQ(static_cast<double>(kMaxInt32),
4699 CallD(test->entry(), sign_extend(kMaxInt32)));
4700 EXPECT_EQ(-1.0, CallD(test->entry(), sign_extend(kMaxUint32)));
4701}
4702
4703ASSEMBLER_TEST_GENERATE(ConvertUnsignedWordToDouble, assembler) {
4704 FLAG_use_compressed_instructions = false;
4705 __ SetExtensions(RV_G);
4706 __ fcvtdwu(FA0, A0);
4707 __ ret();
4708}
4709ASSEMBLER_TEST_RUN(ConvertUnsignedWordToDouble, test) {
4710 EXPECT_DISASSEMBLY(
4711 "d2150553 fcvt.d.wu fa0, a0\n"
4712 "00008067 ret\n");
4713 EXPECT_EQ(
4714 static_cast<double>(static_cast<uint32_t>(static_cast<int32_t>(-42))),
4715 CallD(test->entry(), sign_extend(-42)));
4716 EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
4717 EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
4718 EXPECT_EQ(static_cast<double>(static_cast<uint32_t>(kMinInt32)),
4719 CallD(test->entry(), sign_extend(kMinInt32)));
4720 EXPECT_EQ(static_cast<double>(kMaxInt32),
4721 CallD(test->entry(), sign_extend(kMaxInt32)));
4722 EXPECT_EQ(static_cast<double>(kMaxUint32),
4723 CallD(test->entry(), sign_extend(kMaxUint32)));
4724}
4725
4726ASSEMBLER_TEST_GENERATE(DoubleMove, assembler) {
4727 FLAG_use_compressed_instructions = false;
4728 __ SetExtensions(RV_G);
4729 __ fmvd(FA0, FA1);
4730 __ ret();
4731}
4732ASSEMBLER_TEST_RUN(DoubleMove, test) {
4733 EXPECT_DISASSEMBLY(
4734 "22b58553 fmv.d fa0, fa1\n"
4735 "00008067 ret\n");
4736 EXPECT_EQ(36.0, CallD(test->entry(), 42.0, 36.0));
4737 EXPECT_EQ(std::numeric_limits<double>::infinity(),
4738 CallD(test->entry(), -std::numeric_limits<double>::infinity(),
4739 std::numeric_limits<double>::infinity()));
4740}
4741
4742ASSEMBLER_TEST_GENERATE(DoubleAbsoluteValue, assembler) {
4743 FLAG_use_compressed_instructions = false;
4744 __ SetExtensions(RV_G);
4745 __ fabsd(FA0, FA0);
4746 __ ret();
4747}
4748ASSEMBLER_TEST_RUN(DoubleAbsoluteValue, test) {
4749 EXPECT_DISASSEMBLY(
4750 "22a52553 fabs.d fa0, fa0\n"
4751 "00008067 ret\n");
4752 EXPECT_EQ(0.0, CallD(test->entry(), 0.0));
4753 EXPECT_EQ(0.0, CallD(test->entry(), -0.0));
4754 EXPECT_EQ(42.0, CallD(test->entry(), 42.0));
4755 EXPECT_EQ(42.0, CallD(test->entry(), -42.0));
4756 EXPECT_EQ(std::numeric_limits<double>::infinity(),
4757 CallD(test->entry(), std::numeric_limits<double>::infinity()));
4758 EXPECT_EQ(std::numeric_limits<double>::infinity(),
4759 CallD(test->entry(), -std::numeric_limits<double>::infinity()));
4760}
4761
4762ASSEMBLER_TEST_GENERATE(DoubleNegate, assembler) {
4763 FLAG_use_compressed_instructions = false;
4764 __ SetExtensions(RV_G);
4765 __ fnegd(FA0, FA0);
4766 __ ret();
4767}
4768ASSEMBLER_TEST_RUN(DoubleNegate, test) {
4769 EXPECT_DISASSEMBLY(
4770 "22a51553 fneg.d fa0, fa0\n"
4771 "00008067 ret\n");
4772 EXPECT_EQ(-0.0, CallD(test->entry(), 0.0));
4773 EXPECT_EQ(0.0, CallD(test->entry(), -0.0));
4774 EXPECT_EQ(-42.0, CallD(test->entry(), 42.0));
4775 EXPECT_EQ(42.0, CallD(test->entry(), -42.0));
4776 EXPECT_EQ(-std::numeric_limits<double>::infinity(),
4777 CallD(test->entry(), std::numeric_limits<double>::infinity()));
4778 EXPECT_EQ(std::numeric_limits<double>::infinity(),
4779 CallD(test->entry(), -std::numeric_limits<double>::infinity()));
4780}
4781
4782#if XLEN >= 64
4783ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord, assembler) {
4784 FLAG_use_compressed_instructions = false;
4785 __ SetExtensions(RV_G);
4786 __ fcvtld(A0, FA0);
4787 __ ret();
4788}
4789ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord, test) {
4790 EXPECT_DISASSEMBLY(
4791 "c2250553 fcvt.l.d a0, fa0\n"
4792 "00008067 ret\n");
4793 EXPECT_EQ(-42, CallI(test->entry(), static_cast<double>(-42)));
4794 EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
4795 EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
4796 EXPECT_EQ(static_cast<int64_t>(kMinInt32),
4797 CallI(test->entry(), static_cast<double>(kMinInt32)));
4798 EXPECT_EQ(static_cast<int64_t>(kMaxInt32),
4799 CallI(test->entry(), static_cast<double>(kMaxInt32)));
4800 EXPECT_EQ(static_cast<int64_t>(kMaxUint32),
4801 CallI(test->entry(), static_cast<double>(kMaxUint32)));
4802 EXPECT_EQ(kMinInt64, CallI(test->entry(), static_cast<double>(kMinInt64)));
4803 EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<double>(kMaxInt64)));
4804 EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<double>(kMaxUint64)));
4805 EXPECT_EQ(kMinInt64,
4806 CallI(test->entry(), -std::numeric_limits<double>::infinity()));
4807 EXPECT_EQ(kMaxInt64,
4808 CallI(test->entry(), std::numeric_limits<double>::infinity()));
4809 EXPECT_EQ(kMaxInt64,
4810 CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
4811}
4812
4813ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RNE, assembler) {
4814 FLAG_use_compressed_instructions = false;
4815 __ SetExtensions(RV_G);
4816 __ fcvtld(A0, FA0, RNE);
4817 __ ret();
4818}
4819ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RNE, test) {
4820 EXPECT_DISASSEMBLY(
4821 "c2250553 fcvt.l.d a0, fa0\n"
4822 "00008067 ret\n");
4823 EXPECT_EQ(-44, CallI(test->entry(), -43.6));
4824 EXPECT_EQ(-44, CallI(test->entry(), -43.5));
4825 EXPECT_EQ(-43, CallI(test->entry(), -43.4));
4826 EXPECT_EQ(-43, CallI(test->entry(), -43.0));
4827 EXPECT_EQ(-43, CallI(test->entry(), -42.6));
4828 EXPECT_EQ(-42, CallI(test->entry(), -42.5));
4829 EXPECT_EQ(-42, CallI(test->entry(), -42.4));
4830 EXPECT_EQ(-42, CallI(test->entry(), -42.0));
4831 EXPECT_EQ(0, CallI(test->entry(), -0.0));
4832 EXPECT_EQ(0, CallI(test->entry(), +0.0));
4833 EXPECT_EQ(42, CallI(test->entry(), 42.0));
4834 EXPECT_EQ(42, CallI(test->entry(), 42.4));
4835 EXPECT_EQ(42, CallI(test->entry(), 42.5));
4836 EXPECT_EQ(43, CallI(test->entry(), 42.6));
4837 EXPECT_EQ(43, CallI(test->entry(), 43.0));
4838 EXPECT_EQ(43, CallI(test->entry(), 43.4));
4839 EXPECT_EQ(44, CallI(test->entry(), 43.5));
4840 EXPECT_EQ(44, CallI(test->entry(), 43.6));
4841}
4842
4843ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RTZ, assembler) {
4844 FLAG_use_compressed_instructions = false;
4845 __ SetExtensions(RV_G);
4846 __ fcvtld(A0, FA0, RTZ);
4847 __ ret();
4848}
4849ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RTZ, test) {
4850 EXPECT_DISASSEMBLY(
4851 "c2251553 fcvt.l.d a0, fa0, rtz\n"
4852 "00008067 ret\n");
4853 EXPECT_EQ(-43, CallI(test->entry(), -43.6));
4854 EXPECT_EQ(-43, CallI(test->entry(), -43.5));
4855 EXPECT_EQ(-43, CallI(test->entry(), -43.4));
4856 EXPECT_EQ(-43, CallI(test->entry(), -43.0));
4857 EXPECT_EQ(-42, CallI(test->entry(), -42.6));
4858 EXPECT_EQ(-42, CallI(test->entry(), -42.5));
4859 EXPECT_EQ(-42, CallI(test->entry(), -42.4));
4860 EXPECT_EQ(-42, CallI(test->entry(), -42.0));
4861 EXPECT_EQ(0, CallI(test->entry(), -0.0));
4862 EXPECT_EQ(0, CallI(test->entry(), +0.0));
4863 EXPECT_EQ(42, CallI(test->entry(), 42.0));
4864 EXPECT_EQ(42, CallI(test->entry(), 42.4));
4865 EXPECT_EQ(42, CallI(test->entry(), 42.5));
4866 EXPECT_EQ(42, CallI(test->entry(), 42.6));
4867 EXPECT_EQ(43, CallI(test->entry(), 43.0));
4868 EXPECT_EQ(43, CallI(test->entry(), 43.4));
4869 EXPECT_EQ(43, CallI(test->entry(), 43.5));
4870 EXPECT_EQ(43, CallI(test->entry(), 43.6));
4871}
4872
4873ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RDN, assembler) {
4874 FLAG_use_compressed_instructions = false;
4875 __ SetExtensions(RV_G);
4876 __ fcvtld(A0, FA0, RDN);
4877 __ ret();
4878}
4879ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RDN, test) {
4880 EXPECT_DISASSEMBLY(
4881 "c2252553 fcvt.l.d a0, fa0, rdn\n"
4882 "00008067 ret\n");
4883 EXPECT_EQ(-44, CallI(test->entry(), -43.6));
4884 EXPECT_EQ(-44, CallI(test->entry(), -43.5));
4885 EXPECT_EQ(-44, CallI(test->entry(), -43.4));
4886 EXPECT_EQ(-43, CallI(test->entry(), -43.0));
4887 EXPECT_EQ(-43, CallI(test->entry(), -42.6));
4888 EXPECT_EQ(-43, CallI(test->entry(), -42.5));
4889 EXPECT_EQ(-43, CallI(test->entry(), -42.4));
4890 EXPECT_EQ(-42, CallI(test->entry(), -42.0));
4891 EXPECT_EQ(0, CallI(test->entry(), -0.0));
4892 EXPECT_EQ(0, CallI(test->entry(), +0.0));
4893 EXPECT_EQ(42, CallI(test->entry(), 42.0));
4894 EXPECT_EQ(42, CallI(test->entry(), 42.4));
4895 EXPECT_EQ(42, CallI(test->entry(), 42.5));
4896 EXPECT_EQ(42, CallI(test->entry(), 42.6));
4897 EXPECT_EQ(43, CallI(test->entry(), 43.0));
4898 EXPECT_EQ(43, CallI(test->entry(), 43.4));
4899 EXPECT_EQ(43, CallI(test->entry(), 43.5));
4900 EXPECT_EQ(43, CallI(test->entry(), 43.6));
4901}
4902
4903ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RUP, assembler) {
4904 FLAG_use_compressed_instructions = false;
4905 __ SetExtensions(RV_G);
4906 __ fcvtld(A0, FA0, RUP);
4907 __ ret();
4908}
4909ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RUP, test) {
4910 EXPECT_DISASSEMBLY(
4911 "c2253553 fcvt.l.d a0, fa0, rup\n"
4912 "00008067 ret\n");
4913 EXPECT_EQ(-43, CallI(test->entry(), -43.6));
4914 EXPECT_EQ(-43, CallI(test->entry(), -43.5));
4915 EXPECT_EQ(-43, CallI(test->entry(), -43.4));
4916 EXPECT_EQ(-43, CallI(test->entry(), -43.0));
4917 EXPECT_EQ(-42, CallI(test->entry(), -42.6));
4918 EXPECT_EQ(-42, CallI(test->entry(), -42.5));
4919 EXPECT_EQ(-42, CallI(test->entry(), -42.4));
4920 EXPECT_EQ(-42, CallI(test->entry(), -42.0));
4921 EXPECT_EQ(0, CallI(test->entry(), -0.0));
4922 EXPECT_EQ(0, CallI(test->entry(), +0.0));
4923 EXPECT_EQ(42, CallI(test->entry(), 42.0));
4924 EXPECT_EQ(43, CallI(test->entry(), 42.4));
4925 EXPECT_EQ(43, CallI(test->entry(), 42.5));
4926 EXPECT_EQ(43, CallI(test->entry(), 42.6));
4927 EXPECT_EQ(43, CallI(test->entry(), 43.0));
4928 EXPECT_EQ(44, CallI(test->entry(), 43.5));
4929 EXPECT_EQ(44, CallI(test->entry(), 43.5));
4930 EXPECT_EQ(44, CallI(test->entry(), 43.6));
4931}
4932
4933ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RMM, assembler) {
4934 FLAG_use_compressed_instructions = false;
4935 __ SetExtensions(RV_G);
4936 __ fcvtld(A0, FA0, RMM);
4937 __ ret();
4938}
4939ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RMM, test) {
4940 EXPECT_DISASSEMBLY(
4941 "c2254553 fcvt.l.d a0, fa0, rmm\n"
4942 "00008067 ret\n");
4943 EXPECT_EQ(-44, CallI(test->entry(), -43.6));
4944 EXPECT_EQ(-44, CallI(test->entry(), -43.5));
4945 EXPECT_EQ(-43, CallI(test->entry(), -43.4));
4946 EXPECT_EQ(-43, CallI(test->entry(), -43.0));
4947 EXPECT_EQ(-43, CallI(test->entry(), -42.6));
4948 EXPECT_EQ(-43, CallI(test->entry(), -42.5));
4949 EXPECT_EQ(-42, CallI(test->entry(), -42.4));
4950 EXPECT_EQ(-42, CallI(test->entry(), -42.0));
4951 EXPECT_EQ(0, CallI(test->entry(), -0.0));
4952 EXPECT_EQ(0, CallI(test->entry(), +0.0));
4953 EXPECT_EQ(42, CallI(test->entry(), 42.0));
4954 EXPECT_EQ(42, CallI(test->entry(), 42.4));
4955 EXPECT_EQ(43, CallI(test->entry(), 42.5));
4956 EXPECT_EQ(43, CallI(test->entry(), 42.6));
4957 EXPECT_EQ(43, CallI(test->entry(), 43.0));
4958 EXPECT_EQ(43, CallI(test->entry(), 43.4));
4959 EXPECT_EQ(44, CallI(test->entry(), 43.5));
4960 EXPECT_EQ(44, CallI(test->entry(), 43.6));
4961}
4962
4963ASSEMBLER_TEST_GENERATE(ConvertDoubleToUnsignedDoubleWord, assembler) {
4964 FLAG_use_compressed_instructions = false;
4965 __ SetExtensions(RV_G);
4966 __ fcvtlud(A0, FA0);
4967 __ ret();
4968}
4969ASSEMBLER_TEST_RUN(ConvertDoubleToUnsignedDoubleWord, test) {
4970 EXPECT_DISASSEMBLY(
4971 "c2350553 fcvt.lu.d a0, fa0\n"
4972 "00008067 ret\n");
4973 EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(-42)));
4974 EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
4975 EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
4976 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
4977 CallI(test->entry(), static_cast<double>(kMinInt32)));
4978 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt32)),
4979 CallI(test->entry(), static_cast<double>(kMaxInt32)));
4980 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint32)),
4981 CallI(test->entry(), static_cast<double>(kMaxUint32)));
4982 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
4983 CallI(test->entry(), static_cast<double>(kMinInt64)));
4984 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt64) + 1),
4985 CallI(test->entry(), static_cast<double>(kMaxInt64)));
4986 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
4987 CallI(test->entry(), static_cast<double>(kMaxUint64)));
4988 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
4989 CallI(test->entry(), -std::numeric_limits<double>::infinity()));
4990 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
4991 CallI(test->entry(), std::numeric_limits<double>::infinity()));
4992 EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
4993 CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
4994}
4995
4996ASSEMBLER_TEST_GENERATE(BitCastDoubleToInteger, assembler) {
4997 FLAG_use_compressed_instructions = false;
4998 __ SetExtensions(RV_G);
4999 __ fmvxd(A0, FA0);
5000 __ ret();
5001}
5002ASSEMBLER_TEST_RUN(BitCastDoubleToInteger, test) {
5003 EXPECT_DISASSEMBLY(
5004 "e2050553 fmv.x.d a0, fa0\n"
5005 "00008067 ret\n");
5006 EXPECT_EQ(bit_cast<int64_t>(0.0), CallI(test->entry(), 0.0));
5007 EXPECT_EQ(bit_cast<int64_t>(-0.0), CallI(test->entry(), -0.0));
5008 EXPECT_EQ(bit_cast<int64_t>(42.0), CallI(test->entry(), 42.0));
5009 EXPECT_EQ(bit_cast<int64_t>(-42.0), CallI(test->entry(), -42.0));
5010 EXPECT_EQ(bit_cast<int64_t>(std::numeric_limits<double>::quiet_NaN()),
5011 CallI(test->entry(), std::numeric_limits<double>::quiet_NaN()));
5012 EXPECT_EQ(bit_cast<int64_t>(std::numeric_limits<double>::signaling_NaN()),
5013 CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
5014 EXPECT_EQ(bit_cast<int64_t>(std::numeric_limits<double>::infinity()),
5015 CallI(test->entry(), std::numeric_limits<double>::infinity()));
5016 EXPECT_EQ(bit_cast<int64_t>(-std::numeric_limits<double>::infinity()),
5017 CallI(test->entry(), -std::numeric_limits<double>::infinity()));
5018}
5019
5020ASSEMBLER_TEST_GENERATE(ConvertDoubleWordToDouble, assembler) {
5021 FLAG_use_compressed_instructions = false;
5022 __ SetExtensions(RV_G);
5023 __ fcvtdl(FA0, A0);
5024 __ ret();
5025}
5026ASSEMBLER_TEST_RUN(ConvertDoubleWordToDouble, test) {
5027 EXPECT_DISASSEMBLY(
5028 "d2250553 fcvt.d.l fa0, a0\n"
5029 "00008067 ret\n");
5030 EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
5031 EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
5032 EXPECT_EQ(-42.0, CallD(test->entry(), sign_extend(-42)));
5033 EXPECT_EQ(static_cast<double>(kMinInt32),
5034 CallD(test->entry(), sign_extend(kMinInt32)));
5035 EXPECT_EQ(static_cast<double>(kMaxInt32),
5036 CallD(test->entry(), sign_extend(kMaxInt32)));
5037 EXPECT_EQ(static_cast<double>(sign_extend(kMaxUint32)),
5038 CallD(test->entry(), sign_extend(kMaxUint32)));
5039 EXPECT_EQ(static_cast<double>(kMinInt64),
5040 CallD(test->entry(), sign_extend(kMinInt64)));
5041 EXPECT_EQ(static_cast<double>(kMaxInt64),
5042 CallD(test->entry(), sign_extend(kMaxInt64)));
5043 EXPECT_EQ(static_cast<double>(sign_extend(kMaxUint64)),
5044 CallD(test->entry(), sign_extend(kMaxUint64)));
5045}
5046
5047ASSEMBLER_TEST_GENERATE(ConvertUnsignedDoubleWordToDouble, assembler) {
5048 FLAG_use_compressed_instructions = false;
5049 __ SetExtensions(RV_G);
5050 __ fcvtdlu(FA0, A0);
5051 __ ret();
5052}
5053ASSEMBLER_TEST_RUN(ConvertUnsignedDoubleWordToDouble, test) {
5054 EXPECT_DISASSEMBLY(
5055 "d2350553 fcvt.d.lu fa0, a0\n"
5056 "00008067 ret\n");
5057 EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
5058 EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
5059 EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(-42))),
5060 CallD(test->entry(), sign_extend(-42)));
5061 EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMinInt32))),
5062 CallD(test->entry(), sign_extend(kMinInt32)));
5063 EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMaxInt32))),
5064 CallD(test->entry(), sign_extend(kMaxInt32)));
5065 EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMaxUint32))),
5066 CallD(test->entry(), sign_extend(kMaxUint32)));
5067 EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMinInt64))),
5068 CallD(test->entry(), sign_extend(kMinInt64)));
5069 EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMaxInt64))),
5070 CallD(test->entry(), sign_extend(kMaxInt64)));
5071 EXPECT_EQ(static_cast<double>(kMaxUint64),
5072 CallD(test->entry(), sign_extend(kMaxUint64)));
5073}
5074
5075ASSEMBLER_TEST_GENERATE(BitCastIntegerToDouble, assembler) {
5076 FLAG_use_compressed_instructions = false;
5077 __ SetExtensions(RV_G);
5078 __ fmvdx(FA0, A0);
5079 __ ret();
5080}
5081ASSEMBLER_TEST_RUN(BitCastIntegerToDouble, test) {
5082 EXPECT_DISASSEMBLY(
5083 "f2050553 fmv.d.x fa0, a0\n"
5084 "00008067 ret\n");
5085 EXPECT_EQ(0.0, CallD(test->entry(), bit_cast<int64_t>(0.0)));
5086 EXPECT_EQ(-0.0, CallD(test->entry(), bit_cast<int64_t>(-0.0)));
5087 EXPECT_EQ(42.0, CallD(test->entry(), bit_cast<int64_t>(42.0)));
5088 EXPECT_EQ(-42.0, CallD(test->entry(), bit_cast<int64_t>(-42.0)));
5089 EXPECT_EQ(true, isnan(CallD(test->entry(),
5090 bit_cast<int64_t>(
5091 std::numeric_limits<double>::quiet_NaN()))));
5092 EXPECT_EQ(true,
5093 isnan(CallD(test->entry(),
5094 bit_cast<int64_t>(
5095 std::numeric_limits<double>::signaling_NaN()))));
5096 EXPECT_EQ(std::numeric_limits<double>::infinity(),
5097 CallD(test->entry(),
5098 bit_cast<int64_t>(std::numeric_limits<double>::infinity())));
5099 EXPECT_EQ(-std::numeric_limits<double>::infinity(),
5100 CallD(test->entry(),
5101 bit_cast<int64_t>(-std::numeric_limits<double>::infinity())));
5102}
5103#endif
5104
5105ASSEMBLER_TEST_GENERATE(Fibonacci, assembler) {
5106 FLAG_use_compressed_instructions = false;
5107 __ SetExtensions(RV_G);
5108 Label fib, base, done;
5109 __ Bind(&fib);
5110 __ subi(SP, SP, sizeof(uintx_t) * 4);
5111 __ sx(RA, Address(SP, 3 * sizeof(uintx_t)));
5112 __ sx(A0, Address(SP, 2 * sizeof(uintx_t)));
5113 __ subi(A0, A0, 1);
5114 __ blez(A0, &base);
5115
5116 __ jal(&fib);
5117 __ sx(A0, Address(SP, 1 * sizeof(uintx_t)));
5118 __ lx(A0, Address(SP, 2 * sizeof(uintx_t)));
5119 __ subi(A0, A0, 2);
5120 __ jal(&fib);
5121 __ lx(A1, Address(SP, 1 * sizeof(uintx_t)));
5122 __ add(A0, A0, A1);
5123 __ j(&done);
5124
5125 __ Bind(&base);
5126 __ li(A0, 1);
5127
5128 __ Bind(&done);
5129 __ lx(RA, Address(SP, 3 * sizeof(uintx_t)));
5130 __ addi(SP, SP, sizeof(uintx_t) * 4);
5131 __ ret();
5132 __ trap();
5133}
5134ASSEMBLER_TEST_RUN(Fibonacci, test) {
5135#if XLEN == 32
5136 EXPECT_DISASSEMBLY(
5137 "ff010113 addi sp, sp, -16\n"
5138 "00112623 sw ra, 12(sp)\n"
5139 "00a12423 sw a0, 8(sp)\n"
5140 "fff50513 addi a0, a0, -1\n"
5141 "02a05263 blez a0, +36\n"
5142 "fedff0ef jal -20\n"
5143 "00a12223 sw a0, 4(sp)\n"
5144 "00812503 lw a0, 8(sp)\n"
5145 "ffe50513 addi a0, a0, -2\n"
5146 "fddff0ef jal -36\n"
5147 "00412583 lw a1, 4(sp)\n"
5148 "00b50533 add a0, a0, a1\n"
5149 "0080006f j +8\n"
5150 "00100513 li a0, 1\n"
5151 "00c12083 lw ra, 12(sp)\n"
5152 "01010113 addi sp, sp, 16\n"
5153 "00008067 ret\n"
5154 "00000000 trap\n");
5155#elif XLEN == 64
5156 EXPECT_DISASSEMBLY(
5157 "fe010113 addi sp, sp, -32\n"
5158 "00113c23 sd ra, 24(sp)\n"
5159 "00a13823 sd a0, 16(sp)\n"
5160 "fff50513 addi a0, a0, -1\n"
5161 "02a05263 blez a0, +36\n"
5162 "fedff0ef jal -20\n"
5163 "00a13423 sd a0, 8(sp)\n"
5164 "01013503 ld a0, 16(sp)\n"
5165 "ffe50513 addi a0, a0, -2\n"
5166 "fddff0ef jal -36\n"
5167 "00813583 ld a1, 8(sp)\n"
5168 "00b50533 add a0, a0, a1\n"
5169 "0080006f j +8\n"
5170 "00100513 li a0, 1\n"
5171 "01813083 ld ra, 24(sp)\n"
5172 "02010113 addi sp, sp, 32\n"
5173 "00008067 ret\n"
5174 "00000000 trap\n");
5175#else
5176#error Unimplemented
5177#endif
5178 EXPECT_EQ(1, Call(test->entry(), 0));
5179 EXPECT_EQ(1, Call(test->entry(), 1));
5180 EXPECT_EQ(2, Call(test->entry(), 2));
5181 EXPECT_EQ(3, Call(test->entry(), 3));
5182 EXPECT_EQ(5, Call(test->entry(), 4));
5183 EXPECT_EQ(8, Call(test->entry(), 5));
5184 EXPECT_EQ(13, Call(test->entry(), 6));
5185}
5186
5187ASSEMBLER_TEST_GENERATE(CompressedLoadStoreWordSP_0, assembler) {
5188 FLAG_use_compressed_instructions = true;
5189 __ SetExtensions(RV_GC);
5190
5191 __ subi(SP, SP, 256);
5192 __ sw(A1, Address(SP, 0));
5193 __ lw(A0, Address(SP, 0));
5194 __ addi(SP, SP, 256);
5195 __ ret();
5196}
5197ASSEMBLER_TEST_RUN(CompressedLoadStoreWordSP_0, test) {
5198 EXPECT_DISASSEMBLY(
5199 " 7111 addi sp, sp, -256\n"
5200 " c02e sw a1, 0(sp)\n"
5201 " 4502 lw a0, 0(sp)\n"
5202 " 6111 addi sp, sp, 256\n"
5203 " 8082 ret\n");
5204
5205 EXPECT_EQ(sign_extend(0xAB010203), Call(test->entry(), 0, 0xAB010203));
5206 EXPECT_EQ(sign_extend(0xCD020405), Call(test->entry(), 0, 0xCD020405));
5207 EXPECT_EQ(sign_extend(0xEF030607), Call(test->entry(), 0, 0xEF030607));
5208}
5209ASSEMBLER_TEST_GENERATE(CompressedLoadStoreWordSP_Pos, assembler) {
5210 FLAG_use_compressed_instructions = true;
5211 __ SetExtensions(RV_GC);
5212
5213 __ subi(SP, SP, 256);
5214 __ sw(A1, Address(SP, 4));
5215 __ lw(A0, Address(SP, 4));
5216 __ addi(SP, SP, 256);
5217 __ ret();
5218}
5219ASSEMBLER_TEST_RUN(CompressedLoadStoreWordSP_Pos, test) {
5220 EXPECT_DISASSEMBLY(
5221 " 7111 addi sp, sp, -256\n"
5222 " c22e sw a1, 4(sp)\n"
5223 " 4512 lw a0, 4(sp)\n"
5224 " 6111 addi sp, sp, 256\n"
5225 " 8082 ret\n");
5226
5227 EXPECT_EQ(sign_extend(0xAB010203), Call(test->entry(), 0, 0xAB010203));
5228 EXPECT_EQ(sign_extend(0xCD020405), Call(test->entry(), 0, 0xCD020405));
5229 EXPECT_EQ(sign_extend(0xEF030607), Call(test->entry(), 0, 0xEF030607));
5230}
5231
5232#if XLEN == 32
5233ASSEMBLER_TEST_GENERATE(CompressedLoadStoreSingleFloatSP_0, assembler) {
5234 FLAG_use_compressed_instructions = true;
5235 __ SetExtensions(RV_GC);
5236 __ subi(SP, SP, 256);
5237 __ fsw(FA1, Address(SP, 0));
5238 __ flw(FA0, Address(SP, 0));
5239 __ addi(SP, SP, 256);
5240 __ ret();
5241}
5242ASSEMBLER_TEST_RUN(CompressedLoadStoreSingleFloatSP_0, test) {
5243 EXPECT_DISASSEMBLY(
5244 " 7111 addi sp, sp, -256\n"
5245 " e02e fsw fa1, 0(sp)\n"
5246 " 6502 flw fa0, 0(sp)\n"
5247 " 6111 addi sp, sp, 256\n"
5248 " 8082 ret\n");
5249
5250 EXPECT_EQ(1.7f, CallF(test->entry(), 0.0f, 1.7f));
5251 EXPECT_EQ(2.8f, CallF(test->entry(), 0.0f, 2.8f));
5252 EXPECT_EQ(3.9f, CallF(test->entry(), 0.0f, 3.9f));
5253}
5254
5255ASSEMBLER_TEST_GENERATE(CompressedLoadStoreSingleFloatSP_Pos, assembler) {
5256 FLAG_use_compressed_instructions = true;
5257 __ SetExtensions(RV_GC);
5258 __ subi(SP, SP, 256);
5259 __ fsw(FA1, Address(SP, 4));
5260 __ flw(FA0, Address(SP, 4));
5261 __ addi(SP, SP, 256);
5262 __ ret();
5263}
5264ASSEMBLER_TEST_RUN(CompressedLoadStoreSingleFloatSP_Pos, test) {
5265 EXPECT_DISASSEMBLY(
5266 " 7111 addi sp, sp, -256\n"
5267 " e22e fsw fa1, 4(sp)\n"
5268 " 6512 flw fa0, 4(sp)\n"
5269 " 6111 addi sp, sp, 256\n"
5270 " 8082 ret\n");
5271
5272 EXPECT_EQ(1.7f, CallF(test->entry(), 0.0f, 1.7f));
5273 EXPECT_EQ(2.8f, CallF(test->entry(), 0.0f, 2.8f));
5274 EXPECT_EQ(3.9f, CallF(test->entry(), 0.0f, 3.9f));
5275}
5276#endif
5277
5278ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleFloatSP_0, assembler) {
5279 FLAG_use_compressed_instructions = true;
5280 __ SetExtensions(RV_GC);
5281 __ subi(SP, SP, 256);
5282 __ fsd(FA1, Address(SP, 0));
5283 __ fld(FA0, Address(SP, 0));
5284 __ addi(SP, SP, 256);
5285 __ ret();
5286}
5287ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleFloatSP_0, test) {
5288 EXPECT_DISASSEMBLY(
5289 " 7111 addi sp, sp, -256\n"
5290 " a02e fsd fa1, 0(sp)\n"
5291 " 2502 fld fa0, 0(sp)\n"
5292 " 6111 addi sp, sp, 256\n"
5293 " 8082 ret\n");
5294
5295 EXPECT_EQ(1.7, CallD(test->entry(), 0.0, 1.7));
5296 EXPECT_EQ(2.8, CallD(test->entry(), 0.0, 2.8));
5297 EXPECT_EQ(3.9, CallD(test->entry(), 0.0, 3.9));
5298}
5299ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleFloatSP_Pos, assembler) {
5300 FLAG_use_compressed_instructions = true;
5301 __ SetExtensions(RV_GC);
5302 __ subi(SP, SP, 256);
5303 __ fsd(FA1, Address(SP, 8));
5304 __ fld(FA0, Address(SP, 8));
5305 __ addi(SP, SP, 256);
5306 __ ret();
5307}
5308ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleFloatSP_Pos, test) {
5309 EXPECT_DISASSEMBLY(
5310 " 7111 addi sp, sp, -256\n"
5311 " a42e fsd fa1, 8(sp)\n"
5312 " 2522 fld fa0, 8(sp)\n"
5313 " 6111 addi sp, sp, 256\n"
5314 " 8082 ret\n");
5315
5316 EXPECT_EQ(1.7, CallD(test->entry(), 0.0, 1.7));
5317 EXPECT_EQ(2.8, CallD(test->entry(), 0.0, 2.8));
5318 EXPECT_EQ(3.9, CallD(test->entry(), 0.0, 3.9));
5319}
5320
5321#if XLEN >= 64
5322ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleWordSP_0, assembler) {
5323 FLAG_use_compressed_instructions = true;
5324 __ SetExtensions(RV_GC);
5325 __ subi(SP, SP, 256);
5326 __ sd(A1, Address(SP, 0));
5327 __ ld(A0, Address(SP, 0));
5328 __ addi(SP, SP, 256);
5329 __ ret();
5330}
5331ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleWordSP_0, test) {
5332 EXPECT_DISASSEMBLY(
5333 " 7111 addi sp, sp, -256\n"
5334 " e02e sd a1, 0(sp)\n"
5335 " 6502 ld a0, 0(sp)\n"
5336 " 6111 addi sp, sp, 256\n"
5337 " 8082 ret\n");
5338
5339 EXPECT_EQ((intx_t)0xAB01020304050607,
5340 Call(test->entry(), 0, 0xAB01020304050607));
5341 EXPECT_EQ((intx_t)0xCD02040505060708,
5342 Call(test->entry(), 0, 0xCD02040505060708));
5343 EXPECT_EQ((intx_t)0xEF03060708090A0B,
5344 Call(test->entry(), 0, 0xEF03060708090A0B));
5345}
5346ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleWordSP_Pos, assembler) {
5347 FLAG_use_compressed_instructions = true;
5348 __ SetExtensions(RV_GC);
5349 __ subi(SP, SP, 256);
5350 __ sd(A1, Address(SP, 8));
5351 __ ld(A0, Address(SP, 8));
5352 __ addi(SP, SP, 256);
5353 __ ret();
5354}
5355ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleWordSP_Pos, test) {
5356 EXPECT_DISASSEMBLY(
5357 " 7111 addi sp, sp, -256\n"
5358 " e42e sd a1, 8(sp)\n"
5359 " 6522 ld a0, 8(sp)\n"
5360 " 6111 addi sp, sp, 256\n"
5361 " 8082 ret\n");
5362
5363 EXPECT_EQ((intx_t)0xAB01020304050607,
5364 Call(test->entry(), 0, 0xAB01020304050607));
5365 EXPECT_EQ((intx_t)0xCD02040505060708,
5366 Call(test->entry(), 0, 0xCD02040505060708));
5367 EXPECT_EQ((intx_t)0xEF03060708090A0B,
5368 Call(test->entry(), 0, 0xEF03060708090A0B));
5369}
5370#endif
5371
5372ASSEMBLER_TEST_GENERATE(CompressedLoadWord_0, assembler) {
5373 FLAG_use_compressed_instructions = true;
5374 __ SetExtensions(RV_GC);
5375 __ lw(A0, Address(A0, 0));
5376 __ ret();
5377}
5378ASSEMBLER_TEST_RUN(CompressedLoadWord_0, test) {
5379 EXPECT_DISASSEMBLY(
5380 " 4108 lw a0, 0(a0)\n"
5381 " 8082 ret\n");
5382
5383 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
5384 values[0] = 0xAB010203;
5385 values[1] = 0xCD020405;
5386 values[2] = 0xEF030607;
5387
5388 EXPECT_EQ(-855505915,
5389 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
5390}
5391ASSEMBLER_TEST_GENERATE(CompressedLoadWord_Pos, assembler) {
5392 FLAG_use_compressed_instructions = true;
5393 __ SetExtensions(RV_GC);
5394 __ lw(A0, Address(A0, 4));
5395 __ ret();
5396}
5397ASSEMBLER_TEST_RUN(CompressedLoadWord_Pos, test) {
5398 EXPECT_DISASSEMBLY(
5399 " 4148 lw a0, 4(a0)\n"
5400 " 8082 ret\n");
5401
5402 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
5403 values[0] = 0xAB010203;
5404 values[1] = 0xCD020405;
5405 values[2] = 0xEF030607;
5406
5407 EXPECT_EQ(-285014521,
5408 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
5409}
5410
5411ASSEMBLER_TEST_GENERATE(CompressedStoreWord_0, assembler) {
5412 FLAG_use_compressed_instructions = true;
5413 __ SetExtensions(RV_GC);
5414 __ sw(A1, Address(A0, 0));
5415 __ ret();
5416}
5417ASSEMBLER_TEST_RUN(CompressedStoreWord_0, test) {
5418 EXPECT_DISASSEMBLY(
5419 " c10c sw a1, 0(a0)\n"
5420 " 8082 ret\n");
5421
5422 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
5423 values[0] = 0;
5424 values[1] = 0;
5425 values[2] = 0;
5426
5427 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD020405);
5428 EXPECT_EQ(0u, values[0]);
5429 EXPECT_EQ(0xCD020405, values[1]);
5430 EXPECT_EQ(0u, values[2]);
5431}
5432ASSEMBLER_TEST_GENERATE(CompressedStoreWord_Pos, assembler) {
5433 FLAG_use_compressed_instructions = true;
5434 __ SetExtensions(RV_GC);
5435 __ sw(A1, Address(A0, 4));
5436 __ ret();
5437}
5438ASSEMBLER_TEST_RUN(CompressedStoreWord_Pos, test) {
5439 EXPECT_DISASSEMBLY(
5440 " c14c sw a1, 4(a0)\n"
5441 " 8082 ret\n");
5442
5443 uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
5444 values[0] = 0;
5445 values[1] = 0;
5446 values[2] = 0;
5447
5448 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF030607);
5449 EXPECT_EQ(0u, values[0]);
5450 EXPECT_EQ(0u, values[1]);
5451 EXPECT_EQ(0xEF030607, values[2]);
5452}
5453
5454#if XLEN == 32
5455ASSEMBLER_TEST_GENERATE(CompressedLoadSingleFloat, assembler) {
5456 FLAG_use_compressed_instructions = true;
5457 __ SetExtensions(RV_GC);
5458 __ flw(FA0, Address(A0, 1 * sizeof(float)));
5459 __ ret();
5460}
5461ASSEMBLER_TEST_RUN(CompressedLoadSingleFloat, test) {
5462 EXPECT_DISASSEMBLY(
5463 " 6148 flw fa0, 4(a0)\n"
5464 " 8082 ret\n");
5465
5466 float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
5467 data[0] = 1.7f;
5468 data[1] = 2.8f;
5469 data[2] = 3.9f;
5470 EXPECT_EQ(data[1], CallF(test->entry(), reinterpret_cast<intx_t>(data)));
5471}
5472
5473ASSEMBLER_TEST_GENERATE(CompressedStoreSingleFloat, assembler) {
5474 FLAG_use_compressed_instructions = true;
5475 __ SetExtensions(RV_GC);
5476 __ fsw(FA0, Address(A0, 1 * sizeof(float)));
5477 __ ret();
5478}
5479ASSEMBLER_TEST_RUN(CompressedStoreSingleFloat, test) {
5480 EXPECT_DISASSEMBLY(
5481 " e148 fsw fa0, 4(a0)\n"
5482 " 8082 ret\n");
5483
5484 float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
5485 data[0] = 1.7f;
5486 data[1] = 2.8f;
5487 data[2] = 3.9f;
5488 CallF(test->entry(), reinterpret_cast<intx_t>(data), 4.2f);
5489 EXPECT_EQ(4.2f, data[1]);
5490}
5491#endif
5492
5493#if XLEN >= 64
5494ASSEMBLER_TEST_GENERATE(CompressedLoadDoubleWord_0, assembler) {
5495 FLAG_use_compressed_instructions = true;
5496 __ SetExtensions(RV_GC);
5497 __ ld(A0, Address(A0, 0));
5498 __ ret();
5499}
5500ASSEMBLER_TEST_RUN(CompressedLoadDoubleWord_0, test) {
5501 EXPECT_DISASSEMBLY(
5502 " 6108 ld a0, 0(a0)\n"
5503 " 8082 ret\n");
5504
5505 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
5506 values[0] = 0xAB01020304050607;
5507 values[1] = 0xCD02040505060708;
5508 values[2] = 0xEF03060708090A0B;
5509
5510 EXPECT_EQ(-3674369926375274744,
5511 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
5512}
5513ASSEMBLER_TEST_GENERATE(CompressedLoadDoubleWord_Pos, assembler) {
5514 FLAG_use_compressed_instructions = true;
5515 __ SetExtensions(RV_GC);
5516 __ ld(A0, Address(A0, 8));
5517 __ ret();
5518}
5519ASSEMBLER_TEST_RUN(CompressedLoadDoubleWord_Pos, test) {
5520 EXPECT_DISASSEMBLY(
5521 " 6508 ld a0, 8(a0)\n"
5522 " 8082 ret\n");
5523
5524 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
5525 values[0] = 0xAB01020304050607;
5526 values[1] = 0xCD02040505060708;
5527 values[2] = 0xEF03060708090A0B;
5528
5529 EXPECT_EQ(-1224128046445295093,
5530 Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
5531}
5532
5533ASSEMBLER_TEST_GENERATE(CompressedStoreDoubleWord_0, assembler) {
5534 FLAG_use_compressed_instructions = true;
5535 __ SetExtensions(RV_GC);
5536 __ sd(A1, Address(A0, 0));
5537 __ ret();
5538}
5539ASSEMBLER_TEST_RUN(CompressedStoreDoubleWord_0, test) {
5540 EXPECT_DISASSEMBLY(
5541 " e10c sd a1, 0(a0)\n"
5542 " 8082 ret\n");
5543
5544 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
5545 values[0] = 0;
5546 values[1] = 0;
5547 values[2] = 0;
5548
5549 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD02040505060708);
5550 EXPECT_EQ(0u, values[0]);
5551 EXPECT_EQ(0xCD02040505060708, values[1]);
5552 EXPECT_EQ(0u, values[2]);
5553}
5554ASSEMBLER_TEST_GENERATE(CompressedStoreDoubleWord_Pos, assembler) {
5555 FLAG_use_compressed_instructions = true;
5556 __ SetExtensions(RV_GC);
5557 __ sd(A1, Address(A0, 8));
5558 __ ret();
5559}
5560ASSEMBLER_TEST_RUN(CompressedStoreDoubleWord_Pos, test) {
5561 EXPECT_DISASSEMBLY(
5562 " e50c sd a1, 8(a0)\n"
5563 " 8082 ret\n");
5564
5565 uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
5566 values[0] = 0;
5567 values[1] = 0;
5568 values[2] = 0;
5569
5570 Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF03060708090A0B);
5571 EXPECT_EQ(0u, values[0]);
5572 EXPECT_EQ(0u, values[1]);
5573 EXPECT_EQ(0xEF03060708090A0B, values[2]);
5574}
5575
5576ASSEMBLER_TEST_GENERATE(CompressedLoadDoubleFloat, assembler) {
5577 FLAG_use_compressed_instructions = true;
5578 __ SetExtensions(RV_GC);
5579 __ fld(FA0, Address(A0, 1 * sizeof(double)));
5580 __ ret();
5581}
5582ASSEMBLER_TEST_RUN(CompressedLoadDoubleFloat, test) {
5583 EXPECT_DISASSEMBLY(
5584 " 2508 fld fa0, 8(a0)\n"
5585 " 8082 ret\n");
5586
5587 double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
5588 data[0] = 1.7;
5589 data[1] = 2.8;
5590 data[2] = 3.9;
5591 EXPECT_EQ(data[1], CallD(test->entry(), reinterpret_cast<intx_t>(data)));
5592 free(data);
5593}
5594
5595ASSEMBLER_TEST_GENERATE(CompressedStoreDoubleFloat, assembler) {
5596 FLAG_use_compressed_instructions = true;
5597 __ SetExtensions(RV_GC);
5598 __ fsd(FA0, Address(A0, 1 * sizeof(double)));
5599 __ ret();
5600}
5601ASSEMBLER_TEST_RUN(CompressedStoreDoubleFloat, test) {
5602 EXPECT_DISASSEMBLY(
5603 " a508 fsd fa0, 8(a0)\n"
5604 " 8082 ret\n");
5605
5606 double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
5607 data[0] = 1.7;
5608 data[1] = 2.8;
5609 data[2] = 3.9;
5610 CallD(test->entry(), reinterpret_cast<intx_t>(data), 4.2);
5611 EXPECT_EQ(4.2, data[1]);
5612}
5613#endif
5614
5615#if XLEN == 32
5616ASSEMBLER_TEST_GENERATE(CompressedJumpAndLink, assembler) {
5617 FLAG_use_compressed_instructions = true;
5618 __ SetExtensions(RV_GC);
5619
5620 Label label1, label2;
5621 __ mv(T3, RA);
5622 __ jal(&label1, Assembler::kNearJump); // Forward.
5623 __ sub(A0, T0, T1);
5624 __ mv(RA, T3);
5625 __ ret();
5626 __ trap();
5627
5628 __ Bind(&label2);
5629 __ mv(T5, RA);
5630 __ li(T1, 7);
5631 __ jr(T5);
5632 __ trap();
5633
5634 __ Bind(&label1);
5635 __ mv(T4, RA);
5636 __ li(T0, 4);
5637 __ jal(&label2, Assembler::kNearJump); // Backward.
5638 __ mv(RA, T4);
5639 __ jr(T4);
5640 __ trap();
5641}
5642ASSEMBLER_TEST_RUN(CompressedJumpAndLink, test) {
5643 EXPECT_DISASSEMBLY(
5644 " 8e06 mv t3, ra\n"
5645 " 2811 jal +20\n"
5646 "40628533 sub a0, t0, t1\n"
5647 " 80f2 mv ra, t3\n"
5648 " 8082 ret\n"
5649 " 0000 trap\n"
5650 " 8f06 mv t5, ra\n"
5651 " 431d li t1, 7\n"
5652 " 8f02 jr t5\n"
5653 " 0000 trap\n"
5654 " 8e86 mv t4, ra\n"
5655 " 4291 li t0, 4\n"
5656 " 3fd5 jal -12\n"
5657 " 80f6 mv ra, t4\n"
5658 " 8e82 jr t4\n"
5659 " 0000 trap\n");
5660 EXPECT_EQ(-3, Call(test->entry()));
5661}
5662#endif
5663
5664ASSEMBLER_TEST_GENERATE(CompressedJump, assembler) {
5665 FLAG_use_compressed_instructions = true;
5666 __ SetExtensions(RV_GC);
5667 Label label1, label2;
5668 __ j(&label1, Assembler::kNearJump); // Forward.
5669 __ trap();
5670 __ Bind(&label2);
5671 __ li(T1, 7);
5672 __ sub(A0, T0, T1);
5673 __ ret();
5674 __ Bind(&label1);
5675 __ li(T0, 4);
5676 __ j(&label2, Assembler::kNearJump); // Backward.
5677 __ trap();
5678}
5679ASSEMBLER_TEST_RUN(CompressedJump, test) {
5680 EXPECT_DISASSEMBLY(
5681 " a031 j +12\n"
5682 " 0000 trap\n"
5683 " 431d li t1, 7\n"
5684 "40628533 sub a0, t0, t1\n"
5685 " 8082 ret\n"
5686 " 4291 li t0, 4\n"
5687 " bfdd j -10\n"
5688 " 0000 trap\n");
5689 EXPECT_EQ(-3, Call(test->entry()));
5690}
5691
5692static int CompressedJumpAndLinkRegister_label1 = 0;
5693static int CompressedJumpAndLinkRegister_label2 = 0;
5694ASSEMBLER_TEST_GENERATE(CompressedJumpAndLinkRegister, assembler) {
5695 FLAG_use_compressed_instructions = true;
5696 __ SetExtensions(RV_GC);
5697 Label label1, label2;
5698 __ mv(T3, RA);
5699 __ jalr(A1); // Forward.
5700 __ sub(A0, T0, T1);
5701 __ jr(T3);
5702 __ trap();
5703
5704 __ Bind(&label2);
5705 __ mv(T5, RA);
5706 __ li(T1, 7);
5707 __ jr(T5);
5708 __ trap();
5709
5710 __ Bind(&label1);
5711 __ mv(T4, RA);
5712 __ li(T0, 4);
5713 __ jalr(A2); // Backward.
5714 __ jr(T4);
5715 __ trap();
5716
5717 CompressedJumpAndLinkRegister_label1 = label1.Position();
5718 CompressedJumpAndLinkRegister_label2 = label2.Position();
5719}
5720ASSEMBLER_TEST_RUN(CompressedJumpAndLinkRegister, test) {
5721 EXPECT_DISASSEMBLY(
5722 " 8e06 mv t3, ra\n"
5723 " 9582 jalr a1\n"
5724 "40628533 sub a0, t0, t1\n"
5725 " 8e02 jr t3\n"
5726 " 0000 trap\n"
5727 " 8f06 mv t5, ra\n"
5728 " 431d li t1, 7\n"
5729 " 8f02 jr t5\n"
5730 " 0000 trap\n"
5731 " 8e86 mv t4, ra\n"
5732 " 4291 li t0, 4\n"
5733 " 9602 jalr a2\n"
5734 " 8e82 jr t4\n"
5735 " 0000 trap\n");
5736 EXPECT_EQ(-3,
5737 Call(test->entry(), 0,
5738 static_cast<intx_t>(test->entry() +
5739 CompressedJumpAndLinkRegister_label1),
5740 static_cast<intx_t>(test->entry() +
5741 CompressedJumpAndLinkRegister_label2)));
5742}
5743
5744static int CompressedJumpRegister_label = 0;
5745ASSEMBLER_TEST_GENERATE(CompressedJumpRegister, assembler) {
5746 FLAG_use_compressed_instructions = true;
5747 __ SetExtensions(RV_GC);
5748 Label label;
5749 __ jr(A1);
5750 __ trap();
5751 __ Bind(&label);
5752 __ li(A0, 42);
5753 __ ret();
5754 CompressedJumpRegister_label = label.Position();
5755}
5756ASSEMBLER_TEST_RUN(CompressedJumpRegister, test) {
5757 EXPECT_DISASSEMBLY(
5758 " 8582 jr a1\n"
5759 " 0000 trap\n"
5760 "02a00513 li a0, 42\n"
5761 " 8082 ret\n");
5762 EXPECT_EQ(42, Call(test->entry(), 0,
5763 static_cast<intx_t>(test->entry() +
5764 CompressedJumpRegister_label)));
5765}
5766
5767ASSEMBLER_TEST_GENERATE(CompressedBranchEqualZero, assembler) {
5768 FLAG_use_compressed_instructions = true;
5769 __ SetExtensions(RV_GC);
5770 Label label;
5771 __ beqz(A0, &label, Assembler::kNearJump);
5772 __ li(A0, 3);
5773 __ ret();
5774 __ Bind(&label);
5775 __ li(A0, 4);
5776 __ ret();
5777}
5778ASSEMBLER_TEST_RUN(CompressedBranchEqualZero, test) {
5779 EXPECT_DISASSEMBLY(
5780 " c119 beqz a0, +6\n"
5781 " 450d li a0, 3\n"
5782 " 8082 ret\n"
5783 " 4511 li a0, 4\n"
5784 " 8082 ret\n");
5785 EXPECT_EQ(3, Call(test->entry(), -42));
5786 EXPECT_EQ(4, Call(test->entry(), 0));
5787 EXPECT_EQ(3, Call(test->entry(), 42));
5788}
5789
5790ASSEMBLER_TEST_GENERATE(CompressedBranchNotEqualZero, assembler) {
5791 FLAG_use_compressed_instructions = true;
5792 __ SetExtensions(RV_GC);
5793 Label label;
5794 __ bnez(A0, &label, Assembler::kNearJump);
5795 __ li(A0, 3);
5796 __ ret();
5797 __ Bind(&label);
5798 __ li(A0, 4);
5799 __ ret();
5800}
5801ASSEMBLER_TEST_RUN(CompressedBranchNotEqualZero, test) {
5802 EXPECT_DISASSEMBLY(
5803 " e119 bnez a0, +6\n"
5804 " 450d li a0, 3\n"
5805 " 8082 ret\n"
5806 " 4511 li a0, 4\n"
5807 " 8082 ret\n");
5808 EXPECT_EQ(4, Call(test->entry(), -42));
5809 EXPECT_EQ(3, Call(test->entry(), 0));
5810 EXPECT_EQ(4, Call(test->entry(), 42));
5811}
5812
5813ASSEMBLER_TEST_GENERATE(CompressedLoadImmediate, assembler) {
5814 FLAG_use_compressed_instructions = true;
5815 __ SetExtensions(RV_GC);
5816 __ li(A0, -7);
5817 __ ret();
5818}
5819ASSEMBLER_TEST_RUN(CompressedLoadImmediate, test) {
5820 EXPECT_DISASSEMBLY(
5821 " 5565 li a0, -7\n"
5822 " 8082 ret\n");
5823 EXPECT_EQ(-7, Call(test->entry()));
5824}
5825
5826ASSEMBLER_TEST_GENERATE(CompressedLoadUpperImmediate, assembler) {
5827 FLAG_use_compressed_instructions = true;
5828 __ SetExtensions(RV_GC);
5829 __ lui(A0, 7 << 12);
5830 __ ret();
5831}
5832ASSEMBLER_TEST_RUN(CompressedLoadUpperImmediate, test) {
5833 EXPECT_DISASSEMBLY(
5834 " 651d lui a0, 28672\n"
5835 " 8082 ret\n");
5836 EXPECT_EQ(7 << 12, Call(test->entry()));
5837}
5838
5839ASSEMBLER_TEST_GENERATE(CompressedAddImmediate, assembler) {
5840 FLAG_use_compressed_instructions = true;
5841 __ SetExtensions(RV_GC);
5842 __ addi(A0, A0, 19);
5843 __ ret();
5844}
5845ASSEMBLER_TEST_RUN(CompressedAddImmediate, test) {
5846 EXPECT_DISASSEMBLY(
5847 " 054d addi a0, a0, 19\n"
5848 " 8082 ret\n");
5849 EXPECT_EQ(42, Call(test->entry(), 23));
5850}
5851
5852#if XLEN == 64
5853ASSEMBLER_TEST_GENERATE(CompressedAddImmediateWord, assembler) {
5854 FLAG_use_compressed_instructions = true;
5855 __ SetExtensions(RV_GC);
5856 __ addiw(A0, A0, 19);
5857 __ ret();
5858}
5859ASSEMBLER_TEST_RUN(CompressedAddImmediateWord, test) {
5860 EXPECT_DISASSEMBLY(
5861 " 254d addiw a0, a0, 19\n"
5862 " 8082 ret\n");
5863 EXPECT_EQ(19, Call(test->entry(), 0xFFFFFFFF00000000));
5864 EXPECT_EQ(-237, Call(test->entry(), 0x00000000FFFFFF00));
5865}
5866#endif
5867
5868ASSEMBLER_TEST_GENERATE(CompressedAddImmediateSP16, assembler) {
5869 FLAG_use_compressed_instructions = true;
5870 __ SetExtensions(RV_GC);
5871 __ addi(SP, SP, -128);
5872 __ addi(SP, SP, +128);
5873 __ ret();
5874}
5875ASSEMBLER_TEST_RUN(CompressedAddImmediateSP16, test) {
5876 EXPECT_DISASSEMBLY(
5877 " 7119 addi sp, sp, -128\n"
5878 " 6109 addi sp, sp, 128\n"
5879 " 8082 ret\n");
5880 EXPECT_EQ(0, Call(test->entry(), 0));
5881}
5882
5883ASSEMBLER_TEST_GENERATE(CompressedAddImmediateSP4N, assembler) {
5884 FLAG_use_compressed_instructions = true;
5885 __ SetExtensions(RV_GC);
5886 __ addi(A1, SP, 36);
5887 __ sub(A0, A1, SP);
5888 __ ret();
5889}
5890ASSEMBLER_TEST_RUN(CompressedAddImmediateSP4N, test) {
5891 EXPECT_DISASSEMBLY(
5892 " 104c addi a1, sp, 36\n"
5893 "40258533 sub a0, a1, sp\n"
5894 " 8082 ret\n");
5895 EXPECT_EQ(36, Call(test->entry()));
5896}
5897
5898ASSEMBLER_TEST_GENERATE(CompressedShiftLeftLogicalImmediate, assembler) {
5899 FLAG_use_compressed_instructions = true;
5900 __ SetExtensions(RV_GC);
5901 __ slli(A0, A0, 3);
5902 __ ret();
5903}
5904ASSEMBLER_TEST_RUN(CompressedShiftLeftLogicalImmediate, test) {
5905 EXPECT_DISASSEMBLY(
5906 " 050e slli a0, a0, 3\n"
5907 " 8082 ret\n");
5908 EXPECT_EQ(0, Call(test->entry(), 0));
5909 EXPECT_EQ(336, Call(test->entry(), 42));
5910 EXPECT_EQ(15872, Call(test->entry(), 1984));
5911 EXPECT_EQ(-336, Call(test->entry(), -42));
5912 EXPECT_EQ(-15872, Call(test->entry(), -1984));
5913}
5914
5915ASSEMBLER_TEST_GENERATE(CompressedShiftRightLogicalImmediate, assembler) {
5916 FLAG_use_compressed_instructions = true;
5917 __ SetExtensions(RV_GC);
5918 __ srli(A0, A0, 3);
5919 __ ret();
5920}
5921ASSEMBLER_TEST_RUN(CompressedShiftRightLogicalImmediate, test) {
5922 EXPECT_DISASSEMBLY(
5923 " 810d srli a0, a0, 3\n"
5924 " 8082 ret\n");
5925 EXPECT_EQ(0, Call(test->entry(), 0));
5926 EXPECT_EQ(5, Call(test->entry(), 42));
5927 EXPECT_EQ(248, Call(test->entry(), 1984));
5928 EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-42) >> 3),
5929 Call(test->entry(), -42));
5930 EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-1984) >> 3),
5931 Call(test->entry(), -1984));
5932}
5933
5934ASSEMBLER_TEST_GENERATE(CompressedShiftRightArithmeticImmediate, assembler) {
5935 FLAG_use_compressed_instructions = true;
5936 __ SetExtensions(RV_GC);
5937 __ srai(A0, A0, 3);
5938 __ ret();
5939}
5940ASSEMBLER_TEST_RUN(CompressedShiftRightArithmeticImmediate, test) {
5941 EXPECT_DISASSEMBLY(
5942 " 850d srai a0, a0, 3\n"
5943 " 8082 ret\n");
5944 EXPECT_EQ(0, Call(test->entry(), 0));
5945 EXPECT_EQ(5, Call(test->entry(), 42));
5946 EXPECT_EQ(248, Call(test->entry(), 1984));
5947 EXPECT_EQ(-6, Call(test->entry(), -42));
5948 EXPECT_EQ(-248, Call(test->entry(), -1984));
5949}
5950
5951ASSEMBLER_TEST_GENERATE(CompressedAndImmediate, assembler) {
5952 FLAG_use_compressed_instructions = true;
5953 __ SetExtensions(RV_GC);
5954 __ andi(A0, A0, 6);
5955 __ ret();
5956}
5957ASSEMBLER_TEST_RUN(CompressedAndImmediate, test) {
5958 EXPECT_DISASSEMBLY(
5959 " 8919 andi a0, a0, 6\n"
5960 " 8082 ret\n");
5961 EXPECT_EQ(0, Call(test->entry(), 0));
5962 EXPECT_EQ(2, Call(test->entry(), 43));
5963 EXPECT_EQ(0, Call(test->entry(), 1984));
5964 EXPECT_EQ(6, Call(test->entry(), -42));
5965 EXPECT_EQ(0, Call(test->entry(), -1984));
5966}
5967
5968ASSEMBLER_TEST_GENERATE(CompressedAndImmediate2, assembler) {
5969 FLAG_use_compressed_instructions = true;
5970 __ SetExtensions(RV_GC);
5971 __ andi(A0, A0, -6);
5972 __ ret();
5973}
5974ASSEMBLER_TEST_RUN(CompressedAndImmediate2, test) {
5975 EXPECT_DISASSEMBLY(
5976 " 9969 andi a0, a0, -6\n"
5977 " 8082 ret\n");
5978 EXPECT_EQ(0, Call(test->entry(), 0));
5979 EXPECT_EQ(42, Call(test->entry(), 43));
5980 EXPECT_EQ(1984, Call(test->entry(), 1984));
5981 EXPECT_EQ(-46, Call(test->entry(), -42));
5982 EXPECT_EQ(-1984, Call(test->entry(), -1984));
5983}
5984
5985ASSEMBLER_TEST_GENERATE(CompressedMove, assembler) {
5986 FLAG_use_compressed_instructions = true;
5987 __ SetExtensions(RV_GC);
5988 __ mv(A0, A1);
5989 __ ret();
5990}
5991ASSEMBLER_TEST_RUN(CompressedMove, test) {
5992 EXPECT_DISASSEMBLY(
5993 " 852e mv a0, a1\n"
5994 " 8082 ret\n");
5995 EXPECT_EQ(42, Call(test->entry(), 0, 42));
5996}
5997
5998ASSEMBLER_TEST_GENERATE(CompressedAdd, assembler) {
5999 FLAG_use_compressed_instructions = true;
6000 __ SetExtensions(RV_GC);
6001 __ add(A0, A0, A1);
6002 __ ret();
6003}
6004ASSEMBLER_TEST_RUN(CompressedAdd, test) {
6005 EXPECT_DISASSEMBLY(
6006 " 952e add a0, a0, a1\n"
6007 " 8082 ret\n");
6008 EXPECT_EQ(24, Call(test->entry(), 7, 17));
6009 EXPECT_EQ(-10, Call(test->entry(), 7, -17));
6010 EXPECT_EQ(10, Call(test->entry(), -7, 17));
6011 EXPECT_EQ(-24, Call(test->entry(), -7, -17));
6012 EXPECT_EQ(24, Call(test->entry(), 17, 7));
6013 EXPECT_EQ(10, Call(test->entry(), 17, -7));
6014 EXPECT_EQ(-10, Call(test->entry(), -17, 7));
6015 EXPECT_EQ(-24, Call(test->entry(), -17, -7));
6016}
6017
6018ASSEMBLER_TEST_GENERATE(CompressedAnd, assembler) {
6019 FLAG_use_compressed_instructions = true;
6020 __ SetExtensions(RV_GC);
6021 __ and_(A0, A0, A1);
6022 __ ret();
6023}
6024ASSEMBLER_TEST_RUN(CompressedAnd, test) {
6025 EXPECT_DISASSEMBLY(
6026 " 8d6d and a0, a0, a1\n"
6027 " 8082 ret\n");
6028 EXPECT_EQ(1, Call(test->entry(), 7, 17));
6029 EXPECT_EQ(7, Call(test->entry(), 7, -17));
6030 EXPECT_EQ(17, Call(test->entry(), -7, 17));
6031 EXPECT_EQ(-23, Call(test->entry(), -7, -17));
6032 EXPECT_EQ(1, Call(test->entry(), 17, 7));
6033 EXPECT_EQ(17, Call(test->entry(), 17, -7));
6034 EXPECT_EQ(7, Call(test->entry(), -17, 7));
6035 EXPECT_EQ(-23, Call(test->entry(), -17, -7));
6036}
6037
6038ASSEMBLER_TEST_GENERATE(CompressedOr, assembler) {
6039 FLAG_use_compressed_instructions = true;
6040 __ SetExtensions(RV_GC);
6041 __ or_(A0, A0, A1);
6042 __ ret();
6043}
6044ASSEMBLER_TEST_RUN(CompressedOr, test) {
6045 EXPECT_DISASSEMBLY(
6046 " 8d4d or a0, a0, a1\n"
6047 " 8082 ret\n");
6048 EXPECT_EQ(23, Call(test->entry(), 7, 17));
6049 EXPECT_EQ(-17, Call(test->entry(), 7, -17));
6050 EXPECT_EQ(-7, Call(test->entry(), -7, 17));
6051 EXPECT_EQ(-1, Call(test->entry(), -7, -17));
6052 EXPECT_EQ(23, Call(test->entry(), 17, 7));
6053 EXPECT_EQ(-7, Call(test->entry(), 17, -7));
6054 EXPECT_EQ(-17, Call(test->entry(), -17, 7));
6055 EXPECT_EQ(-1, Call(test->entry(), -17, -7));
6056}
6057
6058ASSEMBLER_TEST_GENERATE(CompressedXor, assembler) {
6059 FLAG_use_compressed_instructions = true;
6060 __ SetExtensions(RV_GC);
6061 __ xor_(A0, A0, A1);
6062 __ ret();
6063}
6064ASSEMBLER_TEST_RUN(CompressedXor, test) {
6065 EXPECT_DISASSEMBLY(
6066 " 8d2d xor a0, a0, a1\n"
6067 " 8082 ret\n");
6068 EXPECT_EQ(22, Call(test->entry(), 7, 17));
6069 EXPECT_EQ(-24, Call(test->entry(), 7, -17));
6070 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
6071 EXPECT_EQ(22, Call(test->entry(), -7, -17));
6072 EXPECT_EQ(22, Call(test->entry(), 17, 7));
6073 EXPECT_EQ(-24, Call(test->entry(), 17, -7));
6074 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
6075 EXPECT_EQ(22, Call(test->entry(), -17, -7));
6076}
6077
6078ASSEMBLER_TEST_GENERATE(CompressedSubtract, assembler) {
6079 FLAG_use_compressed_instructions = true;
6080 __ SetExtensions(RV_GC);
6081 __ sub(A0, A0, A1);
6082 __ ret();
6083}
6084ASSEMBLER_TEST_RUN(CompressedSubtract, test) {
6085 EXPECT_DISASSEMBLY(
6086 " 8d0d sub a0, a0, a1\n"
6087 " 8082 ret\n");
6088 EXPECT_EQ(-10, Call(test->entry(), 7, 17));
6089 EXPECT_EQ(24, Call(test->entry(), 7, -17));
6090 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
6091 EXPECT_EQ(10, Call(test->entry(), -7, -17));
6092 EXPECT_EQ(10, Call(test->entry(), 17, 7));
6093 EXPECT_EQ(24, Call(test->entry(), 17, -7));
6094 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
6095 EXPECT_EQ(-10, Call(test->entry(), -17, -7));
6096}
6097
6098#if XLEN >= 64
6099ASSEMBLER_TEST_GENERATE(CompressedAddWord, assembler) {
6100 FLAG_use_compressed_instructions = true;
6101 __ SetExtensions(RV_GC);
6102 __ addw(A0, A0, A1);
6103 __ ret();
6104}
6105ASSEMBLER_TEST_RUN(CompressedAddWord, test) {
6106 EXPECT_DISASSEMBLY(
6107 " 9d2d addw a0, a0, a1\n"
6108 " 8082 ret\n");
6109 EXPECT_EQ(24, Call(test->entry(), 7, 17));
6110 EXPECT_EQ(-10, Call(test->entry(), 7, -17));
6111 EXPECT_EQ(10, Call(test->entry(), -7, 17));
6112 EXPECT_EQ(-24, Call(test->entry(), -7, -17));
6113 EXPECT_EQ(24, Call(test->entry(), 17, 7));
6114 EXPECT_EQ(10, Call(test->entry(), 17, -7));
6115 EXPECT_EQ(-10, Call(test->entry(), -17, 7));
6116 EXPECT_EQ(-24, Call(test->entry(), -17, -7));
6117 EXPECT_EQ(3, Call(test->entry(), 0x200000002, 0x100000001));
6118}
6119
6120ASSEMBLER_TEST_GENERATE(CompressedSubtractWord, assembler) {
6121 FLAG_use_compressed_instructions = true;
6122 __ SetExtensions(RV_GC);
6123 __ subw(A0, A0, A1);
6124 __ ret();
6125}
6126ASSEMBLER_TEST_RUN(CompressedSubtractWord, test) {
6127 EXPECT_DISASSEMBLY(
6128 " 9d0d subw a0, a0, a1\n"
6129 " 8082 ret\n");
6130 EXPECT_EQ(-10, Call(test->entry(), 7, 17));
6131 EXPECT_EQ(24, Call(test->entry(), 7, -17));
6132 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
6133 EXPECT_EQ(10, Call(test->entry(), -7, -17));
6134 EXPECT_EQ(10, Call(test->entry(), 17, 7));
6135 EXPECT_EQ(24, Call(test->entry(), 17, -7));
6136 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
6137 EXPECT_EQ(-10, Call(test->entry(), -17, -7));
6138 EXPECT_EQ(1, Call(test->entry(), 0x200000002, 0x100000001));
6139}
6140#endif
6141
6142ASSEMBLER_TEST_GENERATE(CompressedNop, assembler) {
6143 FLAG_use_compressed_instructions = true;
6144 __ SetExtensions(RV_GC);
6145 __ nop();
6146 __ ret();
6147}
6148ASSEMBLER_TEST_RUN(CompressedNop, test) {
6149 EXPECT_DISASSEMBLY(
6150 " 0001 nop\n"
6151 " 8082 ret\n");
6152 EXPECT_EQ(123, Call(test->entry(), 123));
6153}
6154
6155ASSEMBLER_TEST_GENERATE(CompressedEnvironmentBreak, assembler) {
6156 FLAG_use_compressed_instructions = true;
6157 __ SetExtensions(RV_GC);
6158 __ ebreak();
6159 __ ret();
6160}
6161ASSEMBLER_TEST_RUN(CompressedEnvironmentBreak, test) {
6162 EXPECT_DISASSEMBLY(
6163 " 9002 ebreak\n"
6164 " 8082 ret\n");
6165
6166 // Not running: would trap.
6167}
6168
6169#if XLEN >= 64
6170ASSEMBLER_TEST_GENERATE(AddUnsignedWord, assembler) {
6171 __ SetExtensions(RV_GCB);
6172 __ adduw(A0, A0, A1);
6173 __ ret();
6174}
6175ASSEMBLER_TEST_RUN(AddUnsignedWord, test) {
6176 EXPECT_DISASSEMBLY(
6177 "08b5053b add.uw a0, a0, a1\n"
6178 " 8082 ret\n");
6179
6180 EXPECT_EQ(0x200000001, Call(test->entry(), 0x1, 0x200000000));
6181 EXPECT_EQ(0x200000001, Call(test->entry(), 0x100000001, 0x200000000));
6182 EXPECT_EQ(0x2FFFFFFFF, Call(test->entry(), -0x1, 0x200000000));
6183}
6184#endif
6185
6186ASSEMBLER_TEST_GENERATE(Shift1Add, assembler) {
6187 __ SetExtensions(RV_GCB);
6188 __ sh1add(A0, A0, A1);
6189 __ ret();
6190}
6191ASSEMBLER_TEST_RUN(Shift1Add, test) {
6192 EXPECT_DISASSEMBLY(
6193 "20b52533 sh1add a0, a0, a1\n"
6194 " 8082 ret\n");
6195
6196 EXPECT_EQ(1002, Call(test->entry(), 1, 1000));
6197 EXPECT_EQ(1000, Call(test->entry(), 0, 1000));
6198 EXPECT_EQ(998, Call(test->entry(), -1, 1000));
6199}
6200
6201ASSEMBLER_TEST_GENERATE(Shift2Add, assembler) {
6202 __ SetExtensions(RV_GCB);
6203 __ sh2add(A0, A0, A1);
6204 __ ret();
6205}
6206ASSEMBLER_TEST_RUN(Shift2Add, test) {
6207 EXPECT_DISASSEMBLY(
6208 "20b54533 sh2add a0, a0, a1\n"
6209 " 8082 ret\n");
6210
6211 EXPECT_EQ(1004, Call(test->entry(), 1, 1000));
6212 EXPECT_EQ(1000, Call(test->entry(), 0, 1000));
6213 EXPECT_EQ(996, Call(test->entry(), -1, 1000));
6214}
6215
6216ASSEMBLER_TEST_GENERATE(Shift3Add, assembler) {
6217 __ SetExtensions(RV_GCB);
6218 __ sh3add(A0, A0, A1);
6219 __ ret();
6220}
6221ASSEMBLER_TEST_RUN(Shift3Add, test) {
6222 EXPECT_DISASSEMBLY(
6223 "20b56533 sh3add a0, a0, a1\n"
6224 " 8082 ret\n");
6225
6226 EXPECT_EQ(1008, Call(test->entry(), 1, 1000));
6227 EXPECT_EQ(1000, Call(test->entry(), 0, 1000));
6228 EXPECT_EQ(992, Call(test->entry(), -1, 1000));
6229}
6230
6231#if XLEN >= 64
6232ASSEMBLER_TEST_GENERATE(Shift1AddUnsignedWord, assembler) {
6233 __ SetExtensions(RV_GCB);
6234 __ sh1adduw(A0, A0, A1);
6235 __ ret();
6236}
6237ASSEMBLER_TEST_RUN(Shift1AddUnsignedWord, test) {
6238 EXPECT_DISASSEMBLY(
6239 "20b5253b sh1add.uw a0, a0, a1\n"
6240 " 8082 ret\n");
6241
6242 EXPECT_EQ(1002, Call(test->entry(), 1, 1000));
6243 EXPECT_EQ(1002, Call(test->entry(), 0x100000001, 1000));
6244 EXPECT_EQ(1000, Call(test->entry(), 0, 1000));
6245 EXPECT_EQ(8589935590, Call(test->entry(), -1, 1000));
6246}
6247
6248ASSEMBLER_TEST_GENERATE(Shift2AddUnsignedWord, assembler) {
6249 __ SetExtensions(RV_GCB);
6250 __ sh2adduw(A0, A0, A1);
6251 __ ret();
6252}
6253ASSEMBLER_TEST_RUN(Shift2AddUnsignedWord, test) {
6254 EXPECT_DISASSEMBLY(
6255 "20b5453b sh2add.uw a0, a0, a1\n"
6256 " 8082 ret\n");
6257
6258 EXPECT_EQ(1004, Call(test->entry(), 1, 1000));
6259 EXPECT_EQ(1004, Call(test->entry(), 0x100000001, 1000));
6260 EXPECT_EQ(1000, Call(test->entry(), 0, 1000));
6261 EXPECT_EQ(17179870180, Call(test->entry(), -1, 1000));
6262}
6263
6264ASSEMBLER_TEST_GENERATE(Shift3AddUnsignedWord, assembler) {
6265 __ SetExtensions(RV_GCB);
6266 __ sh3adduw(A0, A0, A1);
6267 __ ret();
6268}
6269ASSEMBLER_TEST_RUN(Shift3AddUnsignedWord, test) {
6270 EXPECT_DISASSEMBLY(
6271 "20b5653b sh3add.uw a0, a0, a1\n"
6272 " 8082 ret\n");
6273
6274 EXPECT_EQ(1008, Call(test->entry(), 1, 1000));
6275 EXPECT_EQ(1008, Call(test->entry(), 0x100000001, 1000));
6276 EXPECT_EQ(1000, Call(test->entry(), 0, 1000));
6277 EXPECT_EQ(34359739360, Call(test->entry(), -1, 1000));
6278}
6279
6280ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediateUnsignedWord, assembler) {
6281 __ SetExtensions(RV_GCB);
6282 __ slliuw(A0, A0, 8);
6283 __ ret();
6284}
6285ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediateUnsignedWord, test) {
6286 EXPECT_DISASSEMBLY(
6287 "0885151b slli.uw a0, a0, 0x8\n"
6288 " 8082 ret\n");
6289
6290 EXPECT_EQ(0x100, Call(test->entry(), 0x1));
6291 EXPECT_EQ(0x1000000000, Call(test->entry(), 0x10000000));
6292 EXPECT_EQ(0, Call(test->entry(), 0x100000000));
6293 EXPECT_EQ(0x100, Call(test->entry(), 0x100000001));
6294}
6295#endif
6296
6297ASSEMBLER_TEST_GENERATE(AndNot, assembler) {
6298 __ SetExtensions(RV_GCB);
6299 __ andn(A0, A0, A1);
6300 __ ret();
6301}
6302ASSEMBLER_TEST_RUN(AndNot, test) {
6303 EXPECT_DISASSEMBLY(
6304 "40b57533 andn a0, a0, a1\n"
6305 " 8082 ret\n");
6306
6307 EXPECT_EQ(6, Call(test->entry(), 7, 17));
6308 EXPECT_EQ(0, Call(test->entry(), 7, -17));
6309 EXPECT_EQ(-24, Call(test->entry(), -7, 17));
6310 EXPECT_EQ(16, Call(test->entry(), -7, -17));
6311 EXPECT_EQ(16, Call(test->entry(), 17, 7));
6312 EXPECT_EQ(0, Call(test->entry(), 17, -7));
6313 EXPECT_EQ(-24, Call(test->entry(), -17, 7));
6314 EXPECT_EQ(6, Call(test->entry(), -17, -7));
6315}
6316
6317ASSEMBLER_TEST_GENERATE(OrNot, assembler) {
6318 __ SetExtensions(RV_GCB);
6319 __ orn(A0, A0, A1);
6320 __ ret();
6321}
6322ASSEMBLER_TEST_RUN(OrNot, test) {
6323 EXPECT_DISASSEMBLY(
6324 "40b56533 orn a0, a0, a1\n"
6325 " 8082 ret\n");
6326
6327 EXPECT_EQ(-17, Call(test->entry(), 7, 17));
6328 EXPECT_EQ(23, Call(test->entry(), 7, -17));
6329 EXPECT_EQ(-1, Call(test->entry(), -7, 17));
6330 EXPECT_EQ(-7, Call(test->entry(), -7, -17));
6331 EXPECT_EQ(-7, Call(test->entry(), 17, 7));
6332 EXPECT_EQ(23, Call(test->entry(), 17, -7));
6333 EXPECT_EQ(-1, Call(test->entry(), -17, 7));
6334 EXPECT_EQ(-17, Call(test->entry(), -17, -7));
6335}
6336
6337ASSEMBLER_TEST_GENERATE(XorNot, assembler) {
6338 __ SetExtensions(RV_GCB);
6339 __ xnor(A0, A0, A1);
6340 __ ret();
6341}
6342ASSEMBLER_TEST_RUN(XorNot, test) {
6343 EXPECT_DISASSEMBLY(
6344 "40b54533 xnor a0, a0, a1\n"
6345 " 8082 ret\n");
6346
6347 EXPECT_EQ(-23, Call(test->entry(), 7, 17));
6348 EXPECT_EQ(23, Call(test->entry(), 7, -17));
6349 EXPECT_EQ(23, Call(test->entry(), -7, 17));
6350 EXPECT_EQ(-23, Call(test->entry(), -7, -17));
6351 EXPECT_EQ(-23, Call(test->entry(), 17, 7));
6352 EXPECT_EQ(23, Call(test->entry(), 17, -7));
6353 EXPECT_EQ(23, Call(test->entry(), -17, 7));
6354 EXPECT_EQ(-23, Call(test->entry(), -17, -7));
6355}
6356
6357ASSEMBLER_TEST_GENERATE(CountLeadingZeroes, assembler) {
6358 __ SetExtensions(RV_GCB);
6359 __ clz(A0, A0);
6360 __ ret();
6361}
6362ASSEMBLER_TEST_RUN(CountLeadingZeroes, test) {
6363 EXPECT_DISASSEMBLY(
6364 "60051513 clz a0, a0\n"
6365 " 8082 ret\n");
6366
6367 EXPECT_EQ(XLEN, Call(test->entry(), 0));
6368 EXPECT_EQ(XLEN - 1, Call(test->entry(), 1));
6369 EXPECT_EQ(XLEN - 2, Call(test->entry(), 2));
6370 EXPECT_EQ(XLEN - 3, Call(test->entry(), 4));
6371 EXPECT_EQ(XLEN - 8, Call(test->entry(), 240));
6372 EXPECT_EQ(0, Call(test->entry(), -1));
6373 EXPECT_EQ(0, Call(test->entry(), -2));
6374 EXPECT_EQ(0, Call(test->entry(), -4));
6375 EXPECT_EQ(0, Call(test->entry(), -240));
6376}
6377
6378ASSEMBLER_TEST_GENERATE(CountTrailingZeroes, assembler) {
6379 __ SetExtensions(RV_GCB);
6380 __ ctz(A0, A0);
6381 __ ret();
6382}
6383ASSEMBLER_TEST_RUN(CountTrailingZeroes, test) {
6384 EXPECT_DISASSEMBLY(
6385 "60151513 ctz a0, a0\n"
6386 " 8082 ret\n");
6387
6388 EXPECT_EQ(XLEN, Call(test->entry(), 0));
6389 EXPECT_EQ(0, Call(test->entry(), 1));
6390 EXPECT_EQ(1, Call(test->entry(), 2));
6391 EXPECT_EQ(2, Call(test->entry(), 4));
6392 EXPECT_EQ(4, Call(test->entry(), 240));
6393 EXPECT_EQ(0, Call(test->entry(), -1));
6394 EXPECT_EQ(1, Call(test->entry(), -2));
6395 EXPECT_EQ(2, Call(test->entry(), -4));
6396 EXPECT_EQ(4, Call(test->entry(), -240));
6397}
6398
6399ASSEMBLER_TEST_GENERATE(CountPopulation, assembler) {
6400 __ SetExtensions(RV_GCB);
6401 __ cpop(A0, A0);
6402 __ ret();
6403}
6404ASSEMBLER_TEST_RUN(CountPopulation, test) {
6405 EXPECT_DISASSEMBLY(
6406 "60251513 cpop a0, a0\n"
6407 " 8082 ret\n");
6408
6409 EXPECT_EQ(0, Call(test->entry(), 0));
6410 EXPECT_EQ(1, Call(test->entry(), 1));
6411 EXPECT_EQ(3, Call(test->entry(), 7));
6412 EXPECT_EQ(4, Call(test->entry(), 30));
6413 EXPECT_EQ(XLEN, Call(test->entry(), -1));
6414 EXPECT_EQ(XLEN - 2, Call(test->entry(), -7));
6415 EXPECT_EQ(XLEN - 4, Call(test->entry(), -30));
6416}
6417
6418#if XLEN >= 64
6419ASSEMBLER_TEST_GENERATE(CountLeadingZeroesWord, assembler) {
6420 __ SetExtensions(RV_GCB);
6421 __ clzw(A0, A0);
6422 __ ret();
6423}
6424ASSEMBLER_TEST_RUN(CountLeadingZeroesWord, test) {
6425 EXPECT_DISASSEMBLY(
6426 "6005151b clzw a0, a0\n"
6427 " 8082 ret\n");
6428
6429 EXPECT_EQ(32, Call(test->entry(), 0));
6430 EXPECT_EQ(31, Call(test->entry(), 1));
6431 EXPECT_EQ(30, Call(test->entry(), 2));
6432 EXPECT_EQ(29, Call(test->entry(), 4));
6433 EXPECT_EQ(24, Call(test->entry(), 240));
6434 EXPECT_EQ(0, Call(test->entry(), -1));
6435 EXPECT_EQ(0, Call(test->entry(), -2));
6436 EXPECT_EQ(0, Call(test->entry(), -4));
6437 EXPECT_EQ(0, Call(test->entry(), -240));
6438}
6439
6440ASSEMBLER_TEST_GENERATE(CountTrailingZeroesWord, assembler) {
6441 __ SetExtensions(RV_GCB);
6442 __ ctzw(A0, A0);
6443 __ ret();
6444}
6445ASSEMBLER_TEST_RUN(CountTrailingZeroesWord, test) {
6446 EXPECT_DISASSEMBLY(
6447 "6015151b ctzw a0, a0\n"
6448 " 8082 ret\n");
6449
6450 EXPECT_EQ(32, Call(test->entry(), 0));
6451 EXPECT_EQ(0, Call(test->entry(), 1));
6452 EXPECT_EQ(1, Call(test->entry(), 2));
6453 EXPECT_EQ(2, Call(test->entry(), 4));
6454 EXPECT_EQ(4, Call(test->entry(), 240));
6455 EXPECT_EQ(0, Call(test->entry(), -1));
6456 EXPECT_EQ(1, Call(test->entry(), -2));
6457 EXPECT_EQ(2, Call(test->entry(), -4));
6458 EXPECT_EQ(4, Call(test->entry(), -240));
6459}
6460
6461ASSEMBLER_TEST_GENERATE(CountPopulationWord, assembler) {
6462 __ SetExtensions(RV_GCB);
6463 __ cpopw(A0, A0);
6464 __ ret();
6465}
6466ASSEMBLER_TEST_RUN(CountPopulationWord, test) {
6467 EXPECT_DISASSEMBLY(
6468 "6025151b cpopw a0, a0\n"
6469 " 8082 ret\n");
6470
6471 EXPECT_EQ(0, Call(test->entry(), 0));
6472 EXPECT_EQ(1, Call(test->entry(), 1));
6473 EXPECT_EQ(3, Call(test->entry(), 7));
6474 EXPECT_EQ(4, Call(test->entry(), 30));
6475 EXPECT_EQ(32, Call(test->entry(), -1));
6476 EXPECT_EQ(30, Call(test->entry(), -7));
6477 EXPECT_EQ(28, Call(test->entry(), -30));
6478 EXPECT_EQ(0, Call(test->entry(), 0x7FFFFFFF00000000));
6479}
6480#endif
6481
6482ASSEMBLER_TEST_GENERATE(Max, assembler) {
6483 __ SetExtensions(RV_GCB);
6484 __ max(A0, A0, A1);
6485 __ ret();
6486}
6488 EXPECT_DISASSEMBLY(
6489 "0ab56533 max a0, a0, a1\n"
6490 " 8082 ret\n");
6491
6492 EXPECT_EQ(17, Call(test->entry(), 7, 17));
6493 EXPECT_EQ(17, Call(test->entry(), -7, 17));
6494 EXPECT_EQ(7, Call(test->entry(), 7, -17));
6495 EXPECT_EQ(-7, Call(test->entry(), -7, -17));
6496}
6497
6498ASSEMBLER_TEST_GENERATE(MaxUnsigned, assembler) {
6499 __ SetExtensions(RV_GCB);
6500 __ maxu(A0, A0, A1);
6501 __ ret();
6502}
6503ASSEMBLER_TEST_RUN(MaxUnsigned, test) {
6504 EXPECT_DISASSEMBLY(
6505 "0ab57533 maxu a0, a0, a1\n"
6506 " 8082 ret\n");
6507
6508 EXPECT_EQ(17, Call(test->entry(), 7, 17));
6509 EXPECT_EQ(-7, Call(test->entry(), -7, 17));
6510 EXPECT_EQ(-17, Call(test->entry(), 7, -17));
6511 EXPECT_EQ(-7, Call(test->entry(), -7, -17));
6512}
6513
6514ASSEMBLER_TEST_GENERATE(Min, assembler) {
6515 __ SetExtensions(RV_GCB);
6516 __ min(A0, A0, A1);
6517 __ ret();
6518}
6520 EXPECT_DISASSEMBLY(
6521 "0ab54533 min a0, a0, a1\n"
6522 " 8082 ret\n");
6523
6524 EXPECT_EQ(7, Call(test->entry(), 7, 17));
6525 EXPECT_EQ(-7, Call(test->entry(), -7, 17));
6526 EXPECT_EQ(-17, Call(test->entry(), 7, -17));
6527 EXPECT_EQ(-17, Call(test->entry(), -7, -17));
6528}
6529
6530ASSEMBLER_TEST_GENERATE(MinUnsigned, assembler) {
6531 __ SetExtensions(RV_GCB);
6532 __ minu(A0, A0, A1);
6533 __ ret();
6534}
6535ASSEMBLER_TEST_RUN(MinUnsigned, test) {
6536 EXPECT_DISASSEMBLY(
6537 "0ab55533 minu a0, a0, a1\n"
6538 " 8082 ret\n");
6539
6540 EXPECT_EQ(7, Call(test->entry(), 7, 17));
6541 EXPECT_EQ(17, Call(test->entry(), -7, 17));
6542 EXPECT_EQ(7, Call(test->entry(), 7, -17));
6543 EXPECT_EQ(-17, Call(test->entry(), -7, -17));
6544}
6545
6546ASSEMBLER_TEST_GENERATE(SignExtendByte, assembler) {
6547 __ SetExtensions(RV_GCB);
6548 __ sextb(A0, A0);
6549 __ ret();
6550}
6551ASSEMBLER_TEST_RUN(SignExtendByte, test) {
6552 EXPECT_DISASSEMBLY(
6553 "60451513 sext.b a0, a0\n"
6554 " 8082 ret\n");
6555
6556 EXPECT_EQ(1, Call(test->entry(), 1));
6557 EXPECT_EQ(127, Call(test->entry(), 127));
6558 EXPECT_EQ(-128, Call(test->entry(), 128));
6559}
6560
6561ASSEMBLER_TEST_GENERATE(SignExtendHalfWord, assembler) {
6562 __ SetExtensions(RV_GCB);
6563 __ sexth(A0, A0);
6564 __ ret();
6565}
6566ASSEMBLER_TEST_RUN(SignExtendHalfWord, test) {
6567 EXPECT_DISASSEMBLY(
6568 "60551513 sext.h a0, a0\n"
6569 " 8082 ret\n");
6570
6571 EXPECT_EQ(0, Call(test->entry(), 0));
6572 EXPECT_EQ(0x7BCD, Call(test->entry(), 0x12347BCD));
6573 EXPECT_EQ(-1, Call(test->entry(), 0xFFFF));
6574 EXPECT_EQ(-1, Call(test->entry(), -1));
6575}
6576
6577ASSEMBLER_TEST_GENERATE(ZeroExtendHalfWord, assembler) {
6578 __ SetExtensions(RV_GCB);
6579 __ zexth(A0, A0);
6580 __ ret();
6581}
6582ASSEMBLER_TEST_RUN(ZeroExtendHalfWord, test) {
6583#if XLEN == 32
6584 EXPECT_DISASSEMBLY(
6585 "08054533 zext.h a0, a0\n"
6586 " 8082 ret\n");
6587#else
6588 EXPECT_DISASSEMBLY(
6589 "0805453b zext.h a0, a0\n"
6590 " 8082 ret\n");
6591#endif
6592
6593 EXPECT_EQ(0, Call(test->entry(), 0));
6594 EXPECT_EQ(0xABCD, Call(test->entry(), 0x1234ABCD));
6595 EXPECT_EQ(0xFFFF, Call(test->entry(), 0xFFFF));
6596 EXPECT_EQ(0xFFFF, Call(test->entry(), -1));
6597}
6598
6600 __ SetExtensions(RV_GCB);
6601 __ ror(A0, A0, A1);
6602 __ ret();
6603}
6605 EXPECT_DISASSEMBLY(
6606 "60b55533 ror a0, a0, a1\n"
6607 " 8082 ret\n");
6608
6609#if XLEN == 32
6610 EXPECT_EQ(static_cast<intx_t>(0x12345678),
6611 Call(test->entry(), 0x12345678, 0));
6612 EXPECT_EQ(static_cast<intx_t>(0x81234567),
6613 Call(test->entry(), 0x12345678, 4));
6614 EXPECT_EQ(static_cast<intx_t>(0x23456781),
6615 Call(test->entry(), 0x12345678, 28));
6616 EXPECT_EQ(static_cast<intx_t>(0x81234567),
6617 Call(test->entry(), 0x12345678, 36));
6618#else
6619 EXPECT_EQ(static_cast<intx_t>(0x0123456789ABCDEF),
6620 Call(test->entry(), 0x0123456789ABCDEF, 0));
6621 EXPECT_EQ(static_cast<intx_t>(0xF0123456789ABCDE),
6622 Call(test->entry(), 0x0123456789ABCDEF, 4));
6623 EXPECT_EQ(static_cast<intx_t>(0x123456789ABCDEF0),
6624 Call(test->entry(), 0x0123456789ABCDEF, 60));
6625 EXPECT_EQ(static_cast<intx_t>(0xF0123456789ABCDE),
6626 Call(test->entry(), 0x0123456789ABCDEF, 68));
6627#endif
6628}
6629
6630ASSEMBLER_TEST_GENERATE(RotateLeft, assembler) {
6631 __ SetExtensions(RV_GCB);
6632 __ rol(A0, A0, A1);
6633 __ ret();
6634}
6635ASSEMBLER_TEST_RUN(RotateLeft, test) {
6636 EXPECT_DISASSEMBLY(
6637 "60b51533 rol a0, a0, a1\n"
6638 " 8082 ret\n");
6639
6640#if XLEN == 32
6641 EXPECT_EQ(static_cast<intx_t>(0x12345678),
6642 Call(test->entry(), 0x12345678, 0));
6643 EXPECT_EQ(static_cast<intx_t>(0x23456781),
6644 Call(test->entry(), 0x12345678, 4));
6645 EXPECT_EQ(static_cast<intx_t>(0x81234567),
6646 Call(test->entry(), 0x12345678, 28));
6647 EXPECT_EQ(static_cast<intx_t>(0x23456781),
6648 Call(test->entry(), 0x12345678, 36));
6649#else
6650 EXPECT_EQ(static_cast<intx_t>(0x0123456789ABCDEF),
6651 Call(test->entry(), 0x0123456789ABCDEF, 0));
6652 EXPECT_EQ(static_cast<intx_t>(0x123456789ABCDEF0),
6653 Call(test->entry(), 0x0123456789ABCDEF, 4));
6654 EXPECT_EQ(static_cast<intx_t>(0xF0123456789ABCDE),
6655 Call(test->entry(), 0x0123456789ABCDEF, 60));
6656 EXPECT_EQ(static_cast<intx_t>(0x123456789ABCDEF0),
6657 Call(test->entry(), 0x0123456789ABCDEF, 68));
6658#endif
6659}
6660
6661ASSEMBLER_TEST_GENERATE(RotateRightImmediate, assembler) {
6662 __ SetExtensions(RV_GCB);
6663 __ rori(A0, A0, 4);
6664 __ ret();
6665}
6666ASSEMBLER_TEST_RUN(RotateRightImmediate, test) {
6667 EXPECT_DISASSEMBLY(
6668 "60455513 rori a0, a0, 0x4\n"
6669 " 8082 ret\n");
6670
6671#if XLEN == 32
6672 EXPECT_EQ(static_cast<intx_t>(0x81234567), Call(test->entry(), 0x12345678));
6673#else
6674 EXPECT_EQ(static_cast<intx_t>(0xF0123456789ABCDE),
6675 Call(test->entry(), 0x0123456789ABCDEF));
6676#endif
6677}
6678
6679#if XLEN >= 64
6680ASSEMBLER_TEST_GENERATE(RotateRightWord, assembler) {
6681 __ SetExtensions(RV_GCB);
6682 __ rorw(A0, A0, A1);
6683 __ ret();
6684}
6685ASSEMBLER_TEST_RUN(RotateRightWord, test) {
6686 EXPECT_DISASSEMBLY(
6687 "60b5553b rorw a0, a0, a1\n"
6688 " 8082 ret\n");
6689
6690 EXPECT_EQ(sign_extend(0x12345678), Call(test->entry(), 0x12345678, 0));
6691 EXPECT_EQ(sign_extend(0x81234567), Call(test->entry(), 0x12345678, 4));
6692 EXPECT_EQ(sign_extend(0x23456781), Call(test->entry(), 0x12345678, 28));
6693 EXPECT_EQ(sign_extend(0x81234567), Call(test->entry(), 0x12345678, 36));
6694}
6695
6696ASSEMBLER_TEST_GENERATE(RotateLeftWord, assembler) {
6697 __ SetExtensions(RV_GCB);
6698 __ rolw(A0, A0, A1);
6699 __ ret();
6700}
6701ASSEMBLER_TEST_RUN(RotateLeftWord, test) {
6702 EXPECT_DISASSEMBLY(
6703 "60b5153b rolw a0, a0, a1\n"
6704 " 8082 ret\n");
6705
6706 EXPECT_EQ(sign_extend(0x12345678), Call(test->entry(), 0x12345678, 0));
6707 EXPECT_EQ(sign_extend(0x23456781), Call(test->entry(), 0x12345678, 4));
6708 EXPECT_EQ(sign_extend(0x81234567), Call(test->entry(), 0x12345678, 28));
6709 EXPECT_EQ(sign_extend(0x23456781), Call(test->entry(), 0x12345678, 36));
6710}
6711
6712ASSEMBLER_TEST_GENERATE(RotateRightImmediateWord, assembler) {
6713 __ SetExtensions(RV_GCB);
6714 __ roriw(A0, A0, 4);
6715 __ ret();
6716}
6717ASSEMBLER_TEST_RUN(RotateRightImmediateWord, test) {
6718 EXPECT_DISASSEMBLY(
6719 "6045551b roriw a0, a0, 0x4\n"
6720 " 8082 ret\n");
6721
6722 EXPECT_EQ(sign_extend(0x81234567), Call(test->entry(), 0x12345678));
6723}
6724#endif
6725
6726ASSEMBLER_TEST_GENERATE(OrCombineBytes, assembler) {
6727 __ SetExtensions(RV_GCB);
6728 __ orcb(A0, A0);
6729 __ ret();
6730}
6731ASSEMBLER_TEST_RUN(OrCombineBytes, test) {
6732 EXPECT_DISASSEMBLY(
6733 "28755513 orc.b a0, a0\n"
6734 " 8082 ret\n");
6735
6736 EXPECT_EQ(0, Call(test->entry(), 0));
6737 EXPECT_EQ(-1, Call(test->entry(), -1));
6738 EXPECT_EQ(0x00FF00FF, Call(test->entry(), 0x00010001));
6739#if XLEN >= 64
6740 EXPECT_EQ(0x00FF00FF00FF00FF, Call(test->entry(), 0x0001000100010001));
6741#endif
6742}
6743
6744ASSEMBLER_TEST_GENERATE(ByteReverse, assembler) {
6745 __ SetExtensions(RV_GCB);
6746 __ rev8(A0, A0);
6747 __ ret();
6748}
6749ASSEMBLER_TEST_RUN(ByteReverse, test) {
6750#if XLEN == 32
6751 EXPECT_DISASSEMBLY(
6752 "69855513 rev8 a0, a0\n"
6753 " 8082 ret\n");
6754#else
6755 EXPECT_DISASSEMBLY(
6756 "6b855513 rev8 a0, a0\n"
6757 " 8082 ret\n");
6758#endif
6759
6760 EXPECT_EQ(0, Call(test->entry(), 0));
6761 EXPECT_EQ(-1, Call(test->entry(), -1));
6762#if XLEN == 32
6763 EXPECT_EQ(0x11223344, Call(test->entry(), 0x44332211));
6764#elif XLEN == 64
6765 EXPECT_EQ(0x1122334455667788, Call(test->entry(), 0x8877665544332211));
6766#endif
6767}
6768
6769ASSEMBLER_TEST_GENERATE(CarrylessMultiply, assembler) {
6770 __ SetExtensions(RV_GC | RV_Zbc);
6771 __ clmul(A0, A0, A1);
6772 __ ret();
6773}
6774ASSEMBLER_TEST_RUN(CarrylessMultiply, test) {
6775 EXPECT_DISASSEMBLY(
6776 "0ab51533 clmul a0, a0, a1\n"
6777 " 8082 ret\n");
6778
6779#if XLEN == 32
6780 EXPECT_EQ(0x55555555, Call(test->entry(), -1, -1));
6781#else
6782 EXPECT_EQ(0x5555555555555555, Call(test->entry(), -1, -1));
6783#endif
6784 EXPECT_EQ(0, Call(test->entry(), -1, 0));
6785 EXPECT_EQ(-1, Call(test->entry(), -1, 1));
6786 EXPECT_EQ(0, Call(test->entry(), 0, -1));
6787 EXPECT_EQ(0, Call(test->entry(), 0, 0));
6788 EXPECT_EQ(0, Call(test->entry(), 0, 1));
6789 EXPECT_EQ(-1, Call(test->entry(), 1, -1));
6790 EXPECT_EQ(0, Call(test->entry(), 1, 0));
6791 EXPECT_EQ(1, Call(test->entry(), 1, 1));
6792
6793 EXPECT_EQ(4, Call(test->entry(), 2, 2));
6794 EXPECT_EQ(5, Call(test->entry(), 3, 3));
6795 EXPECT_EQ(16, Call(test->entry(), 4, 4));
6796 EXPECT_EQ(20, Call(test->entry(), 6, 6));
6797}
6798
6799ASSEMBLER_TEST_GENERATE(CarrylessMultiplyHigh, assembler) {
6800 __ SetExtensions(RV_GC | RV_Zbc);
6801 __ clmulh(A0, A0, A1);
6802 __ ret();
6803}
6804ASSEMBLER_TEST_RUN(CarrylessMultiplyHigh, test) {
6805 EXPECT_DISASSEMBLY(
6806 "0ab53533 clmulh a0, a0, a1\n"
6807 " 8082 ret\n");
6808
6809#if XLEN == 32
6810 EXPECT_EQ(0x55555555, Call(test->entry(), -1, -1));
6811#else
6812 EXPECT_EQ(0x5555555555555555, Call(test->entry(), -1, -1));
6813#endif
6814 EXPECT_EQ(0, Call(test->entry(), -1, 0));
6815 EXPECT_EQ(0, Call(test->entry(), -1, 1));
6816 EXPECT_EQ(0, Call(test->entry(), 0, -1));
6817 EXPECT_EQ(0, Call(test->entry(), 0, 0));
6818 EXPECT_EQ(0, Call(test->entry(), 0, 1));
6819 EXPECT_EQ(0, Call(test->entry(), 1, -1));
6820 EXPECT_EQ(0, Call(test->entry(), 1, 0));
6821 EXPECT_EQ(0, Call(test->entry(), 1, 1));
6822
6823 EXPECT_EQ(0, Call(test->entry(), 2, 2));
6824 EXPECT_EQ(0, Call(test->entry(), 3, 3));
6825 EXPECT_EQ(0, Call(test->entry(), 4, 4));
6826 EXPECT_EQ(0, Call(test->entry(), 6, 6));
6827}
6828
6829ASSEMBLER_TEST_GENERATE(CarrylessMultiplyReversed, assembler) {
6830 __ SetExtensions(RV_GC | RV_Zbc);
6831 __ clmulr(A0, A0, A1);
6832 __ ret();
6833}
6834ASSEMBLER_TEST_RUN(CarrylessMultiplyReversed, test) {
6835 EXPECT_DISASSEMBLY(
6836 "0ab52533 clmulr a0, a0, a1\n"
6837 " 8082 ret\n");
6838
6839#if XLEN == 32
6840 EXPECT_EQ(-0x55555556, Call(test->entry(), -1, -1));
6841#else
6842 EXPECT_EQ(-0x5555555555555556, Call(test->entry(), -1, -1));
6843#endif
6844 EXPECT_EQ(0, Call(test->entry(), -1, 0));
6845 EXPECT_EQ(1, Call(test->entry(), -1, 1));
6846 EXPECT_EQ(0, Call(test->entry(), 0, -1));
6847 EXPECT_EQ(0, Call(test->entry(), 0, 0));
6848 EXPECT_EQ(0, Call(test->entry(), 0, 1));
6849 EXPECT_EQ(1, Call(test->entry(), 1, -1));
6850 EXPECT_EQ(0, Call(test->entry(), 1, 0));
6851 EXPECT_EQ(0, Call(test->entry(), 1, 1));
6852
6853 EXPECT_EQ(0, Call(test->entry(), 2, 2));
6854 EXPECT_EQ(0, Call(test->entry(), 3, 3));
6855 EXPECT_EQ(0, Call(test->entry(), 4, 4));
6856 EXPECT_EQ(0, Call(test->entry(), 6, 6));
6857}
6858
6859ASSEMBLER_TEST_GENERATE(BitClear, assembler) {
6860 __ SetExtensions(RV_GCB);
6861 __ bclr(A0, A0, A1);
6862 __ ret();
6863}
6864ASSEMBLER_TEST_RUN(BitClear, test) {
6865 EXPECT_DISASSEMBLY(
6866 "48b51533 bclr a0, a0, a1\n"
6867 " 8082 ret\n");
6868
6869 EXPECT_EQ(42, Call(test->entry(), 42, 0));
6870 EXPECT_EQ(40, Call(test->entry(), 42, 1));
6871 EXPECT_EQ(42, Call(test->entry(), 42, 2));
6872 EXPECT_EQ(34, Call(test->entry(), 42, 3));
6873 EXPECT_EQ(42, Call(test->entry(), 42, 4));
6874 EXPECT_EQ(10, Call(test->entry(), 42, 5));
6875 EXPECT_EQ(42, Call(test->entry(), 42, 6));
6876 EXPECT_EQ(42, Call(test->entry(), 42, 7));
6877 EXPECT_EQ(42, Call(test->entry(), 42, 8));
6878
6879 EXPECT_EQ(42, Call(test->entry(), 42, 64));
6880 EXPECT_EQ(40, Call(test->entry(), 42, 65));
6881}
6882
6883ASSEMBLER_TEST_GENERATE(BitClearImmediate, assembler) {
6884 __ SetExtensions(RV_GCB);
6885 __ bclri(A0, A0, 3);
6886 __ ret();
6887}
6888ASSEMBLER_TEST_RUN(BitClearImmediate, test) {
6889 EXPECT_DISASSEMBLY(
6890 "48351513 bclri a0, a0, 0x3\n"
6891 " 8082 ret\n");
6892
6893 EXPECT_EQ(0, Call(test->entry(), 0));
6894 EXPECT_EQ(7, Call(test->entry(), 7));
6895 EXPECT_EQ(0, Call(test->entry(), 8));
6896 EXPECT_EQ(1, Call(test->entry(), 9));
6897 EXPECT_EQ(-15, Call(test->entry(), -7));
6898 EXPECT_EQ(-16, Call(test->entry(), -8));
6899 EXPECT_EQ(-9, Call(test->entry(), -9));
6900}
6901
6902ASSEMBLER_TEST_GENERATE(BitClearImmediate2, assembler) {
6903 __ SetExtensions(RV_GCB);
6904 __ bclri(A0, A0, XLEN - 1);
6905 __ ret();
6906}
6907ASSEMBLER_TEST_RUN(BitClearImmediate2, test) {
6908#if XLEN == 32
6909 EXPECT_DISASSEMBLY(
6910 "49f51513 bclri a0, a0, 0x1f\n"
6911 " 8082 ret\n");
6912#elif XLEN == 64
6913 EXPECT_DISASSEMBLY(
6914 "4bf51513 bclri a0, a0, 0x3f\n"
6915 " 8082 ret\n");
6916#endif
6917
6918 EXPECT_EQ(0, Call(test->entry(), 0));
6919 EXPECT_EQ(1, Call(test->entry(), 1));
6920 EXPECT_EQ(kMaxIntX, Call(test->entry(), -1));
6921}
6922
6923ASSEMBLER_TEST_GENERATE(BitExtract, assembler) {
6924 __ SetExtensions(RV_GCB);
6925 __ bext(A0, A0, A1);
6926 __ ret();
6927}
6928ASSEMBLER_TEST_RUN(BitExtract, test) {
6929 EXPECT_DISASSEMBLY(
6930 "48b55533 bext a0, a0, a1\n"
6931 " 8082 ret\n");
6932
6933 EXPECT_EQ(0, Call(test->entry(), 42, 0));
6934 EXPECT_EQ(1, Call(test->entry(), 42, 1));
6935 EXPECT_EQ(0, Call(test->entry(), 42, 2));
6936 EXPECT_EQ(1, Call(test->entry(), 42, 3));
6937 EXPECT_EQ(0, Call(test->entry(), 42, 4));
6938 EXPECT_EQ(1, Call(test->entry(), 42, 5));
6939 EXPECT_EQ(0, Call(test->entry(), 42, 6));
6940 EXPECT_EQ(0, Call(test->entry(), 42, 7));
6941 EXPECT_EQ(0, Call(test->entry(), 42, 8));
6942
6943 EXPECT_EQ(0, Call(test->entry(), 42, 64));
6944 EXPECT_EQ(1, Call(test->entry(), 42, 65));
6945}
6946
6947ASSEMBLER_TEST_GENERATE(BitExtractImmediate, assembler) {
6948 __ SetExtensions(RV_GCB);
6949 __ bexti(A0, A0, 3);
6950 __ ret();
6951}
6952ASSEMBLER_TEST_RUN(BitExtractImmediate, test) {
6953 EXPECT_DISASSEMBLY(
6954 "48355513 bexti a0, a0, 0x3\n"
6955 " 8082 ret\n");
6956
6957 EXPECT_EQ(0, Call(test->entry(), 0));
6958 EXPECT_EQ(0, Call(test->entry(), 7));
6959 EXPECT_EQ(1, Call(test->entry(), 8));
6960 EXPECT_EQ(1, Call(test->entry(), 9));
6961 EXPECT_EQ(1, Call(test->entry(), -7));
6962 EXPECT_EQ(1, Call(test->entry(), -8));
6963 EXPECT_EQ(0, Call(test->entry(), -9));
6964}
6965
6966ASSEMBLER_TEST_GENERATE(BitExtractImmediate2, assembler) {
6967 __ SetExtensions(RV_GCB);
6968 __ bexti(A0, A0, XLEN - 1);
6969 __ ret();
6970}
6971ASSEMBLER_TEST_RUN(BitExtractImmediate2, test) {
6972#if XLEN == 32
6973 EXPECT_DISASSEMBLY(
6974 "49f55513 bexti a0, a0, 0x1f\n"
6975 " 8082 ret\n");
6976#elif XLEN == 64
6977 EXPECT_DISASSEMBLY(
6978 "4bf55513 bexti a0, a0, 0x3f\n"
6979 " 8082 ret\n");
6980#endif
6981
6982 EXPECT_EQ(0, Call(test->entry(), 0));
6983 EXPECT_EQ(0, Call(test->entry(), 1));
6984 EXPECT_EQ(1, Call(test->entry(), -1));
6985}
6986
6987ASSEMBLER_TEST_GENERATE(BitInvert, assembler) {
6988 __ SetExtensions(RV_GCB);
6989 __ binv(A0, A0, A1);
6990 __ ret();
6991}
6992ASSEMBLER_TEST_RUN(BitInvert, test) {
6993 EXPECT_DISASSEMBLY(
6994 "68b51533 binv a0, a0, a1\n"
6995 " 8082 ret\n");
6996
6997 EXPECT_EQ(43, Call(test->entry(), 42, 0));
6998 EXPECT_EQ(40, Call(test->entry(), 42, 1));
6999 EXPECT_EQ(46, Call(test->entry(), 42, 2));
7000 EXPECT_EQ(34, Call(test->entry(), 42, 3));
7001 EXPECT_EQ(58, Call(test->entry(), 42, 4));
7002 EXPECT_EQ(10, Call(test->entry(), 42, 5));
7003 EXPECT_EQ(106, Call(test->entry(), 42, 6));
7004 EXPECT_EQ(170, Call(test->entry(), 42, 7));
7005 EXPECT_EQ(298, Call(test->entry(), 42, 8));
7006
7007 EXPECT_EQ(43, Call(test->entry(), 42, 64));
7008 EXPECT_EQ(40, Call(test->entry(), 42, 65));
7009}
7010
7011ASSEMBLER_TEST_GENERATE(BitInvertImmediate, assembler) {
7012 __ SetExtensions(RV_GCB);
7013 __ binvi(A0, A0, 3);
7014 __ ret();
7015}
7016ASSEMBLER_TEST_RUN(BitInvertImmediate, test) {
7017 EXPECT_DISASSEMBLY(
7018 "68351513 binvi a0, a0, 0x3\n"
7019 " 8082 ret\n");
7020
7021 EXPECT_EQ(8, Call(test->entry(), 0));
7022 EXPECT_EQ(15, Call(test->entry(), 7));
7023 EXPECT_EQ(0, Call(test->entry(), 8));
7024 EXPECT_EQ(1, Call(test->entry(), 9));
7025 EXPECT_EQ(-15, Call(test->entry(), -7));
7026 EXPECT_EQ(-16, Call(test->entry(), -8));
7027 EXPECT_EQ(-1, Call(test->entry(), -9));
7028}
7029
7030ASSEMBLER_TEST_GENERATE(BitInvertImmediate2, assembler) {
7031 __ SetExtensions(RV_GCB);
7032 __ binvi(A0, A0, XLEN - 1);
7033 __ ret();
7034}
7035ASSEMBLER_TEST_RUN(BitInvertImmediate2, test) {
7036#if XLEN == 32
7037 EXPECT_DISASSEMBLY(
7038 "69f51513 binvi a0, a0, 0x1f\n"
7039 " 8082 ret\n");
7040#elif XLEN == 64
7041 EXPECT_DISASSEMBLY(
7042 "6bf51513 binvi a0, a0, 0x3f\n"
7043 " 8082 ret\n");
7044#endif
7045
7046 EXPECT_EQ(kMinIntX, Call(test->entry(), 0));
7047 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), 1));
7048 EXPECT_EQ(kMaxIntX, Call(test->entry(), -1));
7049}
7050
7051ASSEMBLER_TEST_GENERATE(BitSet, assembler) {
7052 __ SetExtensions(RV_GCB);
7053 __ bset(A0, A0, A1);
7054 __ ret();
7055}
7056ASSEMBLER_TEST_RUN(BitSet, test) {
7057 EXPECT_DISASSEMBLY(
7058 "28b51533 bset a0, a0, a1\n"
7059 " 8082 ret\n");
7060
7061 EXPECT_EQ(43, Call(test->entry(), 42, 0));
7062 EXPECT_EQ(42, Call(test->entry(), 42, 1));
7063 EXPECT_EQ(46, Call(test->entry(), 42, 2));
7064 EXPECT_EQ(42, Call(test->entry(), 42, 3));
7065 EXPECT_EQ(58, Call(test->entry(), 42, 4));
7066 EXPECT_EQ(42, Call(test->entry(), 42, 5));
7067 EXPECT_EQ(106, Call(test->entry(), 42, 6));
7068 EXPECT_EQ(170, Call(test->entry(), 42, 7));
7069 EXPECT_EQ(298, Call(test->entry(), 42, 8));
7070
7071 EXPECT_EQ(43, Call(test->entry(), 42, 64));
7072 EXPECT_EQ(42, Call(test->entry(), 42, 65));
7073}
7074
7075ASSEMBLER_TEST_GENERATE(BitSetImmediate, assembler) {
7076 __ SetExtensions(RV_GCB);
7077 __ bseti(A0, A0, 3);
7078 __ ret();
7079}
7080ASSEMBLER_TEST_RUN(BitSetImmediate, test) {
7081 EXPECT_DISASSEMBLY(
7082 "28351513 bseti a0, a0, 0x3\n"
7083 " 8082 ret\n");
7084
7085 EXPECT_EQ(8, Call(test->entry(), 0));
7086 EXPECT_EQ(15, Call(test->entry(), 7));
7087 EXPECT_EQ(8, Call(test->entry(), 8));
7088 EXPECT_EQ(9, Call(test->entry(), 9));
7089 EXPECT_EQ(-7, Call(test->entry(), -7));
7090 EXPECT_EQ(-8, Call(test->entry(), -8));
7091 EXPECT_EQ(-1, Call(test->entry(), -9));
7092}
7093
7094ASSEMBLER_TEST_GENERATE(BitSetImmediate2, assembler) {
7095 __ SetExtensions(RV_GCB);
7096 __ bseti(A0, A0, XLEN - 1);
7097 __ ret();
7098}
7099ASSEMBLER_TEST_RUN(BitSetImmediate2, test) {
7100#if XLEN == 32
7101 EXPECT_DISASSEMBLY(
7102 "29f51513 bseti a0, a0, 0x1f\n"
7103 " 8082 ret\n");
7104#elif XLEN == 64
7105 EXPECT_DISASSEMBLY(
7106 "2bf51513 bseti a0, a0, 0x3f\n"
7107 " 8082 ret\n");
7108#endif
7109
7110 EXPECT_EQ(kMinIntX, Call(test->entry(), 0));
7111 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), 1));
7112 EXPECT_EQ(-1, Call(test->entry(), -1));
7113}
7114
7115ASSEMBLER_TEST_GENERATE(LoadByteAcquire, assembler) {
7116 __ SetExtensions(RV_GC | RV_Zalasr);
7117 __ lb(A0, Address(A1), std::memory_order_acquire);
7118 __ ret();
7119}
7120ASSEMBLER_TEST_RUN(LoadByteAcquire, test) {
7121 EXPECT_DISASSEMBLY(
7122 "3405852f lb.aq a0, (a1)\n"
7123 " 8082 ret\n");
7124
7125 int8_t data = -42;
7126 EXPECT_EQ(-42, Call(test->entry(), 0, reinterpret_cast<intx_t>(&data)));
7127}
7128
7129ASSEMBLER_TEST_GENERATE(LoadHalfwordAcquire, assembler) {
7130 __ SetExtensions(RV_GC | RV_Zalasr);
7131 __ lh(A0, Address(A1), std::memory_order_acquire);
7132 __ ret();
7133}
7134ASSEMBLER_TEST_RUN(LoadHalfwordAcquire, test) {
7135 EXPECT_DISASSEMBLY(
7136 "3405952f lh.aq a0, (a1)\n"
7137 " 8082 ret\n");
7138
7139 int16_t data = -42;
7140 EXPECT_EQ(-42, Call(test->entry(), 0, reinterpret_cast<intx_t>(&data)));
7141}
7142
7143ASSEMBLER_TEST_GENERATE(LoadWordAcquire, assembler) {
7144 __ SetExtensions(RV_GC | RV_Zalasr);
7145 __ lw(A0, Address(A1), std::memory_order_acquire);
7146 __ ret();
7147}
7148ASSEMBLER_TEST_RUN(LoadWordAcquire, test) {
7149 EXPECT_DISASSEMBLY(
7150 "3405a52f lw.aq a0, (a1)\n"
7151 " 8082 ret\n");
7152
7153 int32_t data = -42;
7154 EXPECT_EQ(-42, Call(test->entry(), 0, reinterpret_cast<intx_t>(&data)));
7155}
7156
7157ASSEMBLER_TEST_GENERATE(StoreByteRelease, assembler) {
7158 __ SetExtensions(RV_GC | RV_Zalasr);
7159 __ sb(A0, Address(A1), std::memory_order_release);
7160 __ ret();
7161}
7162ASSEMBLER_TEST_RUN(StoreByteRelease, test) {
7163 EXPECT_DISASSEMBLY(
7164 "3aa5802f sb.rl a0, (a1)\n"
7165 " 8082 ret\n");
7166
7167 int8_t data = 0;
7168 EXPECT_EQ(-42, Call(test->entry(), -42, reinterpret_cast<intx_t>(&data)));
7169 EXPECT_EQ(-42, data);
7170}
7171
7172ASSEMBLER_TEST_GENERATE(StoreHalfwordRelease, assembler) {
7173 __ SetExtensions(RV_GC | RV_Zalasr);
7174 __ sh(A0, Address(A1), std::memory_order_release);
7175 __ ret();
7176}
7177ASSEMBLER_TEST_RUN(StoreHalfwordRelease, test) {
7178 EXPECT_DISASSEMBLY(
7179 "3aa5902f sh.rl a0, (a1)\n"
7180 " 8082 ret\n");
7181
7182 int16_t data = 0;
7183 EXPECT_EQ(-42, Call(test->entry(), -42, reinterpret_cast<intx_t>(&data)));
7184 EXPECT_EQ(-42, data);
7185}
7186
7187ASSEMBLER_TEST_GENERATE(StoreWordRelease, assembler) {
7188 __ SetExtensions(RV_GC | RV_Zalasr);
7189 __ sw(A0, Address(A1), std::memory_order_release);
7190 __ ret();
7191}
7192ASSEMBLER_TEST_RUN(StoreWordRelease, test) {
7193 EXPECT_DISASSEMBLY(
7194 "3aa5a02f sw.rl a0, (a1)\n"
7195 " 8082 ret\n");
7196
7197 int32_t data = 0;
7198 EXPECT_EQ(-42, Call(test->entry(), -42, reinterpret_cast<intx_t>(&data)));
7199 EXPECT_EQ(-42, data);
7200}
7201
7202#if XLEN >= 64
7203ASSEMBLER_TEST_GENERATE(LoadDoubleWordAcquire, assembler) {
7204 __ SetExtensions(RV_GC | RV_Zalasr);
7205 __ ld(A0, Address(A1), std::memory_order_acquire);
7206 __ ret();
7207}
7208ASSEMBLER_TEST_RUN(LoadDoubleWordAcquire, test) {
7209 EXPECT_DISASSEMBLY(
7210 "3405b52f ld.aq a0, (a1)\n"
7211 " 8082 ret\n");
7212
7213 int64_t data = -42;
7214 EXPECT_EQ(-42, Call(test->entry(), 0, reinterpret_cast<intx_t>(&data)));
7215}
7216
7217ASSEMBLER_TEST_GENERATE(StoreDoubleWordRelease, assembler) {
7218 __ SetExtensions(RV_GC | RV_Zalasr);
7219 __ sd(A0, Address(A1), std::memory_order_release);
7220 __ ret();
7221}
7222ASSEMBLER_TEST_RUN(StoreDoubleWordRelease, test) {
7223 EXPECT_DISASSEMBLY(
7224 "3aa5b02f sd.rl a0, (a1)\n"
7225 " 8082 ret\n");
7226
7227 int64_t data = 0;
7228 EXPECT_EQ(-42, Call(test->entry(), -42, reinterpret_cast<intx_t>(&data)));
7229 EXPECT_EQ(-42, data);
7230}
7231#endif // XLEN >= 64
7232
7233ASSEMBLER_TEST_GENERATE(LoadImmediate_MaxInt32, assembler) {
7234 FLAG_use_compressed_instructions = true;
7235 __ SetExtensions(RV_GC);
7236 __ LoadImmediate(A0, kMaxInt32);
7237 __ ret();
7238}
7239ASSEMBLER_TEST_RUN(LoadImmediate_MaxInt32, test) {
7240#if XLEN == 32
7241 EXPECT_DISASSEMBLY(
7242 "80000537 lui a0, -2147483648\n"
7243 " 157d addi a0, a0, -1\n"
7244 " 8082 ret\n");
7245#elif XLEN == 64
7246 EXPECT_DISASSEMBLY(
7247 "80000537 lui a0, -2147483648\n"
7248 " 357d addiw a0, a0, -1\n"
7249 " 8082 ret\n");
7250#endif
7251 EXPECT_EQ(kMaxInt32, Call(test->entry()));
7252}
7253
7254ASSEMBLER_TEST_GENERATE(LoadImmediate_MinInt32, assembler) {
7255 FLAG_use_compressed_instructions = true;
7256 __ SetExtensions(RV_GC);
7257 __ LoadImmediate(A0, kMinInt32);
7258 __ ret();
7259}
7260ASSEMBLER_TEST_RUN(LoadImmediate_MinInt32, test) {
7261 EXPECT_DISASSEMBLY(
7262 "80000537 lui a0, -2147483648\n"
7263 " 8082 ret\n");
7264 EXPECT_EQ(kMinInt32, Call(test->entry()));
7265}
7266
7267#if XLEN >= 64
7268ASSEMBLER_TEST_GENERATE(LoadImmediate_MinInt64, assembler) {
7269 FLAG_use_compressed_instructions = true;
7270 __ SetExtensions(RV_GC);
7271 __ LoadImmediate(A0, kMinInt64);
7272 __ ret();
7273}
7274ASSEMBLER_TEST_RUN(LoadImmediate_MinInt64, test) {
7275 EXPECT_DISASSEMBLY(
7276 " 557d li a0, -1\n"
7277 "03f51513 slli a0, a0, 0x3f\n"
7278 " 8082 ret\n");
7279 EXPECT_EQ(kMinInt64, Call(test->entry()));
7280}
7281
7282ASSEMBLER_TEST_GENERATE(LoadImmediate_Full, assembler) {
7283 FLAG_use_compressed_instructions = true;
7284 __ SetExtensions(RV_GC);
7285 __ LoadImmediate(A0, 0xABCDABCDABCDABCD);
7286 __ ret();
7287}
7288ASSEMBLER_TEST_RUN(LoadImmediate_Full, test) {
7289 EXPECT_DISASSEMBLY(
7290 "feaf3537 lui a0, -22073344\n"
7291 "6af5051b addiw a0, a0, 1711\n"
7292 " 0532 slli a0, a0, 12\n"
7293 "36b50513 addi a0, a0, 875\n"
7294 " 053a slli a0, a0, 14\n"
7295 "cdb50513 addi a0, a0, -805\n"
7296 " 0532 slli a0, a0, 12\n"
7297 "bcd50513 addi a0, a0, -1075\n"
7298 " 8082 ret\n");
7299 EXPECT_EQ(static_cast<int64_t>(0xABCDABCDABCDABCD), Call(test->entry()));
7300}
7301
7302ASSEMBLER_TEST_GENERATE(LoadImmediate_LuiAddiwSlli, assembler) {
7303 FLAG_use_compressed_instructions = true;
7304 __ SetExtensions(RV_GC);
7305 __ LoadImmediate(A0, 0x7BCDABCD00000);
7306 __ ret();
7307}
7308ASSEMBLER_TEST_RUN(LoadImmediate_LuiAddiwSlli, test) {
7309 EXPECT_DISASSEMBLY(
7310 "7bcdb537 lui a0, 2077077504\n"
7311 "bcd5051b addiw a0, a0, -1075\n"
7312 " 0552 slli a0, a0, 20\n"
7313 " 8082 ret\n");
7314 EXPECT_EQ(static_cast<int64_t>(0x7BCDABCD00000), Call(test->entry()));
7315}
7316
7317ASSEMBLER_TEST_GENERATE(LoadImmediate_LuiSlli, assembler) {
7318 FLAG_use_compressed_instructions = true;
7319 __ SetExtensions(RV_GC);
7320 __ LoadImmediate(A0, 0xABCDE00000000000);
7321 __ ret();
7322}
7323ASSEMBLER_TEST_RUN(LoadImmediate_LuiSlli, test) {
7324 EXPECT_DISASSEMBLY(
7325 "d5e6f537 lui a0, -706285568\n"
7326 "02151513 slli a0, a0, 0x21\n"
7327 " 8082 ret\n");
7328 EXPECT_EQ(static_cast<int64_t>(0xABCDE00000000000), Call(test->entry()));
7329}
7330
7331ASSEMBLER_TEST_GENERATE(LoadImmediate_LiSlli, assembler) {
7332 FLAG_use_compressed_instructions = true;
7333 __ SetExtensions(RV_GC);
7334 __ LoadImmediate(A0, 0xABC00000000000);
7335 __ ret();
7336}
7337ASSEMBLER_TEST_RUN(LoadImmediate_LiSlli, test) {
7338 EXPECT_DISASSEMBLY(
7339 "2af00513 li a0, 687\n"
7340 "02e51513 slli a0, a0, 0x2e\n"
7341 " 8082 ret\n");
7342 EXPECT_EQ(static_cast<int64_t>(0xABC00000000000), Call(test->entry()));
7343}
7344
7345ASSEMBLER_TEST_GENERATE(LoadImmediate_LiSlliAddi, assembler) {
7346 FLAG_use_compressed_instructions = true;
7347 __ SetExtensions(RV_GC);
7348 __ LoadImmediate(A0, 0xFF000000000000FF);
7349 __ ret();
7350}
7351ASSEMBLER_TEST_RUN(LoadImmediate_LiSlliAddi, test) {
7352 EXPECT_DISASSEMBLY(
7353 " 557d li a0, -1\n"
7354 "03851513 slli a0, a0, 0x38\n"
7355 "0ff50513 addi a0, a0, 255\n"
7356 " 8082 ret\n");
7357 EXPECT_EQ(static_cast<int64_t>(0xFF000000000000FF), Call(test->entry()));
7358}
7359#endif
7360
7361ASSEMBLER_TEST_GENERATE(BitwiseImmediates_GC, assembler) {
7362 FLAG_use_compressed_instructions = true;
7363 __ SetExtensions(RV_GC);
7364 __ AndImmediate(A0, A1, ~0x10000000);
7365 __ OrImmediate(A0, A1, 0x10000000);
7366 __ XorImmediate(A0, A1, 0x10000000);
7367 __ ret();
7368}
7369ASSEMBLER_TEST_RUN(BitwiseImmediates_GC, test) {
7370#if XLEN == 32
7371 EXPECT_DISASSEMBLY(
7372 "f0000737 lui tmp2, -268435456\n"
7373 " 177d addi tmp2, tmp2, -1\n"
7374 "00e5f533 and a0, a1, tmp2\n"
7375 "10000737 lui tmp2, 268435456\n"
7376 "00e5e533 or a0, a1, tmp2\n"
7377 "10000737 lui tmp2, 268435456\n"
7378 "00e5c533 xor a0, a1, tmp2\n"
7379 " 8082 ret\n");
7380#else
7381 EXPECT_DISASSEMBLY(
7382 "f0000737 lui tmp2, -268435456\n"
7383 " 377d addiw tmp2, tmp2, -1\n"
7384 "00e5f533 and a0, a1, tmp2\n"
7385 "10000737 lui tmp2, 268435456\n"
7386 "00e5e533 or a0, a1, tmp2\n"
7387 "10000737 lui tmp2, 268435456\n"
7388 "00e5c533 xor a0, a1, tmp2\n"
7389 " 8082 ret\n");
7390#endif
7391}
7392
7393ASSEMBLER_TEST_GENERATE(BitwiseImmediates_GCB, assembler) {
7394 FLAG_use_compressed_instructions = true;
7395 __ SetExtensions(RV_GCB);
7396 __ AndImmediate(A0, A1, ~0x10000000);
7397 __ OrImmediate(A0, A1, 0x10000000);
7398 __ XorImmediate(A0, A1, 0x10000000);
7399 __ ret();
7400}
7401ASSEMBLER_TEST_RUN(BitwiseImmediates_GCB, test) {
7402 EXPECT_DISASSEMBLY(
7403 "49c59513 bclri a0, a1, 0x1c\n"
7404 "29c59513 bseti a0, a1, 0x1c\n"
7405 "69c59513 binvi a0, a1, 0x1c\n"
7406 " 8082 ret\n");
7407}
7408
7409ASSEMBLER_TEST_GENERATE(AddImmediateBranchOverflow, assembler) {
7410 FLAG_use_compressed_instructions = true;
7411 __ SetExtensions(RV_GC);
7412 Label overflow;
7413
7414 __ AddImmediateBranchOverflow(A0, A0, 2, &overflow);
7415 __ ret();
7416 __ Bind(&overflow);
7417 __ li(A0, 0);
7418 __ ret();
7419}
7420ASSEMBLER_TEST_RUN(AddImmediateBranchOverflow, test) {
7421 EXPECT_DISASSEMBLY(
7422 " 872a mv tmp2, a0\n"
7423 " 0509 addi a0, a0, 2\n"
7424 "00e54363 blt a0, tmp2, +6\n"
7425 " 8082 ret\n"
7426 " 4501 li a0, 0\n"
7427 " 8082 ret\n");
7428 EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), kMaxIntX - 3));
7429 EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX - 2));
7430 EXPECT_EQ(0, Call(test->entry(), kMaxIntX - 1));
7431 EXPECT_EQ(0, Call(test->entry(), kMaxIntX));
7432}
7433
7434ASSEMBLER_TEST_GENERATE(AddBranchOverflow_NonDestructive, assembler) {
7435 FLAG_use_compressed_instructions = true;
7436 __ SetExtensions(RV_GC);
7437 Label overflow;
7438
7439 __ AddBranchOverflow(A0, A1, A2, &overflow);
7440 __ ret();
7441 __ Bind(&overflow);
7442 __ li(A0, 0);
7443 __ ret();
7444}
7445ASSEMBLER_TEST_RUN(AddBranchOverflow_NonDestructive, test) {
7446 EXPECT_DISASSEMBLY(
7447 "00c58533 add a0, a1, a2\n"
7448 "00062693 slti tmp, a2, 0\n"
7449 "00b52733 slt tmp2, a0, a1\n"
7450 "00e69363 bne tmp, tmp2, +6\n"
7451 " 8082 ret\n"
7452 " 4501 li a0, 0\n"
7453 " 8082 ret\n");
7454 EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), 42, kMaxIntX, -1));
7455 EXPECT_EQ(kMaxIntX, Call(test->entry(), 42, kMaxIntX, 0));
7456 EXPECT_EQ(0, Call(test->entry(), 42, kMaxIntX, 1));
7457
7458 EXPECT_EQ(0, Call(test->entry(), 42, kMinIntX, -1));
7459 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), 42, kMinIntX, 1));
7460 EXPECT_EQ(kMinIntX, Call(test->entry(), 42, kMinIntX, 0));
7461}
7462
7463ASSEMBLER_TEST_GENERATE(AddBranchOverflow_Destructive, assembler) {
7464 FLAG_use_compressed_instructions = true;
7465 __ SetExtensions(RV_GC);
7466 Label overflow;
7467
7468 __ AddBranchOverflow(A0, A1, A0, &overflow);
7469 __ ret();
7470 __ Bind(&overflow);
7471 __ li(A0, 0);
7472 __ ret();
7473}
7474ASSEMBLER_TEST_RUN(AddBranchOverflow_Destructive, test) {
7475 EXPECT_DISASSEMBLY(
7476 "00052693 slti tmp, a0, 0\n"
7477 " 952e add a0, a0, a1\n"
7478 "00b52733 slt tmp2, a0, a1\n"
7479 "00e69363 bne tmp, tmp2, +6\n"
7480 " 8082 ret\n"
7481 " 4501 li a0, 0\n"
7482 " 8082 ret\n");
7483 EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), kMaxIntX, -1));
7484 EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX, 0));
7485 EXPECT_EQ(0, Call(test->entry(), kMaxIntX, 1));
7486
7487 EXPECT_EQ(0, Call(test->entry(), kMinIntX, -1));
7488 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), kMinIntX, 1));
7489 EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX, 0));
7490}
7491
7492ASSEMBLER_TEST_GENERATE(SubtractImmediateBranchOverflow, assembler) {
7493 FLAG_use_compressed_instructions = true;
7494 __ SetExtensions(RV_GC);
7495 Label overflow;
7496
7497 __ SubtractImmediateBranchOverflow(A0, A0, 2, &overflow);
7498 __ ret();
7499 __ Bind(&overflow);
7500 __ li(A0, 0);
7501 __ ret();
7502}
7503ASSEMBLER_TEST_RUN(SubtractImmediateBranchOverflow, test) {
7504 EXPECT_DISASSEMBLY(
7505 " 872a mv tmp2, a0\n"
7506 " 1579 addi a0, a0, -2\n"
7507 "00a74363 blt tmp2, a0, +6\n"
7508 " 8082 ret\n"
7509 " 4501 li a0, 0\n"
7510 " 8082 ret\n");
7511 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), kMinIntX + 3));
7512 EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX + 2));
7513 EXPECT_EQ(0, Call(test->entry(), kMinIntX + 1));
7514 EXPECT_EQ(0, Call(test->entry(), kMinIntX));
7515}
7516
7517ASSEMBLER_TEST_GENERATE(SubtractBranchOverflow_NonDestructive, assembler) {
7518 FLAG_use_compressed_instructions = true;
7519 __ SetExtensions(RV_GC);
7520
7521 Label overflow;
7522 __ SubtractBranchOverflow(A0, A1, A2, &overflow);
7523 __ ret();
7524 __ Bind(&overflow);
7525 __ li(A0, 0);
7526 __ ret();
7527}
7528ASSEMBLER_TEST_RUN(SubtractBranchOverflow_NonDestructive, test) {
7529 EXPECT_DISASSEMBLY(
7530 "40c58533 sub a0, a1, a2\n"
7531 "00062693 slti tmp, a2, 0\n"
7532 "00a5a733 slt tmp2, a1, a0\n"
7533 "00e69363 bne tmp, tmp2, +6\n"
7534 " 8082 ret\n"
7535 " 4501 li a0, 0\n"
7536 " 8082 ret\n");
7537 EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), 42, kMaxIntX, 1));
7538 EXPECT_EQ(kMaxIntX, Call(test->entry(), 42, kMaxIntX, 0));
7539 EXPECT_EQ(0, Call(test->entry(), 42, kMaxIntX, -1));
7540
7541 EXPECT_EQ(0, Call(test->entry(), 42, kMinIntX, 1));
7542 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), 42, kMinIntX, -1));
7543 EXPECT_EQ(kMinIntX, Call(test->entry(), 42, kMinIntX, 0));
7544}
7545
7546ASSEMBLER_TEST_GENERATE(SubtractBranchOverflow_Destructive, assembler) {
7547 FLAG_use_compressed_instructions = true;
7548 __ SetExtensions(RV_GC);
7549
7550 Label overflow;
7551 __ SubtractBranchOverflow(A0, A0, A1, &overflow);
7552 __ ret();
7553 __ Bind(&overflow);
7554 __ li(A0, 0);
7555 __ ret();
7556}
7557ASSEMBLER_TEST_RUN(SubtractBranchOverflow_Destructive, test) {
7558 EXPECT_DISASSEMBLY(
7559 "00052693 slti tmp, a0, 0\n"
7560 " 8d0d sub a0, a0, a1\n"
7561 "00b52733 slt tmp2, a0, a1\n"
7562 "00e69363 bne tmp, tmp2, +6\n"
7563 " 8082 ret\n"
7564 " 4501 li a0, 0\n"
7565 " 8082 ret\n");
7566 EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), kMaxIntX, 1));
7567 EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX, 0));
7568 EXPECT_EQ(0, Call(test->entry(), kMaxIntX, -1));
7569
7570 EXPECT_EQ(0, Call(test->entry(), kMinIntX, 1));
7571 EXPECT_EQ(kMinIntX + 1, Call(test->entry(), kMinIntX, -1));
7572 EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX, 0));
7573}
7574
7575ASSEMBLER_TEST_GENERATE(MultiplyImmediateBranchOverflow, assembler) {
7576 FLAG_use_compressed_instructions = true;
7577 __ SetExtensions(RV_GC);
7578 Label overflow;
7579
7580 __ MultiplyImmediateBranchOverflow(A0, A0, 2, &overflow);
7581 __ ret();
7582 __ Bind(&overflow);
7583 __ li(A0, 0);
7584 __ ret();
7585}
7586ASSEMBLER_TEST_RUN(MultiplyImmediateBranchOverflow, test) {
7587#if XLEN == 64
7588 EXPECT_DISASSEMBLY(
7589 " 4709 li tmp2, 2\n"
7590 "02e516b3 mulh tmp, a0, tmp2\n"
7591 "02e50533 mul a0, a0, tmp2\n"
7592 "43f55713 srai tmp2, a0, 0x3f\n"
7593 "00e69363 bne tmp, tmp2, +6\n"
7594 " 8082 ret\n"
7595 " 4501 li a0, 0\n"
7596 " 8082 ret\n");
7597#elif XLEN == 32
7598 EXPECT_DISASSEMBLY(
7599 " 4709 li tmp2, 2\n"
7600 "02e516b3 mulh tmp, a0, tmp2\n"
7601 "02e50533 mul a0, a0, tmp2\n"
7602 "41f55713 srai tmp2, a0, 0x1f\n"
7603 "00e69363 bne tmp, tmp2, +6\n"
7604 " 8082 ret\n"
7605 " 4501 li a0, 0\n"
7606 " 8082 ret\n");
7607#endif
7608 EXPECT_EQ(0, Call(test->entry(), kMinIntX));
7609 EXPECT_EQ(0, Call(test->entry(), kMaxIntX));
7610 EXPECT_EQ(-2, Call(test->entry(), -1));
7611 EXPECT_EQ(2, Call(test->entry(), 1));
7612 EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX / 2));
7613 EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), (kMaxIntX - 1) / 2));
7614}
7615
7616ASSEMBLER_TEST_GENERATE(MultiplyBranchOverflow_NonDestructive, assembler) {
7617 FLAG_use_compressed_instructions = true;
7618 __ SetExtensions(RV_GC);
7619
7620 Label overflow;
7621 __ MultiplyBranchOverflow(A0, A1, A2, &overflow);
7622 __ ret();
7623 __ Bind(&overflow);
7624 __ li(A0, 42);
7625 __ ret();
7626}
7627ASSEMBLER_TEST_RUN(MultiplyBranchOverflow_NonDestructive, test) {
7628#if XLEN == 64
7629 EXPECT_DISASSEMBLY(
7630 "02c596b3 mulh tmp, a1, a2\n"
7631 "02c58533 mul a0, a1, a2\n"
7632 "43f55713 srai tmp2, a0, 0x3f\n"
7633 "00e69363 bne tmp, tmp2, +6\n"
7634 " 8082 ret\n"
7635 "02a00513 li a0, 42\n"
7636 " 8082 ret\n");
7637#elif XLEN == 32
7638 EXPECT_DISASSEMBLY(
7639 "02c596b3 mulh tmp, a1, a2\n"
7640 "02c58533 mul a0, a1, a2\n"
7641 "41f55713 srai tmp2, a0, 0x1f\n"
7642 "00e69363 bne tmp, tmp2, +6\n"
7643 " 8082 ret\n"
7644 "02a00513 li a0, 42\n"
7645 " 8082 ret\n");
7646#endif
7647 EXPECT_EQ(42, Call(test->entry(), 42, kMaxIntX, -2));
7648 EXPECT_EQ(-kMaxIntX, Call(test->entry(), 42, kMaxIntX, -1));
7649 EXPECT_EQ(0, Call(test->entry(), 42, kMaxIntX, 0));
7650 EXPECT_EQ(kMaxIntX, Call(test->entry(), 42, kMaxIntX, 1));
7651 EXPECT_EQ(42, Call(test->entry(), 42, kMaxIntX, 2));
7652
7653 EXPECT_EQ(42, Call(test->entry(), 42, kMinIntX, -2));
7654 EXPECT_EQ(42, Call(test->entry(), 42, kMinIntX, -1));
7655 EXPECT_EQ(0, Call(test->entry(), 42, kMinIntX, 0));
7656 EXPECT_EQ(kMinIntX, Call(test->entry(), 42, kMinIntX, 1));
7657 EXPECT_EQ(42, Call(test->entry(), 42, kMinIntX, 2));
7658}
7659
7660ASSEMBLER_TEST_GENERATE(MultiplyBranchOverflow_Destructive, assembler) {
7661 FLAG_use_compressed_instructions = true;
7662 __ SetExtensions(RV_GC);
7663
7664 Label overflow;
7665 __ MultiplyBranchOverflow(A0, A0, A1, &overflow);
7666 __ ret();
7667 __ Bind(&overflow);
7668 __ li(A0, 42);
7669 __ ret();
7670}
7671ASSEMBLER_TEST_RUN(MultiplyBranchOverflow_Destructive, test) {
7672#if XLEN == 64
7673 EXPECT_DISASSEMBLY(
7674 "02b516b3 mulh tmp, a0, a1\n"
7675 "02b50533 mul a0, a0, a1\n"
7676 "43f55713 srai tmp2, a0, 0x3f\n"
7677 "00e69363 bne tmp, tmp2, +6\n"
7678 " 8082 ret\n"
7679 "02a00513 li a0, 42\n"
7680 " 8082 ret\n");
7681#elif XLEN == 32
7682 EXPECT_DISASSEMBLY(
7683 "02b516b3 mulh tmp, a0, a1\n"
7684 "02b50533 mul a0, a0, a1\n"
7685 "41f55713 srai tmp2, a0, 0x1f\n"
7686 "00e69363 bne tmp, tmp2, +6\n"
7687 " 8082 ret\n"
7688 "02a00513 li a0, 42\n"
7689 " 8082 ret\n");
7690#endif
7691 EXPECT_EQ(42, Call(test->entry(), kMaxIntX, -2));
7692 EXPECT_EQ(-kMaxIntX, Call(test->entry(), kMaxIntX, -1));
7693 EXPECT_EQ(0, Call(test->entry(), kMaxIntX, 0));
7694 EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX, 1));
7695 EXPECT_EQ(42, Call(test->entry(), kMaxIntX, 2));
7696
7697 EXPECT_EQ(42, Call(test->entry(), kMinIntX, -2));
7698 EXPECT_EQ(42, Call(test->entry(), kMinIntX, -1));
7699 EXPECT_EQ(0, Call(test->entry(), kMinIntX, 0));
7700 EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX, 1));
7701 EXPECT_EQ(42, Call(test->entry(), kMinIntX, 2));
7702}
7703
7704#define TEST_ENCODING(type, name) \
7705 VM_UNIT_TEST_CASE(Encoding##name) { \
7706 for (intptr_t v = -(1 << 21); v <= (1 << 21); v++) { \
7707 type value = static_cast<type>(v); \
7708 if (!Is##name(value)) continue; \
7709 int32_t encoded = Encode##name(value); \
7710 type decoded = Decode##name(encoded); \
7711 EXPECT_EQ(value, decoded); \
7712 } \
7713 }
7714
7715TEST_ENCODING(Register, Rd)
7716TEST_ENCODING(Register, Rs1)
7717TEST_ENCODING(Register, Rs2)
7718TEST_ENCODING(FRegister, FRd)
7719TEST_ENCODING(FRegister, FRs1)
7720TEST_ENCODING(FRegister, FRs2)
7721TEST_ENCODING(FRegister, FRs3)
7722TEST_ENCODING(Funct2, Funct2)
7723TEST_ENCODING(Funct3, Funct3)
7724TEST_ENCODING(Funct5, Funct5)
7725TEST_ENCODING(Funct7, Funct7)
7726TEST_ENCODING(Funct12, Funct12)
7727TEST_ENCODING(RoundingMode, RoundingMode)
7728TEST_ENCODING(intptr_t, BTypeImm)
7729TEST_ENCODING(intptr_t, JTypeImm)
7730TEST_ENCODING(intptr_t, ITypeImm)
7731TEST_ENCODING(intptr_t, STypeImm)
7732TEST_ENCODING(intptr_t, UTypeImm)
7733
7734TEST_ENCODING(Register, CRd)
7735TEST_ENCODING(Register, CRs1)
7736TEST_ENCODING(Register, CRs2)
7737TEST_ENCODING(Register, CRdp)
7738TEST_ENCODING(Register, CRs1p)
7739TEST_ENCODING(Register, CRs2p)
7740TEST_ENCODING(FRegister, CFRd)
7741TEST_ENCODING(FRegister, CFRs1)
7742TEST_ENCODING(FRegister, CFRs2)
7743TEST_ENCODING(FRegister, CFRdp)
7744TEST_ENCODING(FRegister, CFRs1p)
7745TEST_ENCODING(FRegister, CFRs2p)
7746TEST_ENCODING(intptr_t, CSPLoad4Imm)
7747TEST_ENCODING(intptr_t, CSPLoad8Imm)
7748TEST_ENCODING(intptr_t, CSPStore4Imm)
7749TEST_ENCODING(intptr_t, CSPStore8Imm)
7750TEST_ENCODING(intptr_t, CMem4Imm)
7751TEST_ENCODING(intptr_t, CMem8Imm)
7752TEST_ENCODING(intptr_t, CJImm)
7753TEST_ENCODING(intptr_t, CBImm)
7754TEST_ENCODING(intptr_t, CIImm)
7755TEST_ENCODING(intptr_t, CUImm)
7756TEST_ENCODING(intptr_t, CI16Imm)
7757TEST_ENCODING(intptr_t, CI4SPNImm)
7758
7759#undef TEST_ENCODING
7760
7761static void RangeCheck(Assembler* assembler, Register value, Register temp) {
7762 const Register return_reg = CallingConventions::kReturnReg;
7763 Label in_range;
7764 __ RangeCheck(value, temp, kFirstErrorCid, kLastErrorCid,
7765 AssemblerBase::kIfInRange, &in_range);
7766 __ LoadImmediate(return_reg, 0);
7767 __ Ret();
7768 __ Bind(&in_range);
7769 __ LoadImmediate(return_reg, 1);
7770 __ Ret();
7771}
7772
7773ASSEMBLER_TEST_GENERATE(RangeCheckNoTemp, assembler) {
7775 const Register temp = kNoRegister;
7776 RangeCheck(assembler, value, temp);
7777}
7778
7779ASSEMBLER_TEST_RUN(RangeCheckNoTemp, test) {
7780 intptr_t result;
7781 result = test->Invoke<intptr_t, intptr_t>(kErrorCid);
7782 EXPECT_EQ(1, result);
7783 result = test->Invoke<intptr_t, intptr_t>(kUnwindErrorCid);
7784 EXPECT_EQ(1, result);
7785 result = test->Invoke<intptr_t, intptr_t>(kFunctionCid);
7786 EXPECT_EQ(0, result);
7787 result = test->Invoke<intptr_t, intptr_t>(kMintCid);
7788 EXPECT_EQ(0, result);
7789}
7790
7791ASSEMBLER_TEST_GENERATE(RangeCheckWithTemp, assembler) {
7794 RangeCheck(assembler, value, temp);
7795}
7796
7797ASSEMBLER_TEST_RUN(RangeCheckWithTemp, test) {
7798 intptr_t result;
7799 result = test->Invoke<intptr_t, intptr_t>(kErrorCid);
7800 EXPECT_EQ(1, result);
7801 result = test->Invoke<intptr_t, intptr_t>(kUnwindErrorCid);
7802 EXPECT_EQ(1, result);
7803 result = test->Invoke<intptr_t, intptr_t>(kFunctionCid);
7804 EXPECT_EQ(0, result);
7805 result = test->Invoke<intptr_t, intptr_t>(kMintCid);
7806 EXPECT_EQ(0, result);
7807}
7808
7809ASSEMBLER_TEST_GENERATE(RangeCheckWithTempReturnValue, assembler) {
7812 const Register return_reg = CallingConventions::kReturnReg;
7813 Label in_range;
7814 __ RangeCheck(value, temp, kFirstErrorCid, kLastErrorCid,
7815 AssemblerBase::kIfInRange, &in_range);
7816 __ Bind(&in_range);
7817 __ MoveRegister(return_reg, value);
7818 __ Ret();
7819}
7820
7821ASSEMBLER_TEST_RUN(RangeCheckWithTempReturnValue, test) {
7822 intptr_t result;
7823 result = test->Invoke<intptr_t, intptr_t>(kErrorCid);
7824 EXPECT_EQ(kErrorCid, result);
7825 result = test->Invoke<intptr_t, intptr_t>(kUnwindErrorCid);
7826 EXPECT_EQ(kUnwindErrorCid, result);
7827 result = test->Invoke<intptr_t, intptr_t>(kFunctionCid);
7828 EXPECT_EQ(kFunctionCid, result);
7829 result = test->Invoke<intptr_t, intptr_t>(kMintCid);
7830 EXPECT_EQ(kMintCid, result);
7831}
7832
7833void EnterTestFrame(Assembler* assembler) {
7834 __ EnterFrame(0);
7835 __ PushRegister(CODE_REG);
7836 __ PushRegister(THR);
7837 __ PushRegister(PP);
7838 __ MoveRegister(CODE_REG, A0);
7839 __ MoveRegister(THR, A1);
7840 __ LoadPoolPointer(PP);
7841}
7842
7843void LeaveTestFrame(Assembler* assembler) {
7844 __ PopRegister(PP);
7845 __ PopRegister(THR);
7846 __ PopRegister(CODE_REG);
7847
7848 __ LeaveFrame();
7849}
7850
7851// Tests that JumpAndLink only clobbers CODE_REG in JIT mode and does not
7852// clobber any allocatable registers in AOT mode.
7853ASSEMBLER_TEST_GENERATE(JumpAndLinkPreservesRegisters, assembler) {
7854 const auto& do_nothing_just_return =
7855 AssemblerTest::Generate("DoNothing", [](auto assembler) { __ Ret(); });
7856
7857 EnterTestFrame(assembler);
7858 __ PushRegister(RA);
7859
7860 const RegisterSet clobbered_regs(
7861 kDartAvailableCpuRegs & ~(static_cast<RegList>(1) << A0),
7862 /*fpu_register_mask=*/0);
7863 __ PushRegisters(clobbered_regs);
7864
7865 Label done;
7866
7867 const auto check_all_allocatable_registers_are_preserved_by_call = [&]() {
7868 for (auto reg : RegisterRange(kDartAvailableCpuRegs)) {
7869 __ LoadImmediate(reg, static_cast<int32_t>(reg));
7870 }
7871 __ JumpAndLink(do_nothing_just_return);
7872 for (auto reg : RegisterRange(kDartAvailableCpuRegs)) {
7873 // We expect CODE_REG to be clobbered in JIT mode.
7874 if (!FLAG_precompiled_mode && reg == CODE_REG) continue;
7875
7876 Label ok;
7877 __ CompareImmediate(reg, static_cast<int32_t>(reg));
7878 __ BranchIf(EQ, &ok, Assembler::kNearJump);
7879 __ LoadImmediate(A0, reg);
7880 __ j(&done);
7881 __ Bind(&ok);
7882 }
7883 };
7884
7885 check_all_allocatable_registers_are_preserved_by_call();
7886
7887 FLAG_precompiled_mode = true;
7888 check_all_allocatable_registers_are_preserved_by_call();
7889 FLAG_precompiled_mode = false;
7890
7891 __ LoadImmediate(A0, 42); // 42 is SUCCESS.
7892 __ Bind(&done);
7893 __ PopRegisters(clobbered_regs);
7894 __ PopRegister(RA);
7895 LeaveTestFrame(assembler);
7896 __ Ret();
7897}
7898
7899ASSEMBLER_TEST_RUN(JumpAndLinkPreservesRegisters, test) {
7900 const intptr_t result = test->InvokeWithCodeAndThread<int64_t>();
7901 EXPECT_EQ(42, result);
7902}
7903
7904} // namespace compiler
7905} // namespace dart
7906
7907#endif // defined(TARGET_ARCH_RISCV)
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
Definition: DM.cpp:263
static bool ok(int result)
#define __
static const Code & Generate(const char *name, const std::function< void(compiler::Assembler *assembler)> &generator)
Definition: unit_test.cc:770
static const Register ArgumentRegisters[]
static constexpr Register kReturnReg
static intptr_t data_offset()
Definition: object.h:11136
double CallD(intx_t function, intx_t arg0, intx_t arg1=0)
static Simulator * Current()
intx_t CallI(intx_t function, double arg0, double arg1=0.0)
float CallF(intx_t function, intx_t arg0, intx_t arg1=0)
int64_t Call(int32_t entry, int32_t parameter0, int32_t parameter1, int32_t parameter2, int32_t parameter3, bool fp_return=false, bool fp_args=false)
uint8_t value
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
void LeaveTestFrame(Assembler *assembler)
ASSEMBLER_TEST_GENERATE(InstantiateTypeArgumentsHashKeys, assembler)
void EnterTestFrame(Assembler *assembler)
Definition: dart_vm.cc:33
constexpr int64_t kMaxInt64
Definition: globals.h:486
static constexpr ExtensionSet RV_GCB
constexpr int64_t kMinInt64
Definition: globals.h:485
const Register THR
static Utils::BitsRange< Register > RegisterRange(uint32_t regs)
Definition: constants.h:110
static uint64_t RotateRight(uint64_t value, uint8_t rotate, uint8_t width)
static constexpr Extension RV_Zbc(9)
static constexpr ExtensionSet RV_GC
constexpr int32_t kMinInt32
Definition: globals.h:482
void * malloc(size_t size)
Definition: allocation.cc:19
uint16_t RegList
static const ClassId kLastErrorCid
Definition: class_id.h:311
constexpr uint64_t kMaxUint64
Definition: globals.h:487
constexpr uint32_t kMaxUint32
Definition: globals.h:484
static const ClassId kFirstErrorCid
Definition: class_id.h:310
const Register CODE_REG
static constexpr Extension RV_Zalasr(10)
@ kNoRegister
Definition: constants_arm.h:99
intx_t sign_extend(int32_t x)
constexpr RegList kDartAvailableCpuRegs
ASSEMBLER_TEST_RUN(StoreIntoObject, test)
constexpr int32_t kMaxInt32
Definition: globals.h:483
const Register PP
static int8_t data[kExtLength]
static constexpr ExtensionSet RV_G
static constexpr Color Min(Color c, float threshold)
Definition: color.cc:132
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
sh
Definition: run_sh.py:10
Definition: SkMD5.cpp:120