/ externals / biscuit / tests / src / assembler_rv64i_tests.cpp
assembler_rv64i_tests.cpp
  1  #include <catch/catch.hpp>
  2  
  3  #include <array>
  4  #include <biscuit/assembler.hpp>
  5  
  6  #include "assembler_test_utils.hpp"
  7  
  8  using namespace biscuit;
  9  
 10  TEST_CASE("ADDIW", "[rv64i]") {
 11      uint32_t value = 0;
 12      auto as = MakeAssembler64(value);
 13  
 14      as.ADDIW(x31, x15, 1024);
 15      REQUIRE(value == 0x40078F9B);
 16  
 17      as.RewindBuffer();
 18  
 19      as.ADDIW(x31, x15, 2048);
 20      REQUIRE(value == 0x80078F9B);
 21  
 22      as.RewindBuffer();
 23  
 24      as.ADDIW(x31, x15, 4095);
 25      REQUIRE(value == 0xFFF78F9B);
 26  }
 27  
 28  TEST_CASE("ADDW", "[rv64i]") {
 29      uint32_t value = 0;
 30      auto as = MakeAssembler64(value);
 31  
 32      as.ADDW(x7, x15, x31);
 33      REQUIRE(value == 0x01F783BB);
 34  
 35      as.RewindBuffer();
 36  
 37      as.ADDW(x31, x31, x31);
 38      REQUIRE(value == 0x01FF8FBB);
 39  
 40      as.RewindBuffer();
 41  
 42      as.ADDW(x0, x0, x0);
 43      REQUIRE(value == 0x0000003B);
 44  }
 45  
 46  TEST_CASE("LWU", "[rv64i]") {
 47      uint32_t value = 0;
 48      auto as = MakeAssembler64(value);
 49  
 50      as.LWU(x15, 1024, x31);
 51      REQUIRE(value == 0x400FE783);
 52  
 53      as.RewindBuffer();
 54  
 55      as.LWU(x15, 1536, x31);
 56      REQUIRE(value == 0x600FE783);
 57  
 58      as.RewindBuffer();
 59  
 60      as.LWU(x15, -1, x31);
 61      REQUIRE(value == 0xFFFFE783);
 62  }
 63  
 64  TEST_CASE("LD", "[rv64i]") {
 65      uint32_t value = 0;
 66      auto as = MakeAssembler64(value);
 67  
 68      as.LD(x15, 1024, x31);
 69      REQUIRE(value == 0x400FB783);
 70  
 71      as.RewindBuffer();
 72  
 73      as.LD(x15, 1536, x31);
 74      REQUIRE(value == 0x600FB783);
 75  
 76      as.RewindBuffer();
 77  
 78      as.LD(x15, -1, x31);
 79      REQUIRE(value == 0xFFFFB783);
 80  }
 81  
 82  TEST_CASE("LI (RV64)", "[rv64i]") {
 83      // Up to 8 instructions can be generated
 84      std::array<uint32_t, 8> vals{};
 85      auto as = MakeAssembler64(vals);
 86  
 87      const auto compare_vals = [&vals]<typename... Args>(const Args&... args) {
 88          static_assert(sizeof...(args) <= vals.size());
 89  
 90          size_t i = 0;
 91          for (const auto arg : {args...}) {
 92              REQUIRE(vals[i] == arg);
 93              i++;
 94          }
 95      };
 96  
 97      ///////// Single ADDIW cases
 98  
 99      as.LI(x1, 0);
100      // addiw x1, x0, 0
101      compare_vals(0x0000009BU, 0x00000000U);
102      as.RewindBuffer();
103      vals = {};
104  
105      as.LI(x1, -1);
106      // addiw x1, x0, -1
107      compare_vals(0xFFF0009BU, 0x00000000U);
108      as.RewindBuffer();
109      vals = {};
110  
111      as.LI(x1, 42);
112      // addiw x1, x0, 42
113      compare_vals(0x02A0009BU, 0x000000000U);
114      as.RewindBuffer();
115      vals = {};
116  
117      as.LI(x1, 0x7ff);
118      // addiw x1, x0, 2047
119      compare_vals(0x7FF0009BU, 0x00000000U);
120      as.RewindBuffer();
121      vals = {};
122  
123      ///////// Single LUI cases
124  
125      as.LI(x1, 0x2A000);
126      // lui x1, 42
127      compare_vals(0x0002A0B7U, 0x00000000U);
128      as.RewindBuffer();
129      vals = {};
130  
131      as.LI(x1, ~0xFFF);
132      // lui x1, -1
133      compare_vals(0xFFFFF0B7U, 0x00000000U);
134      as.RewindBuffer();
135      vals = {};
136  
137      as.LI(x1, INT32_MIN);
138      // lui x1, -524288
139      compare_vals(0x800000B7U, 0x00000000U);
140      as.RewindBuffer();
141      vals = {};
142  
143      ///////// LUI+ADDIW cases
144  
145      as.LI(x1, 0x11111111);
146      // lui x1, 69905
147      // addiw x1, x1, 273
148      compare_vals(0x111110B7U, 0x1110809BU, 0x00000000U);
149      as.RewindBuffer();
150      vals = {};
151  
152      as.LI(x1, INT32_MAX);
153      // lui x1, -524288
154      // addiw x1, x1, -1
155      compare_vals(0x800000B7U, 0xFFF0809BU, 0x00000000U);
156      as.RewindBuffer();
157      vals = {};
158  
159      ///////// ADDIW+SLLI cases
160  
161      as.LI(x1, 0x7FF0000000ULL);
162      // addiw x1, x0, 2047
163      // slli x1, x1, 28
164      compare_vals(0x7FF0009BU, 0x01C09093U, 0x000000000U);
165      as.RewindBuffer();
166      vals = {};
167  
168      as.LI(x1, 0xABC00000ULL);
169      // addiw x1, x0, 687
170      // slli x1, x1, 22
171      compare_vals(0x2AF0009BU, 0x01609093U, 0x000000000U);
172      as.RewindBuffer();
173      vals = {};
174  
175      ///////// LUI+ADDIW+SLLI cases
176  
177      as.LI(x1, 0x7FFFFFFF0000ULL);
178      // lui x1, -524288
179      // addiw x1, x1, -1
180      // slli x1, x1, 16
181      compare_vals(0x800000B7U, 0xFFF0809BU, 0x01009093U, 0x000000000U);
182      as.RewindBuffer();
183      vals = {};
184  
185      ///////// LUI+ADDIW+SLLI+ADDI cases
186  
187      as.LI(x1, 0x7FFFFFFF0123);
188      // lui x1, -524288
189      // addiw x1, x1, -1
190      // slli x1, x1, 16
191      // addi x1, x1, 291
192      compare_vals(0x800000B7U, 0xfff0809BU, 0x01009093U, 0x12308093U,
193                   0x000000000U);
194      as.RewindBuffer();
195      vals = {};
196  
197      ///////// ADDIW+SLLI+ADDI+SLLI+ADDI cases
198  
199      as.LI(x1, 0x8000000080000001ULL);
200      // addiw x1, x0, -1
201      // slli x1, x1, 32
202      // addi x1, x1, 1
203      // slli x1, x1, 31
204      // addi x1, x1, 1
205      compare_vals(0xFFF0009BU, 0x02009093U, 0x00108093U, 0x01F09093U,
206                   0x00108093U, 0x000000000U);
207      as.RewindBuffer();
208      vals = {};
209  
210      ///////// Full LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI cases
211  
212      as.LI(x1, 0x80808000808080F1ULL);
213      // lui x1, -16
214      // addiw x1, x1, 257
215      // slli x1, x1, 16
216      // addi x1, x1, 1
217      // slli x1, x1, 16
218      // addi x1, x1, 257
219      // slli x1, x1, 15
220      // addi x1, x1, 241
221      compare_vals(0xFFFF00B7U, 0x1010809BU, 0x01009093U, 0x00108093U,
222                   0x01009093U, 0x10108093U, 0x00F09093U, 0x0F108093U);
223  }
224  
225  TEST_CASE("SD", "[rv64i]") {
226      uint32_t value = 0;
227      auto as = MakeAssembler64(value);
228  
229      as.SD(x15, 1024, x31);
230      REQUIRE(value == 0x40FFB023);
231  
232      as.RewindBuffer();
233  
234      as.SD(x15, 1536, x31);
235      REQUIRE(value == 0x60FFB023);
236  
237      as.RewindBuffer();
238  
239      as.SD(x15, -1, x31);
240      REQUIRE(value == 0xFEFFBFA3);
241  }
242  
243  TEST_CASE("SLLI (RV64)", "[rv64i]") {
244      uint32_t value = 0;
245      auto as = MakeAssembler64(value);
246  
247      as.SLLI(x31, x15, 10);
248      REQUIRE(value == 0x00A79F93);
249  
250      as.RewindBuffer();
251  
252      as.SLLI(x31, x15, 20);
253      REQUIRE(value == 0x01479F93);
254  
255      as.RewindBuffer();
256  
257      as.SLLI(x31, x15, 31);
258      REQUIRE(value == 0x01F79F93);
259  
260      as.RewindBuffer();
261  
262      as.SLLI(x31, x15, 63);
263      REQUIRE(value == 0x03F79F93);
264  }
265  
266  TEST_CASE("SLLIW", "[rv64i]") {
267      uint32_t value = 0;
268      auto as = MakeAssembler64(value);
269  
270      as.SLLIW(x31, x15, 10);
271      REQUIRE(value == 0x00A79F9B);
272  
273      as.RewindBuffer();
274  
275      as.SLLIW(x31, x15, 20);
276      REQUIRE(value == 0x01479F9B);
277  
278      as.RewindBuffer();
279  
280      as.SLLIW(x31, x15, 31);
281      REQUIRE(value == 0x01F79F9B);
282  }
283  
284  TEST_CASE("SLLW", "[rv64i]") {
285      uint32_t value = 0;
286      auto as = MakeAssembler64(value);
287  
288      as.SLLW(x7, x15, x31);
289      REQUIRE(value == 0x01F793BB);
290  
291      as.RewindBuffer();
292  
293      as.SLLW(x31, x31, x31);
294      REQUIRE(value == 0x01FF9FBB);
295  
296      as.RewindBuffer();
297  
298      as.SLLW(x0, x0, x0);
299      REQUIRE(value == 0x0000103B);
300  }
301  
302  TEST_CASE("SRAI (RV64)", "[rv64i]") {
303      uint32_t value = 0;
304      auto as = MakeAssembler64(value);
305  
306      as.SRAI(x31, x15, 10);
307      REQUIRE(value == 0x40A7DF93);
308  
309      as.RewindBuffer();
310  
311      as.SRAI(x31, x15, 20);
312      REQUIRE(value == 0x4147DF93);
313  
314      as.RewindBuffer();
315  
316      as.SRAI(x31, x15, 31);
317      REQUIRE(value == 0x41F7DF93);
318  
319      as.RewindBuffer();
320  
321      as.SRAI(x31, x15, 63);
322      REQUIRE(value == 0x43F7DF93);
323  }
324  
325  TEST_CASE("SRAIW", "[rv64i]") {
326      uint32_t value = 0;
327      auto as = MakeAssembler64(value);
328  
329      as.SRAIW(x31, x15, 10);
330      REQUIRE(value == 0x40A7DF9B);
331  
332      as.RewindBuffer();
333  
334      as.SRAIW(x31, x15, 20);
335      REQUIRE(value == 0x4147DF9B);
336  
337      as.RewindBuffer();
338  
339      as.SRAIW(x31, x15, 31);
340      REQUIRE(value == 0x41F7DF9B);
341  }
342  
343  TEST_CASE("SRAW", "[rv64i]") {
344      uint32_t value = 0;
345      auto as = MakeAssembler64(value);
346  
347      as.SRAW(x7, x15, x31);
348      REQUIRE(value == 0x41F7D3BB);
349  
350      as.RewindBuffer();
351  
352      as.SRAW(x31, x31, x31);
353      REQUIRE(value == 0x41FFDFBB);
354  
355      as.RewindBuffer();
356  
357      as.SRAW(x0, x0, x0);
358      REQUIRE(value == 0x4000503B);
359  }
360  
361  TEST_CASE("SRLI (RV64)", "[rv64i]") {
362      uint32_t value = 0;
363      auto as = MakeAssembler64(value);
364  
365      as.SRLI(x31, x15, 10);
366      REQUIRE(value == 0x00A7DF93);
367  
368      as.RewindBuffer();
369  
370      as.SRLI(x31, x15, 20);
371      REQUIRE(value == 0x0147DF93);
372  
373      as.RewindBuffer();
374  
375      as.SRLI(x31, x15, 31);
376      REQUIRE(value == 0x01F7DF93);
377  
378      as.RewindBuffer();
379  
380      as.SRLI(x31, x15, 63);
381      REQUIRE(value == 0x03F7DF93);
382  }
383  
384  TEST_CASE("SRLIW", "[rv64i]") {
385      uint32_t value = 0;
386      auto as = MakeAssembler64(value);
387  
388      as.SRLIW(x31, x15, 10);
389      REQUIRE(value == 0x00A7DF9B);
390  
391      as.RewindBuffer();
392  
393      as.SRLIW(x31, x15, 20);
394      REQUIRE(value == 0x0147DF9B);
395  
396      as.RewindBuffer();
397  
398      as.SRLIW(x31, x15, 31);
399      REQUIRE(value == 0x01F7DF9B);
400  }
401  
402  TEST_CASE("SRLW", "[rv64i]") {
403      uint32_t value = 0;
404      auto as = MakeAssembler64(value);
405  
406      as.SRLW(x7, x15, x31);
407      REQUIRE(value == 0x01F7D3BB);
408  
409      as.RewindBuffer();
410  
411      as.SRLW(x31, x31, x31);
412      REQUIRE(value == 0x01FFDFBB);
413  
414      as.RewindBuffer();
415  
416      as.SRLW(x0, x0, x0);
417      REQUIRE(value == 0x0000503B);
418  }
419  
420  TEST_CASE("SUBW", "[rv64i]") {
421      uint32_t value = 0;
422      auto as = MakeAssembler64(value);
423  
424      as.SUBW(x7, x15, x31);
425      REQUIRE(value == 0x41F783BB);
426  
427      as.RewindBuffer();
428  
429      as.SUBW(x31, x31, x31);
430      REQUIRE(value == 0x41FF8FBB);
431  
432      as.RewindBuffer();
433  
434      as.SUBW(x0, x0, x0);
435      REQUIRE(value == 0x4000003B);
436  }