1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include <iostream>
29 
30 #include "src/base/utils/random-number-generator.h"
31 #include "src/codegen/assembler-inl.h"
32 #include "src/codegen/macro-assembler.h"
33 #include "src/diagnostics/disassembler.h"
34 #include "src/execution/simulator.h"
35 #include "src/heap/factory.h"
36 #include "src/init/v8.h"
37 #include "test/cctest/cctest.h"
38 
39 namespace v8 {
40 namespace internal {
41 
42 // Define these function prototypes to match JSEntryFunction in execution.cc.
43 // TODO(LOONG64): Refine these signatures per test case.
44 using F1 = void*(int x, int p1, int p2, int p3, int p4);
45 using F2 = void*(int x, int y, int p2, int p3, int p4);
46 using F3 = void*(void* p, int p1, int p2, int p3, int p4);
47 using F4 = void*(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4);
48 using F5 = void*(void* p0, void* p1, int p2, int p3, int p4);
49 
50 #define __ assm.
51 // v0->a2, v1->a3
TEST(LA0)52 TEST(LA0) {
53   CcTest::InitializeVM();
54   Isolate* isolate = CcTest::i_isolate();
55   HandleScope scope(isolate);
56 
57   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
58 
59   // Addition.
60   __ addi_d(a2, a0, 0xC);
61 
62   __ or_(a0, a2, zero_reg);
63   __ jirl(zero_reg, ra, 0);
64 
65   CodeDesc desc;
66   assm.GetCode(isolate, &desc);
67   Handle<Code> code =
68       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
69   auto f = GeneratedCode<F2>::FromCode(*code);
70   int64_t res = reinterpret_cast<int64_t>(f.Call(0xAB0, 0, 0, 0, 0));
71   CHECK_EQ(0xABCL, res);
72 }
73 
TEST(LA1)74 TEST(LA1) {
75   CcTest::InitializeVM();
76   Isolate* isolate = CcTest::i_isolate();
77   HandleScope scope(isolate);
78 
79   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
80   Label L, C;
81 
82   __ ori(a1, a0, 0);
83   __ ori(a2, zero_reg, 0);
84   __ b(&C);
85 
86   __ bind(&L);
87   __ add_d(a2, a2, a1);
88   __ addi_d(a1, a1, -1);
89 
90   __ bind(&C);
91   __ ori(a3, a1, 0);
92 
93   __ Branch(&L, ne, a3, Operand((int64_t)0));
94 
95   __ or_(a0, a2, zero_reg);
96   __ or_(a1, a3, zero_reg);
97   __ jirl(zero_reg, ra, 0);
98 
99   CodeDesc desc;
100   assm.GetCode(isolate, &desc);
101   Handle<Code> code =
102       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
103   auto f = GeneratedCode<F1>::FromCode(*code);
104   int64_t res = reinterpret_cast<int64_t>(f.Call(50, 0, 0, 0, 0));
105   CHECK_EQ(1275L, res);
106 }
107 
TEST(LA2)108 TEST(LA2) {
109   CcTest::InitializeVM();
110   Isolate* isolate = CcTest::i_isolate();
111   HandleScope scope(isolate);
112 
113   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
114 
115   Label exit, error;
116 
117   __ ori(a4, zero_reg, 0);  // 00000000
118   __ lu12i_w(a4, 0x12345);  // 12345000
119   __ ori(a4, a4, 0);        // 12345000
120   __ ori(a2, a4, 0xF0F);    // 12345F0F
121   __ Branch(&error, ne, a2, Operand(0x12345F0F));
122 
123   __ ori(a4, zero_reg, 0);
124   __ lu32i_d(a4, 0x12345);  // 1 2345 0000 0000
125   __ ori(a4, a4, 0xFFF);    // 1 2345 0000 0FFF
126   __ addi_d(a2, a4, 1);
127   __ Branch(&error, ne, a2, Operand(0x1234500001000));
128 
129   __ ori(a4, zero_reg, 0);
130   __ lu52i_d(a4, zero_reg, 0x123);  // 1230 0000 0000 0000
131   __ ori(a4, a4, 0xFFF);            // 123F 0000 0000 0FFF
132   __ addi_d(a2, a4, 1);             // 1230 0000 0000 1000
133   __ Branch(&error, ne, a2, Operand(0x1230000000001000));
134 
135   __ li(a2, 0x31415926);
136   __ b(&exit);
137 
138   __ bind(&error);
139   __ li(a2, 0x666);
140 
141   __ bind(&exit);
142   __ or_(a0, a2, zero_reg);
143   __ jirl(zero_reg, ra, 0);
144 
145   CodeDesc desc;
146   assm.GetCode(isolate, &desc);
147   Handle<Code> code =
148       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
149   auto f = GeneratedCode<F2>::FromCode(*code);
150   int64_t res = reinterpret_cast<int64_t>(f.Call(0, 0, 0, 0, 0));
151 
152   CHECK_EQ(0x31415926L, res);
153 }
154 
TEST(LA3)155 TEST(LA3) {
156   // Test 32bit calculate instructions.
157   CcTest::InitializeVM();
158   Isolate* isolate = CcTest::i_isolate();
159   HandleScope scope(isolate);
160   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
161 
162   Label exit, error;
163 
164   __ li(a4, 0x00000004);
165   __ li(a5, 0x00001234);
166   __ li(a6, 0x12345678);
167   __ li(a7, 0x7FFFFFFF);
168   __ li(t0, static_cast<int32_t>(0xFFFFFFFC));
169   __ li(t1, static_cast<int32_t>(0xFFFFEDCC));
170   __ li(t2, static_cast<int32_t>(0xEDCBA988));
171   __ li(t3, static_cast<int32_t>(0x80000000));
172 
173   __ ori(a2, zero_reg, 0);  // 0x00000000
174   __ add_w(a2, a4, a5);     // 0x00001238
175   __ sub_w(a2, a2, a4);     // 0x00001234
176   __ Branch(&error, ne, a2, Operand(0x00001234));
177   __ ori(a3, zero_reg, 0);  // 0x00000000
178   __ add_w(a3, a7, a4);  // 32bit addu result is sign-extended into 64bit reg.
179   __ Branch(&error, ne, a3, Operand(0xFFFFFFFF80000003));
180 
181   __ sub_w(a3, t3, a4);  // 0x7FFFFFFC
182   __ Branch(&error, ne, a3, Operand(0x7FFFFFFC));
183 
184   __ ori(a2, zero_reg, 0);         // 0x00000000
185   __ ori(a3, zero_reg, 0);         // 0x00000000
186   __ addi_w(a2, zero_reg, 0x421);  // 0x00007421
187   __ addi_w(a2, a2, -0x1);         // 0x00007420
188   __ addi_w(a2, a2, -0x20);        // 0x00007400
189   __ Branch(&error, ne, a2, Operand(0x0000400));
190   __ addi_w(a3, a7, 0x1);  // 0x80000000 - result is sign-extended.
191   __ Branch(&error, ne, a3, Operand(0xFFFFFFFF80000000));
192 
193   __ ori(a2, zero_reg, 0);   // 0x00000000
194   __ ori(a3, zero_reg, 0);   // 0x00000000
195   __ alsl_w(a2, a6, a4, 3);  // 0xFFFFFFFF91A2B3C4
196   __ alsl_w(a2, a2, a4, 2);  // 0x468ACF14
197   __ Branch(&error, ne, a2, Operand(0x468acf14));
198   __ ori(a0, zero_reg, 31);
199   __ alsl_wu(a3, a6, a4, 3);  // 0x91A2B3C4
200   __ alsl_wu(a3, a3, a7, 1);  // 0xFFFFFFFFA3456787
201   __ Branch(&error, ne, a3, Operand(0xA3456787));
202 
203   __ ori(a2, zero_reg, 0);
204   __ ori(a3, zero_reg, 0);
205   __ mul_w(a2, a5, a7);
206   __ div_w(a2, a2, a4);
207   __ Branch(&error, ne, a2, Operand(0xFFFFFFFFFFFFFB73));
208   __ mul_w(a3, a4, t1);
209   __ Branch(&error, ne, a3, Operand(0xFFFFFFFFFFFFB730));
210   __ div_w(a3, t3, a4);
211   __ Branch(&error, ne, a3, Operand(0xFFFFFFFFE0000000));
212 
213   __ ori(a2, zero_reg, 0);
214   __ mulh_w(a2, a4, t1);
215   __ Branch(&error, ne, a2, Operand(0xFFFFFFFFFFFFFFFF));
216   __ mulh_w(a2, a4, a6);
217   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
218 
219   __ ori(a2, zero_reg, 0);
220   __ mulh_wu(a2, a4, t1);
221   __ Branch(&error, ne, a2, Operand(0x3));
222   __ mulh_wu(a2, a4, a6);
223   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
224 
225   __ ori(a2, zero_reg, 0);
226   __ mulw_d_w(a2, a4, t1);
227   __ Branch(&error, ne, a2, Operand(0xFFFFFFFFFFFFB730));
228   __ mulw_d_w(a2, a4, a6);
229   __ Branch(&error, ne, a2, Operand(0x48D159E0));
230 
231   __ ori(a2, zero_reg, 0);
232   __ mulw_d_wu(a2, a4, t1);
233   __ Branch(&error, ne, a2, Operand(0x3FFFFB730));  //========0xFFFFB730
234   __ ori(a2, zero_reg, 81);
235   __ mulw_d_wu(a2, a4, a6);
236   __ Branch(&error, ne, a2, Operand(0x48D159E0));
237 
238   __ ori(a2, zero_reg, 0);
239   __ div_wu(a2, a7, a5);
240   __ Branch(&error, ne, a2, Operand(0x70821));
241   __ div_wu(a2, t0, a5);
242   __ Branch(&error, ne, a2, Operand(0xE1042));
243   __ div_wu(a2, t0, t1);
244   __ Branch(&error, ne, a2, Operand(0x1));
245 
246   __ ori(a2, zero_reg, 0);
247   __ mod_w(a2, a6, a5);
248   __ Branch(&error, ne, a2, Operand(0xDA8));
249   __ ori(a2, zero_reg, 0);
250   __ mod_w(a2, t2, a5);
251   __ Branch(&error, ne, a2, Operand(0xFFFFFFFFFFFFF258));
252   __ ori(a2, zero_reg, 0);
253   __ mod_w(a2, t2, t1);
254   __ Branch(&error, ne, a2, Operand(0xFFFFFFFFFFFFF258));
255 
256   __ ori(a2, zero_reg, 0);
257   __ mod_wu(a2, a6, a5);
258   __ Branch(&error, ne, a2, Operand(0xDA8));
259   __ mod_wu(a2, t2, a5);
260   __ Branch(&error, ne, a2, Operand(0xF0));
261   __ mod_wu(a2, t2, t1);
262   __ Branch(&error, ne, a2, Operand(0xFFFFFFFFEDCBA988));
263 
264   __ li(a2, 0x31415926);
265   __ b(&exit);
266 
267   __ bind(&error);
268   __ li(a2, 0x666);
269 
270   __ bind(&exit);
271   __ or_(a0, a2, zero_reg);
272   __ jirl(zero_reg, ra, 0);
273 
274   CodeDesc desc;
275   assm.GetCode(isolate, &desc);
276   Handle<Code> code =
277       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
278   auto f = GeneratedCode<F2>::FromCode(*code);
279   int64_t res = reinterpret_cast<int64_t>(f.Call(0, 0, 0, 0, 0));
280 
281   CHECK_EQ(0x31415926L, res);
282 }
283 
TEST(LA4)284 TEST(LA4) {
285   // Test 64bit calculate instructions.
286   CcTest::InitializeVM();
287   Isolate* isolate = CcTest::i_isolate();
288   HandleScope scope(isolate);
289   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
290 
291   Label exit, error;
292 
293   __ li(a4, 0x17312);
294   __ li(a5, 0x1012131415161718);
295   __ li(a6, 0x51F4B764A26E7412);
296   __ li(a7, 0x7FFFFFFFFFFFFFFF);
297   __ li(t0, static_cast<int64_t>(0xFFFFFFFFFFFFF547));
298   __ li(t1, static_cast<int64_t>(0xDF6B8F35A10E205C));
299   __ li(t2, static_cast<int64_t>(0x81F25A87C4236841));
300   __ li(t3, static_cast<int64_t>(0x8000000000000000));
301 
302   __ ori(a2, zero_reg, 0);
303   __ add_d(a2, a4, a5);
304   __ sub_d(a2, a2, a4);
305   __ Branch(&error, ne, a2, Operand(0x1012131415161718));
306   __ ori(a3, zero_reg, 0);
307   __ add_d(a3, a6, a7);  //溢出
308   __ Branch(&error, ne, a3, Operand(0xd1f4b764a26e7411));
309   __ sub_d(a3, t3, a4);  //溢出
310   __ Branch(&error, ne, a3, Operand(0x7ffffffffffe8cee));
311 
312   __ ori(a2, zero_reg, 0);
313   __ addi_d(a2, a5, 0x412);  //正值
314   __ Branch(&error, ne, a2, Operand(0x1012131415161b2a));
315   __ addi_d(a2, a7, 0x547);  //负值
316   __ Branch(&error, ne, a2, Operand(0x8000000000000546));
317 
318   __ ori(t4, zero_reg, 0);
319   __ addu16i_d(a2, t4, 0x1234);
320   __ Branch(&error, ne, a2, Operand(0x12340000));
321   __ addu16i_d(a2, a2, 0x9876);
322   __ Branch(&error, ne, a2, Operand(0xffffffffaaaa0000));
323 
324   __ ori(a2, zero_reg, 0);
325   __ alsl_d(a2, t2, t0, 3);
326   __ Branch(&error, ne, a2, Operand(0xf92d43e211b374f));
327 
328   __ ori(a2, zero_reg, 0);
329   __ mul_d(a2, a5, a6);
330   __ Branch(&error, ne, a2, Operand(0xdbe6a8729a547fb0));
331   __ mul_d(a2, t0, t1);
332   __ Branch(&error, ne, a2, Operand(0x57ad69f40f870584));
333   __ mul_d(a2, a4, t0);
334   __ Branch(&error, ne, a2, Operand(0xfffffffff07523fe));
335 
336   __ ori(a2, zero_reg, 0);
337   __ mulh_d(a2, a5, a6);
338   __ Branch(&error, ne, a2, Operand(0x52514c6c6b54467));
339   __ mulh_d(a2, t0, t1);
340   __ Branch(&error, ne, a2, Operand(0x15d));
341 
342   __ ori(a2, zero_reg, 0);
343   __ mulh_du(a2, a5, a6);
344   __ Branch(&error, ne, a2, Operand(0x52514c6c6b54467));
345   __ mulh_du(a2, t0, t1);
346   __ Branch(&error, ne, a2, Operand(0xdf6b8f35a10e1700));
347   __ mulh_du(a2, a4, t0);
348   __ Branch(&error, ne, a2, Operand(0x17311));
349 
350   __ ori(a2, zero_reg, 0);
351   __ div_d(a2, a5, a6);
352   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
353   __ div_d(a2, t0, t1);
354   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
355   __ div_d(a2, t1, a4);
356   __ Branch(&error, ne, a2, Operand(0xffffe985f631e6d9));
357 
358   __ ori(a2, zero_reg, 0);
359   __ div_du(a2, a5, a6);
360   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
361   __ div_du(a2, t0, t1);
362   __ Branch(&error, ne, a2, Operand(0x1));
363   __ div_du(a2, t1, a4);
364   __ Branch(&error, ne, a2, Operand(0x9a22ffd3973d));
365 
366   __ ori(a2, zero_reg, 0);
367   __ mod_d(a2, a6, a4);
368   __ Branch(&error, ne, a2, Operand(0x13558));
369   __ mod_d(a2, t2, t0);
370   __ Branch(&error, ne, a2, Operand(0xfffffffffffffb0a));
371   __ mod_d(a2, t1, a4);
372   __ Branch(&error, ne, a2, Operand(0xffffffffffff6a1a));
373 
374   __ ori(a2, zero_reg, 0);
375   __ mod_du(a2, a6, a4);
376   __ Branch(&error, ne, a2, Operand(0x13558));
377   __ mod_du(a2, t2, t0);
378   __ Branch(&error, ne, a2, Operand(0x81f25a87c4236841));
379   __ mod_du(a2, t1, a4);
380   __ Branch(&error, ne, a2, Operand(0x1712));
381 
382   // Everything was correctly executed. Load the expected result.
383   __ li(a2, 0x31415926);
384   __ b(&exit);
385 
386   __ bind(&error);
387   __ li(a2, 0x666);
388   // Got an error. Return a wrong result.
389 
390   __ bind(&exit);
391   __ or_(a0, a2, zero_reg);
392   __ jirl(zero_reg, ra, 0);
393 
394   CodeDesc desc;
395   assm.GetCode(isolate, &desc);
396   Handle<Code> code =
397       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
398   auto f = GeneratedCode<F2>::FromCode(*code);
399   int64_t res = reinterpret_cast<int64_t>(f.Call(0, 0, 0, 0, 0));
400 
401   CHECK_EQ(0x31415926L, res);
402 }
403 
TEST(LA5)404 TEST(LA5) {
405   CcTest::InitializeVM();
406   Isolate* isolate = CcTest::i_isolate();
407   HandleScope scope(isolate);
408   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
409 
410   Label exit, error;
411 
412   __ li(a4, 0x17312);
413   __ li(a5, 0x1012131415161718);
414   __ li(a6, 0x51F4B764A26E7412);
415   __ li(a7, 0x7FFFFFFFFFFFFFFF);
416   __ li(t0, static_cast<int64_t>(0xFFFFFFFFFFFFF547));
417   __ li(t1, static_cast<int64_t>(0xDF6B8F35A10E205C));
418   __ li(t2, static_cast<int64_t>(0x81F25A87C4236841));
419   __ li(t3, static_cast<int64_t>(0x8000000000000000));
420 
421   __ ori(a2, zero_reg, 0);
422   __ slt(a2, a5, a6);
423   __ Branch(&error, ne, a2, Operand(0x1));
424   __ slt(a2, a7, t0);
425   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
426   __ slt(a2, t1, t1);
427   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
428 
429   __ ori(a2, zero_reg, 0);
430   __ sltu(a2, a5, a6);
431   __ Branch(&error, ne, a2, Operand(0x1));
432   __ sltu(a2, a7, t0);
433   __ Branch(&error, ne, a2, Operand(0x1));
434   __ sltu(a2, t1, t1);
435   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
436 
437   __ ori(a2, zero_reg, 0);
438   __ slti(a2, a5, 0x123);
439   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
440   __ slti(a2, t0, 0x123);
441   __ Branch(&error, ne, a2, Operand(0x1));
442 
443   __ ori(a2, zero_reg, 0);
444   __ sltui(a2, a5, 0x123);
445   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
446   __ sltui(a2, t0, 0x123);
447   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
448 
449   __ ori(a2, zero_reg, 0);
450   __ and_(a2, a4, a5);
451   __ Branch(&error, ne, a2, Operand(0x1310));
452   __ and_(a2, a6, a7);
453   __ Branch(&error, ne, a2, Operand(0x51F4B764A26E7412));
454 
455   __ ori(a2, zero_reg, 0);
456   __ or_(a2, t0, t1);
457   __ Branch(&error, ne, a2, Operand(0xfffffffffffff55f));
458   __ or_(a2, t2, t3);
459   __ Branch(&error, ne, a2, Operand(0x81f25a87c4236841));
460 
461   __ ori(a2, zero_reg, 0);
462   __ nor(a2, a4, a5);
463   __ Branch(&error, ne, a2, Operand(0xefedecebeae888e5));
464   __ nor(a2, a6, a7);
465   __ Branch(&error, ne, a2, Operand(0x8000000000000000));
466 
467   __ ori(a2, zero_reg, 0);
468   __ xor_(a2, t0, t1);
469   __ Branch(&error, ne, a2, Operand(0x209470ca5ef1d51b));
470   __ xor_(a2, t2, t3);
471   __ Branch(&error, ne, a2, Operand(0x1f25a87c4236841));
472 
473   __ ori(a2, zero_reg, 0);
474   __ andn(a2, a4, a5);
475   __ Branch(&error, ne, a2, Operand(0x16002));
476   __ andn(a2, a6, a7);
477   __ Branch(&error, ne, a2, Operand(static_cast<int64_t>(0)));
478 
479   __ ori(a2, zero_reg, 0);
480   __ orn(a2, t0, t1);
481   __ Branch(&error, ne, a2, Operand(0xffffffffffffffe7));
482   __ orn(a2, t2, t3);
483   __ Branch(&error, ne, a2, Operand(0xffffffffffffffff));
484 
485   __ ori(a2, zero_reg, 0);
486   __ andi(a2, a4, 0x123);
487   __ Branch(&error, ne, a2, Operand(0x102));
488   __ andi(a2, a6, 0xDCB);
489   __ Branch(&error, ne, a2, Operand(0x402));
490 
491   __ ori(a2, zero_reg, 0);
492   __ xori(a2, t0, 0x123);
493   __ Branch(&error, ne, a2, Operand(0xfffffffffffff464));
494   __ xori(a2, t2, 0xDCB);
495   __ Branch(&error, ne, a2, Operand(0x81f25a87c423658a));
496 
497   // Everything was correctly executed. Load the expected result.
498   __ li(a2, 0x31415926);
499   __ b(&exit);
500 
501   __ bind(&error);
502   // Got an error. Return a wrong result.
503   __ li(a2, 0x666);
504 
505   __ bind(&exit);
506   __ or_(a0, a2, zero_reg);
507   __ jirl(zero_reg, ra, 0);
508 
509   CodeDesc desc;
510   assm.GetCode(isolate, &desc);
511   Handle<Code> code =
512       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
513   auto f = GeneratedCode<F2>::FromCode(*code);
514   int64_t res = reinterpret_cast<int64_t>(f.Call(0, 0, 0, 0, 0));
515 
516   CHECK_EQ(0x31415926L, res);
517 }
518 
TEST(LA6)519 TEST(LA6) {
520   // Test loads and stores instruction.
521   CcTest::InitializeVM();
522   Isolate* isolate = CcTest::i_isolate();
523   HandleScope scope(isolate);
524   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
525 
526   struct T {
527     int64_t si1;
528     int64_t si2;
529     int64_t si3;
530     int64_t result_ld_b_si1;
531     int64_t result_ld_b_si2;
532     int64_t result_ld_h_si1;
533     int64_t result_ld_h_si2;
534     int64_t result_ld_w_si1;
535     int64_t result_ld_w_si2;
536     int64_t result_ld_d_si1;
537     int64_t result_ld_d_si3;
538     int64_t result_ld_bu_si2;
539     int64_t result_ld_hu_si2;
540     int64_t result_ld_wu_si2;
541     int64_t result_st_b;
542     int64_t result_st_h;
543     int64_t result_st_w;
544   };
545   T t;
546 
547   // Ld_b
548   __ Ld_b(a4, MemOperand(a0, offsetof(T, si1)));
549   __ St_d(a4, MemOperand(a0, offsetof(T, result_ld_b_si1)));
550 
551   __ Ld_b(a4, MemOperand(a0, offsetof(T, si2)));
552   __ St_d(a4, MemOperand(a0, offsetof(T, result_ld_b_si2)));
553 
554   // Ld_h
555   __ Ld_h(a5, MemOperand(a0, offsetof(T, si1)));
556   __ St_d(a5, MemOperand(a0, offsetof(T, result_ld_h_si1)));
557 
558   __ Ld_h(a5, MemOperand(a0, offsetof(T, si2)));
559   __ St_d(a5, MemOperand(a0, offsetof(T, result_ld_h_si2)));
560 
561   // Ld_w
562   __ Ld_w(a6, MemOperand(a0, offsetof(T, si1)));
563   __ St_d(a6, MemOperand(a0, offsetof(T, result_ld_w_si1)));
564 
565   __ Ld_w(a6, MemOperand(a0, offsetof(T, si2)));
566   __ St_d(a6, MemOperand(a0, offsetof(T, result_ld_w_si2)));
567 
568   // Ld_d
569   __ Ld_d(a7, MemOperand(a0, offsetof(T, si1)));
570   __ St_d(a7, MemOperand(a0, offsetof(T, result_ld_d_si1)));
571 
572   __ Ld_d(a7, MemOperand(a0, offsetof(T, si3)));
573   __ St_d(a7, MemOperand(a0, offsetof(T, result_ld_d_si3)));
574 
575   // Ld_bu
576   __ Ld_bu(t0, MemOperand(a0, offsetof(T, si2)));
577   __ St_d(t0, MemOperand(a0, offsetof(T, result_ld_bu_si2)));
578 
579   // Ld_hu
580   __ Ld_hu(t1, MemOperand(a0, offsetof(T, si2)));
581   __ St_d(t1, MemOperand(a0, offsetof(T, result_ld_hu_si2)));
582 
583   // Ld_wu
584   __ Ld_wu(t2, MemOperand(a0, offsetof(T, si2)));
585   __ St_d(t2, MemOperand(a0, offsetof(T, result_ld_wu_si2)));
586 
587   // St
588   __ li(t4, 0x11111111);
589 
590   // St_b
591   __ Ld_d(t5, MemOperand(a0, offsetof(T, si3)));
592   __ St_d(t5, MemOperand(a0, offsetof(T, result_st_b)));
593   __ St_b(t4, MemOperand(a0, offsetof(T, result_st_b)));
594 
595   // St_h
596   __ Ld_d(t6, MemOperand(a0, offsetof(T, si3)));
597   __ St_d(t6, MemOperand(a0, offsetof(T, result_st_h)));
598   __ St_h(t4, MemOperand(a0, offsetof(T, result_st_h)));
599 
600   // St_w
601   __ Ld_d(t7, MemOperand(a0, offsetof(T, si3)));
602   __ St_d(t7, MemOperand(a0, offsetof(T, result_st_w)));
603   __ St_w(t4, MemOperand(a0, offsetof(T, result_st_w)));
604 
605   __ jirl(zero_reg, ra, 0);
606 
607   CodeDesc desc;
608   assm.GetCode(isolate, &desc);
609   Handle<Code> code =
610       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
611   auto f = GeneratedCode<F3>::FromCode(*code);
612   t.si1 = 0x11223344;
613   t.si2 = 0x99AABBCC;
614   t.si3 = 0x1122334455667788;
615   f.Call(&t, 0, 0, 0, 0);
616 
617   CHECK_EQ(static_cast<int64_t>(0x44), t.result_ld_b_si1);
618   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFFFFFFFCC), t.result_ld_b_si2);
619 
620   CHECK_EQ(static_cast<int64_t>(0x3344), t.result_ld_h_si1);
621   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFFFFFBBCC), t.result_ld_h_si2);
622 
623   CHECK_EQ(static_cast<int64_t>(0x11223344), t.result_ld_w_si1);
624   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFF99AABBCC), t.result_ld_w_si2);
625 
626   CHECK_EQ(static_cast<int64_t>(0x11223344), t.result_ld_d_si1);
627   CHECK_EQ(static_cast<int64_t>(0x1122334455667788), t.result_ld_d_si3);
628 
629   CHECK_EQ(static_cast<int64_t>(0xCC), t.result_ld_bu_si2);
630   CHECK_EQ(static_cast<int64_t>(0xBBCC), t.result_ld_hu_si2);
631   CHECK_EQ(static_cast<int64_t>(0x99AABBCC), t.result_ld_wu_si2);
632 
633   CHECK_EQ(static_cast<int64_t>(0x1122334455667711), t.result_st_b);
634   CHECK_EQ(static_cast<int64_t>(0x1122334455661111), t.result_st_h);
635   CHECK_EQ(static_cast<int64_t>(0x1122334411111111), t.result_st_w);
636 }
637 
TEST(LA7)638 TEST(LA7) {
639   CcTest::InitializeVM();
640   Isolate* isolate = CcTest::i_isolate();
641   HandleScope scope(isolate);
642   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
643 
644   struct T {
645     int64_t si1;
646     int64_t si2;
647     int64_t si3;
648     int64_t result_ldx_b_si1;
649     int64_t result_ldx_b_si2;
650     int64_t result_ldx_h_si1;
651     int64_t result_ldx_h_si2;
652     int64_t result_ldx_w_si1;
653     int64_t result_ldx_w_si2;
654     int64_t result_ldx_d_si1;
655     int64_t result_ldx_d_si3;
656     int64_t result_ldx_bu_si2;
657     int64_t result_ldx_hu_si2;
658     int64_t result_ldx_wu_si2;
659     int64_t result_stx_b;
660     int64_t result_stx_h;
661     int64_t result_stx_w;
662   };
663   T t;
664 
665   // ldx_b
666   __ li(a2, static_cast<int64_t>(offsetof(T, si1)));
667   __ Ld_b(a4, MemOperand(a0, a2));
668   __ St_d(a4, MemOperand(a0, offsetof(T, result_ldx_b_si1)));
669 
670   __ li(a2, static_cast<int64_t>(offsetof(T, si2)));
671   __ Ld_b(a4, MemOperand(a0, a2));
672   __ St_d(a4, MemOperand(a0, offsetof(T, result_ldx_b_si2)));
673 
674   // ldx_h
675   __ li(a2, static_cast<int64_t>(offsetof(T, si1)));
676   __ Ld_h(a5, MemOperand(a0, a2));
677   __ St_d(a5, MemOperand(a0, offsetof(T, result_ldx_h_si1)));
678 
679   __ li(a2, static_cast<int64_t>(offsetof(T, si2)));
680   __ Ld_h(a5, MemOperand(a0, a2));
681   __ St_d(a5, MemOperand(a0, offsetof(T, result_ldx_h_si2)));
682 
683   // ldx_w
684   __ li(a2, static_cast<int64_t>(offsetof(T, si1)));
685   __ Ld_w(a6, MemOperand(a0, a2));
686   __ St_d(a6, MemOperand(a0, offsetof(T, result_ldx_w_si1)));
687 
688   __ li(a2, static_cast<int64_t>(offsetof(T, si2)));
689   __ Ld_w(a6, MemOperand(a0, a2));
690   __ St_d(a6, MemOperand(a0, offsetof(T, result_ldx_w_si2)));
691 
692   // Ld_d
693   __ li(a2, static_cast<int64_t>(offsetof(T, si1)));
694   __ Ld_d(a7, MemOperand(a0, a2));
695   __ St_d(a7, MemOperand(a0, offsetof(T, result_ldx_d_si1)));
696 
697   __ li(a2, static_cast<int64_t>(offsetof(T, si3)));
698   __ Ld_d(a7, MemOperand(a0, a2));
699   __ St_d(a7, MemOperand(a0, offsetof(T, result_ldx_d_si3)));
700 
701   // Ld_bu
702   __ li(a2, static_cast<int64_t>(offsetof(T, si2)));
703   __ Ld_bu(t0, MemOperand(a0, a2));
704   __ St_d(t0, MemOperand(a0, offsetof(T, result_ldx_bu_si2)));
705 
706   // Ld_hu
707   __ li(a2, static_cast<int64_t>(offsetof(T, si2)));
708   __ Ld_hu(t1, MemOperand(a0, a2));
709   __ St_d(t1, MemOperand(a0, offsetof(T, result_ldx_hu_si2)));
710 
711   // Ld_wu
712   __ li(a2, static_cast<int64_t>(offsetof(T, si2)));
713   __ Ld_wu(t2, MemOperand(a0, a2));
714   __ St_d(t2, MemOperand(a0, offsetof(T, result_ldx_wu_si2)));
715 
716   // St
717   __ li(t4, 0x11111111);
718 
719   // St_b
720   __ Ld_d(t5, MemOperand(a0, offsetof(T, si3)));
721   __ St_d(t5, MemOperand(a0, offsetof(T, result_stx_b)));
722   __ li(a2, static_cast<int64_t>(offsetof(T, result_stx_b)));
723   __ St_b(t4, MemOperand(a0, a2));
724 
725   // St_h
726   __ Ld_d(t6, MemOperand(a0, offsetof(T, si3)));
727   __ St_d(t6, MemOperand(a0, offsetof(T, result_stx_h)));
728   __ li(a2, static_cast<int64_t>(offsetof(T, result_stx_h)));
729   __ St_h(t4, MemOperand(a0, a2));
730 
731   // St_w
732   __ Ld_d(t7, MemOperand(a0, offsetof(T, si3)));
733   __ li(a2, static_cast<int64_t>(offsetof(T, result_stx_w)));
734   __ St_d(t7, MemOperand(a0, a2));
735   __ li(a3, static_cast<int64_t>(offsetof(T, result_stx_w)));
736   __ St_w(t4, MemOperand(a0, a3));
737 
738   __ jirl(zero_reg, ra, 0);
739 
740   CodeDesc desc;
741   assm.GetCode(isolate, &desc);
742   Handle<Code> code =
743       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
744   auto f = GeneratedCode<F3>::FromCode(*code);
745   t.si1 = 0x11223344;
746   t.si2 = 0x99AABBCC;
747   t.si3 = 0x1122334455667788;
748   f.Call(&t, 0, 0, 0, 0);
749 
750   CHECK_EQ(static_cast<int64_t>(0x44), t.result_ldx_b_si1);
751   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFFFFFFFCC), t.result_ldx_b_si2);
752 
753   CHECK_EQ(static_cast<int64_t>(0x3344), t.result_ldx_h_si1);
754   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFFFFFBBCC), t.result_ldx_h_si2);
755 
756   CHECK_EQ(static_cast<int64_t>(0x11223344), t.result_ldx_w_si1);
757   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFF99AABBCC), t.result_ldx_w_si2);
758 
759   CHECK_EQ(static_cast<int64_t>(0x11223344), t.result_ldx_d_si1);
760   CHECK_EQ(static_cast<int64_t>(0x1122334455667788), t.result_ldx_d_si3);
761 
762   CHECK_EQ(static_cast<int64_t>(0xCC), t.result_ldx_bu_si2);
763   CHECK_EQ(static_cast<int64_t>(0xBBCC), t.result_ldx_hu_si2);
764   CHECK_EQ(static_cast<int64_t>(0x99AABBCC), t.result_ldx_wu_si2);
765 
766   CHECK_EQ(static_cast<int64_t>(0x1122334455667711), t.result_stx_b);
767   CHECK_EQ(static_cast<int64_t>(0x1122334455661111), t.result_stx_h);
768   CHECK_EQ(static_cast<int64_t>(0x1122334411111111), t.result_stx_w);
769 }
770 
TEST(LDPTR_STPTR)771 TEST(LDPTR_STPTR) {
772   CcTest::InitializeVM();
773   Isolate* isolate = CcTest::i_isolate();
774   HandleScope scope(isolate);
775   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
776 
777   int64_t test[10];
778 
779   __ ldptr_w(a4, a0, 0);
780   __ stptr_d(a4, a0, 24);  // test[3]
781 
782   __ ldptr_w(a5, a0, 8);   // test[1]
783   __ stptr_d(a5, a0, 32);  // test[4]
784 
785   __ ldptr_d(a6, a0, 16);  // test[2]
786   __ stptr_d(a6, a0, 40);  // test[5]
787 
788   __ li(t0, 0x11111111);
789 
790   __ stptr_d(a6, a0, 48);  // test[6]
791   __ stptr_w(t0, a0, 48);  // test[6]
792 
793   __ jirl(zero_reg, ra, 0);
794 
795   CodeDesc desc;
796   assm.GetCode(isolate, &desc);
797   Handle<Code> code =
798       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
799   auto f = GeneratedCode<F3>::FromCode(*code);
800   test[0] = 0x11223344;
801   test[1] = 0x99AABBCC;
802   test[2] = 0x1122334455667788;
803   f.Call(&test, 0, 0, 0, 0);
804 
805   CHECK_EQ(static_cast<int64_t>(0x11223344), test[3]);
806   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFF99AABBCC), test[4]);
807   CHECK_EQ(static_cast<int64_t>(0x1122334455667788), test[5]);
808   CHECK_EQ(static_cast<int64_t>(0x1122334411111111), test[6]);
809 }
810 
TEST(LA8)811 TEST(LA8) {
812   // Test 32bit shift instructions.
813   CcTest::InitializeVM();
814   Isolate* isolate = CcTest::i_isolate();
815   HandleScope scope(isolate);
816 
817   struct T {
818     int32_t input;
819     int32_t result_sll_w_0;
820     int32_t result_sll_w_8;
821     int32_t result_sll_w_10;
822     int32_t result_sll_w_31;
823     int32_t result_srl_w_0;
824     int32_t result_srl_w_8;
825     int32_t result_srl_w_10;
826     int32_t result_srl_w_31;
827     int32_t result_sra_w_0;
828     int32_t result_sra_w_8;
829     int32_t result_sra_w_10;
830     int32_t result_sra_w_31;
831     int32_t result_rotr_w_0;
832     int32_t result_rotr_w_8;
833     int32_t result_slli_w_0;
834     int32_t result_slli_w_8;
835     int32_t result_slli_w_10;
836     int32_t result_slli_w_31;
837     int32_t result_srli_w_0;
838     int32_t result_srli_w_8;
839     int32_t result_srli_w_10;
840     int32_t result_srli_w_31;
841     int32_t result_srai_w_0;
842     int32_t result_srai_w_8;
843     int32_t result_srai_w_10;
844     int32_t result_srai_w_31;
845     int32_t result_rotri_w_0;
846     int32_t result_rotri_w_8;
847     int32_t result_rotri_w_10;
848     int32_t result_rotri_w_31;
849   };
850   T t;
851   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
852 
853   __ Ld_w(a4, MemOperand(a0, offsetof(T, input)));
854 
855   // sll_w
856   __ li(a5, 0);
857   __ sll_w(t0, a4, a5);
858   __ li(a5, 0x8);
859   __ sll_w(t1, a4, a5);
860   __ li(a5, 0xA);
861   __ sll_w(t2, a4, a5);
862   __ li(a5, 0x1F);
863   __ sll_w(t3, a4, a5);
864 
865   __ St_w(t0, MemOperand(a0, offsetof(T, result_sll_w_0)));
866   __ St_w(t1, MemOperand(a0, offsetof(T, result_sll_w_8)));
867   __ St_w(t2, MemOperand(a0, offsetof(T, result_sll_w_10)));
868   __ St_w(t3, MemOperand(a0, offsetof(T, result_sll_w_31)));
869 
870   // srl_w
871   __ li(a5, 0x0);
872   __ srl_w(t0, a4, a5);
873   __ li(a5, 0x8);
874   __ srl_w(t1, a4, a5);
875   __ li(a5, 0xA);
876   __ srl_w(t2, a4, a5);
877   __ li(a5, 0x1F);
878   __ srl_w(t3, a4, a5);
879 
880   __ St_w(t0, MemOperand(a0, offsetof(T, result_srl_w_0)));
881   __ St_w(t1, MemOperand(a0, offsetof(T, result_srl_w_8)));
882   __ St_w(t2, MemOperand(a0, offsetof(T, result_srl_w_10)));
883   __ St_w(t3, MemOperand(a0, offsetof(T, result_srl_w_31)));
884 
885   // sra_w
886   __ li(a5, 0x0);
887   __ sra_w(t0, a4, a5);
888   __ li(a5, 0x8);
889   __ sra_w(t1, a4, a5);
890 
891   __ li(a6, static_cast<int32_t>(0x80000000));
892   __ add_w(a6, a6, a4);
893   __ li(a5, 0xA);
894   __ sra_w(t2, a6, a5);
895   __ li(a5, 0x1F);
896   __ sra_w(t3, a6, a5);
897 
898   __ St_w(t0, MemOperand(a0, offsetof(T, result_sra_w_0)));
899   __ St_w(t1, MemOperand(a0, offsetof(T, result_sra_w_8)));
900   __ St_w(t2, MemOperand(a0, offsetof(T, result_sra_w_10)));
901   __ St_w(t3, MemOperand(a0, offsetof(T, result_sra_w_31)));
902 
903   // rotr
904   __ li(a5, 0x0);
905   __ rotr_w(t0, a4, a5);
906   __ li(a6, 0x8);
907   __ rotr_w(t1, a4, a6);
908 
909   __ St_w(t0, MemOperand(a0, offsetof(T, result_rotr_w_0)));
910   __ St_w(t1, MemOperand(a0, offsetof(T, result_rotr_w_8)));
911 
912   // slli_w
913   __ slli_w(t0, a4, 0);
914   __ slli_w(t1, a4, 0x8);
915   __ slli_w(t2, a4, 0xA);
916   __ slli_w(t3, a4, 0x1F);
917 
918   __ St_w(t0, MemOperand(a0, offsetof(T, result_slli_w_0)));
919   __ St_w(t1, MemOperand(a0, offsetof(T, result_slli_w_8)));
920   __ St_w(t2, MemOperand(a0, offsetof(T, result_slli_w_10)));
921   __ St_w(t3, MemOperand(a0, offsetof(T, result_slli_w_31)));
922 
923   // srli_w
924   __ srli_w(t0, a4, 0);
925   __ srli_w(t1, a4, 0x8);
926   __ srli_w(t2, a4, 0xA);
927   __ srli_w(t3, a4, 0x1F);
928 
929   __ St_w(t0, MemOperand(a0, offsetof(T, result_srli_w_0)));
930   __ St_w(t1, MemOperand(a0, offsetof(T, result_srli_w_8)));
931   __ St_w(t2, MemOperand(a0, offsetof(T, result_srli_w_10)));
932   __ St_w(t3, MemOperand(a0, offsetof(T, result_srli_w_31)));
933 
934   // srai_w
935   __ srai_w(t0, a4, 0);
936   __ srai_w(t1, a4, 0x8);
937 
938   __ li(a6, static_cast<int32_t>(0x80000000));
939   __ add_w(a6, a6, a4);
940   __ srai_w(t2, a6, 0xA);
941   __ srai_w(t3, a6, 0x1F);
942 
943   __ St_w(t0, MemOperand(a0, offsetof(T, result_srai_w_0)));
944   __ St_w(t1, MemOperand(a0, offsetof(T, result_srai_w_8)));
945   __ St_w(t2, MemOperand(a0, offsetof(T, result_srai_w_10)));
946   __ St_w(t3, MemOperand(a0, offsetof(T, result_srai_w_31)));
947 
948   // rotri_w
949   __ rotri_w(t0, a4, 0);
950   __ rotri_w(t1, a4, 0x8);
951   __ rotri_w(t2, a4, 0xA);
952   __ rotri_w(t3, a4, 0x1F);
953 
954   __ St_w(t0, MemOperand(a0, offsetof(T, result_rotri_w_0)));
955   __ St_w(t1, MemOperand(a0, offsetof(T, result_rotri_w_8)));
956   __ St_w(t2, MemOperand(a0, offsetof(T, result_rotri_w_10)));
957   __ St_w(t3, MemOperand(a0, offsetof(T, result_rotri_w_31)));
958 
959   __ jirl(zero_reg, ra, 0);
960 
961   CodeDesc desc;
962   assm.GetCode(isolate, &desc);
963   Handle<Code> code =
964       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
965   auto f = GeneratedCode<F3>::FromCode(*code);
966   t.input = 0x12345678;
967   f.Call(&t, 0x0, 0, 0, 0);
968 
969   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_sll_w_0);
970   CHECK_EQ(static_cast<int32_t>(0x34567800), t.result_sll_w_8);
971   CHECK_EQ(static_cast<int32_t>(0xD159E000), t.result_sll_w_10);
972   CHECK_EQ(static_cast<int32_t>(0x0), t.result_sll_w_31);
973 
974   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_srl_w_0);
975   CHECK_EQ(static_cast<int32_t>(0x123456), t.result_srl_w_8);
976   CHECK_EQ(static_cast<int32_t>(0x48D15), t.result_srl_w_10);
977   CHECK_EQ(static_cast<int32_t>(0x0), t.result_srl_w_31);
978 
979   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_sra_w_0);
980   CHECK_EQ(static_cast<int32_t>(0x123456), t.result_sra_w_8);
981   CHECK_EQ(static_cast<int32_t>(0xFFE48D15), t.result_sra_w_10);
982   CHECK_EQ(static_cast<int32_t>(0xFFFFFFFF), t.result_sra_w_31);
983 
984   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_rotr_w_0);
985   CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotr_w_8);
986 
987   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_slli_w_0);
988   CHECK_EQ(static_cast<int32_t>(0x34567800), t.result_slli_w_8);
989   CHECK_EQ(static_cast<int32_t>(0xD159E000), t.result_slli_w_10);
990   CHECK_EQ(static_cast<int32_t>(0x0), t.result_slli_w_31);
991 
992   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_srli_w_0);
993   CHECK_EQ(static_cast<int32_t>(0x123456), t.result_srli_w_8);
994   CHECK_EQ(static_cast<int32_t>(0x48D15), t.result_srli_w_10);
995   CHECK_EQ(static_cast<int32_t>(0x0), t.result_srli_w_31);
996 
997   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_srai_w_0);
998   CHECK_EQ(static_cast<int32_t>(0x123456), t.result_srai_w_8);
999   CHECK_EQ(static_cast<int32_t>(0xFFE48D15), t.result_srai_w_10);
1000   CHECK_EQ(static_cast<int32_t>(0xFFFFFFFF), t.result_srai_w_31);
1001 
1002   CHECK_EQ(static_cast<int32_t>(0x12345678), t.result_rotri_w_0);
1003   CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotri_w_8);
1004   CHECK_EQ(static_cast<int32_t>(0x9E048D15), t.result_rotri_w_10);
1005   CHECK_EQ(static_cast<int32_t>(0x2468ACF0), t.result_rotri_w_31);
1006 }
1007 
TEST(LA9)1008 TEST(LA9) {
1009   // Test 64bit shift instructions.
1010   CcTest::InitializeVM();
1011   Isolate* isolate = CcTest::i_isolate();
1012   HandleScope scope(isolate);
1013 
1014   struct T {
1015     int64_t input;
1016     int64_t result_sll_d_0;
1017     int64_t result_sll_d_13;
1018     int64_t result_sll_d_30;
1019     int64_t result_sll_d_63;
1020     int64_t result_srl_d_0;
1021     int64_t result_srl_d_13;
1022     int64_t result_srl_d_30;
1023     int64_t result_srl_d_63;
1024     int64_t result_sra_d_0;
1025     int64_t result_sra_d_13;
1026     int64_t result_sra_d_30;
1027     int64_t result_sra_d_63;
1028     int64_t result_rotr_d_0;
1029     int64_t result_rotr_d_13;
1030     int64_t result_slli_d_0;
1031     int64_t result_slli_d_13;
1032     int64_t result_slli_d_30;
1033     int64_t result_slli_d_63;
1034     int64_t result_srli_d_0;
1035     int64_t result_srli_d_13;
1036     int64_t result_srli_d_30;
1037     int64_t result_srli_d_63;
1038     int64_t result_srai_d_0;
1039     int64_t result_srai_d_13;
1040     int64_t result_srai_d_30;
1041     int64_t result_srai_d_63;
1042     int64_t result_rotri_d_0;
1043     int64_t result_rotri_d_13;
1044     int64_t result_rotri_d_30;
1045     int64_t result_rotri_d_63;
1046   };
1047 
1048   T t;
1049   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1050 
1051   __ Ld_d(a4, MemOperand(a0, offsetof(T, input)));
1052 
1053   // sll_d
1054   __ li(a5, 0);
1055   __ sll_d(t0, a4, a5);
1056   __ li(a5, 0xD);
1057   __ sll_d(t1, a4, a5);
1058   __ li(a5, 0x1E);
1059   __ sll_d(t2, a4, a5);
1060   __ li(a5, 0x3F);
1061   __ sll_d(t3, a4, a5);
1062 
1063   __ St_d(t0, MemOperand(a0, offsetof(T, result_sll_d_0)));
1064   __ St_d(t1, MemOperand(a0, offsetof(T, result_sll_d_13)));
1065   __ St_d(t2, MemOperand(a0, offsetof(T, result_sll_d_30)));
1066   __ St_d(t3, MemOperand(a0, offsetof(T, result_sll_d_63)));
1067 
1068   // srl_d
1069   __ li(a5, 0x0);
1070   __ srl_d(t0, a4, a5);
1071   __ li(a5, 0xD);
1072   __ srl_d(t1, a4, a5);
1073   __ li(a5, 0x1E);
1074   __ srl_d(t2, a4, a5);
1075   __ li(a5, 0x3F);
1076   __ srl_d(t3, a4, a5);
1077 
1078   __ St_d(t0, MemOperand(a0, offsetof(T, result_srl_d_0)));
1079   __ St_d(t1, MemOperand(a0, offsetof(T, result_srl_d_13)));
1080   __ St_d(t2, MemOperand(a0, offsetof(T, result_srl_d_30)));
1081   __ St_d(t3, MemOperand(a0, offsetof(T, result_srl_d_63)));
1082 
1083   // sra_d
1084   __ li(a5, 0x0);
1085   __ sra_d(t0, a4, a5);
1086   __ li(a5, 0xD);
1087   __ sra_d(t1, a4, a5);
1088 
1089   __ li(a6, static_cast<int64_t>(0x8000000000000000));
1090   __ add_d(a6, a6, a4);
1091   __ li(a5, 0x1E);
1092   __ sra_d(t2, a6, a5);
1093   __ li(a5, 0x3F);
1094   __ sra_d(t3, a6, a5);
1095 
1096   __ St_d(t0, MemOperand(a0, offsetof(T, result_sra_d_0)));
1097   __ St_d(t1, MemOperand(a0, offsetof(T, result_sra_d_13)));
1098   __ St_d(t2, MemOperand(a0, offsetof(T, result_sra_d_30)));
1099   __ St_d(t3, MemOperand(a0, offsetof(T, result_sra_d_63)));
1100 
1101   // rotr
1102   __ li(a5, 0x0);
1103   __ rotr_d(t0, a4, a5);
1104   __ li(a6, 0xD);
1105   __ rotr_d(t1, a4, a6);
1106 
1107   __ St_d(t0, MemOperand(a0, offsetof(T, result_rotr_d_0)));
1108   __ St_d(t1, MemOperand(a0, offsetof(T, result_rotr_d_13)));
1109 
1110   // slli_d
1111   __ slli_d(t0, a4, 0);
1112   __ slli_d(t1, a4, 0xD);
1113   __ slli_d(t2, a4, 0x1E);
1114   __ slli_d(t3, a4, 0x3F);
1115 
1116   __ St_d(t0, MemOperand(a0, offsetof(T, result_slli_d_0)));
1117   __ St_d(t1, MemOperand(a0, offsetof(T, result_slli_d_13)));
1118   __ St_d(t2, MemOperand(a0, offsetof(T, result_slli_d_30)));
1119   __ St_d(t3, MemOperand(a0, offsetof(T, result_slli_d_63)));
1120 
1121   // srli_d
1122   __ srli_d(t0, a4, 0);
1123   __ srli_d(t1, a4, 0xD);
1124   __ srli_d(t2, a4, 0x1E);
1125   __ srli_d(t3, a4, 0x3F);
1126 
1127   __ St_d(t0, MemOperand(a0, offsetof(T, result_srli_d_0)));
1128   __ St_d(t1, MemOperand(a0, offsetof(T, result_srli_d_13)));
1129   __ St_d(t2, MemOperand(a0, offsetof(T, result_srli_d_30)));
1130   __ St_d(t3, MemOperand(a0, offsetof(T, result_srli_d_63)));
1131 
1132   // srai_d
1133   __ srai_d(t0, a4, 0);
1134   __ srai_d(t1, a4, 0xD);
1135 
1136   __ li(a6, static_cast<int64_t>(0x8000000000000000));
1137   __ add_d(a6, a6, a4);
1138   __ srai_d(t2, a6, 0x1E);
1139   __ srai_d(t3, a6, 0x3F);
1140 
1141   __ St_d(t0, MemOperand(a0, offsetof(T, result_srai_d_0)));
1142   __ St_d(t1, MemOperand(a0, offsetof(T, result_srai_d_13)));
1143   __ St_d(t2, MemOperand(a0, offsetof(T, result_srai_d_30)));
1144   __ St_d(t3, MemOperand(a0, offsetof(T, result_srai_d_63)));
1145 
1146   // rotri_d
1147   __ rotri_d(t0, a4, 0);
1148   __ rotri_d(t1, a4, 0xD);
1149   __ rotri_d(t2, a4, 0x1E);
1150   __ rotri_d(t3, a4, 0x3F);
1151 
1152   __ St_d(t0, MemOperand(a0, offsetof(T, result_rotri_d_0)));
1153   __ St_d(t1, MemOperand(a0, offsetof(T, result_rotri_d_13)));
1154   __ St_d(t2, MemOperand(a0, offsetof(T, result_rotri_d_30)));
1155   __ St_d(t3, MemOperand(a0, offsetof(T, result_rotri_d_63)));
1156 
1157   __ jirl(zero_reg, ra, 0);
1158 
1159   CodeDesc desc;
1160   assm.GetCode(isolate, &desc);
1161   Handle<Code> code =
1162       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1163   auto f = GeneratedCode<F3>::FromCode(*code);
1164   t.input = 0x51F4B764A26E7412;
1165   f.Call(&t, 0, 0, 0, 0);
1166 
1167   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_sll_d_0);
1168   CHECK_EQ(static_cast<int64_t>(0x96ec944dce824000), t.result_sll_d_13);
1169   CHECK_EQ(static_cast<int64_t>(0x289b9d0480000000), t.result_sll_d_30);
1170   CHECK_EQ(static_cast<int64_t>(0x0), t.result_sll_d_63);
1171 
1172   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_srl_d_0);
1173   CHECK_EQ(static_cast<int64_t>(0x28fa5bb251373), t.result_srl_d_13);
1174   CHECK_EQ(static_cast<int64_t>(0x147d2dd92), t.result_srl_d_30);
1175   CHECK_EQ(static_cast<int64_t>(0x0), t.result_srl_d_63);
1176 
1177   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_sra_d_0);
1178   CHECK_EQ(static_cast<int64_t>(0x28fa5bb251373), t.result_sra_d_13);
1179   CHECK_EQ(static_cast<int64_t>(0xffffffff47d2dd92), t.result_sra_d_30);
1180   CHECK_EQ(static_cast<int64_t>(0xffffffffffffffff), t.result_sra_d_63);
1181 
1182   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_rotr_d_0);
1183   CHECK_EQ(static_cast<int64_t>(0xa0928fa5bb251373), t.result_rotr_d_13);
1184 
1185   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_slli_d_0);
1186   CHECK_EQ(static_cast<int64_t>(0x96ec944dce824000), t.result_slli_d_13);
1187   CHECK_EQ(static_cast<int64_t>(0x289b9d0480000000), t.result_slli_d_30);
1188   CHECK_EQ(static_cast<int64_t>(0x0), t.result_slli_d_63);
1189 
1190   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_srli_d_0);
1191   CHECK_EQ(static_cast<int64_t>(0x28fa5bb251373), t.result_srli_d_13);
1192   CHECK_EQ(static_cast<int64_t>(0x147d2dd92), t.result_srli_d_30);
1193   CHECK_EQ(static_cast<int64_t>(0x0), t.result_srli_d_63);
1194 
1195   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_srai_d_0);
1196   CHECK_EQ(static_cast<int64_t>(0x28fa5bb251373), t.result_srai_d_13);
1197   CHECK_EQ(static_cast<int64_t>(0xffffffff47d2dd92), t.result_srai_d_30);
1198   CHECK_EQ(static_cast<int64_t>(0xffffffffffffffff), t.result_srai_d_63);
1199 
1200   CHECK_EQ(static_cast<int64_t>(0x51f4b764a26e7412), t.result_rotri_d_0);
1201   CHECK_EQ(static_cast<int64_t>(0xa0928fa5bb251373), t.result_rotri_d_13);
1202   CHECK_EQ(static_cast<int64_t>(0x89b9d04947d2dd92), t.result_rotri_d_30);
1203   CHECK_EQ(static_cast<int64_t>(0xa3e96ec944dce824), t.result_rotri_d_63);
1204 }
1205 
TEST(LA10)1206 TEST(LA10) {
1207   // Test 32bit bit operation instructions.
1208   CcTest::InitializeVM();
1209   Isolate* isolate = CcTest::i_isolate();
1210   HandleScope scope(isolate);
1211   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1212 
1213   struct T {
1214     int64_t si1;
1215     int64_t si2;
1216     int32_t result_ext_w_b_si1;
1217     int32_t result_ext_w_b_si2;
1218     int32_t result_ext_w_h_si1;
1219     int32_t result_ext_w_h_si2;
1220     int32_t result_clo_w_si1;
1221     int32_t result_clo_w_si2;
1222     int32_t result_clz_w_si1;
1223     int32_t result_clz_w_si2;
1224     int32_t result_cto_w_si1;
1225     int32_t result_cto_w_si2;
1226     int32_t result_ctz_w_si1;
1227     int32_t result_ctz_w_si2;
1228     int32_t result_bytepick_w_si1;
1229     int32_t result_bytepick_w_si2;
1230     int32_t result_revb_2h_si1;
1231     int32_t result_revb_2h_si2;
1232     int32_t result_bitrev_4b_si1;
1233     int32_t result_bitrev_4b_si2;
1234     int32_t result_bitrev_w_si1;
1235     int32_t result_bitrev_w_si2;
1236     int32_t result_bstrins_w_si1;
1237     int32_t result_bstrins_w_si2;
1238     int32_t result_bstrpick_w_si1;
1239     int32_t result_bstrpick_w_si2;
1240   };
1241   T t;
1242 
1243   __ Ld_d(a4, MemOperand(a0, offsetof(T, si1)));
1244   __ Ld_d(a5, MemOperand(a0, offsetof(T, si2)));
1245 
1246   // ext_w_b
1247   __ ext_w_b(t0, a4);
1248   __ ext_w_b(t1, a5);
1249   __ St_w(t0, MemOperand(a0, offsetof(T, result_ext_w_b_si1)));
1250   __ St_w(t1, MemOperand(a0, offsetof(T, result_ext_w_b_si2)));
1251 
1252   // ext_w_h
1253   __ ext_w_h(t0, a4);
1254   __ ext_w_h(t1, a5);
1255   __ St_w(t0, MemOperand(a0, offsetof(T, result_ext_w_h_si1)));
1256   __ St_w(t1, MemOperand(a0, offsetof(T, result_ext_w_h_si2)));
1257 
1258   /*    //clo_w
1259     __ clo_w(t0, a4);
1260     __ clo_w(t1, a5);
1261     __ St_w(t0, MemOperand(a0, offsetof(T, result_clo_w_si1)));
1262     __ St_w(t1, MemOperand(a0, offsetof(T, result_clo_w_si2)));*/
1263 
1264   // clz_w
1265   __ clz_w(t0, a4);
1266   __ clz_w(t1, a5);
1267   __ St_w(t0, MemOperand(a0, offsetof(T, result_clz_w_si1)));
1268   __ St_w(t1, MemOperand(a0, offsetof(T, result_clz_w_si2)));
1269 
1270   /*    //cto_w
1271     __ cto_w(t0, a4);
1272     __ cto_w(t1, a5);
1273     __ St_w(t0, MemOperand(a0, offsetof(T, result_cto_w_si1)));
1274     __ St_w(t1, MemOperand(a0, offsetof(T, result_cto_w_si2)));*/
1275 
1276   // ctz_w
1277   __ ctz_w(t0, a4);
1278   __ ctz_w(t1, a5);
1279   __ St_w(t0, MemOperand(a0, offsetof(T, result_ctz_w_si1)));
1280   __ St_w(t1, MemOperand(a0, offsetof(T, result_ctz_w_si2)));
1281 
1282   // bytepick_w
1283   __ bytepick_w(t0, a4, a5, 0);
1284   __ bytepick_w(t1, a5, a4, 2);
1285   __ St_w(t0, MemOperand(a0, offsetof(T, result_bytepick_w_si1)));
1286   __ St_w(t1, MemOperand(a0, offsetof(T, result_bytepick_w_si2)));
1287 
1288   // revb_2h
1289   __ revb_2h(t0, a4);
1290   __ revb_2h(t1, a5);
1291   __ St_w(t0, MemOperand(a0, offsetof(T, result_revb_2h_si1)));
1292   __ St_w(t1, MemOperand(a0, offsetof(T, result_revb_2h_si2)));
1293 
1294   // bitrev
1295   __ bitrev_4b(t0, a4);
1296   __ bitrev_4b(t1, a5);
1297   __ St_w(t0, MemOperand(a0, offsetof(T, result_bitrev_4b_si1)));
1298   __ St_w(t1, MemOperand(a0, offsetof(T, result_bitrev_4b_si2)));
1299 
1300   // bitrev_w
1301   __ bitrev_w(t0, a4);
1302   __ bitrev_w(t1, a5);
1303   __ St_w(t0, MemOperand(a0, offsetof(T, result_bitrev_w_si1)));
1304   __ St_w(t1, MemOperand(a0, offsetof(T, result_bitrev_w_si2)));
1305 
1306   // bstrins
1307   __ or_(t0, zero_reg, zero_reg);
1308   __ or_(t1, zero_reg, zero_reg);
1309   __ bstrins_w(t0, a4, 0xD, 0x4);
1310   __ bstrins_w(t1, a5, 0x16, 0x5);
1311   __ St_w(t0, MemOperand(a0, offsetof(T, result_bstrins_w_si1)));
1312   __ St_w(t1, MemOperand(a0, offsetof(T, result_bstrins_w_si2)));
1313 
1314   // bstrpick
1315   __ or_(t0, zero_reg, zero_reg);
1316   __ or_(t1, zero_reg, zero_reg);
1317   __ bstrpick_w(t0, a4, 0xD, 0x4);
1318   __ bstrpick_w(t1, a5, 0x16, 0x5);
1319   __ St_w(t0, MemOperand(a0, offsetof(T, result_bstrpick_w_si1)));
1320   __ St_w(t1, MemOperand(a0, offsetof(T, result_bstrpick_w_si2)));
1321 
1322   __ jirl(zero_reg, ra, 0);
1323 
1324   CodeDesc desc;
1325   assm.GetCode(isolate, &desc);
1326   Handle<Code> code =
1327       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1328   auto f = GeneratedCode<F3>::FromCode(*code);
1329   t.si1 = 0x51F4B764A26E7412;
1330   t.si2 = 0x81F25A87C423B891;
1331   f.Call(&t, 0, 0, 0, 0);
1332 
1333   CHECK_EQ(static_cast<int32_t>(0x12), t.result_ext_w_b_si1);
1334   CHECK_EQ(static_cast<int32_t>(0xffffff91), t.result_ext_w_b_si2);
1335   CHECK_EQ(static_cast<int32_t>(0x7412), t.result_ext_w_h_si1);
1336   CHECK_EQ(static_cast<int32_t>(0xffffb891), t.result_ext_w_h_si2);
1337   //    CHECK_EQ(static_cast<int32_t>(0x1), t.result_clo_w_si1);
1338   //    CHECK_EQ(static_cast<int32_t>(0x2), t.result_clo_w_si2);
1339   CHECK_EQ(static_cast<int32_t>(0x0), t.result_clz_w_si1);
1340   CHECK_EQ(static_cast<int32_t>(0x0), t.result_clz_w_si2);
1341   //    CHECK_EQ(static_cast<int32_t>(0x0), t.result_cto_w_si1);
1342   //    CHECK_EQ(static_cast<int32_t>(0x1), t.result_cto_w_si2);
1343   CHECK_EQ(static_cast<int32_t>(0x1), t.result_ctz_w_si1);
1344   CHECK_EQ(static_cast<int32_t>(0x0), t.result_ctz_w_si2);
1345   CHECK_EQ(static_cast<int32_t>(0xc423b891), t.result_bytepick_w_si1);
1346   CHECK_EQ(static_cast<int32_t>(0x7412c423),
1347            t.result_bytepick_w_si2);  // 0xffffc423
1348   CHECK_EQ(static_cast<int32_t>(0x6ea21274), t.result_revb_2h_si1);
1349   CHECK_EQ(static_cast<int32_t>(0x23c491b8), t.result_revb_2h_si2);
1350   CHECK_EQ(static_cast<int32_t>(0x45762e48), t.result_bitrev_4b_si1);
1351   CHECK_EQ(static_cast<int32_t>(0x23c41d89), t.result_bitrev_4b_si2);
1352   CHECK_EQ(static_cast<int32_t>(0x482e7645), t.result_bitrev_w_si1);
1353   CHECK_EQ(static_cast<int32_t>(0x891dc423), t.result_bitrev_w_si2);
1354   CHECK_EQ(static_cast<int32_t>(0x120), t.result_bstrins_w_si1);
1355   CHECK_EQ(static_cast<int32_t>(0x771220), t.result_bstrins_w_si2);
1356   CHECK_EQ(static_cast<int32_t>(0x341), t.result_bstrpick_w_si1);
1357   CHECK_EQ(static_cast<int32_t>(0x11dc4), t.result_bstrpick_w_si2);
1358 }
1359 
TEST(LA11)1360 TEST(LA11) {
1361   // Test 64bit bit operation instructions.
1362   CcTest::InitializeVM();
1363   Isolate* isolate = CcTest::i_isolate();
1364   HandleScope scope(isolate);
1365   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1366 
1367   struct T {
1368     int64_t si1;
1369     int64_t si2;
1370     int64_t result_clo_d_si1;
1371     int64_t result_clo_d_si2;
1372     int64_t result_clz_d_si1;
1373     int64_t result_clz_d_si2;
1374     int64_t result_cto_d_si1;
1375     int64_t result_cto_d_si2;
1376     int64_t result_ctz_d_si1;
1377     int64_t result_ctz_d_si2;
1378     int64_t result_bytepick_d_si1;
1379     int64_t result_bytepick_d_si2;
1380     int64_t result_revb_4h_si1;
1381     int64_t result_revb_4h_si2;
1382     int64_t result_revb_2w_si1;
1383     int64_t result_revb_2w_si2;
1384     int64_t result_revb_d_si1;
1385     int64_t result_revb_d_si2;
1386     int64_t result_revh_2w_si1;
1387     int64_t result_revh_2w_si2;
1388     int64_t result_revh_d_si1;
1389     int64_t result_revh_d_si2;
1390     int64_t result_bitrev_8b_si1;
1391     int64_t result_bitrev_8b_si2;
1392     int64_t result_bitrev_d_si1;
1393     int64_t result_bitrev_d_si2;
1394     int64_t result_bstrins_d_si1;
1395     int64_t result_bstrins_d_si2;
1396     int64_t result_bstrpick_d_si1;
1397     int64_t result_bstrpick_d_si2;
1398     int64_t result_maskeqz_si1;
1399     int64_t result_maskeqz_si2;
1400     int64_t result_masknez_si1;
1401     int64_t result_masknez_si2;
1402   };
1403 
1404   T t;
1405 
1406   __ Ld_d(a4, MemOperand(a0, offsetof(T, si1)));
1407   __ Ld_d(a5, MemOperand(a0, offsetof(T, si2)));
1408 
1409   /*    //clo_d
1410     __ clo_d(t0, a4);
1411     __ clo_d(t1, a5);
1412     __ St_w(t0, MemOperand(a0, offsetof(T, result_clo_d_si1)));
1413     __ St_w(t1, MemOperand(a0, offsetof(T, result_clo_d_si2)));*/
1414 
1415   // clz_d
1416   __ or_(t0, zero_reg, zero_reg);
1417   __ clz_d(t0, a4);
1418   __ clz_d(t1, a5);
1419   __ St_d(t0, MemOperand(a0, offsetof(T, result_clz_d_si1)));
1420   __ St_d(t1, MemOperand(a0, offsetof(T, result_clz_d_si2)));
1421 
1422   /*    //cto_d
1423     __ cto_d(t0, a4);
1424     __ cto_d(t1, a5);
1425     __ St_w(t0, MemOperand(a0, offsetof(T, result_cto_d_si1)));
1426     __ St_w(t1, MemOperand(a0, offsetof(T, result_cto_d_si2)));*/
1427 
1428   // ctz_d
1429   __ ctz_d(t0, a4);
1430   __ ctz_d(t1, a5);
1431   __ St_d(t0, MemOperand(a0, offsetof(T, result_ctz_d_si1)));
1432   __ St_d(t1, MemOperand(a0, offsetof(T, result_ctz_d_si2)));
1433 
1434   // bytepick_d
1435   __ bytepick_d(t0, a4, a5, 0);
1436   __ bytepick_d(t1, a5, a4, 5);
1437   __ St_d(t0, MemOperand(a0, offsetof(T, result_bytepick_d_si1)));
1438   __ St_d(t1, MemOperand(a0, offsetof(T, result_bytepick_d_si2)));
1439 
1440   // revb_4h
1441   __ revb_4h(t0, a4);
1442   __ revb_4h(t1, a5);
1443   __ St_d(t0, MemOperand(a0, offsetof(T, result_revb_4h_si1)));
1444   __ St_d(t1, MemOperand(a0, offsetof(T, result_revb_4h_si2)));
1445 
1446   // revb_2w
1447   __ revb_2w(t0, a4);
1448   __ revb_2w(t1, a5);
1449   __ St_d(t0, MemOperand(a0, offsetof(T, result_revb_2w_si1)));
1450   __ St_d(t1, MemOperand(a0, offsetof(T, result_revb_2w_si2)));
1451 
1452   // revb_d
1453   __ revb_d(t0, a4);
1454   __ revb_d(t1, a5);
1455   __ St_d(t0, MemOperand(a0, offsetof(T, result_revb_d_si1)));
1456   __ St_d(t1, MemOperand(a0, offsetof(T, result_revb_d_si2)));
1457 
1458   // revh_2w
1459   __ revh_2w(t0, a4);
1460   __ revh_2w(t1, a5);
1461   __ St_d(t0, MemOperand(a0, offsetof(T, result_revh_2w_si1)));
1462   __ St_d(t1, MemOperand(a0, offsetof(T, result_revh_2w_si2)));
1463 
1464   // revh_d
1465   __ revh_d(t0, a4);
1466   __ revh_d(t1, a5);
1467   __ St_d(t0, MemOperand(a0, offsetof(T, result_revh_d_si1)));
1468   __ St_d(t1, MemOperand(a0, offsetof(T, result_revh_d_si2)));
1469 
1470   // bitrev_8b
1471   __ bitrev_8b(t0, a4);
1472   __ bitrev_8b(t1, a5);
1473   __ St_d(t0, MemOperand(a0, offsetof(T, result_bitrev_8b_si1)));
1474   __ St_d(t1, MemOperand(a0, offsetof(T, result_bitrev_8b_si2)));
1475 
1476   // bitrev_d
1477   __ bitrev_d(t0, a4);
1478   __ bitrev_d(t1, a5);
1479   __ St_d(t0, MemOperand(a0, offsetof(T, result_bitrev_d_si1)));
1480   __ St_d(t1, MemOperand(a0, offsetof(T, result_bitrev_d_si2)));
1481 
1482   // bstrins_d
1483   __ or_(t0, zero_reg, zero_reg);
1484   __ or_(t1, zero_reg, zero_reg);
1485   __ bstrins_d(t0, a4, 5, 0);
1486   __ bstrins_d(t1, a5, 39, 12);
1487   __ St_d(t0, MemOperand(a0, offsetof(T, result_bstrins_d_si1)));
1488   __ St_d(t1, MemOperand(a0, offsetof(T, result_bstrins_d_si2)));
1489 
1490   // bstrpick_d
1491   __ or_(t0, zero_reg, zero_reg);
1492   __ or_(t1, zero_reg, zero_reg);
1493   __ bstrpick_d(t0, a4, 5, 0);
1494   __ bstrpick_d(t1, a5, 63, 48);
1495   __ St_d(t0, MemOperand(a0, offsetof(T, result_bstrpick_d_si1)));
1496   __ St_d(t1, MemOperand(a0, offsetof(T, result_bstrpick_d_si2)));
1497 
1498   // maskeqz
1499   __ maskeqz(t0, a4, a4);
1500   __ maskeqz(t1, a5, zero_reg);
1501   __ St_d(t0, MemOperand(a0, offsetof(T, result_maskeqz_si1)));
1502   __ St_d(t1, MemOperand(a0, offsetof(T, result_maskeqz_si2)));
1503 
1504   // masknez
1505   __ masknez(t0, a4, a4);
1506   __ masknez(t1, a5, zero_reg);
1507   __ St_d(t0, MemOperand(a0, offsetof(T, result_masknez_si1)));
1508   __ St_d(t1, MemOperand(a0, offsetof(T, result_masknez_si2)));
1509 
1510   __ jirl(zero_reg, ra, 0);
1511 
1512   CodeDesc desc;
1513   assm.GetCode(isolate, &desc);
1514   Handle<Code> code =
1515       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1516   auto f = GeneratedCode<F3>::FromCode(*code);
1517   t.si1 = 0x10C021098B710CDE;
1518   t.si2 = 0xFB8017FF781A15C3;
1519   f.Call(&t, 0, 0, 0, 0);
1520 
1521   //    CHECK_EQ(static_cast<int64_t>(0x0), t.result_clo_d_si1);
1522   //    CHECK_EQ(static_cast<int64_t>(0x5), t.result_clo_d_si2);
1523   CHECK_EQ(static_cast<int64_t>(0x3), t.result_clz_d_si1);
1524   CHECK_EQ(static_cast<int64_t>(0x0), t.result_clz_d_si2);
1525   //    CHECK_EQ(static_cast<int64_t>(0x0), t.result_cto_d_si1);
1526   //    CHECK_EQ(static_cast<int64_t>(0x2), t.result_cto_d_si2);
1527   CHECK_EQ(static_cast<int64_t>(0x1), t.result_ctz_d_si1);
1528   CHECK_EQ(static_cast<int64_t>(0x0), t.result_ctz_d_si2);
1529   CHECK_EQ(static_cast<int64_t>(0xfb8017ff781a15c3), t.result_bytepick_d_si1);
1530   CHECK_EQ(static_cast<int64_t>(0x710cdefb8017ff78), t.result_bytepick_d_si2);
1531   CHECK_EQ(static_cast<int64_t>(0xc0100921718bde0c), t.result_revb_4h_si1);
1532   CHECK_EQ(static_cast<int64_t>(0x80fbff171a78c315), t.result_revb_4h_si2);
1533   CHECK_EQ(static_cast<int64_t>(0x921c010de0c718b), t.result_revb_2w_si1);
1534   CHECK_EQ(static_cast<int64_t>(0xff1780fbc3151a78), t.result_revb_2w_si2);
1535   CHECK_EQ(static_cast<int64_t>(0xde0c718b0921c010), t.result_revb_d_si1);
1536   CHECK_EQ(static_cast<int64_t>(0xc3151a78ff1780fb), t.result_revb_d_si2);
1537   CHECK_EQ(static_cast<int64_t>(0x210910c00cde8b71), t.result_revh_2w_si1);
1538   CHECK_EQ(static_cast<int64_t>(0x17fffb8015c3781a), t.result_revh_2w_si2);
1539   CHECK_EQ(static_cast<int64_t>(0xcde8b71210910c0), t.result_revh_d_si1);
1540   CHECK_EQ(static_cast<int64_t>(0x15c3781a17fffb80), t.result_revh_d_si2);
1541   CHECK_EQ(static_cast<int64_t>(0x8038490d18e307b), t.result_bitrev_8b_si1);
1542   CHECK_EQ(static_cast<int64_t>(0xdf01e8ff1e58a8c3), t.result_bitrev_8b_si2);
1543   CHECK_EQ(static_cast<int64_t>(0x7b308ed190840308), t.result_bitrev_d_si1);
1544   CHECK_EQ(static_cast<int64_t>(0xc3a8581effe801df), t.result_bitrev_d_si2);
1545   CHECK_EQ(static_cast<int64_t>(0x1e), t.result_bstrins_d_si1);
1546   CHECK_EQ(static_cast<int64_t>(0x81a15c3000), t.result_bstrins_d_si2);
1547   CHECK_EQ(static_cast<int64_t>(0x1e), t.result_bstrpick_d_si1);
1548   CHECK_EQ(static_cast<int64_t>(0xfb80), t.result_bstrpick_d_si2);
1549   CHECK_EQ(static_cast<int64_t>(0), t.result_maskeqz_si1);
1550   CHECK_EQ(static_cast<int64_t>(0xFB8017FF781A15C3), t.result_maskeqz_si2);
1551   CHECK_EQ(static_cast<int64_t>(0x10C021098B710CDE), t.result_masknez_si1);
1552   CHECK_EQ(static_cast<int64_t>(0), t.result_masknez_si2);
1553 }
1554 
run_beq(int64_t value1,int64_t value2,int16_t offset)1555 uint64_t run_beq(int64_t value1, int64_t value2, int16_t offset) {
1556   Isolate* isolate = CcTest::i_isolate();
1557   HandleScope scope(isolate);
1558 
1559   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1560 
1561   Label main_block, L;
1562   __ li(a2, 0l);
1563   __ b(&main_block);
1564   // Block 1
1565   __ addi_d(a2, a2, 0x1);
1566   __ addi_d(a2, a2, 0x2);
1567   __ b(&L);
1568 
1569   // Block 2
1570   __ addi_d(a2, a2, 0x10);
1571   __ addi_d(a2, a2, 0x20);
1572   __ b(&L);
1573 
1574   // Block 3 (Main)
1575   __ bind(&main_block);
1576   __ beq(a0, a1, offset);
1577   __ bind(&L);
1578   __ or_(a0, a2, zero_reg);
1579   __ jirl(zero_reg, ra, 0);
1580 
1581   // Block 4
1582   __ addi_d(a2, a2, 0x100);
1583   __ addi_d(a2, a2, 0x200);
1584   __ b(&L);
1585 
1586   // Block 5
1587   __ addi_d(a2, a2, 0x300);
1588   __ addi_d(a2, a2, 0x400);
1589   __ b(&L);
1590 
1591   CodeDesc desc;
1592   assm.GetCode(isolate, &desc);
1593   Handle<Code> code =
1594       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1595 
1596   auto f = GeneratedCode<F2>::FromCode(*code);
1597   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value1, value2, 0, 0, 0));
1598 
1599   return res;
1600 }
1601 
TEST(BEQ)1602 TEST(BEQ) {
1603   CcTest::InitializeVM();
1604   struct TestCaseBeq {
1605     int64_t value1;
1606     int64_t value2;
1607     int16_t offset;
1608     uint64_t expected_res;
1609   };
1610 
1611   // clang-format off
1612   struct TestCaseBeq tc[] = {
1613     // value1, value2, offset, expected_res
1614     {       0,      0,    -6,          0x3 },
1615     {       1,      1,    -3,         0x30 },
1616     {      -2,     -2,     3,        0x300 },
1617     {       3,     -3,     6,            0 },
1618     {       4,      4,     6,        0x700 },
1619   };
1620   // clang-format on
1621 
1622   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeq);
1623   for (size_t i = 0; i < nr_test_cases; ++i) {
1624     uint64_t res = run_beq(tc[i].value1, tc[i].value2, tc[i].offset);
1625     CHECK_EQ(tc[i].expected_res, res);
1626   }
1627 }
1628 
run_bne(int64_t value1,int64_t value2,int16_t offset)1629 uint64_t run_bne(int64_t value1, int64_t value2, int16_t offset) {
1630   Isolate* isolate = CcTest::i_isolate();
1631   HandleScope scope(isolate);
1632 
1633   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1634 
1635   Label main_block, L;
1636   __ li(a2, 0l);
1637   __ b(&main_block);
1638   // Block 1
1639   __ addi_d(a2, a2, 0x1);
1640   __ addi_d(a2, a2, 0x2);
1641   __ b(&L);
1642 
1643   // Block 2
1644   __ addi_d(a2, a2, 0x10);
1645   __ addi_d(a2, a2, 0x20);
1646   __ b(&L);
1647 
1648   // Block 3 (Main)
1649   __ bind(&main_block);
1650   __ bne(a0, a1, offset);
1651   __ bind(&L);
1652   __ or_(a0, a2, zero_reg);
1653   __ jirl(zero_reg, ra, 0);
1654 
1655   // Block 4
1656   __ addi_d(a2, a2, 0x100);
1657   __ addi_d(a2, a2, 0x200);
1658   __ b(&L);
1659 
1660   // Block 5
1661   __ addi_d(a2, a2, 0x300);
1662   __ addi_d(a2, a2, 0x400);
1663   __ b(&L);
1664 
1665   CodeDesc desc;
1666   assm.GetCode(isolate, &desc);
1667   Handle<Code> code =
1668       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1669 
1670   auto f = GeneratedCode<F2>::FromCode(*code);
1671   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value1, value2, 0, 0, 0));
1672 
1673   return res;
1674 }
1675 
TEST(BNE)1676 TEST(BNE) {
1677   CcTest::InitializeVM();
1678   struct TestCaseBne {
1679     int64_t value1;
1680     int64_t value2;
1681     int16_t offset;
1682     uint64_t expected_res;
1683   };
1684 
1685   // clang-format off
1686   struct TestCaseBne tc[] = {
1687     // value1, value2, offset, expected_res
1688     {       1,     -1,    -6,          0x3 },
1689     {       2,     -2,    -3,         0x30 },
1690     {       3,     -3,     3,        0x300 },
1691     {       4,     -4,     6,        0x700 },
1692     {       0,      0,     6,            0 },
1693   };
1694   // clang-format on
1695 
1696   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBne);
1697   for (size_t i = 0; i < nr_test_cases; ++i) {
1698     uint64_t res = run_bne(tc[i].value1, tc[i].value2, tc[i].offset);
1699     CHECK_EQ(tc[i].expected_res, res);
1700   }
1701 }
1702 
run_blt(int64_t value1,int64_t value2,int16_t offset)1703 uint64_t run_blt(int64_t value1, int64_t value2, int16_t offset) {
1704   Isolate* isolate = CcTest::i_isolate();
1705   HandleScope scope(isolate);
1706 
1707   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1708 
1709   Label main_block, L;
1710   __ li(a2, 0l);
1711   __ b(&main_block);
1712   // Block 1
1713   __ addi_d(a2, a2, 0x1);
1714   __ addi_d(a2, a2, 0x2);
1715   __ b(&L);
1716 
1717   // Block 2
1718   __ addi_d(a2, a2, 0x10);
1719   __ addi_d(a2, a2, 0x20);
1720   __ b(&L);
1721 
1722   // Block 3 (Main)
1723   __ bind(&main_block);
1724   __ blt(a0, a1, offset);
1725   __ bind(&L);
1726   __ or_(a0, a2, zero_reg);
1727   __ jirl(zero_reg, ra, 0);
1728 
1729   // Block 4
1730   __ addi_d(a2, a2, 0x100);
1731   __ addi_d(a2, a2, 0x200);
1732   __ b(&L);
1733 
1734   // Block 5
1735   __ addi_d(a2, a2, 0x300);
1736   __ addi_d(a2, a2, 0x400);
1737   __ b(&L);
1738 
1739   CodeDesc desc;
1740   assm.GetCode(isolate, &desc);
1741   Handle<Code> code =
1742       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1743 
1744   auto f = GeneratedCode<F2>::FromCode(*code);
1745   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value1, value2, 0, 0, 0));
1746 
1747   return res;
1748 }
1749 
TEST(BLT)1750 TEST(BLT) {
1751   CcTest::InitializeVM();
1752   struct TestCaseBlt {
1753     int64_t value1;
1754     int64_t value2;
1755     int16_t offset;
1756     uint64_t expected_res;
1757   };
1758 
1759   // clang-format off
1760   struct TestCaseBlt tc[] = {
1761     // value1, value2, offset, expected_res
1762     {      -1,      1,    -6,          0x3 },
1763     {      -2,      2,    -3,         0x30 },
1764     {      -3,      3,     3,        0x300 },
1765     {      -4,      4,     6,        0x700 },
1766     {       5,     -5,     6,            0 },
1767     {       0,      0,     6,            0 },
1768   };
1769   // clang-format on
1770 
1771   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBlt);
1772   for (size_t i = 0; i < nr_test_cases; ++i) {
1773     uint64_t res = run_blt(tc[i].value1, tc[i].value2, tc[i].offset);
1774     CHECK_EQ(tc[i].expected_res, res);
1775   }
1776 }
1777 
run_bge(uint64_t value1,uint64_t value2,int16_t offset)1778 uint64_t run_bge(uint64_t value1, uint64_t value2, int16_t offset) {
1779   Isolate* isolate = CcTest::i_isolate();
1780   HandleScope scope(isolate);
1781 
1782   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1783 
1784   Label main_block, L;
1785   __ li(a2, 0l);
1786   __ b(&main_block);
1787   // Block 1
1788   __ addi_d(a2, a2, 0x1);
1789   __ addi_d(a2, a2, 0x2);
1790   __ b(&L);
1791 
1792   // Block 2
1793   __ addi_d(a2, a2, 0x10);
1794   __ addi_d(a2, a2, 0x20);
1795   __ b(&L);
1796 
1797   // Block 3 (Main)
1798   __ bind(&main_block);
1799   __ bge(a0, a1, offset);
1800   __ bind(&L);
1801   __ or_(a0, a2, zero_reg);
1802   __ jirl(zero_reg, ra, 0);
1803 
1804   // Block 4
1805   __ addi_d(a2, a2, 0x100);
1806   __ addi_d(a2, a2, 0x200);
1807   __ b(&L);
1808 
1809   // Block 5
1810   __ addi_d(a2, a2, 0x300);
1811   __ addi_d(a2, a2, 0x400);
1812   __ b(&L);
1813 
1814   CodeDesc desc;
1815   assm.GetCode(isolate, &desc);
1816   Handle<Code> code =
1817       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1818 
1819   auto f = GeneratedCode<F2>::FromCode(*code);
1820   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value1, value2, 0, 0, 0));
1821 
1822   return res;
1823 }
1824 
TEST(BGE)1825 TEST(BGE) {
1826   CcTest::InitializeVM();
1827   struct TestCaseBge {
1828     int64_t value1;
1829     int64_t value2;
1830     int16_t offset;
1831     uint64_t expected_res;
1832   };
1833 
1834   // clang-format off
1835   struct TestCaseBge tc[] = {
1836     // value1, value2, offset, expected_res
1837     {       0,      0,    -6,          0x3 },
1838     {       1,      1,    -3,         0x30 },
1839     {       2,     -2,     3,        0x300 },
1840     {       3,     -3,     6,        0x700 },
1841     {      -4,      4,     6,            0 },
1842   };
1843   // clang-format on
1844 
1845   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBge);
1846   for (size_t i = 0; i < nr_test_cases; ++i) {
1847     uint64_t res = run_bge(tc[i].value1, tc[i].value2, tc[i].offset);
1848     CHECK_EQ(tc[i].expected_res, res);
1849   }
1850 }
1851 
run_bltu(int64_t value1,int64_t value2,int16_t offset)1852 uint64_t run_bltu(int64_t value1, int64_t value2, int16_t offset) {
1853   Isolate* isolate = CcTest::i_isolate();
1854   HandleScope scope(isolate);
1855 
1856   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1857 
1858   Label main_block, L;
1859   __ li(a2, 0l);
1860   __ b(&main_block);
1861   // Block 1
1862   __ addi_d(a2, a2, 0x1);
1863   __ addi_d(a2, a2, 0x2);
1864   __ b(&L);
1865 
1866   // Block 2
1867   __ addi_d(a2, a2, 0x10);
1868   __ addi_d(a2, a2, 0x20);
1869   __ b(&L);
1870 
1871   // Block 3 (Main)
1872   __ bind(&main_block);
1873   __ bltu(a0, a1, offset);
1874   __ bind(&L);
1875   __ or_(a0, a2, zero_reg);
1876   __ jirl(zero_reg, ra, 0);
1877 
1878   // Block 4
1879   __ addi_d(a2, a2, 0x100);
1880   __ addi_d(a2, a2, 0x200);
1881   __ b(&L);
1882 
1883   // Block 5
1884   __ addi_d(a2, a2, 0x300);
1885   __ addi_d(a2, a2, 0x400);
1886   __ b(&L);
1887 
1888   CodeDesc desc;
1889   assm.GetCode(isolate, &desc);
1890   Handle<Code> code =
1891       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1892 
1893   auto f = GeneratedCode<F2>::FromCode(*code);
1894   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value1, value2, 0, 0, 0));
1895 
1896   return res;
1897 }
1898 
TEST(BLTU)1899 TEST(BLTU) {
1900   CcTest::InitializeVM();
1901   struct TestCaseBltu {
1902     int64_t value1;
1903     int64_t value2;
1904     int16_t offset;
1905     uint64_t expected_res;
1906   };
1907 
1908   // clang-format off
1909   struct TestCaseBltu tc[] = {
1910     // value1, value2, offset, expected_res
1911     {       0,      1,    -6,          0x3 },
1912     {       1,     -1,    -3,         0x30 },
1913     {       2,     -2,     3,        0x300 },
1914     {       3,     -3,     6,        0x700 },
1915     {       4,      4,     6,            0 },
1916   };
1917   // clang-format on
1918 
1919   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBltu);
1920   for (size_t i = 0; i < nr_test_cases; ++i) {
1921     uint64_t res = run_bltu(tc[i].value1, tc[i].value2, tc[i].offset);
1922     CHECK_EQ(tc[i].expected_res, res);
1923   }
1924 }
1925 
run_bgeu(int64_t value1,int64_t value2,int16_t offset)1926 uint64_t run_bgeu(int64_t value1, int64_t value2, int16_t offset) {
1927   Isolate* isolate = CcTest::i_isolate();
1928   HandleScope scope(isolate);
1929 
1930   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
1931 
1932   Label main_block, L;
1933   __ li(a2, 0l);
1934   __ b(&main_block);
1935   // Block 1
1936   __ addi_d(a2, a2, 0x1);
1937   __ addi_d(a2, a2, 0x2);
1938   __ b(&L);
1939 
1940   // Block 2
1941   __ addi_d(a2, a2, 0x10);
1942   __ addi_d(a2, a2, 0x20);
1943   __ b(&L);
1944 
1945   // Block 3 (Main)
1946   __ bind(&main_block);
1947   __ bgeu(a0, a1, offset);
1948   __ bind(&L);
1949   __ or_(a0, a2, zero_reg);
1950   __ jirl(zero_reg, ra, 0);
1951 
1952   // Block 4
1953   __ addi_d(a2, a2, 0x100);
1954   __ addi_d(a2, a2, 0x200);
1955   __ b(&L);
1956 
1957   // Block 5
1958   __ addi_d(a2, a2, 0x300);
1959   __ addi_d(a2, a2, 0x400);
1960   __ b(&L);
1961 
1962   CodeDesc desc;
1963   assm.GetCode(isolate, &desc);
1964   Handle<Code> code =
1965       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
1966 
1967   auto f = GeneratedCode<F2>::FromCode(*code);
1968   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value1, value2, 0, 0, 0));
1969 
1970   return res;
1971 }
1972 
TEST(BGEU)1973 TEST(BGEU) {
1974   CcTest::InitializeVM();
1975   struct TestCaseBgeu {
1976     int64_t value1;
1977     int64_t value2;
1978     int16_t offset;
1979     uint64_t expected_res;
1980   };
1981 
1982   // clang-format off
1983   struct TestCaseBgeu tc[] = {
1984     // value1, value2, offset, expected_res
1985     {       0,      0,    -6,          0x3 },
1986     {      -1,      1,    -3,         0x30 },
1987     {      -2,      2,     3,        0x300 },
1988     {      -3,      3,     6,        0x700 },
1989     {       4,     -4,     6,            0 },
1990   };
1991   // clang-format on
1992 
1993   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBgeu);
1994   for (size_t i = 0; i < nr_test_cases; ++i) {
1995     uint64_t res = run_bgeu(tc[i].value1, tc[i].value2, tc[i].offset);
1996     CHECK_EQ(tc[i].expected_res, res);
1997   }
1998 }
1999 
run_beqz(int64_t value,int32_t offset)2000 uint64_t run_beqz(int64_t value, int32_t offset) {
2001   Isolate* isolate = CcTest::i_isolate();
2002   HandleScope scope(isolate);
2003 
2004   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2005 
2006   Label main_block, L;
2007   __ li(a2, 0l);
2008   __ b(&main_block);
2009   // Block 1
2010   __ addi_d(a2, a2, 0x1);
2011   __ addi_d(a2, a2, 0x2);
2012   __ b(&L);
2013 
2014   // Block 2
2015   __ addi_d(a2, a2, 0x10);
2016   __ addi_d(a2, a2, 0x20);
2017   __ b(&L);
2018 
2019   // Block 3 (Main)
2020   __ bind(&main_block);
2021   __ beqz(a0, offset);
2022   __ bind(&L);
2023   __ or_(a0, a2, zero_reg);
2024   __ jirl(zero_reg, ra, 0);
2025 
2026   // Block 4
2027   __ addi_d(a2, a2, 0x100);
2028   __ addi_d(a2, a2, 0x200);
2029   __ b(&L);
2030 
2031   // Block 5
2032   __ addi_d(a2, a2, 0x300);
2033   __ addi_d(a2, a2, 0x400);
2034   __ b(&L);
2035 
2036   CodeDesc desc;
2037   assm.GetCode(isolate, &desc);
2038   Handle<Code> code =
2039       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2040 
2041   auto f = GeneratedCode<F2>::FromCode(*code);
2042   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value, 0, 0, 0, 0));
2043 
2044   return res;
2045 }
2046 
TEST(BEQZ)2047 TEST(BEQZ) {
2048   CcTest::InitializeVM();
2049   struct TestCaseBeqz {
2050     int64_t value;
2051     int32_t offset;
2052     uint64_t expected_res;
2053   };
2054 
2055   // clang-format off
2056   struct TestCaseBeqz tc[] = {
2057     // value, offset, expected_res
2058     {      0,     -6,          0x3 },
2059     {      0,     -3,         0x30 },
2060     {      0,      3,        0x300 },
2061     {      0,      6,        0x700 },
2062     {      1,      6,            0 },
2063   };
2064   // clang-format on
2065 
2066   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqz);
2067   for (size_t i = 0; i < nr_test_cases; ++i) {
2068     uint64_t res = run_beqz(tc[i].value, tc[i].offset);
2069     CHECK_EQ(tc[i].expected_res, res);
2070   }
2071 }
2072 
run_bnez_b(int64_t value,int32_t offset)2073 uint64_t run_bnez_b(int64_t value, int32_t offset) {
2074   // bnez, b.
2075   Isolate* isolate = CcTest::i_isolate();
2076   HandleScope scope(isolate);
2077 
2078   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2079 
2080   Label main_block, L;
2081   __ li(a2, 0l);
2082   __ b(&main_block);
2083   // Block 1
2084   __ addi_d(a2, a2, 0x1);
2085   __ addi_d(a2, a2, 0x2);
2086   __ b(5);
2087 
2088   // Block 2
2089   __ addi_d(a2, a2, 0x10);
2090   __ addi_d(a2, a2, 0x20);
2091   __ b(2);
2092 
2093   // Block 3 (Main)
2094   __ bind(&main_block);
2095   __ bnez(a0, offset);
2096   __ bind(&L);
2097   __ or_(a0, a2, zero_reg);
2098   __ jirl(zero_reg, ra, 0);
2099 
2100   // Block 4
2101   __ addi_d(a2, a2, 0x100);
2102   __ addi_d(a2, a2, 0x200);
2103   __ b(-4);
2104 
2105   // Block 5
2106   __ addi_d(a2, a2, 0x300);
2107   __ addi_d(a2, a2, 0x400);
2108   __ b(-7);
2109 
2110   CodeDesc desc;
2111   assm.GetCode(isolate, &desc);
2112   Handle<Code> code =
2113       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2114 
2115   auto f = GeneratedCode<F2>::FromCode(*code);
2116   uint64_t res = reinterpret_cast<uint64_t>(f.Call(value, 0, 0, 0, 0));
2117 
2118   return res;
2119 }
2120 
TEST(BNEZ_B)2121 TEST(BNEZ_B) {
2122   CcTest::InitializeVM();
2123   struct TestCaseBnez {
2124     int64_t value;
2125     int32_t offset;
2126     uint64_t expected_res;
2127   };
2128 
2129   // clang-format off
2130   struct TestCaseBnez tc[] = {
2131     // value, offset, expected_res
2132     {      1,     -6,          0x3 },
2133     {     -2,     -3,         0x30 },
2134     {      3,      3,        0x300 },
2135     {     -4,      6,        0x700 },
2136     {      0,      6,            0 },
2137   };
2138   // clang-format on
2139 
2140   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBnez);
2141   for (size_t i = 0; i < nr_test_cases; ++i) {
2142     uint64_t res = run_bnez_b(tc[i].value, tc[i].offset);
2143     CHECK_EQ(tc[i].expected_res, res);
2144   }
2145 }
2146 
run_bl(int32_t offset)2147 uint64_t run_bl(int32_t offset) {
2148   Isolate* isolate = CcTest::i_isolate();
2149   HandleScope scope(isolate);
2150 
2151   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2152 
2153   Label main_block;
2154   __ li(a2, 0l);
2155   __ Push(ra);  // Push is implemented by two instructions, addi_d and st_d
2156   __ b(&main_block);
2157 
2158   // Block 1
2159   __ addi_d(a2, a2, 0x1);
2160   __ addi_d(a2, a2, 0x2);
2161   __ jirl(zero_reg, ra, 0);
2162 
2163   // Block 2
2164   __ addi_d(a2, a2, 0x10);
2165   __ addi_d(a2, a2, 0x20);
2166   __ jirl(zero_reg, ra, 0);
2167 
2168   // Block 3 (Main)
2169   __ bind(&main_block);
2170   __ bl(offset);
2171   __ or_(a0, a2, zero_reg);
2172   __ Pop(ra);  // Pop is implemented by two instructions, ld_d and addi_d.
2173   __ jirl(zero_reg, ra, 0);
2174 
2175   // Block 4
2176   __ addi_d(a2, a2, 0x100);
2177   __ addi_d(a2, a2, 0x200);
2178   __ jirl(zero_reg, ra, 0);
2179 
2180   // Block 5
2181   __ addi_d(a2, a2, 0x300);
2182   __ addi_d(a2, a2, 0x400);
2183   __ jirl(zero_reg, ra, 0);
2184 
2185   CodeDesc desc;
2186   assm.GetCode(isolate, &desc);
2187   Handle<Code> code =
2188       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2189 
2190   auto f = GeneratedCode<F2>::FromCode(*code);
2191   uint64_t res = reinterpret_cast<uint64_t>(f.Call(0, 0, 0, 0, 0));
2192 
2193   return res;
2194 }
2195 
TEST(BL)2196 TEST(BL) {
2197   CcTest::InitializeVM();
2198   struct TestCaseBl {
2199     int32_t offset;
2200     uint64_t expected_res;
2201   };
2202 
2203   // clang-format off
2204   struct TestCaseBl tc[] = {
2205     // offset, expected_res
2206     {     -6,          0x3 },
2207     {     -3,         0x30 },
2208     {      5,        0x300 },
2209     {      8,        0x700 },
2210   };
2211   // clang-format on
2212 
2213   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBl);
2214   for (size_t i = 0; i < nr_test_cases; ++i) {
2215     uint64_t res = run_bl(tc[i].offset);
2216     CHECK_EQ(tc[i].expected_res, res);
2217   }
2218 }
2219 
TEST(PCADD)2220 TEST(PCADD) {
2221   CcTest::InitializeVM();
2222   Isolate* isolate = CcTest::i_isolate();
2223   HandleScope scope(isolate);
2224 
2225   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2226 
2227   Label exit, error;
2228   __ Push(ra);
2229 
2230   // pcaddi
2231   __ li(a4, 0x1FFFFC);
2232   __ li(a5, 0);
2233   __ li(a6, static_cast<int32_t>(0xFFE00000));
2234 
2235   __ bl(1);
2236   __ pcaddi(a3, 0x7FFFF);
2237   __ add_d(a2, ra, a4);
2238   __ Branch(&error, ne, a2, Operand(a3));
2239 
2240   __ bl(1);
2241   __ pcaddi(a3, 0);
2242   __ add_d(a2, ra, a5);
2243   __ Branch(&error, ne, a2, Operand(a3));
2244 
2245   __ bl(1);
2246   __ pcaddi(a3, 0x80000);
2247   __ add_d(a2, ra, a6);
2248   __ Branch(&error, ne, a2, Operand(a3));
2249 
2250   // pcaddu12i
2251   __ li(a4, 0x7FFFF000);
2252   __ li(a5, 0);
2253   __ li(a6, static_cast<int32_t>(0x80000000));
2254 
2255   __ bl(1);
2256   __ pcaddu12i(a2, 0x7FFFF);
2257   __ add_d(a3, ra, a4);
2258   __ Branch(&error, ne, a2, Operand(a3));
2259   __ bl(1);
2260   __ pcaddu12i(a2, 0);
2261   __ add_d(a3, ra, a5);
2262   __ Branch(&error, ne, a2, Operand(a3));
2263   __ bl(1);
2264   __ pcaddu12i(a2, 0x80000);
2265   __ add_d(a3, ra, a6);
2266   __ Branch(&error, ne, a2, Operand(a3));
2267 
2268   // pcaddu18i
2269   __ li(a4, 0x1FFFFC0000);
2270   __ li(a5, 0);
2271   __ li(a6, static_cast<int64_t>(0xFFFFFFE000000000));
2272 
2273   __ bl(1);
2274   __ pcaddu18i(a2, 0x7FFFF);
2275   __ add_d(a3, ra, a4);
2276   __ Branch(&error, ne, a2, Operand(a3));
2277 
2278   __ bl(1);
2279   __ pcaddu18i(a2, 0);
2280   __ add_d(a3, ra, a5);
2281   __ Branch(&error, ne, a2, Operand(a3));
2282 
2283   __ bl(1);
2284   __ pcaddu18i(a2, 0x80000);
2285   __ add_d(a3, ra, a6);
2286   __ Branch(&error, ne, a2, Operand(a3));
2287 
2288   // pcalau12i
2289   __ li(a4, 0x7FFFF000);
2290   __ li(a5, 0);
2291   __ li(a6, static_cast<int32_t>(0x80000000));
2292   __ li(a7, static_cast<int64_t>(0xFFFFFFFFFFFFF000));
2293 
2294   __ bl(1);
2295   __ pcalau12i(a3, 0x7FFFF);
2296   __ add_d(a2, ra, a4);
2297   __ and_(t0, a2, a7);
2298   __ and_(t1, a3, a7);
2299   __ Branch(&error, ne, t0, Operand(t1));
2300 
2301   __ bl(1);
2302   __ pcalau12i(a3, 0);
2303   __ add_d(a2, ra, a5);
2304   __ and_(t0, a2, a7);
2305   __ and_(t1, a3, a7);
2306   __ Branch(&error, ne, t0, Operand(t1));
2307 
2308   __ bl(1);
2309   __ pcalau12i(a2, 0x80000);
2310   __ add_d(a3, ra, a6);
2311   __ and_(t0, a2, a7);
2312   __ and_(t1, a3, a7);
2313   __ Branch(&error, ne, t0, Operand(t1));
2314 
2315   __ li(a0, 0x31415926);
2316   __ b(&exit);
2317 
2318   __ bind(&error);
2319   __ li(a0, 0x666);
2320 
2321   __ bind(&exit);
2322   __ Pop(ra);
2323   __ jirl(zero_reg, ra, 0);
2324 
2325   CodeDesc desc;
2326   assm.GetCode(isolate, &desc);
2327   Handle<Code> code =
2328       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2329   auto f = GeneratedCode<F2>::FromCode(*code);
2330   int64_t res = reinterpret_cast<int64_t>(f.Call(0, 0, 0, 0, 0));
2331 
2332   CHECK_EQ(0x31415926L, res);
2333 }
2334 
run_jirl(int16_t offset)2335 uint64_t run_jirl(int16_t offset) {
2336   Isolate* isolate = CcTest::i_isolate();
2337   HandleScope scope(isolate);
2338 
2339   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2340 
2341   Label main_block;
2342   __ li(a2, 0l);
2343   __ Push(ra);
2344   __ b(&main_block);
2345 
2346   // Block 1
2347   __ addi_d(a2, a2, 0x1);
2348   __ addi_d(a2, a2, 0x2);
2349   __ jirl(zero_reg, ra, 0);
2350 
2351   // Block 2
2352   __ addi_d(a2, a2, 0x10);
2353   __ addi_d(a2, a2, 0x20);
2354   __ jirl(zero_reg, ra, 0);
2355 
2356   // Block 3 (Main)
2357   __ bind(&main_block);
2358   __ pcaddi(a3, 1);
2359   __ jirl(ra, a3, offset);
2360   __ or_(a0, a2, zero_reg);
2361   __ Pop(ra);  // Pop is implemented by two instructions, ld_d and addi_d.
2362   __ jirl(zero_reg, ra, 0);
2363 
2364   // Block 4
2365   __ addi_d(a2, a2, 0x100);
2366   __ addi_d(a2, a2, 0x200);
2367   __ jirl(zero_reg, ra, 0);
2368 
2369   // Block 5
2370   __ addi_d(a2, a2, 0x300);
2371   __ addi_d(a2, a2, 0x400);
2372   __ jirl(zero_reg, ra, 0);
2373 
2374   CodeDesc desc;
2375   assm.GetCode(isolate, &desc);
2376   Handle<Code> code =
2377       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2378 
2379   auto f = GeneratedCode<F2>::FromCode(*code);
2380   uint64_t res = reinterpret_cast<uint64_t>(f.Call(0, 0, 0, 0, 0));
2381 
2382   return res;
2383 }
2384 
TEST(JIRL)2385 TEST(JIRL) {
2386   CcTest::InitializeVM();
2387   struct TestCaseJirl {
2388     int16_t offset;
2389     uint64_t expected_res;
2390   };
2391 
2392   // clang-format off
2393   struct TestCaseJirl tc[] = {
2394     // offset, expected_res
2395     {     -7,          0x3 },
2396     {     -4,         0x30 },
2397     {      5,        0x300 },
2398     {      8,        0x700 },
2399   };
2400   // clang-format on
2401 
2402   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJirl);
2403   for (size_t i = 0; i < nr_test_cases; ++i) {
2404     uint64_t res = run_jirl(tc[i].offset);
2405     CHECK_EQ(tc[i].expected_res, res);
2406   }
2407 }
2408 
TEST(LA12)2409 TEST(LA12) {
2410   // Test floating point calculate instructions.
2411   CcTest::InitializeVM();
2412   Isolate* isolate = CcTest::i_isolate();
2413   HandleScope scope(isolate);
2414 
2415   struct T {
2416     double a;
2417     double b;
2418     double c;
2419     double d;
2420     double e;
2421     double f;
2422     double result_fadd_d;
2423     double result_fsub_d;
2424     double result_fmul_d;
2425     double result_fdiv_d;
2426     double result_fmadd_d;
2427     double result_fmsub_d;
2428     double result_fnmadd_d;
2429     double result_fnmsub_d;
2430     double result_fsqrt_d;
2431     double result_frecip_d;
2432     double result_frsqrt_d;
2433     double result_fscaleb_d;
2434     double result_flogb_d;
2435     double result_fcopysign_d;
2436     double result_fclass_d;
2437   };
2438   T t;
2439 
2440   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2441 
2442   // Double precision floating point instructions.
2443   __ Fld_d(f8, MemOperand(a0, offsetof(T, a)));
2444   __ Fld_d(f9, MemOperand(a0, offsetof(T, b)));
2445 
2446   __ fneg_d(f10, f8);
2447   __ fadd_d(f11, f9, f10);
2448   __ Fst_d(f11, MemOperand(a0, offsetof(T, result_fadd_d)));
2449   __ fabs_d(f11, f11);
2450   __ fsub_d(f12, f11, f9);
2451   __ Fst_d(f12, MemOperand(a0, offsetof(T, result_fsub_d)));
2452 
2453   __ Fld_d(f13, MemOperand(a0, offsetof(T, c)));
2454   __ Fld_d(f14, MemOperand(a0, offsetof(T, d)));
2455   __ Fld_d(f15, MemOperand(a0, offsetof(T, e)));
2456 
2457   __ fmin_d(f16, f13, f14);
2458   __ fmul_d(f17, f15, f16);
2459   __ Fst_d(f17, MemOperand(a0, offsetof(T, result_fmul_d)));
2460   __ fmax_d(f18, f13, f14);
2461   __ fdiv_d(f19, f15, f18);
2462   __ Fst_d(f19, MemOperand(a0, offsetof(T, result_fdiv_d)));
2463 
2464   __ fmina_d(f16, f13, f14);
2465   __ fmadd_d(f18, f17, f15, f16);
2466   __ Fst_d(f18, MemOperand(a0, offsetof(T, result_fmadd_d)));
2467   __ fnmadd_d(f19, f17, f15, f16);
2468   __ Fst_d(f19, MemOperand(a0, offsetof(T, result_fnmadd_d)));
2469   __ fmaxa_d(f16, f13, f14);
2470   __ fmsub_d(f20, f17, f15, f16);
2471   __ Fst_d(f20, MemOperand(a0, offsetof(T, result_fmsub_d)));
2472   __ fnmsub_d(f21, f17, f15, f16);
2473   __ Fst_d(f21, MemOperand(a0, offsetof(T, result_fnmsub_d)));
2474 
2475   __ Fld_d(f8, MemOperand(a0, offsetof(T, f)));
2476   __ fsqrt_d(f10, f8);
2477   __ Fst_d(f10, MemOperand(a0, offsetof(T, result_fsqrt_d)));
2478   //__ frecip_d(f11, f10);
2479   //__ frsqrt_d(f12, f8);
2480   //__ Fst_d(f11, MemOperand(a0, offsetof(T, result_frecip_d)));
2481   //__ Fst_d(f12, MemOperand(a0, offsetof(T, result_frsqrt_d)));
2482 
2483   /*__ fscaleb_d(f16, f13, f15);
2484   __ flogb_d(f17, f15);
2485   __ fcopysign_d(f18, f8, f9);
2486   __ fclass_d(f19, f9);
2487   __ Fst_d(f16, MemOperand(a0, offsetof(T, result_fscaleb_d)));
2488   __ Fst_d(f17, MemOperand(a0, offsetof(T, result_flogb_d)));
2489   __ Fst_d(f18, MemOperand(a0, offsetof(T, result_fcopysign_d)));
2490   __ Fst_d(f19, MemOperand(a0, offsetof(T, result_fclass_d)));*/
2491 
2492   __ jirl(zero_reg, ra, 0);
2493 
2494   CodeDesc desc;
2495   assm.GetCode(isolate, &desc);
2496   Handle<Code> code =
2497       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2498   auto f = GeneratedCode<F3>::FromCode(*code);
2499   // Double test values.
2500   t.a = 1.5e14;
2501   t.b = -2.75e11;
2502   t.c = 1.5;
2503   t.d = -2.75;
2504   t.e = 120.0;
2505   t.f = 120.44;
2506   f.Call(&t, 0, 0, 0, 0);
2507 
2508   CHECK_EQ(static_cast<double>(-1.502750e14), t.result_fadd_d);
2509   CHECK_EQ(static_cast<double>(1.505500e14), t.result_fsub_d);
2510   CHECK_EQ(static_cast<double>(-3.300000e02), t.result_fmul_d);
2511   CHECK_EQ(static_cast<double>(8.000000e01), t.result_fdiv_d);
2512   CHECK_EQ(static_cast<double>(-3.959850e04), t.result_fmadd_d);
2513   CHECK_EQ(static_cast<double>(-3.959725e04), t.result_fmsub_d);
2514   CHECK_EQ(static_cast<double>(3.959850e04), t.result_fnmadd_d);
2515   CHECK_EQ(static_cast<double>(3.959725e04), t.result_fnmsub_d);
2516   CHECK_EQ(static_cast<double>(10.97451593465515908537), t.result_fsqrt_d);
2517   // CHECK_EQ(static_cast<double>( 8.164965e-08), t.result_frecip_d);
2518   // CHECK_EQ(static_cast<double>( 8.164966e-08), t.result_frsqrt_d);
2519   // CHECK_EQ(static_cast<double>(), t.result_fscaleb_d);
2520   // CHECK_EQ(static_cast<double>( 6.906891), t.result_flogb_d);
2521   // CHECK_EQ(static_cast<double>( 2.75e11), t.result_fcopysign_d);
2522   // CHECK_EQ(static_cast<double>(), t.result_fclass_d);
2523 }
2524 
TEST(LA13)2525 TEST(LA13) {
2526   CcTest::InitializeVM();
2527   Isolate* isolate = CcTest::i_isolate();
2528   HandleScope scope(isolate);
2529 
2530   struct T {
2531     float a;
2532     float b;
2533     float c;
2534     float d;
2535     float e;
2536     float result_fadd_s;
2537     float result_fsub_s;
2538     float result_fmul_s;
2539     float result_fdiv_s;
2540     float result_fmadd_s;
2541     float result_fmsub_s;
2542     float result_fnmadd_s;
2543     float result_fnmsub_s;
2544     float result_fsqrt_s;
2545     float result_frecip_s;
2546     float result_frsqrt_s;
2547     float result_fscaleb_s;
2548     float result_flogb_s;
2549     float result_fcopysign_s;
2550     float result_fclass_s;
2551   };
2552   T t;
2553 
2554   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2555 
2556   // Float precision floating point instructions.
2557   __ Fld_s(f8, MemOperand(a0, offsetof(T, a)));
2558   __ Fld_s(f9, MemOperand(a0, offsetof(T, b)));
2559 
2560   __ fneg_s(f10, f8);
2561   __ fadd_s(f11, f9, f10);
2562   __ Fst_s(f11, MemOperand(a0, offsetof(T, result_fadd_s)));
2563   __ fabs_s(f11, f11);
2564   __ fsub_s(f12, f11, f9);
2565   __ Fst_s(f12, MemOperand(a0, offsetof(T, result_fsub_s)));
2566 
2567   __ Fld_s(f13, MemOperand(a0, offsetof(T, c)));
2568   __ Fld_s(f14, MemOperand(a0, offsetof(T, d)));
2569   __ Fld_s(f15, MemOperand(a0, offsetof(T, e)));
2570 
2571   __ fmin_s(f16, f13, f14);
2572   __ fmul_s(f17, f15, f16);
2573   __ Fst_s(f17, MemOperand(a0, offsetof(T, result_fmul_s)));
2574   __ fmax_s(f18, f13, f14);
2575   __ fdiv_s(f19, f15, f18);
2576   __ Fst_s(f19, MemOperand(a0, offsetof(T, result_fdiv_s)));
2577 
2578   __ fmina_s(f16, f13, f14);
2579   __ fmadd_s(f18, f17, f15, f16);
2580   __ Fst_s(f18, MemOperand(a0, offsetof(T, result_fmadd_s)));
2581   __ fnmadd_s(f19, f17, f15, f16);
2582   __ Fst_s(f19, MemOperand(a0, offsetof(T, result_fnmadd_s)));
2583   __ fmaxa_s(f16, f13, f14);
2584   __ fmsub_s(f20, f17, f15, f16);
2585   __ Fst_s(f20, MemOperand(a0, offsetof(T, result_fmsub_s)));
2586   __ fnmsub_s(f21, f17, f15, f16);
2587   __ Fst_s(f21, MemOperand(a0, offsetof(T, result_fnmsub_s)));
2588 
2589   __ fsqrt_s(f10, f8);
2590   //__ frecip_s(f11, f10);
2591   //__ frsqrt_s(f12, f8);
2592   __ Fst_s(f10, MemOperand(a0, offsetof(T, result_fsqrt_s)));
2593   //__ Fst_s(f11, MemOperand(a0, offsetof(T, result_frecip_s)));
2594   //__ Fst_s(f12, MemOperand(a0, offsetof(T, result_frsqrt_s)));
2595 
2596   /*__ fscaleb_s(f16, f13, f15);
2597   __ flogb_s(f17, f15);
2598   __ fcopysign_s(f18, f8, f9);
2599   __ fclass_s(f19, f9);
2600   __ Fst_s(f16, MemOperand(a0, offsetof(T, result_fscaleb_s)));
2601   __ Fst_s(f17, MemOperand(a0, offsetof(T, result_flogb_s)));
2602   __ Fst_s(f18, MemOperand(a0, offsetof(T, result_fcopysign_s)));
2603   __ Fst_s(f19, MemOperand(a0, offsetof(T, result_fclass_s)));*/
2604   __ jirl(zero_reg, ra, 0);
2605 
2606   CodeDesc desc;
2607   assm.GetCode(isolate, &desc);
2608   Handle<Code> code =
2609       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2610   auto f = GeneratedCode<F3>::FromCode(*code);
2611   // Float test values.
2612   t.a = 1.5e6;
2613   t.b = -2.75e4;
2614   t.c = 1.5;
2615   t.d = -2.75;
2616   t.e = 120.0;
2617   f.Call(&t, 0, 0, 0, 0);
2618 
2619   CHECK_EQ(static_cast<float>(-1.527500e06), t.result_fadd_s);
2620   CHECK_EQ(static_cast<float>(1.555000e06), t.result_fsub_s);
2621   CHECK_EQ(static_cast<float>(-3.300000e02), t.result_fmul_s);
2622   CHECK_EQ(static_cast<float>(8.000000e01), t.result_fdiv_s);
2623   CHECK_EQ(static_cast<float>(-3.959850e04), t.result_fmadd_s);
2624   CHECK_EQ(static_cast<float>(-3.959725e04), t.result_fmsub_s);
2625   CHECK_EQ(static_cast<float>(3.959850e04), t.result_fnmadd_s);
2626   CHECK_EQ(static_cast<float>(3.959725e04), t.result_fnmsub_s);
2627   CHECK_EQ(static_cast<float>(1224.744873), t.result_fsqrt_s);
2628   // CHECK_EQ(static_cast<float>( 8.164966e-04), t.result_frecip_s);
2629   // CHECK_EQ(static_cast<float>( 8.164966e-04), t.result_frsqrt_s);
2630   // CHECK_EQ(static_cast<float>(), t.result_fscaleb_s);
2631   // CHECK_EQ(static_cast<float>( 6.906890), t.result_flogb_s);
2632   // CHECK_EQ(static_cast<float>( 2.75e4), t.result_fcopysign_s);
2633   // CHECK_EQ(static_cast<float>(), t.result_fclass_s);
2634 }
2635 
TEST(FCMP_COND)2636 TEST(FCMP_COND) {
2637   CcTest::InitializeVM();
2638   Isolate* isolate = CcTest::i_isolate();
2639   HandleScope scope(isolate);
2640   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
2641 
2642   struct TestFloat {
2643     double dTrue;
2644     double dFalse;
2645     double dOp1;
2646     double dOp2;
2647     double dCaf;
2648     double dCun;
2649     double dCeq;
2650     double dCueq;
2651     double dClt;
2652     double dCult;
2653     double dCle;
2654     double dCule;
2655     double dCne;
2656     double dCor;
2657     double dCune;
2658     double dSaf;
2659     double dSun;
2660     double dSeq;
2661     double dSueq;
2662     double dSlt;
2663     double dSult;
2664     double dSle;
2665     double dSule;
2666     double dSne;
2667     double dSor;
2668     double dSune;
2669     float fTrue;
2670     float fFalse;
2671     float fOp1;
2672     float fOp2;
2673     float fCaf;
2674     float fCun;
2675     float fCeq;
2676     float fCueq;
2677     float fClt;
2678     float fCult;
2679     float fCle;
2680     float fCule;
2681     float fCne;
2682     float fCor;
2683     float fCune;
2684     float fSaf;
2685     float fSun;
2686     float fSeq;
2687     float fSueq;
2688     float fSlt;
2689     float fSult;
2690     float fSle;
2691     float fSule;
2692     float fSne;
2693     float fSor;
2694     float fSune;
2695   };
2696 
2697   TestFloat test;
2698 
2699   __ Fld_d(f8, MemOperand(a0, offsetof(TestFloat, dOp1)));
2700   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, dOp2)));
2701 
2702   __ Fld_s(f10, MemOperand(a0, offsetof(TestFloat, fOp1)));
2703   __ Fld_s(f11, MemOperand(a0, offsetof(TestFloat, fOp2)));
2704 
2705   __ Fld_d(f12, MemOperand(a0, offsetof(TestFloat, dFalse)));
2706   __ Fld_d(f13, MemOperand(a0, offsetof(TestFloat, dTrue)));
2707 
2708   __ Fld_s(f14, MemOperand(a0, offsetof(TestFloat, fFalse)));
2709   __ Fld_s(f15, MemOperand(a0, offsetof(TestFloat, fTrue)));
2710 
2711   __ fcmp_cond_d(CAF, f8, f9, FCC0);
2712   __ fcmp_cond_s(CAF, f10, f11, FCC1);
2713   __ fsel(FCC0, f16, f12, f13);
2714   __ fsel(FCC1, f17, f14, f15);
2715   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCaf)));
2716   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCaf)));
2717 
2718   __ fcmp_cond_d(CUN, f8, f9, FCC0);
2719   __ fcmp_cond_s(CUN, f10, f11, FCC1);
2720   __ fsel(FCC0, f16, f12, f13);
2721   __ fsel(FCC1, f17, f14, f15);
2722   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCun)));
2723   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCun)));
2724 
2725   __ fcmp_cond_d(CEQ, f8, f9, FCC0);
2726   __ fcmp_cond_s(CEQ, f10, f11, FCC1);
2727   __ fsel(FCC0, f16, f12, f13);
2728   __ fsel(FCC1, f17, f14, f15);
2729   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCeq)));
2730   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCeq)));
2731 
2732   __ fcmp_cond_d(CUEQ, f8, f9, FCC0);
2733   __ fcmp_cond_s(CUEQ, f10, f11, FCC1);
2734   __ fsel(FCC0, f16, f12, f13);
2735   __ fsel(FCC1, f17, f14, f15);
2736   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCueq)));
2737   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCueq)));
2738 
2739   __ fcmp_cond_d(CLT, f8, f9, FCC0);
2740   __ fcmp_cond_s(CLT, f10, f11, FCC1);
2741   __ fsel(FCC0, f16, f12, f13);
2742   __ fsel(FCC1, f17, f14, f15);
2743   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dClt)));
2744   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fClt)));
2745 
2746   __ fcmp_cond_d(CULT, f8, f9, FCC0);
2747   __ fcmp_cond_s(CULT, f10, f11, FCC1);
2748   __ fsel(FCC0, f16, f12, f13);
2749   __ fsel(FCC1, f17, f14, f15);
2750   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCult)));
2751   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCult)));
2752 
2753   __ fcmp_cond_d(CLE, f8, f9, FCC0);
2754   __ fcmp_cond_s(CLE, f10, f11, FCC1);
2755   __ fsel(FCC0, f16, f12, f13);
2756   __ fsel(FCC1, f17, f14, f15);
2757   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCle)));
2758   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCle)));
2759 
2760   __ fcmp_cond_d(CULE, f8, f9, FCC0);
2761   __ fcmp_cond_s(CULE, f10, f11, FCC1);
2762   __ fsel(FCC0, f16, f12, f13);
2763   __ fsel(FCC1, f17, f14, f15);
2764   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCule)));
2765   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCule)));
2766 
2767   __ fcmp_cond_d(CNE, f8, f9, FCC0);
2768   __ fcmp_cond_s(CNE, f10, f11, FCC1);
2769   __ fsel(FCC0, f16, f12, f13);
2770   __ fsel(FCC1, f17, f14, f15);
2771   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCne)));
2772   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCne)));
2773 
2774   __ fcmp_cond_d(COR, f8, f9, FCC0);
2775   __ fcmp_cond_s(COR, f10, f11, FCC1);
2776   __ fsel(FCC0, f16, f12, f13);
2777   __ fsel(FCC1, f17, f14, f15);
2778   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCor)));
2779   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCor)));
2780 
2781   __ fcmp_cond_d(CUNE, f8, f9, FCC0);
2782   __ fcmp_cond_s(CUNE, f10, f11, FCC1);
2783   __ fsel(FCC0, f16, f12, f13);
2784   __ fsel(FCC1, f17, f14, f15);
2785   __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dCune)));
2786   __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fCune)));
2787 
2788   /*  __ fcmp_cond_d(SAF, f8, f9, FCC0);
2789     __ fcmp_cond_s(SAF, f10, f11, FCC1);
2790     __ fsel(FCC0, f16, f12, f13);
2791     __ fsel(FCC1, f17, f14, f15);
2792     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSaf)));
2793     __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fSaf)));
2794 
2795     __ fcmp_cond_d(SUN, f8, f9, FCC0);
2796     __ fcmp_cond_s(SUN, f10, f11, FCC1);
2797     __ fsel(FCC0, f16, f12, f13);
2798     __ fsel(FCC1, f17, f14, f15);
2799     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSun)));
2800     __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fSun)));
2801 
2802     __ fcmp_cond_d(SEQ, f8, f9, FCC0);
2803     __ fcmp_cond_s(SEQ, f10, f11, FCC1);
2804     __ fsel(FCC0, f16, f12, f13);
2805     __ fsel(FCC1, f17, f14, f15);
2806     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSeq)));
2807     __ Fst_f(f17, MemOperand(a0, offsetof(TestFloat, fSeq)));
2808 
2809     __ fcmp_cond_d(SUEQ, f8, f9, FCC0);
2810     __ fcmp_cond_s(SUEQ, f10, f11, FCC1);
2811     __ fsel(FCC0, f16, f12, f13);
2812     __ fsel(FCC1, f17, f14, f15);
2813     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSueq)));
2814     __ Fst_f(f17, MemOperand(a0, offsetof(TestFloat, fSueq)));
2815 
2816     __ fcmp_cond_d(SLT, f8, f9, FCC0);
2817     __ fcmp_cond_s(SLT, f10, f11, FCC1);
2818     __ fsel(f16, f12, f13, FCC0);
2819     __ fsel(f17, f14, f15, FCC1);
2820     __ Fld_d(f16, MemOperand(a0, offsetof(TestFloat, dSlt)));
2821     __ Fst_d(f17, MemOperand(a0, offsetof(TestFloat, fSlt)));
2822 
2823     __ fcmp_cond_d(SULT, f8, f9, FCC0);
2824     __ fcmp_cond_s(SULT, f10, f11, FCC1);
2825     __ fsel(FCC0, f16, f12, f13);
2826     __ fsel(FCC1, f17, f14, f15);
2827     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSult)));
2828     __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fSult)));
2829 
2830     __ fcmp_cond_d(SLE, f8, f9, FCC0);
2831     __ fcmp_cond_s(SLE, f10, f11, FCC1);
2832     __ fsel(FCC0, f16, f12, f13);
2833     __ fsel(FCC1, f17, f14, f15);
2834     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSle)));
2835     __ Fst_f(f17, MemOperand(a0, offsetof(TestFloat, fSle)));
2836 
2837     __ fcmp_cond_d(SULE, f8, f9, FCC0);
2838     __ fcmp_cond_s(SULE, f10, f11, FCC1);
2839     __ fsel(FCC0, f16, f12, f13);
2840     __ fsel(FCC1, f17, f14, f15);
2841     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSule)));
2842     __ Fst_f(f17, MemOperand(a0, offsetof(TestFloat, fSule)));
2843 
2844     __ fcmp_cond_d(SNE, f8, f9, FCC0);
2845     __ fcmp_cond_s(SNE, f10, f11, FCC1);
2846     __ fsel(FCC0, f16, f12, f13);
2847     __ fsel(FCC1, f17, f14, f15);
2848     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSne)));
2849     __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fSne)));
2850 
2851     __ fcmp_cond_d(SOR, f8, f9, FCC0);
2852     __ fcmp_cond_s(SOR, f10, f11, FCC1);
2853     __ fsel(FCC0, f16, f12, f13);
2854     __ fsel(FCC1, f17, f14, f15);
2855     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSor)));
2856     __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fSor)));
2857 
2858     __ fcmp_cond_d(SUNE, f8, f9, FCC0);
2859     __ fcmp_cond_s(SUNE, f10, f11, FCC1);
2860     __ fsel(FCC0, f16, f12, f13);
2861     __ fsel(FCC1, f17, f14, f15);
2862     __ Fst_d(f16, MemOperand(a0, offsetof(TestFloat, dSune)));
2863     __ Fst_s(f17, MemOperand(a0, offsetof(TestFloat, fSune)));*/
2864 
2865   __ jirl(zero_reg, ra, 0);
2866 
2867   CodeDesc desc;
2868   assm.GetCode(isolate, &desc);
2869   Handle<Code> code =
2870       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
2871   auto f = GeneratedCode<F3>::FromCode(*code);
2872   test.dTrue = 1234.0;
2873   test.dFalse = 0.0;
2874   test.fTrue = 12.0;
2875   test.fFalse = 0.0;
2876 
2877   test.dOp1 = 2.0;
2878   test.dOp2 = 3.0;
2879   test.fOp1 = 2.0;
2880   test.fOp2 = 3.0;
2881   f.Call(&test, 0, 0, 0, 0);
2882 
2883   CHECK_EQ(test.dCaf, test.dFalse);
2884   CHECK_EQ(test.fCaf, test.fFalse);
2885   CHECK_EQ(test.dCun, test.dFalse);
2886   CHECK_EQ(test.fCun, test.fFalse);
2887   CHECK_EQ(test.dCeq, test.dFalse);
2888   CHECK_EQ(test.fCeq, test.fFalse);
2889   CHECK_EQ(test.dCueq, test.dFalse);
2890   CHECK_EQ(test.fCueq, test.fFalse);
2891   CHECK_EQ(test.dClt, test.dTrue);
2892   CHECK_EQ(test.fClt, test.fTrue);
2893   CHECK_EQ(test.dCult, test.dTrue);
2894   CHECK_EQ(test.fCult, test.fTrue);
2895   CHECK_EQ(test.dCle, test.dTrue);
2896   CHECK_EQ(test.fCle, test.fTrue);
2897   CHECK_EQ(test.dCule, test.dTrue);
2898   CHECK_EQ(test.fCule, test.fTrue);
2899   CHECK_EQ(test.dCne, test.dTrue);
2900   CHECK_EQ(test.fCne, test.fTrue);
2901   CHECK_EQ(test.dCor, test.dTrue);
2902   CHECK_EQ(test.fCor, test.fTrue);
2903   CHECK_EQ(test.dCune, test.dTrue);
2904   CHECK_EQ(test.fCune, test.fTrue);
2905   /*  CHECK_EQ(test.dSaf, test.dFalse);
2906     CHECK_EQ(test.fSaf, test.fFalse);
2907     CHECK_EQ(test.dSun, test.dFalse);
2908     CHECK_EQ(test.fSun, test.fFalse);
2909     CHECK_EQ(test.dSeq, test.dFalse);
2910     CHECK_EQ(test.fSeq, test.fFalse);
2911     CHECK_EQ(test.dSueq, test.dFalse);
2912     CHECK_EQ(test.fSueq, test.fFalse);
2913     CHECK_EQ(test.dClt, test.dTrue);
2914     CHECK_EQ(test.fClt, test.fTrue);
2915     CHECK_EQ(test.dCult, test.dTrue);
2916     CHECK_EQ(test.fCult, test.fTrue);
2917     CHECK_EQ(test.dSle, test.dTrue);
2918     CHECK_EQ(test.fSle, test.fTrue);
2919     CHECK_EQ(test.dSule, test.dTrue);
2920     CHECK_EQ(test.fSule, test.fTrue);
2921     CHECK_EQ(test.dSne, test.dTrue);
2922     CHECK_EQ(test.fSne, test.fTrue);
2923     CHECK_EQ(test.dSor, test.dTrue);
2924     CHECK_EQ(test.fSor, test.fTrue);
2925     CHECK_EQ(test.dSune, test.dTrue);
2926     CHECK_EQ(test.fSune, test.fTrue);*/
2927 
2928   test.dOp1 = std::numeric_limits<double>::max();
2929   test.dOp2 = std::numeric_limits<double>::min();
2930   test.fOp1 = std::numeric_limits<float>::min();
2931   test.fOp2 = -std::numeric_limits<float>::max();
2932   f.Call(&test, 0, 0, 0, 0);
2933 
2934   CHECK_EQ(test.dCaf, test.dFalse);
2935   CHECK_EQ(test.fCaf, test.fFalse);
2936   CHECK_EQ(test.dCun, test.dFalse);
2937   CHECK_EQ(test.fCun, test.fFalse);
2938   CHECK_EQ(test.dCeq, test.dFalse);
2939   CHECK_EQ(test.fCeq, test.fFalse);
2940   CHECK_EQ(test.dCueq, test.dFalse);
2941   CHECK_EQ(test.fCueq, test.fFalse);
2942   CHECK_EQ(test.dClt, test.dFalse);
2943   CHECK_EQ(test.fClt, test.fFalse);
2944   CHECK_EQ(test.dCult, test.dFalse);
2945   CHECK_EQ(test.fCult, test.fFalse);
2946   CHECK_EQ(test.dCle, test.dFalse);
2947   CHECK_EQ(test.fCle, test.fFalse);
2948   CHECK_EQ(test.dCule, test.dFalse);
2949   CHECK_EQ(test.fCule, test.fFalse);
2950   CHECK_EQ(test.dCne, test.dTrue);
2951   CHECK_EQ(test.fCne, test.fTrue);
2952   CHECK_EQ(test.dCor, test.dTrue);
2953   CHECK_EQ(test.fCor, test.fTrue);
2954   CHECK_EQ(test.dCune, test.dTrue);
2955   CHECK_EQ(test.fCune, test.fTrue);
2956   /*  CHECK_EQ(test.dSaf, test.dFalse);
2957     CHECK_EQ(test.fSaf, test.fFalse);
2958     CHECK_EQ(test.dSun, test.dFalse);
2959     CHECK_EQ(test.fSun, test.fFalse);
2960     CHECK_EQ(test.dSeq, test.dFalse);
2961     CHECK_EQ(test.fSeq, test.fFalse);
2962     CHECK_EQ(test.dSueq, test.dFalse);
2963     CHECK_EQ(test.fSueq, test.fFalse);
2964     CHECK_EQ(test.dSlt, test.dFalse);
2965     CHECK_EQ(test.fSlt, test.fFalse);
2966     CHECK_EQ(test.dSult, test.dFalse);
2967     CHECK_EQ(test.fSult, test.fFalse);
2968     CHECK_EQ(test.dSle, test.dFalse);
2969     CHECK_EQ(test.fSle, test.fFalse);
2970     CHECK_EQ(test.dSule, test.dFalse);
2971     CHECK_EQ(test.fSule, test.fFalse);
2972     CHECK_EQ(test.dSne, test.dTrue);
2973     CHECK_EQ(test.fSne, test.fTrue);
2974     CHECK_EQ(test.dSor, test.dTrue);
2975     CHECK_EQ(test.fSor, test.fTrue);
2976     CHECK_EQ(test.dSune, test.dTrue);
2977     CHECK_EQ(test.fSune, test.fTrue);*/
2978 
2979   test.dOp1 = std::numeric_limits<double>::quiet_NaN();
2980   test.dOp2 = 0.0;
2981   test.fOp1 = std::numeric_limits<float>::quiet_NaN();
2982   test.fOp2 = 0.0;
2983   f.Call(&test, 0, 0, 0, 0);
2984 
2985   CHECK_EQ(test.dCaf, test.dFalse);
2986   CHECK_EQ(test.fCaf, test.fFalse);
2987   CHECK_EQ(test.dCun, test.dTrue);
2988   CHECK_EQ(test.fCun, test.fTrue);
2989   CHECK_EQ(test.dCeq, test.dFalse);
2990   CHECK_EQ(test.fCeq, test.fFalse);
2991   CHECK_EQ(test.dCueq, test.dTrue);
2992   CHECK_EQ(test.fCueq, test.fTrue);
2993   CHECK_EQ(test.dClt, test.dFalse);
2994   CHECK_EQ(test.fClt, test.fFalse);
2995   CHECK_EQ(test.dCult, test.dTrue);
2996   CHECK_EQ(test.fCult, test.fTrue);
2997   CHECK_EQ(test.dCle, test.dFalse);
2998   CHECK_EQ(test.fCle, test.fFalse);
2999   CHECK_EQ(test.dCule, test.dTrue);
3000   CHECK_EQ(test.fCule, test.fTrue);
3001   CHECK_EQ(test.dCne, test.dFalse);
3002   CHECK_EQ(test.fCne, test.fFalse);
3003   CHECK_EQ(test.dCor, test.dFalse);
3004   CHECK_EQ(test.fCor, test.fFalse);
3005   CHECK_EQ(test.dCune, test.dTrue);
3006   CHECK_EQ(test.fCune, test.fTrue);
3007   /*  CHECK_EQ(test.dSaf, test.dTrue);
3008     CHECK_EQ(test.fSaf, test.fTrue);
3009     CHECK_EQ(test.dSun, test.dTrue);
3010     CHECK_EQ(test.fSun, test.fTrue);
3011     CHECK_EQ(test.dSeq, test.dFalse);
3012     CHECK_EQ(test.fSeq, test.fFalse);
3013     CHECK_EQ(test.dSueq, test.dTrue);
3014     CHECK_EQ(test.fSueq, test.fTrue);
3015     CHECK_EQ(test.dSlt, test.dFalse);
3016     CHECK_EQ(test.fSlt, test.fFalse);
3017     CHECK_EQ(test.dSult, test.dTrue);
3018     CHECK_EQ(test.fSult, test.fTrue);
3019     CHECK_EQ(test.dSle, test.dFalse);
3020     CHECK_EQ(test.fSle, test.fFalse);
3021     CHECK_EQ(test.dSule, test.dTrue);
3022     CHECK_EQ(test.fSule, test.fTrue);
3023     CHECK_EQ(test.dSne, test.dFalse);
3024     CHECK_EQ(test.fSne, test.fFalse);
3025     CHECK_EQ(test.dSor, test.dFalse);
3026     CHECK_EQ(test.fSor, test.fFalse);
3027     CHECK_EQ(test.dSune, test.dTrue);
3028     CHECK_EQ(test.fSune, test.fTrue);*/
3029 }
3030 
TEST(FCVT)3031 TEST(FCVT) {
3032   CcTest::InitializeVM();
3033   Isolate* isolate = CcTest::i_isolate();
3034   HandleScope scope(isolate);
3035   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3036 
3037   struct TestFloat {
3038     float fcvt_d_s_in;
3039     double fcvt_s_d_in;
3040     double fcvt_d_s_out;
3041     float fcvt_s_d_out;
3042     int fcsr;
3043   };
3044   TestFloat test;
3045   __ xor_(a4, a4, a4);
3046   __ xor_(a5, a5, a5);
3047   __ Ld_w(a4, MemOperand(a0, offsetof(TestFloat, fcsr)));
3048   __ movfcsr2gr(a5);
3049   __ movgr2fcsr(a4);
3050   __ Fld_s(f8, MemOperand(a0, offsetof(TestFloat, fcvt_d_s_in)));
3051   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, fcvt_s_d_in)));
3052   __ fcvt_d_s(f10, f8);
3053   __ fcvt_s_d(f11, f9);
3054   __ Fst_d(f10, MemOperand(a0, offsetof(TestFloat, fcvt_d_s_out)));
3055   __ Fst_s(f11, MemOperand(a0, offsetof(TestFloat, fcvt_s_d_out)));
3056   __ movgr2fcsr(a5);
3057   __ jirl(zero_reg, ra, 0);
3058 
3059   CodeDesc desc;
3060   assm.GetCode(isolate, &desc);
3061   Handle<Code> code =
3062       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3063   auto f = GeneratedCode<F3>::FromCode(*code);
3064   test.fcsr = kRoundToNearest;
3065 
3066   test.fcvt_d_s_in = -0.51;
3067   test.fcvt_s_d_in = -0.51;
3068   f.Call(&test, 0, 0, 0, 0);
3069   CHECK_EQ(test.fcvt_d_s_out, static_cast<double>(test.fcvt_d_s_in));
3070   CHECK_EQ(test.fcvt_s_d_out, static_cast<float>(test.fcvt_s_d_in));
3071 
3072   test.fcvt_d_s_in = 0.49;
3073   test.fcvt_s_d_in = 0.49;
3074   f.Call(&test, 0, 0, 0, 0);
3075   CHECK_EQ(test.fcvt_d_s_out, static_cast<double>(test.fcvt_d_s_in));
3076   CHECK_EQ(test.fcvt_s_d_out, static_cast<float>(test.fcvt_s_d_in));
3077 
3078   test.fcvt_d_s_in = std::numeric_limits<float>::max();
3079   test.fcvt_s_d_in = std::numeric_limits<double>::max();
3080   f.Call(&test, 0, 0, 0, 0);
3081   CHECK_EQ(test.fcvt_d_s_out, static_cast<double>(test.fcvt_d_s_in));
3082   CHECK_EQ(test.fcvt_s_d_out, static_cast<float>(test.fcvt_s_d_in));
3083 
3084   test.fcvt_d_s_in = -std::numeric_limits<float>::max();
3085   test.fcvt_s_d_in = -std::numeric_limits<double>::max();
3086   f.Call(&test, 0, 0, 0, 0);
3087   CHECK_EQ(test.fcvt_d_s_out, static_cast<double>(test.fcvt_d_s_in));
3088   CHECK_EQ(test.fcvt_s_d_out, static_cast<float>(test.fcvt_s_d_in));
3089 
3090   test.fcvt_d_s_in = std::numeric_limits<float>::min();
3091   test.fcvt_s_d_in = std::numeric_limits<double>::min();
3092   f.Call(&test, 0, 0, 0, 0);
3093   CHECK_EQ(test.fcvt_d_s_out, static_cast<double>(test.fcvt_d_s_in));
3094   CHECK_EQ(test.fcvt_s_d_out, static_cast<float>(test.fcvt_s_d_in));
3095 }
3096 
TEST(FFINT)3097 TEST(FFINT) {
3098   CcTest::InitializeVM();
3099   Isolate* isolate = CcTest::i_isolate();
3100   HandleScope scope(isolate);
3101   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3102 
3103   struct TestFloat {
3104     int32_t ffint_s_w_in;
3105     int64_t ffint_s_l_in;
3106     int32_t ffint_d_w_in;
3107     int64_t ffint_d_l_in;
3108     float ffint_s_w_out;
3109     float ffint_s_l_out;
3110     double ffint_d_w_out;
3111     double ffint_d_l_out;
3112     int fcsr;
3113   };
3114   TestFloat test;
3115   __ xor_(a4, a4, a4);
3116   __ xor_(a5, a5, a5);
3117   __ Ld_w(a4, MemOperand(a0, offsetof(TestFloat, fcsr)));
3118   __ movfcsr2gr(a5);
3119   __ movgr2fcsr(a4);
3120   __ Fld_s(f8, MemOperand(a0, offsetof(TestFloat, ffint_s_w_in)));
3121   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, ffint_s_l_in)));
3122   __ Fld_s(f10, MemOperand(a0, offsetof(TestFloat, ffint_d_w_in)));
3123   __ Fld_d(f11, MemOperand(a0, offsetof(TestFloat, ffint_d_l_in)));
3124   __ ffint_s_w(f12, f8);
3125   __ ffint_s_l(f13, f9);
3126   __ ffint_d_w(f14, f10);
3127   __ ffint_d_l(f15, f11);
3128   __ Fst_s(f12, MemOperand(a0, offsetof(TestFloat, ffint_s_w_out)));
3129   __ Fst_s(f13, MemOperand(a0, offsetof(TestFloat, ffint_s_l_out)));
3130   __ Fst_d(f14, MemOperand(a0, offsetof(TestFloat, ffint_d_w_out)));
3131   __ Fst_d(f15, MemOperand(a0, offsetof(TestFloat, ffint_d_l_out)));
3132   __ movgr2fcsr(a5);
3133   __ jirl(zero_reg, ra, 0);
3134 
3135   CodeDesc desc;
3136   assm.GetCode(isolate, &desc);
3137   Handle<Code> code =
3138       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3139   auto f = GeneratedCode<F3>::FromCode(*code);
3140   test.fcsr = kRoundToNearest;
3141 
3142   test.ffint_s_w_in = -1;
3143   test.ffint_s_l_in = -1;
3144   test.ffint_d_w_in = -1;
3145   test.ffint_d_l_in = -1;
3146   f.Call(&test, 0, 0, 0, 0);
3147   CHECK_EQ(test.ffint_s_w_out, static_cast<float>(test.ffint_s_w_in));
3148   CHECK_EQ(test.ffint_s_l_out, static_cast<float>(test.ffint_s_l_in));
3149   CHECK_EQ(test.ffint_d_w_out, static_cast<double>(test.ffint_d_w_in));
3150   CHECK_EQ(test.ffint_d_l_out, static_cast<double>(test.ffint_d_l_in));
3151 
3152   test.ffint_s_w_in = 1;
3153   test.ffint_s_l_in = 1;
3154   test.ffint_d_w_in = 1;
3155   test.ffint_d_l_in = 1;
3156   f.Call(&test, 0, 0, 0, 0);
3157   CHECK_EQ(test.ffint_s_w_out, static_cast<float>(test.ffint_s_w_in));
3158   CHECK_EQ(test.ffint_s_l_out, static_cast<float>(test.ffint_s_l_in));
3159   CHECK_EQ(test.ffint_d_w_out, static_cast<double>(test.ffint_d_w_in));
3160   CHECK_EQ(test.ffint_d_l_out, static_cast<double>(test.ffint_d_l_in));
3161 
3162   test.ffint_s_w_in = std::numeric_limits<int32_t>::max();
3163   test.ffint_s_l_in = std::numeric_limits<int64_t>::max();
3164   test.ffint_d_w_in = std::numeric_limits<int32_t>::max();
3165   test.ffint_d_l_in = std::numeric_limits<int64_t>::max();
3166   f.Call(&test, 0, 0, 0, 0);
3167   CHECK_EQ(test.ffint_s_w_out, static_cast<float>(test.ffint_s_w_in));
3168   CHECK_EQ(test.ffint_s_l_out, static_cast<float>(test.ffint_s_l_in));
3169   CHECK_EQ(test.ffint_d_w_out, static_cast<double>(test.ffint_d_w_in));
3170   CHECK_EQ(test.ffint_d_l_out, static_cast<double>(test.ffint_d_l_in));
3171 
3172   test.ffint_s_w_in = std::numeric_limits<int32_t>::min();
3173   test.ffint_s_l_in = std::numeric_limits<int64_t>::min();
3174   test.ffint_d_w_in = std::numeric_limits<int32_t>::min();
3175   test.ffint_d_l_in = std::numeric_limits<int64_t>::min();
3176   f.Call(&test, 0, 0, 0, 0);
3177   CHECK_EQ(test.ffint_s_w_out, static_cast<float>(test.ffint_s_w_in));
3178   CHECK_EQ(test.ffint_s_l_out, static_cast<float>(test.ffint_s_l_in));
3179   CHECK_EQ(test.ffint_d_w_out, static_cast<double>(test.ffint_d_w_in));
3180   CHECK_EQ(test.ffint_d_l_out, static_cast<double>(test.ffint_d_l_in));
3181 }
3182 
TEST(FTINT)3183 TEST(FTINT) {
3184   CcTest::InitializeVM();
3185   Isolate* isolate = CcTest::i_isolate();
3186   HandleScope scope(isolate);
3187   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3188 
3189   struct Test {
3190     double a;
3191     float b;
3192     int32_t c;
3193     int32_t d;
3194     int64_t e;
3195     int64_t f;
3196     int fcsr;
3197   };
3198   Test test;
3199 
3200   const int kTableLength = 9;
3201   // clang-format off
3202   double inputs_d[kTableLength] = {
3203       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3204       2147483648.0,
3205       std::numeric_limits<double>::quiet_NaN(),
3206       std::numeric_limits<double>::infinity()
3207       };
3208   float inputs_s[kTableLength] = {
3209       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3210       2147483648.0,
3211       std::numeric_limits<double>::quiet_NaN(),
3212       std::numeric_limits<double>::infinity()
3213       };
3214   double outputs_RN_W[kTableLength] = {
3215       3.0, 4.0, 4.0, -3.0, -4.0, -4.0,
3216       kFPUInvalidResult, 0,
3217       kFPUInvalidResult};
3218   double outputs_RN_L[kTableLength] = {
3219       3.0, 4.0, 4.0, -3.0, -4.0, -4.0,
3220       2147483648.0, 0,
3221       static_cast<double>(kFPU64InvalidResult)};
3222   double outputs_RZ_W[kTableLength] = {
3223       3.0, 3.0, 3.0, -3.0, -3.0, -3.0,
3224       kFPUInvalidResult, 0,
3225       kFPUInvalidResult};
3226   double outputs_RZ_L[kTableLength] = {
3227       3.0, 3.0, 3.0, -3.0, -3.0, -3.0,
3228       2147483648.0, 0,
3229       static_cast<double>(kFPU64InvalidResult)};
3230   double outputs_RP_W[kTableLength] = {
3231       4.0, 4.0, 4.0, -3.0, -3.0, -3.0,
3232       kFPUInvalidResult, 0,
3233       kFPUInvalidResult};
3234   double outputs_RP_L[kTableLength] = {
3235       4.0, 4.0, 4.0, -3.0, -3.0, -3.0,
3236       2147483648.0, 0,
3237       static_cast<double>(kFPU64InvalidResult)};
3238   double outputs_RM_W[kTableLength] = {
3239       3.0, 3.0, 3.0, -4.0, -4.0, -4.0,
3240       kFPUInvalidResult, 0,
3241       kFPUInvalidResult};
3242   double outputs_RM_L[kTableLength] = {
3243       3.0, 3.0, 3.0, -4.0, -4.0, -4.0,
3244       2147483648.0, 0,
3245       static_cast<double>(kFPU64InvalidResult)};
3246   // clang-format on
3247 
3248   int fcsr_inputs[4] = {kRoundToNearest, kRoundToZero, kRoundToPlusInf,
3249                         kRoundToMinusInf};
3250   double* outputs[8] = {
3251       outputs_RN_W, outputs_RN_L, outputs_RZ_W, outputs_RZ_L,
3252       outputs_RP_W, outputs_RP_L, outputs_RM_W, outputs_RM_L,
3253   };
3254 
3255   __ Fld_d(f8, MemOperand(a0, offsetof(Test, a)));
3256   __ Fld_s(f9, MemOperand(a0, offsetof(Test, b)));
3257   __ xor_(a5, a5, a5);
3258   __ Ld_w(a5, MemOperand(a0, offsetof(Test, fcsr)));
3259   __ movfcsr2gr(a4);
3260   __ movgr2fcsr(a5);
3261   __ ftint_w_d(f10, f8);
3262   __ ftint_w_s(f11, f9);
3263   __ ftint_l_d(f12, f8);
3264   __ ftint_l_s(f13, f9);
3265   __ Fst_s(f10, MemOperand(a0, offsetof(Test, c)));
3266   __ Fst_s(f11, MemOperand(a0, offsetof(Test, d)));
3267   __ Fst_d(f12, MemOperand(a0, offsetof(Test, e)));
3268   __ Fst_d(f13, MemOperand(a0, offsetof(Test, f)));
3269   __ movgr2fcsr(a4);
3270   __ jirl(zero_reg, ra, 0);
3271 
3272   CodeDesc desc;
3273   assm.GetCode(isolate, &desc);
3274   Handle<Code> code =
3275       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3276   auto f = GeneratedCode<F3>::FromCode(*code);
3277   for (int j = 0; j < 4; j++) {
3278     test.fcsr = fcsr_inputs[j];
3279     for (int i = 0; i < kTableLength; i++) {
3280       test.a = inputs_d[i];
3281       test.b = inputs_s[i];
3282       f.Call(&test, 0, 0, 0, 0);
3283       CHECK_EQ(test.c, outputs[2 * j][i]);
3284       CHECK_EQ(test.d, outputs[2 * j][i]);
3285       CHECK_EQ(test.e, outputs[2 * j + 1][i]);
3286       CHECK_EQ(test.f, outputs[2 * j + 1][i]);
3287     }
3288   }
3289 }
3290 
TEST(FTINTRM)3291 TEST(FTINTRM) {
3292   CcTest::InitializeVM();
3293   Isolate* isolate = CcTest::i_isolate();
3294   HandleScope scope(isolate);
3295   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3296 
3297   struct Test {
3298     double a;
3299     float b;
3300     int32_t c;
3301     int32_t d;
3302     int64_t e;
3303     int64_t f;
3304   };
3305   Test test;
3306 
3307   const int kTableLength = 9;
3308 
3309   // clang-format off
3310   double inputs_d[kTableLength] = {
3311       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3312       2147483648.0,
3313       std::numeric_limits<double>::quiet_NaN(),
3314       std::numeric_limits<double>::infinity()
3315   };
3316   float inputs_s[kTableLength] = {
3317       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3318       2147483648.0,
3319       std::numeric_limits<double>::quiet_NaN(),
3320       std::numeric_limits<double>::infinity()
3321   };
3322   double outputs_w[kTableLength] = {
3323       3.0, 3.0, 3.0, -4.0, -4.0, -4.0,
3324       kFPUInvalidResult, 0,
3325       kFPUInvalidResult};
3326   double outputs_l[kTableLength] = {
3327       3.0, 3.0, 3.0, -4.0, -4.0, -4.0,
3328       2147483648.0, 0,
3329       static_cast<double>(kFPU64InvalidResult)};
3330   // clang-format on
3331 
3332   __ Fld_d(f8, MemOperand(a0, offsetof(Test, a)));
3333   __ Fld_s(f9, MemOperand(a0, offsetof(Test, b)));
3334   __ ftintrm_w_d(f10, f8);
3335   __ ftintrm_w_s(f11, f9);
3336   __ ftintrm_l_d(f12, f8);
3337   __ ftintrm_l_s(f13, f9);
3338   __ Fst_s(f10, MemOperand(a0, offsetof(Test, c)));
3339   __ Fst_s(f11, MemOperand(a0, offsetof(Test, d)));
3340   __ Fst_d(f12, MemOperand(a0, offsetof(Test, e)));
3341   __ Fst_d(f13, MemOperand(a0, offsetof(Test, f)));
3342   __ jirl(zero_reg, ra, 0);
3343 
3344   CodeDesc desc;
3345   assm.GetCode(isolate, &desc);
3346   Handle<Code> code =
3347       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3348   auto f = GeneratedCode<F3>::FromCode(*code);
3349   for (int i = 0; i < kTableLength; i++) {
3350     test.a = inputs_d[i];
3351     test.b = inputs_s[i];
3352     f.Call(&test, 0, 0, 0, 0);
3353     CHECK_EQ(test.c, outputs_w[i]);
3354     CHECK_EQ(test.d, outputs_w[i]);
3355     CHECK_EQ(test.e, outputs_l[i]);
3356     CHECK_EQ(test.f, outputs_l[i]);
3357   }
3358 }
3359 
TEST(FTINTRP)3360 TEST(FTINTRP) {
3361   CcTest::InitializeVM();
3362   Isolate* isolate = CcTest::i_isolate();
3363   HandleScope scope(isolate);
3364   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3365 
3366   struct Test {
3367     double a;
3368     float b;
3369     int32_t c;
3370     int32_t d;
3371     int64_t e;
3372     int64_t f;
3373   };
3374   Test test;
3375 
3376   const int kTableLength = 9;
3377 
3378   // clang-format off
3379   double inputs_d[kTableLength] = {
3380       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3381       2147483648.0,
3382       std::numeric_limits<double>::quiet_NaN(),
3383       std::numeric_limits<double>::infinity()
3384   };
3385   float inputs_s[kTableLength] = {
3386       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3387       2147483648.0,
3388       std::numeric_limits<double>::quiet_NaN(),
3389       std::numeric_limits<double>::infinity()
3390   };
3391   double outputs_w[kTableLength] = {
3392       4.0, 4.0, 4.0, -3.0, -3.0, -3.0,
3393       kFPUInvalidResult, 0,
3394       kFPUInvalidResult};
3395   double outputs_l[kTableLength] = {
3396       4.0, 4.0, 4.0, -3.0, -3.0, -3.0,
3397       2147483648.0, 0,
3398       static_cast<double>(kFPU64InvalidResult)};
3399   // clang-format on
3400 
3401   __ Fld_d(f8, MemOperand(a0, offsetof(Test, a)));
3402   __ Fld_s(f9, MemOperand(a0, offsetof(Test, b)));
3403   __ ftintrp_w_d(f10, f8);
3404   __ ftintrp_w_s(f11, f9);
3405   __ ftintrp_l_d(f12, f8);
3406   __ ftintrp_l_s(f13, f9);
3407   __ Fst_s(f10, MemOperand(a0, offsetof(Test, c)));
3408   __ Fst_s(f11, MemOperand(a0, offsetof(Test, d)));
3409   __ Fst_d(f12, MemOperand(a0, offsetof(Test, e)));
3410   __ Fst_d(f13, MemOperand(a0, offsetof(Test, f)));
3411   __ jirl(zero_reg, ra, 0);
3412 
3413   CodeDesc desc;
3414   assm.GetCode(isolate, &desc);
3415   Handle<Code> code =
3416       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3417   auto f = GeneratedCode<F3>::FromCode(*code);
3418   for (int i = 0; i < kTableLength; i++) {
3419     test.a = inputs_d[i];
3420     test.b = inputs_s[i];
3421     f.Call(&test, 0, 0, 0, 0);
3422     CHECK_EQ(test.c, outputs_w[i]);
3423     CHECK_EQ(test.d, outputs_w[i]);
3424     CHECK_EQ(test.e, outputs_l[i]);
3425     CHECK_EQ(test.f, outputs_l[i]);
3426   }
3427 }
3428 
TEST(FTINTRZ)3429 TEST(FTINTRZ) {
3430   CcTest::InitializeVM();
3431   Isolate* isolate = CcTest::i_isolate();
3432   HandleScope scope(isolate);
3433   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3434 
3435   struct Test {
3436     double a;
3437     float b;
3438     int32_t c;
3439     int32_t d;
3440     int64_t e;
3441     int64_t f;
3442   };
3443   Test test;
3444 
3445   const int kTableLength = 9;
3446 
3447   // clang-format off
3448   double inputs_d[kTableLength] = {
3449       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3450       2147483648.0,
3451       std::numeric_limits<double>::quiet_NaN(),
3452       std::numeric_limits<double>::infinity()
3453   };
3454   float inputs_s[kTableLength] = {
3455       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3456       2147483648.0,
3457       std::numeric_limits<double>::quiet_NaN(),
3458       std::numeric_limits<double>::infinity()
3459   };
3460   double outputs_w[kTableLength] = {
3461       3.0, 3.0, 3.0, -3.0, -3.0, -3.0,
3462       kFPUInvalidResult, 0,
3463       kFPUInvalidResult};
3464   double outputs_l[kTableLength] = {
3465       3.0, 3.0, 3.0, -3.0, -3.0, -3.0,
3466       2147483648.0, 0,
3467       static_cast<double>(kFPU64InvalidResult)};
3468   // clang-format on
3469 
3470   __ Fld_d(f8, MemOperand(a0, offsetof(Test, a)));
3471   __ Fld_s(f9, MemOperand(a0, offsetof(Test, b)));
3472   __ ftintrz_w_d(f10, f8);
3473   __ ftintrz_w_s(f11, f9);
3474   __ ftintrz_l_d(f12, f8);
3475   __ ftintrz_l_s(f13, f9);
3476   __ Fst_s(f10, MemOperand(a0, offsetof(Test, c)));
3477   __ Fst_s(f11, MemOperand(a0, offsetof(Test, d)));
3478   __ Fst_d(f12, MemOperand(a0, offsetof(Test, e)));
3479   __ Fst_d(f13, MemOperand(a0, offsetof(Test, f)));
3480   __ jirl(zero_reg, ra, 0);
3481 
3482   CodeDesc desc;
3483   assm.GetCode(isolate, &desc);
3484   Handle<Code> code =
3485       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3486   auto f = GeneratedCode<F3>::FromCode(*code);
3487   for (int i = 0; i < kTableLength; i++) {
3488     test.a = inputs_d[i];
3489     test.b = inputs_s[i];
3490     f.Call(&test, 0, 0, 0, 0);
3491     CHECK_EQ(test.c, outputs_w[i]);
3492     CHECK_EQ(test.d, outputs_w[i]);
3493     CHECK_EQ(test.e, outputs_l[i]);
3494     CHECK_EQ(test.f, outputs_l[i]);
3495   }
3496 }
3497 
TEST(FTINTRNE)3498 TEST(FTINTRNE) {
3499   CcTest::InitializeVM();
3500   Isolate* isolate = CcTest::i_isolate();
3501   HandleScope scope(isolate);
3502   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3503 
3504   struct Test {
3505     double a;
3506     float b;
3507     int32_t c;
3508     int32_t d;
3509     int64_t e;
3510     int64_t f;
3511   };
3512   Test test;
3513 
3514   const int kTableLength = 9;
3515 
3516   // clang-format off
3517   double inputs_d[kTableLength] = {
3518       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3519       2147483648.0,
3520       std::numeric_limits<double>::quiet_NaN(),
3521       std::numeric_limits<double>::infinity()
3522   };
3523   float inputs_s[kTableLength] = {
3524       3.1, 3.6, 3.5, -3.1, -3.6, -3.5,
3525       2147483648.0,
3526       std::numeric_limits<double>::quiet_NaN(),
3527       std::numeric_limits<double>::infinity()
3528   };
3529   double outputs_w[kTableLength] = {
3530       3.0, 4.0, 4.0, -3.0, -4.0, -4.0,
3531       kFPUInvalidResult, 0,
3532       kFPUInvalidResult};
3533   double outputs_l[kTableLength] = {
3534       3.0, 4.0, 4.0, -3.0, -4.0, -4.0,
3535       2147483648.0, 0,
3536       static_cast<double>(kFPU64InvalidResult)};
3537   // clang-format on
3538 
3539   __ Fld_d(f8, MemOperand(a0, offsetof(Test, a)));
3540   __ Fld_s(f9, MemOperand(a0, offsetof(Test, b)));
3541   __ ftintrne_w_d(f10, f8);
3542   __ ftintrne_w_s(f11, f9);
3543   __ ftintrne_l_d(f12, f8);
3544   __ ftintrne_l_s(f13, f9);
3545   __ Fst_s(f10, MemOperand(a0, offsetof(Test, c)));
3546   __ Fst_s(f11, MemOperand(a0, offsetof(Test, d)));
3547   __ Fst_d(f12, MemOperand(a0, offsetof(Test, e)));
3548   __ Fst_d(f13, MemOperand(a0, offsetof(Test, f)));
3549   __ jirl(zero_reg, ra, 0);
3550 
3551   CodeDesc desc;
3552   assm.GetCode(isolate, &desc);
3553   Handle<Code> code =
3554       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3555   auto f = GeneratedCode<F3>::FromCode(*code);
3556   for (int i = 0; i < kTableLength; i++) {
3557     test.a = inputs_d[i];
3558     test.b = inputs_s[i];
3559     f.Call(&test, 0, 0, 0, 0);
3560     CHECK_EQ(test.c, outputs_w[i]);
3561     CHECK_EQ(test.d, outputs_w[i]);
3562     CHECK_EQ(test.e, outputs_l[i]);
3563     CHECK_EQ(test.f, outputs_l[i]);
3564   }
3565 }
3566 
TEST(FRINT)3567 TEST(FRINT) {
3568   CcTest::InitializeVM();
3569   Isolate* isolate = CcTest::i_isolate();
3570   HandleScope scope(isolate);
3571   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3572 
3573   struct Test {
3574     double a;
3575     float b;
3576     double c;
3577     float d;
3578     int fcsr;
3579   };
3580   Test test;
3581 
3582   const int kTableLength = 32;
3583 
3584   // clang-format off
3585   double inputs_d[kTableLength] = {
3586       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3587       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
3588       1.7976931348623157E+308, 6.27463370218383111104242366943E-307,
3589       309485009821345068724781056.89,
3590       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
3591       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
3592       37778931862957161709568.0, 37778931862957161709569.0,
3593       37778931862957161709580.0, 37778931862957161709581.0,
3594       37778931862957161709582.0, 37778931862957161709583.0,
3595       37778931862957161709584.0, 37778931862957161709585.0,
3596       37778931862957161709586.0, 37778931862957161709587.0,
3597       std::numeric_limits<double>::max() - 0.1,
3598       std::numeric_limits<double>::infinity()
3599       };
3600   float inputs_s[kTableLength] = {
3601       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3602       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
3603       1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
3604       309485009821345068724781056.89,
3605       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
3606       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
3607       37778931862957161709568.0, 37778931862957161709569.0,
3608       37778931862957161709580.0, 37778931862957161709581.0,
3609       37778931862957161709582.0, 37778931862957161709583.0,
3610       37778931862957161709584.0, 37778931862957161709585.0,
3611       37778931862957161709586.0, 37778931862957161709587.0,
3612       std::numeric_limits<float>::lowest() + 0.6,
3613       std::numeric_limits<float>::infinity()
3614       };
3615   float outputs_RN_S[kTableLength] = {
3616       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3617       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
3618       1.7976931348623157E38, 0,
3619       309485009821345068724781057.0,
3620       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
3621       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
3622       37778931862957161709568.0, 37778931862957161709569.0,
3623       37778931862957161709580.0, 37778931862957161709581.0,
3624       37778931862957161709582.0, 37778931862957161709583.0,
3625       37778931862957161709584.0, 37778931862957161709585.0,
3626       37778931862957161709586.0, 37778931862957161709587.0,
3627       std::numeric_limits<float>::lowest() + 1,
3628       std::numeric_limits<float>::infinity()
3629       };
3630   double outputs_RN_D[kTableLength] = {
3631       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3632       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
3633       1.7976931348623157E308, 0,
3634       309485009821345068724781057.0,
3635       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
3636       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
3637       37778931862957161709568.0, 37778931862957161709569.0,
3638       37778931862957161709580.0, 37778931862957161709581.0,
3639       37778931862957161709582.0, 37778931862957161709583.0,
3640       37778931862957161709584.0, 37778931862957161709585.0,
3641       37778931862957161709586.0, 37778931862957161709587.0,
3642       std::numeric_limits<double>::max(),
3643       std::numeric_limits<double>::infinity()
3644   };
3645   float outputs_RZ_S[kTableLength] = {
3646       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3647       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
3648       1.7976931348623157E38, 0,
3649       309485009821345068724781057.0,
3650       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
3651       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
3652       37778931862957161709568.0, 37778931862957161709569.0,
3653       37778931862957161709580.0, 37778931862957161709581.0,
3654       37778931862957161709582.0, 37778931862957161709583.0,
3655       37778931862957161709584.0, 37778931862957161709585.0,
3656       37778931862957161709586.0, 37778931862957161709587.0,
3657       std::numeric_limits<float>::lowest() + 1,
3658       std::numeric_limits<float>::infinity()
3659   };
3660   double outputs_RZ_D[kTableLength] = {
3661       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3662       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
3663       1.7976931348623157E308, 0,
3664       309485009821345068724781057.0,
3665       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
3666       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
3667       37778931862957161709568.0, 37778931862957161709569.0,
3668       37778931862957161709580.0, 37778931862957161709581.0,
3669       37778931862957161709582.0, 37778931862957161709583.0,
3670       37778931862957161709584.0, 37778931862957161709585.0,
3671       37778931862957161709586.0, 37778931862957161709587.0,
3672       std::numeric_limits<double>::max() - 1,
3673       std::numeric_limits<double>::infinity()
3674   };
3675   float outputs_RP_S[kTableLength] = {
3676       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3677       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
3678       1.7976931348623157E38, 1,
3679       309485009821345068724781057.0,
3680       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
3681       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
3682       37778931862957161709568.0, 37778931862957161709569.0,
3683       37778931862957161709580.0, 37778931862957161709581.0,
3684       37778931862957161709582.0, 37778931862957161709583.0,
3685       37778931862957161709584.0, 37778931862957161709585.0,
3686       37778931862957161709586.0, 37778931862957161709587.0,
3687       std::numeric_limits<float>::lowest() + 1,
3688       std::numeric_limits<float>::infinity()
3689   };
3690   double outputs_RP_D[kTableLength] = {
3691       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3692       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
3693       1.7976931348623157E308, 1,
3694       309485009821345068724781057.0,
3695       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
3696       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
3697       37778931862957161709568.0, 37778931862957161709569.0,
3698       37778931862957161709580.0, 37778931862957161709581.0,
3699       37778931862957161709582.0, 37778931862957161709583.0,
3700       37778931862957161709584.0, 37778931862957161709585.0,
3701       37778931862957161709586.0, 37778931862957161709587.0,
3702       std::numeric_limits<double>::max(),
3703       std::numeric_limits<double>::infinity()
3704   };
3705   float outputs_RM_S[kTableLength] = {
3706       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3707       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
3708       1.7976931348623157E38, 0,
3709       309485009821345068724781057.0,
3710       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
3711       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
3712       37778931862957161709568.0, 37778931862957161709569.0,
3713       37778931862957161709580.0, 37778931862957161709581.0,
3714       37778931862957161709582.0, 37778931862957161709583.0,
3715       37778931862957161709584.0, 37778931862957161709585.0,
3716       37778931862957161709586.0, 37778931862957161709587.0,
3717       std::numeric_limits<float>::lowest() + 1,
3718       std::numeric_limits<float>::infinity()
3719   };
3720   double outputs_RM_D[kTableLength] = {
3721       18446744073709551617.0, 4503599627370496.0, -4503599627370496.0,
3722       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
3723       1.7976931348623157E308, 0,
3724       309485009821345068724781057.0,
3725       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
3726       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
3727       37778931862957161709568.0, 37778931862957161709569.0,
3728       37778931862957161709580.0, 37778931862957161709581.0,
3729       37778931862957161709582.0, 37778931862957161709583.0,
3730       37778931862957161709584.0, 37778931862957161709585.0,
3731       37778931862957161709586.0, 37778931862957161709587.0,
3732       std::numeric_limits<double>::max(),
3733       std::numeric_limits<double>::infinity()
3734   };
3735   // clang-format on
3736 
3737   int fcsr_inputs[4] = {kRoundToNearest, kRoundToZero, kRoundToPlusInf,
3738                         kRoundToMinusInf};
3739   double* outputs_d[4] = {outputs_RN_D, outputs_RZ_D, outputs_RP_D,
3740                           outputs_RM_D};
3741   float* outputs_s[4] = {outputs_RN_S, outputs_RZ_S, outputs_RP_S,
3742                          outputs_RM_S};
3743 
3744   __ Fld_d(f8, MemOperand(a0, offsetof(Test, a)));
3745   __ Fld_s(f9, MemOperand(a0, offsetof(Test, b)));
3746   __ xor_(a5, a5, a5);
3747   __ Ld_w(a5, MemOperand(a0, offsetof(Test, fcsr)));
3748   __ movfcsr2gr(a4);
3749   __ movgr2fcsr(a5);
3750   __ frint_d(f10, f8);
3751   __ frint_s(f11, f9);
3752   __ Fst_d(f10, MemOperand(a0, offsetof(Test, c)));
3753   __ Fst_s(f11, MemOperand(a0, offsetof(Test, d)));
3754   __ movgr2fcsr(a4);
3755   __ jirl(zero_reg, ra, 0);
3756 
3757   CodeDesc desc;
3758   assm.GetCode(isolate, &desc);
3759   Handle<Code> code =
3760       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3761   auto f = GeneratedCode<F3>::FromCode(*code);
3762   for (int j = 0; j < 4; j++) {
3763     test.fcsr = fcsr_inputs[j];
3764     for (int i = 0; i < kTableLength; i++) {
3765       test.a = inputs_d[i];
3766       test.b = inputs_s[i];
3767       f.Call(&test, 0, 0, 0, 0);
3768       CHECK_EQ(test.c, outputs_d[j][i]);
3769       CHECK_EQ(test.d, outputs_s[j][i]);
3770     }
3771   }
3772 }
3773 
TEST(FMOV)3774 TEST(FMOV) {
3775   const int kTableLength = 7;
3776   CcTest::InitializeVM();
3777   Isolate* isolate = CcTest::i_isolate();
3778   HandleScope scope(isolate);
3779   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3780 
3781   struct TestFloat {
3782     double a;
3783     float b;
3784     double c;
3785     float d;
3786   };
3787 
3788   TestFloat test;
3789 
3790   // clang-format off
3791   double inputs_D[kTableLength] = {
3792     5.3, -5.3, 0.29, -0.29, 0,
3793   std::numeric_limits<double>::max(),
3794   -std::numeric_limits<double>::max()
3795   };
3796   float inputs_S[kTableLength] = {
3797     4.8, -4.8, 0.29, -0.29, 0,
3798   std::numeric_limits<float>::max(),
3799   -std::numeric_limits<float>::max()
3800   };
3801 
3802   double outputs_D[kTableLength] = {
3803     5.3, -5.3, 0.29, -0.29, 0,
3804   std::numeric_limits<double>::max(),
3805   -std::numeric_limits<double>::max()
3806   };
3807 
3808   float outputs_S[kTableLength] = {
3809     4.8, -4.8, 0.29, -0.29, 0,
3810   std::numeric_limits<float>::max(),
3811   -std::numeric_limits<float>::max()
3812   };
3813   // clang-format on
3814 
3815   __ Fld_d(f8, MemOperand(a0, offsetof(TestFloat, a)));
3816   __ Fld_s(f9, MemOperand(a0, offsetof(TestFloat, b)));
3817   __ fmov_d(f10, f8);
3818   __ fmov_s(f11, f9);
3819   __ Fst_d(f10, MemOperand(a0, offsetof(TestFloat, c)));
3820   __ Fst_s(f11, MemOperand(a0, offsetof(TestFloat, d)));
3821   __ jirl(zero_reg, ra, 0);
3822 
3823   CodeDesc desc;
3824   assm.GetCode(isolate, &desc);
3825   Handle<Code> code =
3826       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3827   auto f = GeneratedCode<F3>::FromCode(*code);
3828   for (int i = 0; i < kTableLength; i++) {
3829     test.a = inputs_D[i];
3830     test.b = inputs_S[i];
3831     f.Call(&test, 0, 0, 0, 0);
3832     CHECK_EQ(test.c, outputs_D[i]);
3833     CHECK_EQ(test.d, outputs_S[i]);
3834   }
3835 }
3836 
TEST(LA14)3837 TEST(LA14) {
3838   CcTest::InitializeVM();
3839   Isolate* isolate = CcTest::i_isolate();
3840   HandleScope scope(isolate);
3841 
3842   struct T {
3843     double a;
3844     double b;
3845     double c;
3846     double d;
3847     int64_t high;
3848     int64_t low;
3849   };
3850   T t;
3851 
3852   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3853 
3854   __ Fld_d(f8, MemOperand(a0, offsetof(T, a)));
3855   __ Fld_d(f9, MemOperand(a0, offsetof(T, b)));
3856 
3857   __ movfr2gr_s(a4, f8);
3858   __ movfrh2gr_s(a5, f8);
3859   __ movfr2gr_d(a6, f9);
3860 
3861   __ movgr2fr_w(f9, a4);
3862   __ movgr2frh_w(f9, a5);
3863   __ movgr2fr_d(f8, a6);
3864 
3865   __ Fst_d(f8, MemOperand(a0, offsetof(T, a)));
3866   __ Fst_d(f9, MemOperand(a0, offsetof(T, c)));
3867 
3868   __ Fld_d(f8, MemOperand(a0, offsetof(T, d)));
3869   __ movfrh2gr_s(a4, f8);
3870   __ movfr2gr_s(a5, f8);
3871 
3872   __ St_d(a4, MemOperand(a0, offsetof(T, high)));
3873   __ St_d(a5, MemOperand(a0, offsetof(T, low)));
3874 
3875   __ jirl(zero_reg, ra, 0);
3876 
3877   CodeDesc desc;
3878   assm.GetCode(isolate, &desc);
3879   Handle<Code> code =
3880       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3881   auto f = GeneratedCode<F3>::FromCode(*code);
3882 
3883   t.a = 1.5e22;
3884   t.b = 2.75e11;
3885   t.c = 17.17;
3886   t.d = -2.75e11;
3887   f.Call(&t, 0, 0, 0, 0);
3888   CHECK_EQ(2.75e11, t.a);
3889   CHECK_EQ(2.75e11, t.b);
3890   CHECK_EQ(1.5e22, t.c);
3891   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFC25001D1L), t.high);
3892   CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFBF800000L), t.low);
3893 
3894   t.a = -1.5e22;
3895   t.b = -2.75e11;
3896   t.c = 17.17;
3897   t.d = 274999868928.0;
3898   f.Call(&t, 0, 0, 0, 0);
3899   CHECK_EQ(-2.75e11, t.a);
3900   CHECK_EQ(-2.75e11, t.b);
3901   CHECK_EQ(-1.5e22, t.c);
3902   CHECK_EQ(static_cast<int64_t>(0x425001D1L), t.high);
3903   CHECK_EQ(static_cast<int64_t>(0x3F800000L), t.low);
3904 }
3905 
run_bceqz(int fcc_value,int32_t offset)3906 uint64_t run_bceqz(int fcc_value, int32_t offset) {
3907   Isolate* isolate = CcTest::i_isolate();
3908   HandleScope scope(isolate);
3909 
3910   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3911 
3912   Label main_block, L;
3913   __ li(a2, 0);
3914   __ li(t0, fcc_value);
3915   __ b(&main_block);
3916   // Block 1
3917   for (int32_t i = -104; i <= -55; ++i) {
3918     __ addi_d(a2, a2, 0x1);
3919   }
3920   __ b(&L);
3921 
3922   // Block 2
3923   for (int32_t i = -53; i <= -4; ++i) {
3924     __ addi_d(a2, a2, 0x10);
3925   }
3926   __ b(&L);
3927 
3928   // Block 3 (Main)
3929   __ bind(&main_block);
3930   __ movcf2gr(t1, FCC0);
3931   __ movgr2cf(FCC0, t0);
3932   __ bceqz(FCC0, offset);
3933   __ bind(&L);
3934   __ movgr2cf(FCC0, t1);
3935   __ or_(a0, a2, zero_reg);
3936   __ jirl(zero_reg, ra, 0);
3937 
3938   // Block 4
3939   for (int32_t i = 4; i <= 53; ++i) {
3940     __ addi_d(a2, a2, 0x100);
3941   }
3942   __ b(&L);
3943 
3944   // Block 5
3945   for (int32_t i = 55; i <= 104; ++i) {
3946     __ addi_d(a2, a2, 0x300);
3947   }
3948   __ b(&L);
3949 
3950   CodeDesc desc;
3951   assm.GetCode(isolate, &desc);
3952   Handle<Code> code =
3953       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
3954   auto f = GeneratedCode<F2>::FromCode(*code);
3955   uint64_t res = reinterpret_cast<uint64_t>(f.Call(0, 0, 0, 0, 0));
3956 
3957   return res;
3958 }
3959 
TEST(BCEQZ)3960 TEST(BCEQZ) {
3961   CcTest::InitializeVM();
3962   struct TestCaseBceqz {
3963     int fcc;
3964     int32_t offset;
3965     uint64_t expected_res;
3966   };
3967 
3968   // clang-format off
3969   struct TestCaseBceqz tc[] = {
3970     // fcc, offset, expected_res
3971     {    0,    -90,         0x24 },
3972     {    0,    -27,        0x180 },
3973     {    0,     47,        0x700 },
3974     {    0,     70,       0x6900 },
3975     {    1,    -27,            0 },
3976     {    1,     47,            0 },
3977   };
3978   // clang-format on
3979 
3980   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBceqz);
3981   for (size_t i = 0; i < nr_test_cases; ++i) {
3982     uint64_t res = run_bceqz(tc[i].fcc, tc[i].offset);
3983     CHECK_EQ(tc[i].expected_res, res);
3984   }
3985 }
3986 
run_bcnez(int fcc_value,int32_t offset)3987 uint64_t run_bcnez(int fcc_value, int32_t offset) {
3988   Isolate* isolate = CcTest::i_isolate();
3989   HandleScope scope(isolate);
3990 
3991   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
3992 
3993   Label main_block, L;
3994   __ li(a2, 0);
3995   __ li(t0, fcc_value);
3996   __ b(&main_block);
3997   // Block 1
3998   for (int32_t i = -104; i <= -55; ++i) {
3999     __ addi_d(a2, a2, 0x1);
4000   }
4001   __ b(&L);
4002 
4003   // Block 2
4004   for (int32_t i = -53; i <= -4; ++i) {
4005     __ addi_d(a2, a2, 0x10);
4006   }
4007   __ b(&L);
4008 
4009   // Block 3 (Main)
4010   __ bind(&main_block);
4011   __ movcf2gr(t1, FCC0);
4012   __ movgr2cf(FCC0, t0);
4013   __ bcnez(FCC0, offset);
4014   __ bind(&L);
4015   __ movgr2cf(FCC0, t1);
4016   __ or_(a0, a2, zero_reg);
4017   __ jirl(zero_reg, ra, 0);
4018 
4019   // Block 4
4020   for (int32_t i = 4; i <= 53; ++i) {
4021     __ addi_d(a2, a2, 0x100);
4022   }
4023   __ b(&L);
4024 
4025   // Block 5
4026   for (int32_t i = 55; i <= 104; ++i) {
4027     __ addi_d(a2, a2, 0x300);
4028   }
4029   __ b(&L);
4030 
4031   CodeDesc desc;
4032   assm.GetCode(isolate, &desc);
4033   Handle<Code> code =
4034       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4035   auto f = GeneratedCode<F2>::FromCode(*code);
4036   uint64_t res = reinterpret_cast<uint64_t>(f.Call(0, 0, 0, 0, 0));
4037 
4038   return res;
4039 }
4040 
TEST(BCNEZ)4041 TEST(BCNEZ) {
4042   CcTest::InitializeVM();
4043   struct TestCaseBcnez {
4044     int fcc;
4045     int32_t offset;
4046     uint64_t expected_res;
4047   };
4048 
4049   // clang-format off
4050   struct TestCaseBcnez tc[] = {
4051     // fcc, offset, expected_res
4052     {    1,    -90,         0x24 },
4053     {    1,    -27,        0x180 },
4054     {    1,     47,        0x700 },
4055     {    1,     70,       0x6900 },
4056     {    0,    -27,            0 },
4057     {    0,     47,            0 },
4058   };
4059   // clang-format on
4060 
4061   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBcnez);
4062   for (size_t i = 0; i < nr_test_cases; ++i) {
4063     uint64_t res = run_bcnez(tc[i].fcc, tc[i].offset);
4064     CHECK_EQ(tc[i].expected_res, res);
4065   }
4066 }
4067 
TEST(jump_tables1)4068 TEST(jump_tables1) {
4069   // Test jump tables with forward jumps.
4070   CcTest::InitializeVM();
4071   Isolate* isolate = CcTest::i_isolate();
4072   HandleScope scope(isolate);
4073   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4074 
4075   const int kNumCases = 512;
4076   int values[kNumCases];
4077   isolate->random_number_generator()->NextBytes(values, sizeof(values));
4078   Label labels[kNumCases];
4079 
4080   __ addi_d(sp, sp, -8);
4081   __ St_d(ra, MemOperand(sp, 0));
4082   __ Align(8);
4083 
4084   Label done;
4085   {
4086     __ BlockTrampolinePoolFor(kNumCases * 2 + 6);
4087     __ pcaddi(ra, 2);
4088     __ slli_d(t7, a0, 3);
4089     __ add_d(t7, t7, ra);
4090     __ Ld_d(t7, MemOperand(t7, 4 * kInstrSize));
4091     __ jirl(zero_reg, t7, 0);
4092     __ nop();
4093     for (int i = 0; i < kNumCases; ++i) {
4094       __ dd(&labels[i]);
4095     }
4096   }
4097 
4098   for (int i = 0; i < kNumCases; ++i) {
4099     __ bind(&labels[i]);
4100     __ lu12i_w(a2, (values[i] >> 12) & 0xFFFFF);
4101     __ ori(a2, a2, values[i] & 0xFFF);
4102     __ b(&done);
4103     __ nop();
4104   }
4105 
4106   __ bind(&done);
4107   __ Ld_d(ra, MemOperand(sp, 0));
4108   __ addi_d(sp, sp, 8);
4109   __ or_(a0, a2, zero_reg);
4110   __ jirl(zero_reg, ra, 0);
4111 
4112   CHECK_EQ(0, assm.UnboundLabelsCount());
4113 
4114   CodeDesc desc;
4115   assm.GetCode(isolate, &desc);
4116   Handle<Code> code =
4117       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4118 #ifdef OBJECT_PRINT
4119   code->Print(std::cout);
4120 #endif
4121   auto f = GeneratedCode<F1>::FromCode(*code);
4122   for (int i = 0; i < kNumCases; ++i) {
4123     int64_t res = reinterpret_cast<int64_t>(f.Call(i, 0, 0, 0, 0));
4124     ::printf("f(%d) = %" PRId64 "\n", i, res);
4125     CHECK_EQ((values[i]), static_cast<int>(res));
4126   }
4127 }
4128 
TEST(jump_tables2)4129 TEST(jump_tables2) {
4130   // Test jump tables with backward jumps.
4131   CcTest::InitializeVM();
4132   Isolate* isolate = CcTest::i_isolate();
4133   HandleScope scope(isolate);
4134   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4135 
4136   const int kNumCases = 512;
4137   int values[kNumCases];
4138   isolate->random_number_generator()->NextBytes(values, sizeof(values));
4139   Label labels[kNumCases];
4140 
4141   __ addi_d(sp, sp, -8);
4142   __ St_d(ra, MemOperand(sp, 0));
4143 
4144   Label done, dispatch;
4145   __ b(&dispatch);
4146   __ nop();
4147 
4148   for (int i = 0; i < kNumCases; ++i) {
4149     __ bind(&labels[i]);
4150     __ lu12i_w(a2, (values[i] >> 12) & 0xFFFFF);
4151     __ ori(a2, a2, values[i] & 0xFFF);
4152     __ b(&done);
4153     __ nop();
4154   }
4155 
4156   __ Align(8);
4157   __ bind(&dispatch);
4158   {
4159     __ BlockTrampolinePoolFor(kNumCases * 2 + 6);
4160     __ pcaddi(ra, 2);
4161     __ slli_d(t7, a0, 3);
4162     __ add_d(t7, t7, ra);
4163     __ Ld_d(t7, MemOperand(t7, 4 * kInstrSize));
4164     __ jirl(zero_reg, t7, 0);
4165     __ nop();
4166     for (int i = 0; i < kNumCases; ++i) {
4167       __ dd(&labels[i]);
4168     }
4169   }
4170 
4171   __ bind(&done);
4172   __ Ld_d(ra, MemOperand(sp, 0));
4173   __ addi_d(sp, sp, 8);
4174   __ or_(a0, a2, zero_reg);
4175   __ jirl(zero_reg, ra, 0);
4176 
4177   CodeDesc desc;
4178   assm.GetCode(isolate, &desc);
4179   Handle<Code> code =
4180       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4181 #ifdef OBJECT_PRINT
4182   code->Print(std::cout);
4183 #endif
4184   auto f = GeneratedCode<F1>::FromCode(*code);
4185   for (int i = 0; i < kNumCases; ++i) {
4186     int64_t res = reinterpret_cast<int64_t>(f.Call(i, 0, 0, 0, 0));
4187     ::printf("f(%d) = %" PRId64 "\n", i, res);
4188     CHECK_EQ(values[i], res);
4189   }
4190 }
4191 
TEST(jump_tables3)4192 TEST(jump_tables3) {
4193   // Test jump tables with backward jumps and embedded heap objects.
4194   CcTest::InitializeVM();
4195   Isolate* isolate = CcTest::i_isolate();
4196   HandleScope scope(isolate);
4197   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4198 
4199   const int kNumCases = 512;
4200   Handle<Object> values[kNumCases];
4201   for (int i = 0; i < kNumCases; ++i) {
4202     double value = isolate->random_number_generator()->NextDouble();
4203     values[i] = isolate->factory()->NewHeapNumber<AllocationType::kOld>(value);
4204   }
4205   Label labels[kNumCases];
4206   Object obj;
4207   int64_t imm64;
4208 
4209   __ addi_d(sp, sp, -8);
4210   __ St_d(ra, MemOperand(sp, 0));
4211 
4212   Label done, dispatch;
4213   __ b(&dispatch);
4214   __ nop();
4215 
4216   for (int i = 0; i < kNumCases; ++i) {
4217     __ bind(&labels[i]);
4218     obj = *values[i];
4219     imm64 = obj.ptr();
4220     __ lu12i_w(a2, (imm64 >> 12) & 0xFFFFF);
4221     __ ori(a2, a2, imm64 & 0xFFF);
4222     __ lu32i_d(a2, (imm64 >> 32) & 0xFFFFF);
4223     __ lu52i_d(a2, a2, (imm64 >> 52) & 0xFFF);
4224     __ b(&done);
4225   }
4226 
4227   __ Align(8);
4228   __ bind(&dispatch);
4229   {
4230     __ BlockTrampolinePoolFor(kNumCases * 2 + 6);
4231     __ pcaddi(ra, 2);
4232     __ slli_d(t7, a0, 3);  // In delay slot.
4233     __ add_d(t7, t7, ra);
4234     __ Ld_d(t7, MemOperand(t7, 4 * kInstrSize));
4235     __ jirl(zero_reg, t7, 0);
4236     __ nop();
4237     for (int i = 0; i < kNumCases; ++i) {
4238       __ dd(&labels[i]);
4239     }
4240   }
4241   __ bind(&done);
4242   __ Ld_d(ra, MemOperand(sp, 0));
4243   __ addi_d(sp, sp, 8);
4244   __ or_(a0, a2, zero_reg);
4245   __ jirl(zero_reg, ra, 0);
4246 
4247   CodeDesc desc;
4248   assm.GetCode(isolate, &desc);
4249   Handle<Code> code =
4250       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4251 #ifdef OBJECT_PRINT
4252   code->Print(std::cout);
4253 #endif
4254   auto f = GeneratedCode<F1>::FromCode(*code);
4255   for (int i = 0; i < kNumCases; ++i) {
4256     Handle<Object> result(
4257         Object(reinterpret_cast<Address>(f.Call(i, 0, 0, 0, 0))), isolate);
4258 #ifdef OBJECT_PRINT
4259     ::printf("f(%d) = ", i);
4260     result->Print(std::cout);
4261     ::printf("\n");
4262 #endif
4263     CHECK(values[i].is_identical_to(result));
4264   }
4265 }
4266 
run_li_macro(int64_t imm,LiFlags mode,int32_t num_instr=0)4267 uint64_t run_li_macro(int64_t imm, LiFlags mode, int32_t num_instr = 0) {
4268   Isolate* isolate = CcTest::i_isolate();
4269   HandleScope scope(isolate);
4270   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4271 
4272   Label code_start;
4273   __ bind(&code_start);
4274   __ li(a2, imm, mode);
4275   if (num_instr > 0) {
4276     CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr);
4277     CHECK_EQ(__ InstrCountForLi64Bit(imm), num_instr);
4278   }
4279   __ or_(a0, a2, zero_reg);
4280   __ jirl(zero_reg, ra, 0);
4281 
4282   CodeDesc desc;
4283   assm.GetCode(isolate, &desc);
4284   Handle<Code> code =
4285       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4286 #ifdef OBJECT_PRINT
4287   code->Print(std::cout);
4288 #endif
4289   auto f = GeneratedCode<F2>::FromCode(*code);
4290 
4291   uint64_t res = reinterpret_cast<uint64_t>(f.Call(0, 0, 0, 0, 0));
4292 
4293   return res;
4294 }
4295 
TEST(li_macro)4296 TEST(li_macro) {
4297   CcTest::InitializeVM();
4298 
4299   // Test li macro-instruction for border cases.
4300 
4301   struct TestCase_li {
4302     uint64_t imm;
4303     int32_t num_instr;
4304   };
4305   // clang-format off
4306   struct TestCase_li tc[] = {
4307       //              imm, num_instr
4308       {0xFFFFFFFFFFFFF800,         1},  // min_int12
4309       // The test case above generates addi_d instruction.
4310       // This is int12 value and we can load it using just addi_d.
4311       {             0x800,         1},  // max_int12 + 1
4312       // Generates ori
4313       // max_int12 + 1 is not int12 but is uint12, just use ori.
4314       {0xFFFFFFFFFFFFF7FF,         2},  // min_int12 - 1
4315       // Generates lu12i + ori
4316       // We load int32 value using lu12i_w + ori.
4317       {             0x801,         1},  // max_int12 + 2
4318       // Generates ori
4319       // Also an uint1 value, use ori.
4320       {        0x00001000,         1},  // max_uint12 + 1
4321       // Generates lu12i_w
4322       // Low 12 bits are 0, load value using lu12i_w.
4323       {        0x00001001,         2},  // max_uint12 + 2
4324       // Generates lu12i_w + ori
4325       // We have to generate two instructions in this case.
4326       {0x00000000FFFFFFFF,         2},  // max_uint32
4327       // addi_w + lu32i_d
4328       {0x00000000FFFFFFFE,         2},  // max_uint32 - 1
4329       // addi_w + lu32i_d
4330       {0xFFFFFFFF80000000,         1},  // min_int32
4331       // lu12i_w
4332       {0x0000000080000000,         2},  // max_int32 + 1
4333       // lu12i_w + lu32i_d
4334       {0xFFFF0000FFFF8765,         3},
4335       // lu12i_w + ori + lu32i_d
4336       {0x1234ABCD87654321,         4},
4337       // lu12i_w + ori + lu32i_d + lu52i_d
4338       {0xFFFF789100000000,         2},
4339       // xor + lu32i_d
4340       {0xF12F789100000000,         3},
4341       // xor + lu32i_d + lu52i_d
4342       {0xF120000000000800,         2},
4343       // ori + lu52i_d
4344       {0xFFF0000000000000,         1},
4345       // lu52i_d
4346       {0xF100000000000000,         1},
4347       {0x0122000000000000,         2},
4348       {0x1234FFFF77654321,         4},
4349       {0x1230000077654321,         3},
4350   };
4351   // clang-format on
4352 
4353   size_t nr_test_cases = sizeof(tc) / sizeof(TestCase_li);
4354   for (size_t i = 0; i < nr_test_cases; ++i) {
4355     CHECK_EQ(tc[i].imm,
4356              run_li_macro(tc[i].imm, OPTIMIZE_SIZE, tc[i].num_instr));
4357     CHECK_EQ(tc[i].imm, run_li_macro(tc[i].imm, CONSTANT_SIZE));
4358     if (is_int48(tc[i].imm)) {
4359       CHECK_EQ(tc[i].imm, run_li_macro(tc[i].imm, ADDRESS_LOAD));
4360     }
4361   }
4362 }
4363 
TEST(FMIN_FMAX)4364 TEST(FMIN_FMAX) {
4365   CcTest::InitializeVM();
4366   Isolate* isolate = CcTest::i_isolate();
4367   HandleScope scope(isolate);
4368   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4369 
4370   struct TestFloat {
4371     double a;
4372     double b;
4373     float c;
4374     float d;
4375     double e;
4376     double f;
4377     float g;
4378     float h;
4379   };
4380 
4381   TestFloat test;
4382   const double dnan = std::numeric_limits<double>::quiet_NaN();
4383   const double dinf = std::numeric_limits<double>::infinity();
4384   const double dminf = -std::numeric_limits<double>::infinity();
4385   const float fnan = std::numeric_limits<float>::quiet_NaN();
4386   const float finf = std::numeric_limits<float>::infinity();
4387   const float fminf = -std::numeric_limits<float>::infinity();
4388   const int kTableLength = 13;
4389 
4390   // clang-format off
4391   double inputsa[kTableLength] = {2.0,  3.0,  dnan, 3.0,   -0.0, 0.0, dinf,
4392                                   dnan, 42.0, dinf, dminf, dinf, dnan};
4393   double inputsb[kTableLength] = {3.0,  2.0,  3.0,  dnan, 0.0,   -0.0, dnan,
4394                                   dinf, dinf, 42.0, dinf, dminf, dnan};
4395   double outputsdmin[kTableLength] = {2.0,   2.0,   3.0,  3.0,  -0.0,
4396                                       -0.0,  dinf,  dinf, 42.0, 42.0,
4397                                       dminf, dminf, dnan};
4398   double outputsdmax[kTableLength] = {3.0,  3.0,  3.0,  3.0,  0.0,  0.0, dinf,
4399                                       dinf, dinf, dinf, dinf, dinf, dnan};
4400 
4401   float inputsc[kTableLength] = {2.0,  3.0,  fnan, 3.0,   -0.0, 0.0, finf,
4402                                  fnan, 42.0, finf, fminf, finf, fnan};
4403   float inputsd[kTableLength] = {3.0,  2.0,  3.0,  fnan, 0.0,   -0.0, fnan,
4404                                  finf, finf, 42.0, finf, fminf, fnan};
4405   float outputsfmin[kTableLength] = {2.0,   2.0,   3.0,  3.0,  -0.0,
4406                                      -0.0,  finf,  finf, 42.0, 42.0,
4407                                      fminf, fminf, fnan};
4408   float outputsfmax[kTableLength] = {3.0,  3.0,  3.0,  3.0,  0.0,  0.0, finf,
4409                                      finf, finf, finf, finf, finf, fnan};
4410   // clang-format on
4411 
4412   __ Fld_d(f8, MemOperand(a0, offsetof(TestFloat, a)));
4413   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, b)));
4414   __ Fld_s(f10, MemOperand(a0, offsetof(TestFloat, c)));
4415   __ Fld_s(f11, MemOperand(a0, offsetof(TestFloat, d)));
4416   __ fmin_d(f12, f8, f9);
4417   __ fmax_d(f13, f8, f9);
4418   __ fmin_s(f14, f10, f11);
4419   __ fmax_s(f15, f10, f11);
4420   __ Fst_d(f12, MemOperand(a0, offsetof(TestFloat, e)));
4421   __ Fst_d(f13, MemOperand(a0, offsetof(TestFloat, f)));
4422   __ Fst_s(f14, MemOperand(a0, offsetof(TestFloat, g)));
4423   __ Fst_s(f15, MemOperand(a0, offsetof(TestFloat, h)));
4424   __ jirl(zero_reg, ra, 0);
4425 
4426   CodeDesc desc;
4427   assm.GetCode(isolate, &desc);
4428   Handle<Code> code =
4429       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4430   auto f = GeneratedCode<F3>::FromCode(*code);
4431   for (int i = 4; i < kTableLength; i++) {
4432     test.a = inputsa[i];
4433     test.b = inputsb[i];
4434     test.c = inputsc[i];
4435     test.d = inputsd[i];
4436 
4437     f.Call(&test, 0, 0, 0, 0);
4438 
4439     CHECK_EQ(0, memcmp(&test.e, &outputsdmin[i], sizeof(test.e)));
4440     CHECK_EQ(0, memcmp(&test.f, &outputsdmax[i], sizeof(test.f)));
4441     CHECK_EQ(0, memcmp(&test.g, &outputsfmin[i], sizeof(test.g)));
4442     CHECK_EQ(0, memcmp(&test.h, &outputsfmax[i], sizeof(test.h)));
4443   }
4444 }
4445 
TEST(FMINA_FMAXA)4446 TEST(FMINA_FMAXA) {
4447   const int kTableLength = 23;
4448   CcTest::InitializeVM();
4449   Isolate* isolate = CcTest::i_isolate();
4450   HandleScope scope(isolate);
4451   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4452   const double dnan = std::numeric_limits<double>::quiet_NaN();
4453   const double dinf = std::numeric_limits<double>::infinity();
4454   const double dminf = -std::numeric_limits<double>::infinity();
4455   const float fnan = std::numeric_limits<float>::quiet_NaN();
4456   const float finf = std::numeric_limits<float>::infinity();
4457   const float fminf = std::numeric_limits<float>::infinity();
4458 
4459   struct TestFloat {
4460     double a;
4461     double b;
4462     double resd1;
4463     double resd2;
4464     float c;
4465     float d;
4466     float resf1;
4467     float resf2;
4468   };
4469 
4470   TestFloat test;
4471   // clang-format off
4472   double inputsa[kTableLength] = {
4473         5.3,  4.8, 6.1,  9.8, 9.8,  9.8,  -10.0, -8.9, -9.8,  -10.0, -8.9, -9.8,
4474     dnan, 3.0, -0.0, 0.0, dinf, dnan, 42.0,  dinf, dminf, dinf,  dnan};
4475   double inputsb[kTableLength] = {
4476         4.8, 5.3,  6.1, -10.0, -8.9, -9.8, 9.8,  9.8,  9.8,  -9.8,  -11.2, -9.8,
4477     3.0, dnan, 0.0, -0.0,  dnan, dinf, dinf, 42.0, dinf, dminf, dnan};
4478   double resd1[kTableLength] = {
4479         4.8, 4.8, 6.1,  9.8,  -8.9, -9.8, 9.8,  -8.9, -9.8,  -9.8,  -8.9, -9.8,
4480     3.0, 3.0, -0.0, -0.0, dinf, dinf, 42.0, 42.0, dminf, dminf, dnan};
4481   double resd2[kTableLength] = {
4482         5.3, 5.3, 6.1, -10.0, 9.8,  9.8,  -10.0, 9.8,  9.8,  -10.0, -11.2, -9.8,
4483     3.0, 3.0, 0.0, 0.0,   dinf, dinf, dinf,  dinf, dinf, dinf,  dnan};
4484   float inputsc[kTableLength] = {
4485         5.3,  4.8, 6.1,  9.8, 9.8,  9.8,  -10.0, -8.9, -9.8,  -10.0, -8.9, -9.8,
4486     fnan, 3.0, -0.0, 0.0, finf, fnan, 42.0,  finf, fminf, finf,  fnan};
4487   float inputsd[kTableLength] = {
4488         4.8,  5.3,  6.1, -10.0, -8.9,  -9.8, 9.8, 9.8, 9.8,  -9.8, -11.2, -9.8,
4489     3.0,  fnan, -0.0, 0.0, fnan, finf, finf, 42.0, finf, fminf, fnan};
4490   float resf1[kTableLength] = {
4491         4.8, 4.8, 6.1,  9.8,  -8.9, -9.8, 9.8,  -8.9, -9.8,  -9.8,  -8.9, -9.8,
4492     3.0, 3.0, -0.0, -0.0, finf, finf, 42.0, 42.0, fminf, fminf, fnan};
4493   float resf2[kTableLength] = {
4494         5.3, 5.3, 6.1, -10.0, 9.8,  9.8,  -10.0, 9.8,  9.8,  -10.0, -11.2, -9.8,
4495     3.0, 3.0, 0.0, 0.0,   finf, finf, finf,  finf, finf, finf,  fnan};
4496   // clang-format on
4497 
4498   __ Fld_d(f8, MemOperand(a0, offsetof(TestFloat, a)));
4499   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, b)));
4500   __ Fld_s(f10, MemOperand(a0, offsetof(TestFloat, c)));
4501   __ Fld_s(f11, MemOperand(a0, offsetof(TestFloat, d)));
4502   __ fmina_d(f12, f8, f9);
4503   __ fmaxa_d(f13, f8, f9);
4504   __ fmina_s(f14, f10, f11);
4505   __ fmaxa_s(f15, f10, f11);
4506   __ Fst_d(f12, MemOperand(a0, offsetof(TestFloat, resd1)));
4507   __ Fst_d(f13, MemOperand(a0, offsetof(TestFloat, resd2)));
4508   __ Fst_s(f14, MemOperand(a0, offsetof(TestFloat, resf1)));
4509   __ Fst_s(f15, MemOperand(a0, offsetof(TestFloat, resf2)));
4510   __ jirl(zero_reg, ra, 0);
4511 
4512   CodeDesc desc;
4513   assm.GetCode(isolate, &desc);
4514   Handle<Code> code =
4515       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4516   auto f = GeneratedCode<F3>::FromCode(*code);
4517   for (int i = 0; i < kTableLength; i++) {
4518     test.a = inputsa[i];
4519     test.b = inputsb[i];
4520     test.c = inputsc[i];
4521     test.d = inputsd[i];
4522     f.Call(&test, 0, 0, 0, 0);
4523     if (i < kTableLength - 1) {
4524       CHECK_EQ(test.resd1, resd1[i]);
4525       CHECK_EQ(test.resd2, resd2[i]);
4526       CHECK_EQ(test.resf1, resf1[i]);
4527       CHECK_EQ(test.resf2, resf2[i]);
4528     } else {
4529       CHECK(std::isnan(test.resd1));
4530       CHECK(std::isnan(test.resd2));
4531       CHECK(std::isnan(test.resf1));
4532       CHECK(std::isnan(test.resf2));
4533     }
4534   }
4535 }
4536 
TEST(FADD)4537 TEST(FADD) {
4538   CcTest::InitializeVM();
4539   Isolate* isolate = CcTest::i_isolate();
4540   HandleScope scope(isolate);
4541   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4542 
4543   struct TestFloat {
4544     double a;
4545     double b;
4546     double c;
4547     float d;
4548     float e;
4549     float f;
4550   };
4551 
4552   TestFloat test;
4553 
4554   __ Fld_d(f8, MemOperand(a0, offsetof(TestFloat, a)));
4555   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, b)));
4556   __ fadd_d(f10, f8, f9);
4557   __ Fst_d(f10, MemOperand(a0, offsetof(TestFloat, c)));
4558 
4559   __ Fld_s(f11, MemOperand(a0, offsetof(TestFloat, d)));
4560   __ Fld_s(f12, MemOperand(a0, offsetof(TestFloat, e)));
4561   __ fadd_s(f13, f11, f12);
4562   __ Fst_s(f13, MemOperand(a0, offsetof(TestFloat, f)));
4563   __ jirl(zero_reg, ra, 0);
4564 
4565   CodeDesc desc;
4566   assm.GetCode(isolate, &desc);
4567   Handle<Code> code =
4568       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4569   auto f = GeneratedCode<F3>::FromCode(*code);
4570   test.a = 2.0;
4571   test.b = 3.0;
4572   test.d = 2.0;
4573   test.e = 3.0;
4574   f.Call(&test, 0, 0, 0, 0);
4575   CHECK_EQ(test.c, 5.0);
4576   CHECK_EQ(test.f, 5.0);
4577 
4578   test.a = std::numeric_limits<double>::max();
4579   test.b = -std::numeric_limits<double>::max();  // lowest()
4580   test.d = std::numeric_limits<float>::max();
4581   test.e = -std::numeric_limits<float>::max();  // lowest()
4582   f.Call(&test, 0, 0, 0, 0);
4583   CHECK_EQ(test.c, 0.0);
4584   CHECK_EQ(test.f, 0.0);
4585 
4586   test.a = std::numeric_limits<double>::max();
4587   test.b = std::numeric_limits<double>::max();
4588   test.d = std::numeric_limits<float>::max();
4589   test.e = std::numeric_limits<float>::max();
4590   f.Call(&test, 0, 0, 0, 0);
4591   CHECK(!std::isfinite(test.c));
4592   CHECK(!std::isfinite(test.f));
4593 
4594   test.a = 5.0;
4595   test.b = std::numeric_limits<double>::signaling_NaN();
4596   test.d = 5.0;
4597   test.e = std::numeric_limits<float>::signaling_NaN();
4598   f.Call(&test, 0, 0, 0, 0);
4599   CHECK(std::isnan(test.c));
4600   CHECK(std::isnan(test.f));
4601 }
4602 
TEST(FSUB)4603 TEST(FSUB) {
4604   const int kTableLength = 12;
4605   CcTest::InitializeVM();
4606   Isolate* isolate = CcTest::i_isolate();
4607   HandleScope scope(isolate);
4608   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4609 
4610   struct TestFloat {
4611     float a;
4612     float b;
4613     float resultS;
4614     double c;
4615     double d;
4616     double resultD;
4617   };
4618 
4619   TestFloat test;
4620 
4621   // clang-format off
4622   double inputfs_D[kTableLength] = {
4623     5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
4624     5.3, 4.8, 2.9, -5.3, -4.8, -2.9
4625   };
4626   double inputft_D[kTableLength] = {
4627     4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
4628     -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
4629   };
4630   double outputs_D[kTableLength] = {
4631     0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
4632     10.1, 10.1, 5.8, -0.5, 0.5, 0.0
4633   };
4634   float inputfs_S[kTableLength] = {
4635     5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
4636     5.3, 4.8, 2.9, -5.3, -4.8, -2.9
4637   };
4638   float inputft_S[kTableLength] = {
4639     4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
4640     -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
4641   };
4642   float outputs_S[kTableLength] = {
4643     0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
4644     10.1, 10.1, 5.8, -0.5, 0.5, 0.0
4645   };
4646   // clang-format on
4647 
4648   __ Fld_s(f8, MemOperand(a0, offsetof(TestFloat, a)));
4649   __ Fld_s(f9, MemOperand(a0, offsetof(TestFloat, b)));
4650   __ Fld_d(f10, MemOperand(a0, offsetof(TestFloat, c)));
4651   __ Fld_d(f11, MemOperand(a0, offsetof(TestFloat, d)));
4652   __ fsub_s(f12, f8, f9);
4653   __ fsub_d(f13, f10, f11);
4654   __ Fst_s(f12, MemOperand(a0, offsetof(TestFloat, resultS)));
4655   __ Fst_d(f13, MemOperand(a0, offsetof(TestFloat, resultD)));
4656   __ jirl(zero_reg, ra, 0);
4657 
4658   CodeDesc desc;
4659   assm.GetCode(isolate, &desc);
4660   Handle<Code> code =
4661       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4662   auto f = GeneratedCode<F3>::FromCode(*code);
4663   for (int i = 0; i < kTableLength; i++) {
4664     test.a = inputfs_S[i];
4665     test.b = inputft_S[i];
4666     test.c = inputfs_D[i];
4667     test.d = inputft_D[i];
4668     f.Call(&test, 0, 0, 0, 0);
4669     CHECK_EQ(test.resultS, outputs_S[i]);
4670     CHECK_EQ(test.resultD, outputs_D[i]);
4671   }
4672 }
4673 
TEST(FMUL)4674 TEST(FMUL) {
4675   const int kTableLength = 4;
4676   CcTest::InitializeVM();
4677   Isolate* isolate = CcTest::i_isolate();
4678   HandleScope scope(isolate);
4679   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4680 
4681   struct TestFloat {
4682     float a;
4683     float b;
4684     float resultS;
4685     double c;
4686     double d;
4687     double resultD;
4688   };
4689 
4690   TestFloat test;
4691   // clang-format off
4692   double inputfs_D[kTableLength] = {
4693     5.3, -5.3, 5.3, -2.9
4694   };
4695   double inputft_D[kTableLength] = {
4696     4.8, 4.8, -4.8, -0.29
4697   };
4698 
4699   float inputfs_S[kTableLength] = {
4700     5.3, -5.3, 5.3, -2.9
4701   };
4702   float inputft_S[kTableLength] = {
4703     4.8, 4.8, -4.8, -0.29
4704   };
4705   // clang-format on
4706   __ Fld_s(f8, MemOperand(a0, offsetof(TestFloat, a)));
4707   __ Fld_s(f9, MemOperand(a0, offsetof(TestFloat, b)));
4708   __ Fld_d(f10, MemOperand(a0, offsetof(TestFloat, c)));
4709   __ Fld_d(f11, MemOperand(a0, offsetof(TestFloat, d)));
4710   __ fmul_s(f12, f8, f9);
4711   __ fmul_d(f13, f10, f11);
4712   __ Fst_s(f12, MemOperand(a0, offsetof(TestFloat, resultS)));
4713   __ Fst_d(f13, MemOperand(a0, offsetof(TestFloat, resultD)));
4714   __ jirl(zero_reg, ra, 0);
4715 
4716   CodeDesc desc;
4717   assm.GetCode(isolate, &desc);
4718   Handle<Code> code =
4719       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4720   auto f = GeneratedCode<F3>::FromCode(*code);
4721   for (int i = 0; i < kTableLength; i++) {
4722     test.a = inputfs_S[i];
4723     test.b = inputft_S[i];
4724     test.c = inputfs_D[i];
4725     test.d = inputft_D[i];
4726     f.Call(&test, 0, 0, 0, 0);
4727     CHECK_EQ(test.resultS, inputfs_S[i] * inputft_S[i]);
4728     CHECK_EQ(test.resultD, inputfs_D[i] * inputft_D[i]);
4729   }
4730 }
4731 
TEST(FDIV)4732 TEST(FDIV) {
4733   CcTest::InitializeVM();
4734   Isolate* isolate = CcTest::i_isolate();
4735   HandleScope scope(isolate);
4736   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4737 
4738   struct Test {
4739     double dOp1;
4740     double dOp2;
4741     double dRes;
4742     float fOp1;
4743     float fOp2;
4744     float fRes;
4745   };
4746 
4747   Test test;
4748 
4749   __ movfcsr2gr(a4);
4750   __ movgr2fcsr(zero_reg);
4751 
4752   __ Fld_d(f8, MemOperand(a0, offsetof(Test, dOp1)));
4753   __ Fld_d(f9, MemOperand(a0, offsetof(Test, dOp2)));
4754   __ Fld_s(f10, MemOperand(a0, offsetof(Test, fOp1)));
4755   __ Fld_s(f11, MemOperand(a0, offsetof(Test, fOp2)));
4756   __ fdiv_d(f12, f8, f9);
4757   __ fdiv_s(f13, f10, f11);
4758   __ Fst_d(f12, MemOperand(a0, offsetof(Test, dRes)));
4759   __ Fst_s(f13, MemOperand(a0, offsetof(Test, fRes)));
4760 
4761   __ movgr2fcsr(a4);
4762   __ jirl(zero_reg, ra, 0);
4763 
4764   CodeDesc desc;
4765   assm.GetCode(isolate, &desc);
4766   Handle<Code> code =
4767       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4768   auto f = GeneratedCode<F3>::FromCode(*code);
4769   f.Call(&test, 0, 0, 0, 0);
4770   const int test_size = 3;
4771   // clang-format off
4772   double dOp1[test_size] = {
4773     5.0,  DBL_MAX,  DBL_MAX};
4774 
4775   double dOp2[test_size] = {
4776     2.0,  2.0,  -DBL_MAX};
4777 
4778   double dRes[test_size] = {
4779     2.5,  DBL_MAX / 2.0,  -1.0};
4780 
4781   float fOp1[test_size] = {
4782     5.0,  FLT_MAX,  FLT_MAX};
4783 
4784   float fOp2[test_size] = {
4785     2.0,  2.0,  -FLT_MAX};
4786 
4787   float fRes[test_size] = {
4788     2.5,  FLT_MAX / 2.0,  -1.0};
4789   // clang-format on
4790 
4791   for (int i = 0; i < test_size; i++) {
4792     test.dOp1 = dOp1[i];
4793     test.dOp2 = dOp2[i];
4794     test.fOp1 = fOp1[i];
4795     test.fOp2 = fOp2[i];
4796 
4797     f.Call(&test, 0, 0, 0, 0);
4798     CHECK_EQ(test.dRes, dRes[i]);
4799     CHECK_EQ(test.fRes, fRes[i]);
4800   }
4801 
4802   test.dOp1 = DBL_MAX;
4803   test.dOp2 = -0.0;
4804   test.fOp1 = FLT_MAX;
4805   test.fOp2 = -0.0;
4806 
4807   f.Call(&test, 0, 0, 0, 0);
4808   CHECK(!std::isfinite(test.dRes));
4809   CHECK(!std::isfinite(test.fRes));
4810 
4811   test.dOp1 = 0.0;
4812   test.dOp2 = -0.0;
4813   test.fOp1 = 0.0;
4814   test.fOp2 = -0.0;
4815 
4816   f.Call(&test, 0, 0, 0, 0);
4817   CHECK(std::isnan(test.dRes));
4818   CHECK(std::isnan(test.fRes));
4819 
4820   test.dOp1 = std::numeric_limits<double>::quiet_NaN();
4821   test.dOp2 = -5.0;
4822   test.fOp1 = std::numeric_limits<float>::quiet_NaN();
4823   test.fOp2 = -5.0;
4824 
4825   f.Call(&test, 0, 0, 0, 0);
4826   CHECK(std::isnan(test.dRes));
4827   CHECK(std::isnan(test.fRes));
4828 }
4829 
TEST(FABS)4830 TEST(FABS) {
4831   CcTest::InitializeVM();
4832   Isolate* isolate = CcTest::i_isolate();
4833   HandleScope scope(isolate);
4834   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4835 
4836   struct TestFloat {
4837     double a;
4838     float b;
4839   };
4840 
4841   TestFloat test;
4842 
4843   __ movfcsr2gr(a4);
4844   __ movgr2fcsr(zero_reg);
4845 
4846   __ Fld_d(f8, MemOperand(a0, offsetof(TestFloat, a)));
4847   __ Fld_s(f9, MemOperand(a0, offsetof(TestFloat, b)));
4848   __ fabs_d(f10, f8);
4849   __ fabs_s(f11, f9);
4850   __ Fst_d(f10, MemOperand(a0, offsetof(TestFloat, a)));
4851   __ Fst_s(f11, MemOperand(a0, offsetof(TestFloat, b)));
4852 
4853   __ movgr2fcsr(a4);
4854   __ jirl(zero_reg, ra, 0);
4855 
4856   CodeDesc desc;
4857   assm.GetCode(isolate, &desc);
4858   Handle<Code> code =
4859       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4860   auto f = GeneratedCode<F3>::FromCode(*code);
4861   test.a = -2.0;
4862   test.b = -2.0;
4863   f.Call(&test, 0, 0, 0, 0);
4864   CHECK_EQ(test.a, 2.0);
4865   CHECK_EQ(test.b, 2.0);
4866 
4867   test.a = 2.0;
4868   test.b = 2.0;
4869   f.Call(&test, 0, 0, 0, 0);
4870   CHECK_EQ(test.a, 2.0);
4871   CHECK_EQ(test.b, 2.0);
4872 
4873   // Testing biggest positive number
4874   test.a = std::numeric_limits<double>::max();
4875   test.b = std::numeric_limits<float>::max();
4876   f.Call(&test, 0, 0, 0, 0);
4877   CHECK_EQ(test.a, std::numeric_limits<double>::max());
4878   CHECK_EQ(test.b, std::numeric_limits<float>::max());
4879 
4880   // Testing smallest negative number
4881   test.a = -std::numeric_limits<double>::max();  // lowest()
4882   test.b = -std::numeric_limits<float>::max();   // lowest()
4883   f.Call(&test, 0, 0, 0, 0);
4884   CHECK_EQ(test.a, std::numeric_limits<double>::max());
4885   CHECK_EQ(test.b, std::numeric_limits<float>::max());
4886 
4887   // Testing smallest positive number
4888   test.a = -std::numeric_limits<double>::min();
4889   test.b = -std::numeric_limits<float>::min();
4890   f.Call(&test, 0, 0, 0, 0);
4891   CHECK_EQ(test.a, std::numeric_limits<double>::min());
4892   CHECK_EQ(test.b, std::numeric_limits<float>::min());
4893 
4894   // Testing infinity
4895   test.a =
4896       -std::numeric_limits<double>::max() / std::numeric_limits<double>::min();
4897   test.b =
4898       -std::numeric_limits<float>::max() / std::numeric_limits<float>::min();
4899   f.Call(&test, 0, 0, 0, 0);
4900   CHECK_EQ(test.a, std::numeric_limits<double>::max() /
4901                        std::numeric_limits<double>::min());
4902   CHECK_EQ(test.b, std::numeric_limits<float>::max() /
4903                        std::numeric_limits<float>::min());
4904 
4905   test.a = std::numeric_limits<double>::quiet_NaN();
4906   test.b = std::numeric_limits<float>::quiet_NaN();
4907   f.Call(&test, 0, 0, 0, 0);
4908   CHECK(std::isnan(test.a));
4909   CHECK(std::isnan(test.b));
4910 
4911   test.a = std::numeric_limits<double>::signaling_NaN();
4912   test.b = std::numeric_limits<float>::signaling_NaN();
4913   f.Call(&test, 0, 0, 0, 0);
4914   CHECK(std::isnan(test.a));
4915   CHECK(std::isnan(test.b));
4916 }
4917 
4918 template <class T>
4919 struct TestCaseMaddMsub {
4920   T fj, fk, fa, fd_fmadd, fd_fmsub, fd_fnmadd, fd_fnmsub;
4921 };
4922 
4923 template <typename T, typename F>
helper_fmadd_fmsub_fnmadd_fnmsub(F func)4924 void helper_fmadd_fmsub_fnmadd_fnmsub(F func) {
4925   CcTest::InitializeVM();
4926   Isolate* isolate = CcTest::i_isolate();
4927   HandleScope scope(isolate);
4928   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
4929 
4930   T x = std::sqrt(static_cast<T>(2.0));
4931   T y = std::sqrt(static_cast<T>(3.0));
4932   T z = std::sqrt(static_cast<T>(5.0));
4933   T x2 = 11.11, y2 = 22.22, z2 = 33.33;
4934   // clang-format off
4935   TestCaseMaddMsub<T> test_cases[] = {
4936       {x, y, z, 0.0, 0.0, 0.0, 0.0},
4937       {x, y, -z, 0.0, 0.0, 0.0, 0.0},
4938       {x, -y, z, 0.0, 0.0, 0.0, 0.0},
4939       {x, -y, -z, 0.0, 0.0, 0.0, 0.0},
4940       {-x, y, z, 0.0, 0.0, 0.0, 0.0},
4941       {-x, y, -z, 0.0, 0.0, 0.0, 0.0},
4942       {-x, -y, z, 0.0, 0.0, 0.0, 0.0},
4943       {-x, -y, -z, 0.0, 0.0, 0.0, 0.0},
4944       {-3.14, 0.2345, -123.000056, 0.0, 0.0, 0.0, 0.0},
4945       {7.3, -23.257, -357.1357, 0.0, 0.0, 0.0, 0.0},
4946       {x2, y2, z2, 0.0, 0.0, 0.0, 0.0},
4947       {x2, y2, -z2, 0.0, 0.0, 0.0, 0.0},
4948       {x2, -y2, z2, 0.0, 0.0, 0.0, 0.0},
4949       {x2, -y2, -z2, 0.0, 0.0, 0.0, 0.0},
4950       {-x2, y2, z2, 0.0, 0.0, 0.0, 0.0},
4951       {-x2, y2, -z2, 0.0, 0.0, 0.0, 0.0},
4952       {-x2, -y2, z2, 0.0, 0.0, 0.0, 0.0},
4953       {-x2, -y2, -z2, 0.0, 0.0, 0.0, 0.0},
4954   };
4955   // clang-format on
4956   if (std::is_same<T, float>::value) {
4957     __ Fld_s(f8, MemOperand(a0, offsetof(TestCaseMaddMsub<T>, fj)));
4958     __ Fld_s(f9, MemOperand(a0, offsetof(TestCaseMaddMsub<T>, fk)));
4959     __ Fld_s(f10, MemOperand(a0, offsetof(TestCaseMaddMsub<T>, fa)));
4960   } else if (std::is_same<T, double>::value) {
4961     __ Fld_d(f8, MemOperand(a0, offsetof(TestCaseMaddMsub<T>, fj)));
4962     __ Fld_d(f9, MemOperand(a0, offsetof(TestCaseMaddMsub<T>, fk)));
4963     __ Fld_d(f10, MemOperand(a0, offsetof(TestCaseMaddMsub<T>, fa)));
4964   } else {
4965     UNREACHABLE();
4966   }
4967 
4968   func(assm);
4969   __ jirl(zero_reg, ra, 0);
4970 
4971   CodeDesc desc;
4972   assm.GetCode(isolate, &desc);
4973   Handle<Code> code =
4974       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
4975   auto f = GeneratedCode<F3>::FromCode(*code);
4976 
4977   const size_t kTableLength = sizeof(test_cases) / sizeof(TestCaseMaddMsub<T>);
4978   TestCaseMaddMsub<T> tc;
4979   for (size_t i = 0; i < kTableLength; i++) {
4980     tc.fj = test_cases[i].fj;
4981     tc.fk = test_cases[i].fk;
4982     tc.fa = test_cases[i].fa;
4983 
4984     f.Call(&tc, 0, 0, 0, 0);
4985 
4986     T res_fmadd;
4987     T res_fmsub;
4988     T res_fnmadd;
4989     T res_fnmsub;
4990     res_fmadd = std::fma(tc.fj, tc.fk, tc.fa);
4991     res_fmsub = std::fma(tc.fj, tc.fk, -tc.fa);
4992     res_fnmadd = -std::fma(tc.fj, tc.fk, tc.fa);
4993     res_fnmsub = -std::fma(tc.fj, tc.fk, -tc.fa);
4994 
4995     CHECK_EQ(tc.fd_fmadd, res_fmadd);
4996     CHECK_EQ(tc.fd_fmsub, res_fmsub);
4997     CHECK_EQ(tc.fd_fnmadd, res_fnmadd);
4998     CHECK_EQ(tc.fd_fnmsub, res_fnmsub);
4999   }
5000 }
5001 
TEST(FMADD_FMSUB_FNMADD_FNMSUB_S)5002 TEST(FMADD_FMSUB_FNMADD_FNMSUB_S) {
5003   helper_fmadd_fmsub_fnmadd_fnmsub<float>([](MacroAssembler& assm) {
5004     __ fmadd_s(f11, f8, f9, f10);
5005     __ Fst_s(f11, MemOperand(a0, offsetof(TestCaseMaddMsub<float>, fd_fmadd)));
5006     __ fmsub_s(f12, f8, f9, f10);
5007     __ Fst_s(f12, MemOperand(a0, offsetof(TestCaseMaddMsub<float>, fd_fmsub)));
5008     __ fnmadd_s(f13, f8, f9, f10);
5009     __ Fst_s(f13, MemOperand(a0, offsetof(TestCaseMaddMsub<float>, fd_fnmadd)));
5010     __ fnmsub_s(f14, f8, f9, f10);
5011     __ Fst_s(f14, MemOperand(a0, offsetof(TestCaseMaddMsub<float>, fd_fnmsub)));
5012   });
5013 }
5014 
TEST(FMADD_FMSUB_FNMADD_FNMSUB_D)5015 TEST(FMADD_FMSUB_FNMADD_FNMSUB_D) {
5016   helper_fmadd_fmsub_fnmadd_fnmsub<double>([](MacroAssembler& assm) {
5017     __ fmadd_d(f11, f8, f9, f10);
5018     __ Fst_d(f11, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_fmadd)));
5019     __ fmsub_d(f12, f8, f9, f10);
5020     __ Fst_d(f12, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_fmsub)));
5021     __ fnmadd_d(f13, f8, f9, f10);
5022     __ Fst_d(f13,
5023              MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_fnmadd)));
5024     __ fnmsub_d(f14, f8, f9, f10);
5025     __ Fst_d(f14,
5026              MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_fnmsub)));
5027   });
5028 }
5029 
5030 /*
5031 TEST(FSQRT_FRSQRT_FRECIP) {
5032   const int kTableLength = 4;
5033   const double deltaDouble = 2E-15;
5034   const float deltaFloat = 2E-7;
5035   const float sqrt2_s = sqrt(2);
5036   const double sqrt2_d = sqrt(2);
5037   CcTest::InitializeVM();
5038   Isolate* isolate = CcTest::i_isolate();
5039   HandleScope scope(isolate);
5040   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
5041 
5042   struct TestFloat {
5043     float a;
5044     float resultS1;
5045     float resultS2;
5046     float resultS3;
5047     double b;
5048     double resultD1;
5049     double resultD2;
5050     double resultD3;
5051   };
5052   TestFloat test;
5053   // clang-format off
5054   double inputs_D[kTableLength] = {
5055     0.0L, 4.0L, 2.0L, 4e-28L
5056   };
5057 
5058   double outputs_D[kTableLength] = {
5059     0.0L, 2.0L, sqrt2_d, 2e-14L
5060   };
5061   float inputs_S[kTableLength] = {
5062     0.0, 4.0, 2.0, 4e-28
5063   };
5064 
5065   float outputs_S[kTableLength] = {
5066     0.0, 2.0, sqrt2_s, 2e-14
5067   };
5068   // clang-format on
5069   __ Fld_s(f8, MemOperand(a0, offsetof(TestFloat, a)));
5070   __ Fld_d(f9, MemOperand(a0, offsetof(TestFloat, b)));
5071   __ fsqrt_s(f10, f8);
5072   __ fsqrt_d(f11, f9);
5073   __ frsqrt_s(f12, f8);
5074   __ frsqrt_d(f13, f9);
5075   __ frecip_s(f14, f8);
5076   __ frecip_d(f15, f9);
5077   __ Fst_s(f10, MemOperand(a0, offsetof(TestFloat, resultS1)));
5078   __ Fst_d(f11, MemOperand(a0, offsetof(TestFloat, resultD1)));
5079   __ Fst_s(f12, MemOperand(a0, offsetof(TestFloat, resultS2)));
5080   __ Fst_d(f13, MemOperand(a0, offsetof(TestFloat, resultD2)));
5081   __ Fst_s(f14, MemOperand(a0, offsetof(TestFloat, resultS3)));
5082   __ Fst_d(f15, MemOperand(a0, offsetof(TestFloat, resultD3)));
5083   __ jirl(zero_reg, ra, 0);
5084 
5085   CodeDesc desc;
5086   assm.GetCode(isolate, &desc);
5087   Handle<Code> code = Factory::CodeBuilder(isolate, desc,
5088 CodeKind::STUB).Build(); auto f = GeneratedCode<F3>::FromCode(*code);
5089 
5090   for (int i = 0; i < kTableLength; i++) {
5091     float f1;
5092     double d1;
5093     test.a = inputs_S[i];
5094     test.b = inputs_D[i];
5095 
5096     f.Call(&test, 0, 0, 0, 0);
5097 
5098     CHECK_EQ(test.resultS1, outputs_S[i]);
5099     CHECK_EQ(test.resultD1, outputs_D[i]);
5100 
5101     if (i != 0) {
5102       f1 = test.resultS2 - 1.0F/outputs_S[i];
5103       f1 = (f1 < 0) ? f1 : -f1;
5104       CHECK(f1 <= deltaFloat);
5105       d1 = test.resultD2 - 1.0L/outputs_D[i];
5106       d1 = (d1 < 0) ? d1 : -d1;
5107       CHECK(d1 <= deltaDouble);
5108       f1 = test.resultS3 - 1.0F/inputs_S[i];
5109       f1 = (f1 < 0) ? f1 : -f1;
5110       CHECK(f1 <= deltaFloat);
5111       d1 = test.resultD3 - 1.0L/inputs_D[i];
5112       d1 = (d1 < 0) ? d1 : -d1;
5113       CHECK(d1 <= deltaDouble);
5114     } else {
5115       CHECK_EQ(test.resultS2, 1.0F/outputs_S[i]);
5116       CHECK_EQ(test.resultD2, 1.0L/outputs_D[i]);
5117       CHECK_EQ(test.resultS3, 1.0F/inputs_S[i]);
5118       CHECK_EQ(test.resultD3, 1.0L/inputs_D[i]);
5119     }
5120   }
5121 }*/
5122 
TEST(LA15)5123 TEST(LA15) {
5124   // Test chaining of label usages within instructions (issue 1644).
5125   CcTest::InitializeVM();
5126   Isolate* isolate = CcTest::i_isolate();
5127   HandleScope scope(isolate);
5128   Assembler assm(AssemblerOptions{});
5129 
5130   Label target;
5131   __ beq(a0, a1, &target);
5132   __ nop();
5133   __ bne(a0, a1, &target);
5134   __ nop();
5135   __ bind(&target);
5136   __ nop();
5137   __ jirl(zero_reg, ra, 0);
5138 
5139   CodeDesc desc;
5140   assm.GetCode(isolate, &desc);
5141   Handle<Code> code =
5142       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
5143   auto f = GeneratedCode<F2>::FromCode(*code);
5144   f.Call(1, 1, 0, 0, 0);
5145 }
5146 
TEST(Trampoline)5147 TEST(Trampoline) {
5148   static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
5149 
5150   CcTest::InitializeVM();
5151   Isolate* isolate = CcTest::i_isolate();
5152   HandleScope scope(isolate);
5153 
5154   MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes);
5155   Label done;
5156   size_t nr_calls = kMaxBranchOffset / kInstrSize + 5;
5157 
5158   __ xor_(a2, a2, a2);
5159   __ BranchShort(&done, eq, a0, Operand(a1));
5160   for (size_t i = 0; i < nr_calls; ++i) {
5161     __ addi_d(a2, a2, 1);
5162   }
5163   __ bind(&done);
5164   __ or_(a0, a2, zero_reg);
5165   __ jirl(zero_reg, ra, 0);
5166 
5167   CodeDesc desc;
5168   assm.GetCode(isolate, &desc);
5169   Handle<Code> code =
5170       Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
5171   auto f = GeneratedCode<F2>::FromCode(*code);
5172 
5173   int64_t res = reinterpret_cast<int64_t>(f.Call(42, 42, 0, 0, 0));
5174   CHECK_EQ(0, res);
5175 }
5176 
5177 #undef __
5178 
5179 }  // namespace internal
5180 }  // namespace v8
5181