• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gtest/gtest.h"
18 
19 #include <unistd.h>
20 
21 #include <cstdint>
22 #include <initializer_list>
23 #include <tuple>
24 #include <type_traits>
25 
26 #include "berberis/base/bit_util.h"
27 #include "berberis/guest_state/guest_addr.h"
28 #include "berberis/guest_state/guest_state_riscv64.h"
29 #include "berberis/interpreter/riscv64/interpreter.h"
30 #include "berberis/intrinsics/guest_fpstate.h"
31 
32 namespace berberis {
33 
34 namespace {
35 
36 class Riscv64InterpreterTest : public ::testing::Test {
37  public:
38   template <RegisterType register_type, uint64_t expected_result>
InterpretCompressedStore(uint16_t insn_bytes,uint64_t offset)39   void InterpretCompressedStore(uint16_t insn_bytes, uint64_t offset) {
40     auto code_start = ToGuestAddr(&insn_bytes);
41     state_.cpu.insn_addr = code_start;
42     store_area_ = 0;
43     SetXReg<8>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&store_area_) - offset));
44     SetReg<register_type, 9>(state_.cpu, kDataToLoad);
45     InterpretInsn(&state_);
46     EXPECT_EQ(store_area_, expected_result);
47   }
48 
49   template <RegisterType register_type, uint64_t expected_result>
InterpretCompressedLoad(uint16_t insn_bytes,uint64_t offset)50   void InterpretCompressedLoad(uint16_t insn_bytes, uint64_t offset) {
51     auto code_start = ToGuestAddr(&insn_bytes);
52     state_.cpu.insn_addr = code_start;
53     SetXReg<8>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&kDataToLoad) - offset));
54     InterpretInsn(&state_);
55     EXPECT_EQ((GetReg<register_type, 9>(state_.cpu)), expected_result);
56   }
57 
InterpretCAddi4spn(uint16_t insn_bytes,uint64_t expected_offset)58   void InterpretCAddi4spn(uint16_t insn_bytes, uint64_t expected_offset) {
59     auto code_start = ToGuestAddr(&insn_bytes);
60     state_.cpu.insn_addr = code_start;
61     SetXReg<2>(state_.cpu, 1);
62     InterpretInsn(&state_);
63     EXPECT_EQ(GetXReg<9>(state_.cpu), 1 + expected_offset);
64   }
65 
InterpretCAddi(uint16_t insn_bytes,uint64_t expected_increment)66   void InterpretCAddi(uint16_t insn_bytes, uint64_t expected_increment) {
67     auto code_start = ToGuestAddr(&insn_bytes);
68     state_.cpu.insn_addr = code_start;
69     SetXReg<2>(state_.cpu, 1);
70     InterpretInsn(&state_);
71     EXPECT_EQ(GetXReg<2>(state_.cpu), 1 + expected_increment);
72   }
73 
InterpretCJ(uint16_t insn_bytes,int16_t expected_offset)74   void InterpretCJ(uint16_t insn_bytes, int16_t expected_offset) {
75     auto code_start = ToGuestAddr(&insn_bytes);
76     state_.cpu.insn_addr = code_start;
77     InterpretInsn(&state_);
78     EXPECT_EQ(state_.cpu.insn_addr, code_start + expected_offset);
79   }
80 
InterpretCsr(uint32_t insn_bytes,uint8_t expected_rm)81   void InterpretCsr(uint32_t insn_bytes, uint8_t expected_rm) {
82     auto code_start = ToGuestAddr(&insn_bytes);
83     state_.cpu.insn_addr = code_start;
84     state_.cpu.frm = 0b001u;
85     InterpretInsn(&state_);
86     EXPECT_EQ(GetXReg<2>(state_.cpu), 0b001u);
87     EXPECT_EQ(state_.cpu.frm, expected_rm);
88   }
89 
InterpretOp(uint32_t insn_bytes,std::initializer_list<std::tuple<uint64_t,uint64_t,uint64_t>> args)90   void InterpretOp(uint32_t insn_bytes,
91                    std::initializer_list<std::tuple<uint64_t, uint64_t, uint64_t>> args) {
92     for (auto [arg1, arg2, expected_result] : args) {
93       state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
94       SetXReg<2>(state_.cpu, arg1);
95       SetXReg<3>(state_.cpu, arg2);
96       InterpretInsn(&state_);
97       EXPECT_EQ(GetXReg<1>(state_.cpu), expected_result);
98     }
99   }
100 
InterpretOpFp(uint32_t insn_bytes,std::initializer_list<std::tuple<uint64_t,uint64_t,uint64_t>> args)101   void InterpretOpFp(uint32_t insn_bytes,
102                      std::initializer_list<std::tuple<uint64_t, uint64_t, uint64_t>> args) {
103     for (auto [arg1, arg2, expected_result] : args) {
104       state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
105       SetFReg<2>(state_.cpu, arg1);
106       SetFReg<3>(state_.cpu, arg2);
107       InterpretInsn(&state_);
108       EXPECT_EQ(GetFReg<1>(state_.cpu), expected_result);
109     }
110   }
111 
InterpretFence(uint32_t insn_bytes)112   void InterpretFence(uint32_t insn_bytes) {
113     state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
114     InterpretInsn(&state_);
115   }
116 
InterpretAmo(uint32_t insn_bytes,uint64_t arg1,uint64_t arg2,uint64_t expected_result,uint64_t expected_memory)117   void InterpretAmo(uint32_t insn_bytes, uint64_t arg1, uint64_t arg2, uint64_t expected_result,
118                     uint64_t expected_memory) {
119     state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
120     // Copy arg1 into store_area_
121     store_area_ = arg1;
122     SetXReg<2>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&store_area_)));
123     SetXReg<3>(state_.cpu, arg2);
124     InterpretInsn(&state_);
125     EXPECT_EQ(GetXReg<1>(state_.cpu), expected_result);
126     EXPECT_EQ(store_area_, expected_memory);
127   }
128 
InterpretAmo(uint32_t insn_bytes32,uint32_t insn_bytes64,uint64_t expected_memory)129   void InterpretAmo(uint32_t insn_bytes32, uint32_t insn_bytes64, uint64_t expected_memory) {
130     InterpretAmo(insn_bytes32, 0xffff'eeee'dddd'ccccULL, 0xaaaa'bbbb'cccc'ddddULL,
131                  0xffff'ffff'dddd'ccccULL, 0xffff'eeee'0000'0000 | uint32_t(expected_memory));
132     InterpretAmo(insn_bytes64, 0xffff'eeee'dddd'ccccULL, 0xaaaa'bbbb'cccc'ddddULL,
133                  0xffff'eeee'dddd'ccccULL, expected_memory);
134   }
135 
InterpretLui(uint32_t insn_bytes,uint64_t expected_result)136   void InterpretLui(uint32_t insn_bytes, uint64_t expected_result) {
137     auto code_start = ToGuestAddr(&insn_bytes);
138     state_.cpu.insn_addr = code_start;
139     InterpretInsn(&state_);
140     EXPECT_EQ(GetXReg<1>(state_.cpu), expected_result);
141   }
142 
InterpretAuipc(uint32_t insn_bytes,uint64_t expected_offset)143   void InterpretAuipc(uint32_t insn_bytes, uint64_t expected_offset) {
144     auto code_start = ToGuestAddr(&insn_bytes);
145     state_.cpu.insn_addr = code_start;
146     InterpretInsn(&state_);
147     EXPECT_EQ(GetXReg<1>(state_.cpu), expected_offset + code_start);
148   }
149 
InterpretOpImm(uint32_t insn_bytes,std::initializer_list<std::tuple<uint64_t,uint16_t,uint64_t>> args)150   void InterpretOpImm(uint32_t insn_bytes,
151                       std::initializer_list<std::tuple<uint64_t, uint16_t, uint64_t>> args) {
152     for (auto [arg1, imm, expected_result] : args) {
153       CHECK_LE(imm, 63);
154       uint32_t insn_bytes_with_immediate = insn_bytes | imm << 20;
155       state_.cpu.insn_addr = bit_cast<GuestAddr>(&insn_bytes_with_immediate);
156       SetXReg<2>(state_.cpu, arg1);
157       InterpretInsn(&state_);
158       EXPECT_EQ(GetXReg<1>(state_.cpu), expected_result);
159     }
160   }
161 
InterpretLoad(uint32_t insn_bytes,uint64_t expected_result)162   void InterpretLoad(uint32_t insn_bytes, uint64_t expected_result) {
163     state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
164     // Offset is always 8.
165     SetXReg<2>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&kDataToLoad) - 8));
166     InterpretInsn(&state_);
167     EXPECT_EQ(GetXReg<1>(state_.cpu), expected_result);
168   }
169 
InterpretLoadFp(uint32_t insn_bytes,uint64_t expected_result)170   void InterpretLoadFp(uint32_t insn_bytes, uint64_t expected_result) {
171     state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
172     // Offset is always 8.
173     SetXReg<2>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&kDataToLoad) - 8));
174     InterpretInsn(&state_);
175     EXPECT_EQ(GetFReg<1>(state_.cpu), expected_result);
176   }
177 
InterpretStore(uint32_t insn_bytes,uint64_t expected_result)178   void InterpretStore(uint32_t insn_bytes, uint64_t expected_result) {
179     state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
180     // Offset is always 8.
181     SetXReg<1>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&store_area_) - 8));
182     SetXReg<2>(state_.cpu, kDataToStore);
183     store_area_ = 0;
184     InterpretInsn(&state_);
185     EXPECT_EQ(store_area_, expected_result);
186   }
187 
InterpretStoreFp(uint32_t insn_bytes,uint64_t expected_result)188   void InterpretStoreFp(uint32_t insn_bytes, uint64_t expected_result) {
189     state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
190     // Offset is always 8.
191     SetXReg<1>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&store_area_) - 8));
192     SetFReg<2>(state_.cpu, kDataToStore);
193     store_area_ = 0;
194     InterpretInsn(&state_);
195     EXPECT_EQ(store_area_, expected_result);
196   }
197 
InterpretBranch(uint32_t insn_bytes,std::initializer_list<std::tuple<uint64_t,uint64_t,int8_t>> args)198   void InterpretBranch(uint32_t insn_bytes,
199                        std::initializer_list<std::tuple<uint64_t, uint64_t, int8_t>> args) {
200     auto code_start = ToGuestAddr(&insn_bytes);
201     for (auto [arg1, arg2, expected_offset] : args) {
202       state_.cpu.insn_addr = code_start;
203       SetXReg<1>(state_.cpu, arg1);
204       SetXReg<2>(state_.cpu, arg2);
205       InterpretInsn(&state_);
206       EXPECT_EQ(state_.cpu.insn_addr, code_start + expected_offset);
207     }
208   }
209 
InterpretJumpAndLink(uint32_t insn_bytes,int8_t expected_offset)210   void InterpretJumpAndLink(uint32_t insn_bytes, int8_t expected_offset) {
211     auto code_start = ToGuestAddr(&insn_bytes);
212     state_.cpu.insn_addr = code_start;
213     InterpretInsn(&state_);
214     EXPECT_EQ(state_.cpu.insn_addr, code_start + expected_offset);
215     EXPECT_EQ(GetXReg<1>(state_.cpu), code_start + 4);
216   }
217 
InterpretJumpAndLinkRegister(uint32_t insn_bytes,uint64_t base_disp,int64_t expected_offset)218   void InterpretJumpAndLinkRegister(uint32_t insn_bytes, uint64_t base_disp,
219                                     int64_t expected_offset) {
220     auto code_start = ToGuestAddr(&insn_bytes);
221     state_.cpu.insn_addr = code_start;
222     SetXReg<2>(state_.cpu, code_start + base_disp);
223     InterpretInsn(&state_);
224     EXPECT_EQ(state_.cpu.insn_addr, code_start + expected_offset);
225   }
226 
227  protected:
228   static constexpr uint64_t kDataToLoad{0xffffeeeeddddccccULL};
229   static constexpr uint64_t kDataToStore = kDataToLoad;
230   uint64_t store_area_;
231   ThreadState state_;
232 };
233 
TEST_F(Riscv64InterpreterTest,CLw)234 TEST_F(Riscv64InterpreterTest, CLw) {
235   union {
236     uint16_t offset;
237     struct {
238       uint8_t : 2;
239       uint8_t i2 : 1;
240       uint8_t i3_i5 : 3;
241       uint8_t i6 : 1;
242     } i_bits;
243   };
244   for (offset = uint8_t{0}; offset < uint8_t{128}; offset += 4) {
245     union {
246       int16_t parcel;
247       struct {
248         uint8_t low_opcode : 2;
249         uint8_t rd : 3;
250         uint8_t i6 : 1;
251         uint8_t i2 : 1;
252         uint8_t rs : 3;
253         uint8_t i3_i5 : 3;
254         uint8_t high_opcode : 3;
255       } __attribute__((__packed__));
256     } o_bits = {
257         .low_opcode = 0b00,
258         .rd = 1,
259         .i6 = i_bits.i6,
260         .i2 = i_bits.i2,
261         .rs = 0,
262         .i3_i5 = i_bits.i3_i5,
263         .high_opcode = 0b010,
264     };
265     InterpretCompressedLoad<RegisterType::kReg,
266                             static_cast<uint64_t>(static_cast<int32_t>(kDataToLoad))>(o_bits.parcel,
267                                                                                       offset);
268   }
269 }
270 
271 template <uint16_t opcode, auto execute_instruction_func>
TestCompressedLoadOrStore(Riscv64InterpreterTest * that)272 void TestCompressedLoadOrStore(Riscv64InterpreterTest* that) {
273   union {
274     uint16_t offset;
275     struct {
276       uint8_t : 3;
277       uint8_t i3_i5 : 3;
278       uint8_t i6_i7 : 2;
279     } i_bits;
280   };
281   for (offset = int16_t{0}; offset < int16_t{256}; offset += 8) {
282     union {
283       int16_t parcel;
284       struct [[gnu::packed]] {
285         uint8_t low_opcode : 2;
286         uint8_t rd : 3;
287         uint8_t i6_i7 : 2;
288         uint8_t rs : 3;
289         uint8_t i3_i5 : 3;
290         uint8_t high_opcode : 3;
291       };
292     } o_bits = {
293         .low_opcode = 0b00,
294         .rd = 1,
295         .i6_i7 = i_bits.i6_i7,
296         .rs = 0,
297         .i3_i5 = i_bits.i3_i5,
298         .high_opcode = 0b000,
299     };
300     (that->*execute_instruction_func)(o_bits.parcel | opcode, offset);
301   }
302 }
303 
TEST_F(Riscv64InterpreterTest,CompressedLoadAndStores)304 TEST_F(Riscv64InterpreterTest, CompressedLoadAndStores) {
305   // c.Fld
306   TestCompressedLoadOrStore<
307       0b001'000'000'00'000'00,
308       &Riscv64InterpreterTest::InterpretCompressedLoad<RegisterType::kFpReg, kDataToLoad>>(this);
309   // c.Ld
310   TestCompressedLoadOrStore<
311       0b011'000'000'00'000'00,
312       &Riscv64InterpreterTest::InterpretCompressedLoad<RegisterType::kReg, kDataToLoad>>(this);
313   // c.Fsd
314   TestCompressedLoadOrStore<
315       0b101'000'000'00'000'00,
316       &Riscv64InterpreterTest::InterpretCompressedStore<RegisterType::kFpReg, kDataToLoad>>(this);
317   // c.Sd
318   TestCompressedLoadOrStore<
319       0b111'000'000'00'000'00,
320       &Riscv64InterpreterTest::InterpretCompressedStore<RegisterType::kReg, kDataToLoad>>(this);
321 }
322 
TEST_F(Riscv64InterpreterTest,CAddi)323 TEST_F(Riscv64InterpreterTest, CAddi) {
324   union {
325     int8_t offset;
326     struct {
327       uint8_t i4_i0 : 5;
328       uint8_t i5 : 1;
329     } i_bits;
330   };
331   for (offset = int8_t{-32}; offset < int8_t{31}; offset++) {
332     union {
333       int16_t parcel;
334       struct {
335         uint8_t low_opcode : 2;
336         uint8_t i4_i0 : 5;
337         uint8_t r : 5;
338         uint8_t i5 : 1;
339         uint8_t high_opcode : 3;
340       } __attribute__((__packed__));
341     } o_bits = {
342         .low_opcode = 0b01,
343         .i4_i0 = i_bits.i4_i0,
344         .r = 2,
345         .i5 = i_bits.i5,
346         .high_opcode = 0b000,
347     };
348     InterpretCAddi(o_bits.parcel, offset);
349   }
350 }
351 
TEST_F(Riscv64InterpreterTest,CAddi4spn)352 TEST_F(Riscv64InterpreterTest, CAddi4spn) {
353   union {
354     int16_t offset;
355     struct {
356       uint8_t : 2;
357       uint8_t i2 : 1;
358       uint8_t i3 : 1;
359       uint8_t i4 : 1;
360       uint8_t i5 : 1;
361       uint8_t i6 : 1;
362       uint8_t i7 : 1;
363       uint8_t i8 : 1;
364       uint8_t i9 : 1;
365     } i_bits;
366   };
367   for (offset = int16_t{4}; offset < int16_t{1024}; offset += 4) {
368     union {
369       int16_t parcel;
370       struct {
371         uint8_t low_opcode : 2;
372         uint8_t rd : 3;
373         uint8_t i3 : 1;
374         uint8_t i2 : 1;
375         uint8_t i6 : 1;
376         uint8_t i7 : 1;
377         uint8_t i8 : 1;
378         uint8_t i9 : 1;
379         uint8_t i4 : 1;
380         uint8_t i5 : 1;
381         uint8_t high_opcode : 3;
382       };
383     } o_bits = {
384         .low_opcode = 0b00,
385         .rd = 1,
386         .i3 = i_bits.i3,
387         .i2 = i_bits.i2,
388         .i6 = i_bits.i6,
389         .i7 = i_bits.i7,
390         .i8 = i_bits.i8,
391         .i9 = i_bits.i9,
392         .i4 = i_bits.i4,
393         .i5 = i_bits.i5,
394         .high_opcode = 0b000,
395     };
396     InterpretCAddi4spn(o_bits.parcel, offset);
397   }
398 }
399 
TEST_F(Riscv64InterpreterTest,CJ)400 TEST_F(Riscv64InterpreterTest, CJ) {
401   union {
402     int16_t offset;
403     struct {
404       uint8_t : 1;
405       uint8_t i1 : 1;
406       uint8_t i2 : 1;
407       uint8_t i3 : 1;
408       uint8_t i4 : 1;
409       uint8_t i5 : 1;
410       uint8_t i6 : 1;
411       uint8_t i7 : 1;
412       uint8_t i8 : 1;
413       uint8_t i9 : 1;
414       uint8_t i10 : 1;
415       uint8_t i11 : 1;
416     } i_bits;
417   };
418   for (offset = int16_t{-2048}; offset < int16_t{2048}; offset += 2) {
419     union {
420       int16_t parcel;
421       struct {
422         uint8_t low_opcode : 2;
423         uint8_t i5 : 1;
424         uint8_t i1 : 1;
425         uint8_t i2 : 1;
426         uint8_t i3 : 1;
427         uint8_t i7 : 1;
428         uint8_t i6 : 1;
429         uint8_t i10 : 1;
430         uint8_t i8 : 1;
431         uint8_t i9 : 1;
432         uint8_t i4 : 1;
433         uint8_t i11 : 1;
434         uint8_t high_opcode : 3;
435       };
436     } o_bits = {
437         .low_opcode = 0b01,
438         .i5 = i_bits.i5,
439         .i1 = i_bits.i1,
440         .i2 = i_bits.i2,
441         .i3 = i_bits.i3,
442         .i7 = i_bits.i7,
443         .i6 = i_bits.i6,
444         .i10 = i_bits.i10,
445         .i8 = i_bits.i8,
446         .i9 = i_bits.i9,
447         .i4 = i_bits.i4,
448         .i11 = i_bits.i11,
449         .high_opcode = 0b101,
450     };
451     InterpretCJ(o_bits.parcel, offset);
452   }
453 }
454 
TEST_F(Riscv64InterpreterTest,CsrInstrctuion)455 TEST_F(Riscv64InterpreterTest, CsrInstrctuion) {
456   ScopedRoundingMode scoped_rounding_mode;
457   // Csrrw x2, frm, 2
458   InterpretCsr(0x00215173, 2);
459   // Csrrsi x2, frm, 2
460   InterpretCsr(0x00216173, 3);
461   // Csrrci x2, frm, 1
462   InterpretCsr(0x0020f173, 0);
463 }
464 
TEST_F(Riscv64InterpreterTest,FenceInstructions)465 TEST_F(Riscv64InterpreterTest, FenceInstructions) {
466   // Fence
467   InterpretFence(0x0ff0000f);
468   // FenceTso
469   InterpretFence(0x8330000f);
470   // FenceI
471   InterpretFence(0x0000100f);
472 }
473 
TEST_F(Riscv64InterpreterTest,OpInstructions)474 TEST_F(Riscv64InterpreterTest, OpInstructions) {
475   // Add
476   InterpretOp(0x003100b3, {{19, 23, 42}});
477   // Sub
478   InterpretOp(0x403100b3, {{42, 23, 19}});
479   // And
480   InterpretOp(0x003170b3, {{0b0101, 0b0011, 0b0001}});
481   // Or
482   InterpretOp(0x003160b3, {{0b0101, 0b0011, 0b0111}});
483   // Xor
484   InterpretOp(0x003140b3, {{0b0101, 0b0011, 0b0110}});
485   // Sll
486   InterpretOp(0x003110b3, {{0b1010, 3, 0b1010'000}});
487   // Srl
488   InterpretOp(0x003150b3, {{0xf000'0000'0000'0000ULL, 12, 0x000f'0000'0000'0000ULL}});
489   // Sra
490   InterpretOp(0x403150b3, {{0xf000'0000'0000'0000ULL, 12, 0xffff'0000'0000'0000ULL}});
491   // Slt
492   InterpretOp(0x003120b3, {
493                               {19, 23, 1},
494                               {23, 19, 0},
495                               {~0ULL, 0, 1},
496                           });
497   // Sltu
498   InterpretOp(0x003130b3, {
499                               {19, 23, 1},
500                               {23, 19, 0},
501                               {~0ULL, 0, 0},
502                           });
503 
504   // Mul
505   InterpretOp(0x023100b3, {{0x9999'9999'9999'9999, 0x9999'9999'9999'9999, 0x0a3d'70a3'd70a'3d71}});
506   // Mulh
507   InterpretOp(0x23110b3, {{0x9999'9999'9999'9999, 0x9999'9999'9999'9999, 0x28f5'c28f'5c28'f5c3}});
508   // Mulhsu
509   InterpretOp(0x23120b3, {{0x9999'9999'9999'9999, 0x9999'9999'9999'9999, 0xc28f'5c28'f5c2'8f5c}});
510   // Mulhu
511   InterpretOp(0x23130b3, {{0x9999'9999'9999'9999, 0x9999'9999'9999'9999, 0x5c28'f5c2'8f5c'28f5}});
512   // Div
513   InterpretOp(0x23140b3, {{0x9999'9999'9999'9999, 0x3333, 0xfffd'fffd'fffd'fffe}});
514   // Div
515   InterpretOp(0x23150b3, {{0x9999'9999'9999'9999, 0x3333, 0x0003'0003'0003'0003}});
516   // Rem
517   InterpretOp(0x23160b3, {{0x9999'9999'9999'9999, 0x3333, 0xffff'ffff'ffff'ffff}});
518   // Remu
519   InterpretOp(0x23170b3, {{0x9999'9999'9999'9999, 0x3333, 0}});
520 }
521 
TEST_F(Riscv64InterpreterTest,Op32Instructions)522 TEST_F(Riscv64InterpreterTest, Op32Instructions) {
523   // Addw
524   InterpretOp(0x003100bb, {{19, 23, 42}});
525   // Subw
526   InterpretOp(0x403100bb, {{42, 23, 19}});
527   // Sllw
528   InterpretOp(0x003110bb, {{0b1010, 3, 0b1010'000}});
529   // Srlw
530   InterpretOp(0x003150bb, {{0x0000'0000'f000'0000ULL, 12, 0x0000'0000'000f'0000ULL}});
531   // Sraw
532   InterpretOp(0x403150bb, {{0x0000'0000'f000'0000ULL, 12, 0xffff'ffff'ffff'0000ULL}});
533   // Mulw
534   InterpretOp(0x023100bb, {{0x9999'9999'9999'9999, 0x9999'9999'9999'9999, 0xffff'ffff'd70a'3d71}});
535   // Divw
536   InterpretOp(0x23140bb, {{0x9999'9999'9999'9999, 0x3333, 0xffff'ffff'fffd'fffe}});
537   // Divuw
538   InterpretOp(0x23150bb, {{0x9999'9999'9999'9999, 0x3333, 0x0000'0000'0003'0003}});
539   // Remw
540   InterpretOp(0x23160bb, {{0x9999'9999'9999'9999, 0x3333, 0xffff'ffff'ffff'ffff}});
541   // Remuw
542   InterpretOp(0x23170bb, {{0x9999'9999'9999'9999, 0x3333, 0}});
543 }
544 
TEST_F(Riscv64InterpreterTest,AmoInstructions)545 TEST_F(Riscv64InterpreterTest, AmoInstructions) {
546   // Verifying that all aq and rl combinations work for Amoswap, but only test relaxed one for most
547   // other instructions for brevity.
548 
549   // AmoswaoW/AmoswaoD
550   InterpretAmo(0x083120af, 0x083130af, 0xaaaa'bbbb'cccc'ddddULL);
551 
552   // AmoswapWAq/AmoswapDAq
553   InterpretAmo(0x0c3120af, 0x0c3130af, 0xaaaa'bbbb'cccc'ddddULL);
554 
555   // AmoswapWRl/AmoswapDRl
556   InterpretAmo(0x0a3120af, 0x0a3130af, 0xaaaa'bbbb'cccc'ddddULL);
557 
558   // AmoswapWAqrl/AmoswapDAqrl
559   InterpretAmo(0x0e3120af, 0x0e3130af, 0xaaaa'bbbb'cccc'ddddULL);
560 
561   // AmoaddW/AmoaddD
562   InterpretAmo(0x003120af, 0x003130af, 0xaaaa'aaaa'aaaa'aaa9);
563 
564   // AmoxorW/AmoxorD
565   InterpretAmo(0x203120af, 0x203130af, 0x5555'5555'1111'1111);
566 
567   // AmoandW/AmoandD
568   InterpretAmo(0x603120af, 0x603130af, 0xaaaa'aaaa'cccc'cccc);
569 
570   // AmoorW/AmoorD
571   InterpretAmo(0x403120af, 0x403130af, 0xffff'ffff'dddd'dddd);
572 
573   // AmominW/AmominD
574   InterpretAmo(0x803120af, 0x803130af, 0xaaaa'bbbb'cccc'ddddULL);
575 
576   // AmomaxW/AmomaxD
577   InterpretAmo(0xa03120af, 0xa03130af, 0xffff'eeee'dddd'ccccULL);
578 
579   // AmominuW/AmominuD
580   InterpretAmo(0xc03120af, 0xc03130af, 0xaaaa'bbbb'cccc'ddddULL);
581 
582   // AmomaxuW/AmomaxuD
583   InterpretAmo(0xe03120af, 0xe03130af, 0xffff'eeee'dddd'ccccULL);
584 }
585 
TEST_F(Riscv64InterpreterTest,UpperImmArgs)586 TEST_F(Riscv64InterpreterTest, UpperImmArgs) {
587   // Lui
588   InterpretLui(0xfedcb0b7, 0xffff'ffff'fedc'b000);
589   // Auipc
590   InterpretAuipc(0xfedcb097, 0xffff'ffff'fedc'b000);
591 }
592 
TEST_F(Riscv64InterpreterTest,OpImmInstructions)593 TEST_F(Riscv64InterpreterTest, OpImmInstructions) {
594   // Addi
595   InterpretOpImm(0x00010093, {{19, 23, 42}});
596   // Slli
597   InterpretOpImm(0x00011093, {{0b1010, 3, 0b1010'000}});
598   // Slti
599   InterpretOpImm(0x00012093, {
600                                  {19, 23, 1},
601                                  {23, 19, 0},
602                                  {~0ULL, 0, 1},
603                              });
604   // Sltiu
605   InterpretOpImm(0x00013093, {
606                                  {19, 23, 1},
607                                  {23, 19, 0},
608                                  {~0ULL, 0, 0},
609                              });
610   // Xori
611   InterpretOpImm(0x00014093, {{0b0101, 0b0011, 0b0110}});
612   // Srli
613   InterpretOpImm(0x00015093, {{0xf000'0000'0000'0000ULL, 12, 0x000f'0000'0000'0000ULL}});
614   // Srai
615   InterpretOpImm(0x40015093, {{0xf000'0000'0000'0000ULL, 12, 0xffff'0000'0000'0000ULL}});
616   // Ori
617   InterpretOpImm(0x00016093, {{0b0101, 0b0011, 0b0111}});
618   // Andi
619   InterpretOpImm(0x00017093, {{0b0101, 0b0011, 0b0001}});
620 }
621 
TEST_F(Riscv64InterpreterTest,OpImm32Instructions)622 TEST_F(Riscv64InterpreterTest, OpImm32Instructions) {
623   // Addiw
624   InterpretOpImm(0x0001009b, {{19, 23, 42}});
625   // Slliw
626   InterpretOpImm(0x0001109b, {{0b1010, 3, 0b1010'000}});
627   // Srliw
628   InterpretOpImm(0x0001509b, {{0x0000'0000'f000'0000ULL, 12, 0x0000'0000'000f'0000ULL}});
629   // Sraiw
630   InterpretOpImm(0x4001509b, {{0x0000'0000'f000'0000ULL, 12, 0xffff'ffff'ffff'0000ULL}});
631 }
632 
TEST_F(Riscv64InterpreterTest,OpFpInstructions)633 TEST_F(Riscv64InterpreterTest, OpFpInstructions) {
634   // FAdd.S
635   InterpretOpFp(0x003100d3,
636                 {{bit_cast<uint32_t>(1.0f) | 0xffff'ffff'0000'0000,
637                   bit_cast<uint32_t>(2.0f) | 0xffff'ffff'0000'0000,
638                   bit_cast<uint32_t>(3.0f) | 0xffff'ffff'0000'0000}});
639   // FAdd.D
640   InterpretOpFp(0x023100d3,
641                 {{bit_cast<uint64_t>(1.0), bit_cast<uint64_t>(2.0), bit_cast<uint64_t>(3.0)}});
642 }
643 
TEST_F(Riscv64InterpreterTest,RoundingModeTest)644 TEST_F(Riscv64InterpreterTest, RoundingModeTest) {
645   // FAdd.S
646   InterpretOpFp(0x003100d3,
647                 // Test RNE
648                 {{bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000,
649                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
650                   bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000},
651                  {bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000,
652                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
653                   bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000},
654                  {bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000,
655                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
656                   bit_cast<uint32_t>(1.0000005f) | 0xffff'ffff'0000'0000},
657                  {bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000,
658                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
659                   bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000},
660                  {bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000,
661                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
662                   bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000},
663                  {bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000,
664                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
665                   bit_cast<uint32_t>(-1.0000005f) | 0xffff'ffff'0000'0000}});
666   // FAdd.S
667   InterpretOpFp(0x003110d3,
668                 // Test RTZ
669                 {{bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000,
670                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
671                   bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000},
672                  {bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000,
673                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
674                   bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000},
675                  {bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000,
676                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
677                   bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000},
678                  {bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000,
679                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
680                   bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000},
681                  {bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000,
682                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
683                   bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000},
684                  {bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000,
685                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
686                   bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000}});
687   // FAdd.S
688   InterpretOpFp(0x003120d3,
689                 // Test RDN
690                 {{bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000,
691                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
692                   bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000},
693                  {bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000,
694                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
695                   bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000},
696                  {bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000,
697                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
698                   bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000},
699                  {bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000,
700                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
701                   bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000},
702                  {bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000,
703                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
704                   bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000},
705                  {bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000,
706                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
707                   bit_cast<uint32_t>(-1.0000005f) | 0xffff'ffff'0000'0000}});
708   // FAdd.S
709   InterpretOpFp(0x003130d3,
710                 // Test RUP
711                 {{bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000,
712                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
713                   bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000},
714                  {bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000,
715                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
716                   bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000},
717                  {bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000,
718                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
719                   bit_cast<uint32_t>(1.0000005f) | 0xffff'ffff'0000'0000},
720                  {bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000,
721                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
722                   bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000},
723                  {bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000,
724                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
725                   bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000},
726                  {bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000,
727                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
728                   bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000}});
729   // FAdd.S
730   InterpretOpFp(0x003140d3,
731                 // Test RMM
732                 {{bit_cast<uint32_t>(1.0000001f) | 0xffff'ffff'0000'0000,
733                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
734                   bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000},
735                  {bit_cast<uint32_t>(1.0000002f) | 0xffff'ffff'0000'0000,
736                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
737                   bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000},
738                  {bit_cast<uint32_t>(1.0000004f) | 0xffff'ffff'0000'0000,
739                   bit_cast<uint32_t>(0.000000059604645f) | 0xffff'ffff'0000'0000,
740                   bit_cast<uint32_t>(1.0000005f) | 0xffff'ffff'0000'0000},
741                  {bit_cast<uint32_t>(-1.0000001f) | 0xffff'ffff'0000'0000,
742                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
743                   bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000},
744                  {bit_cast<uint32_t>(-1.0000002f) | 0xffff'ffff'0000'0000,
745                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
746                   bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000},
747                  {bit_cast<uint32_t>(-1.0000004f) | 0xffff'ffff'0000'0000,
748                   bit_cast<uint32_t>(-0.000000059604645f) | 0xffff'ffff'0000'0000,
749                   bit_cast<uint32_t>(-1.0000005f) | 0xffff'ffff'0000'0000}});
750 
751   // FAdd.D
752   InterpretOpFp(0x023100d3,
753                 // Test RNE
754                 {{bit_cast<uint64_t>(1.0000000000000002),
755                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
756                   bit_cast<uint64_t>(1.0000000000000004)},
757                  {bit_cast<uint64_t>(1.0000000000000004),
758                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
759                   bit_cast<uint64_t>(1.0000000000000004)},
760                  {bit_cast<uint64_t>(1.0000000000000007),
761                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
762                   bit_cast<uint64_t>(1.0000000000000009)},
763                  {bit_cast<uint64_t>(-1.0000000000000002),
764                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
765                   bit_cast<uint64_t>(-1.0000000000000004)},
766                  {bit_cast<uint64_t>(-1.0000000000000004),
767                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
768                   bit_cast<uint64_t>(-1.0000000000000004)},
769                  {bit_cast<uint64_t>(-1.0000000000000007),
770                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
771                   bit_cast<uint64_t>(-1.0000000000000009)}});
772   // FAdd.D
773   InterpretOpFp(0x023110d3,
774                 // Test RTZ
775                 {{bit_cast<uint64_t>(1.0000000000000002),
776                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
777                   bit_cast<uint64_t>(1.0000000000000002)},
778                  {bit_cast<uint64_t>(1.0000000000000004),
779                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
780                   bit_cast<uint64_t>(1.0000000000000004)},
781                  {bit_cast<uint64_t>(1.0000000000000007),
782                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
783                   bit_cast<uint64_t>(1.0000000000000007)},
784                  {bit_cast<uint64_t>(-1.0000000000000002),
785                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
786                   bit_cast<uint64_t>(-1.0000000000000002)},
787                  {bit_cast<uint64_t>(-1.0000000000000004),
788                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
789                   bit_cast<uint64_t>(-1.0000000000000004)},
790                  {bit_cast<uint64_t>(-1.0000000000000007),
791                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
792                   bit_cast<uint64_t>(-1.0000000000000007)}});
793   // FAdd.D
794   InterpretOpFp(0x023120d3,
795                 // Test RDN
796                 {{bit_cast<uint64_t>(1.0000000000000002),
797                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
798                   bit_cast<uint64_t>(1.0000000000000002)},
799                  {bit_cast<uint64_t>(1.0000000000000004),
800                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
801                   bit_cast<uint64_t>(1.0000000000000004)},
802                  {bit_cast<uint64_t>(1.0000000000000007),
803                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
804                   bit_cast<uint64_t>(1.0000000000000007)},
805                  {bit_cast<uint64_t>(-1.0000000000000002),
806                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
807                   bit_cast<uint64_t>(-1.0000000000000004)},
808                  {bit_cast<uint64_t>(-1.0000000000000004),
809                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
810                   bit_cast<uint64_t>(-1.0000000000000007)},
811                  {bit_cast<uint64_t>(-1.0000000000000007),
812                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
813                   bit_cast<uint64_t>(-1.0000000000000009)}});
814   // FAdd.D
815   InterpretOpFp(0x023130d3,
816                 // Test RUP
817                 {{bit_cast<uint64_t>(1.0000000000000002),
818                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
819                   bit_cast<uint64_t>(1.0000000000000004)},
820                  {bit_cast<uint64_t>(1.0000000000000004),
821                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
822                   bit_cast<uint64_t>(1.0000000000000007)},
823                  {bit_cast<uint64_t>(1.0000000000000007),
824                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
825                   bit_cast<uint64_t>(1.0000000000000009)},
826                  {bit_cast<uint64_t>(-1.0000000000000002),
827                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
828                   bit_cast<uint64_t>(-1.0000000000000002)},
829                  {bit_cast<uint64_t>(-1.0000000000000004),
830                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
831                   bit_cast<uint64_t>(-1.0000000000000004)},
832                  {bit_cast<uint64_t>(-1.0000000000000007),
833                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
834                   bit_cast<uint64_t>(-1.0000000000000007)}});
835   // FAdd.D
836   InterpretOpFp(0x023140d3,
837                 // Test RMM
838                 {{bit_cast<uint64_t>(1.0000000000000002),
839                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
840                   bit_cast<uint64_t>(1.0000000000000004)},
841                  {bit_cast<uint64_t>(1.0000000000000004),
842                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
843                   bit_cast<uint64_t>(1.0000000000000007)},
844                  {bit_cast<uint64_t>(1.0000000000000007),
845                   bit_cast<uint64_t>(0.00000000000000011102230246251565),
846                   bit_cast<uint64_t>(1.0000000000000009)},
847                  {bit_cast<uint64_t>(-1.0000000000000002),
848                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
849                   bit_cast<uint64_t>(-1.0000000000000004)},
850                  {bit_cast<uint64_t>(-1.0000000000000004),
851                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
852                   bit_cast<uint64_t>(-1.0000000000000007)},
853                  {bit_cast<uint64_t>(-1.0000000000000007),
854                   bit_cast<uint64_t>(-0.00000000000000011102230246251565),
855                   bit_cast<uint64_t>(-1.0000000000000009)}});
856 }
857 
TEST_F(Riscv64InterpreterTest,LoadInstructions)858 TEST_F(Riscv64InterpreterTest, LoadInstructions) {
859   // Offset is always 8.
860   // Lbu
861   InterpretLoad(0x00814083, kDataToLoad & 0xffULL);
862   // Lhu
863   InterpretLoad(0x00815083, kDataToLoad & 0xffffULL);
864   // Lwu
865   InterpretLoad(0x00816083, kDataToLoad & 0xffff'ffffULL);
866   // Ldu
867   InterpretLoad(0x00813083, kDataToLoad);
868   // Lb
869   InterpretLoad(0x00810083, int64_t{int8_t(kDataToLoad)});
870   // Lh
871   InterpretLoad(0x00811083, int64_t{int16_t(kDataToLoad)});
872   // Lw
873   InterpretLoad(0x00812083, int64_t{int32_t(kDataToLoad)});
874 }
875 
TEST_F(Riscv64InterpreterTest,LoadFpInstructions)876 TEST_F(Riscv64InterpreterTest, LoadFpInstructions) {
877   // Offset is always 8.
878   // Flw
879   InterpretLoadFp(0x00812087, kDataToLoad | 0xffffffff00000000ULL);
880   // Fld
881   InterpretLoadFp(0x00813087, kDataToLoad);
882 }
883 
TEST_F(Riscv64InterpreterTest,StoreInstructions)884 TEST_F(Riscv64InterpreterTest, StoreInstructions) {
885   // Offset is always 8.
886   // Sb
887   InterpretStore(0x00208423, kDataToStore & 0xffULL);
888   // Sh
889   InterpretStore(0x00209423, kDataToStore & 0xffffULL);
890   // Sw
891   InterpretStore(0x0020a423, kDataToStore & 0xffff'ffffULL);
892   // Sd
893   InterpretStore(0x0020b423, kDataToStore);
894 }
895 
TEST_F(Riscv64InterpreterTest,StoreFpInstructions)896 TEST_F(Riscv64InterpreterTest, StoreFpInstructions) {
897   // Offset is always 8.
898   // Fsw
899   InterpretStoreFp(0x0020a427, kDataToStore & 0xffff'ffffULL);
900   // Fsd
901   InterpretStoreFp(0x0020b427, kDataToStore);
902 }
903 
TEST_F(Riscv64InterpreterTest,BranchInstructions)904 TEST_F(Riscv64InterpreterTest, BranchInstructions) {
905   // Beq
906   InterpretBranch(0x00208463, {
907                                   {42, 42, 8},
908                                   {41, 42, 4},
909                                   {42, 41, 4},
910                               });
911   // Bne
912   InterpretBranch(0x00209463, {
913                                   {42, 42, 4},
914                                   {41, 42, 8},
915                                   {42, 41, 8},
916                               });
917   // Blt
918   InterpretBranch(0x0020c463, {
919                                   {41, 42, 8},
920                                   {42, 42, 4},
921                                   {42, 41, 4},
922                                   {0xf000'0000'0000'0000ULL, 42, 8},
923                                   {42, 0xf000'0000'0000'0000ULL, 4},
924                               });
925   // Bltu
926   InterpretBranch(0x0020e463, {
927                                   {41, 42, 8},
928                                   {42, 42, 4},
929                                   {42, 41, 4},
930                                   {0xf000'0000'0000'0000ULL, 42, 4},
931                                   {42, 0xf000'0000'0000'0000ULL, 8},
932                               });
933   // Bge
934   InterpretBranch(0x0020d463, {
935                                   {42, 41, 8},
936                                   {42, 42, 8},
937                                   {41, 42, 4},
938                                   {0xf000'0000'0000'0000ULL, 42, 4},
939                                   {42, 0xf000'0000'0000'0000ULL, 8},
940                               });
941   // Bgeu
942   InterpretBranch(0x0020f463, {
943                                   {42, 41, 8},
944                                   {42, 42, 8},
945                                   {41, 42, 4},
946                                   {0xf000'0000'0000'0000ULL, 42, 8},
947                                   {42, 0xf000'0000'0000'0000ULL, 4},
948                               });
949   // Beq with negative offset.
950   InterpretBranch(0xfe208ee3, {
951                                   {42, 42, -4},
952                               });
953 }
954 
TEST_F(Riscv64InterpreterTest,JumpAndLinkInstructions)955 TEST_F(Riscv64InterpreterTest, JumpAndLinkInstructions) {
956   // Jal
957   InterpretJumpAndLink(0x008000ef, 8);
958   // Jal with negative offset.
959   InterpretJumpAndLink(0xffdff0ef, -4);
960 }
961 
TEST_F(Riscv64InterpreterTest,JumpAndLinkRegisterInstructions)962 TEST_F(Riscv64InterpreterTest, JumpAndLinkRegisterInstructions) {
963   // Jalr offset=4.
964   InterpretJumpAndLinkRegister(0x004100e7, 38, 42);
965   // Jalr offset=-4.
966   InterpretJumpAndLinkRegister(0xffc100e7, 42, 38);
967   // Jalr offset=5 - must properly align the target to even.
968   InterpretJumpAndLinkRegister(0x005100e7, 38, 42);
969 }
970 
TEST_F(Riscv64InterpreterTest,SyscallWrite)971 TEST_F(Riscv64InterpreterTest, SyscallWrite) {
972   const char message[] = "Hello";
973   // Prepare a pipe to write to.
974   int pipefd[2];
975   ASSERT_EQ(0, pipe(pipefd));
976 
977   // SYS_write
978   SetXReg<17>(state_.cpu, 0x40);
979   // File descriptor
980   SetXReg<10>(state_.cpu, pipefd[1]);
981   // String
982   SetXReg<11>(state_.cpu, bit_cast<uint64_t>(&message[0]));
983   // Size
984   SetXReg<12>(state_.cpu, sizeof(message));
985 
986   uint32_t insn_bytes = 0x00000073;
987   state_.cpu.insn_addr = ToGuestAddr(&insn_bytes);
988   InterpretInsn(&state_);
989 
990   // Check number of bytes written.
991   EXPECT_EQ(GetXReg<10>(state_.cpu), sizeof(message));
992 
993   // Check the message was written to the pipe.
994   char buf[sizeof(message)] = {};
995   read(pipefd[0], &buf, sizeof(buf));
996   EXPECT_EQ(0, strcmp(message, buf));
997   close(pipefd[0]);
998   close(pipefd[1]);
999 }
1000 
1001 }  // namespace
1002 
1003 }  // namespace berberis
1004