summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-disasm-riscv64.cc
blob: c5c7a2eb419f9e5d903ae3b7a35778e285df98a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
// Copyright 2021 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#include <stdlib.h>

#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames-inl.h"
#include "src/init/v8.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

bool prev_instr_compact_branch = false;

bool DisassembleAndCompare(byte* pc, const char* compare_string) {
  disasm::NameConverter converter;
  disasm::Disassembler disasm(converter);
  EmbeddedVector<char, 128> disasm_buffer;

  if (prev_instr_compact_branch) {
    disasm.InstructionDecode(disasm_buffer, pc);
    pc += 4;
  }

  disasm.InstructionDecode(disasm_buffer, pc);

  if (strcmp(compare_string, disasm_buffer.begin()) != 0) {
    fprintf(stderr,
            "expected: \n"
            "%s\n"
            "disassembled: \n"
            "%s\n\n",
            compare_string, disasm_buffer.begin());
    return false;
  }
  return true;
}

// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
#define SET_UP()                                             \
  CcTest::InitializeVM();                                    \
  Isolate* isolate = CcTest::i_isolate();                    \
  HandleScope scope(isolate);                                \
  byte* buffer = reinterpret_cast<byte*>(malloc(4 * 1024));  \
  Assembler assm(AssemblerOptions{},                         \
                 ExternalAssemblerBuffer(buffer, 4 * 1024)); \
  bool failure = false;

// This macro assembles one instruction using the preallocated assembler and
// disassembles the generated instruction, comparing the output to the expected
// value. If the comparison fails an error message is printed, but the test
// continues to run until the end.
#define COMPARE(asm_, compare_string)                                        \
  {                                                                          \
    int pc_offset = assm.pc_offset();                                        \
    byte* progcounter = &buffer[pc_offset];                                  \
    assm.asm_;                                                               \
    if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
  }

#define COMPARE_PC_REL(asm_, compare_string, offset)                           \
  {                                                                            \
    int pc_offset = assm.pc_offset();                                          \
    byte* progcounter = &buffer[pc_offset];                                    \
    char str_with_address[100];                                                \
    snprintf(str_with_address, sizeof(str_with_address), "%s -> %p",           \
             compare_string, static_cast<void*>(progcounter + (offset)));      \
    assm.asm_;                                                                 \
    if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
  }

// Verify that all invocations of the COMPARE macro passed successfully.
// Exit with a failure if at least one of the tests failed.
#define VERIFY_RUN()                             \
  if (failure) {                                 \
    FATAL("RISCV Disassembler tests failed.\n"); \
  }

TEST(Arith) {
  SET_UP();

  // Arithmetic with immediate
  COMPARE(addi(t6, s3, -268), "ef498f93       addi      t6, s3, -268");
  COMPARE(slti(t5, s4, -268), "ef4a2f13       slti      t5, s4, -268");
  COMPARE(sltiu(t4, s5, -268), "ef4abe93       sltiu     t4, s5, -268");
  COMPARE(xori(t3, s6, static_cast<int16_t>(0xfffffef4)),
          "ef4b4e13       xori      t3, s6, 0xfffffef4");
  COMPARE(ori(s11, zero_reg, static_cast<int16_t>(0xfffffef4)),
          "ef406d93       ori       s11, zero_reg, 0xfffffef4");
  COMPARE(andi(s10, ra, static_cast<int16_t>(0xfffffef4)),
          "ef40fd13       andi      s10, ra, 0xfffffef4");
  COMPARE(slli(s9, sp, 17), "01111c93       slli      s9, sp, 17");
  COMPARE(srli(s8, gp, 17), "0111dc13       srli      s8, gp, 17");
  COMPARE(srai(s7, tp, 17), "41125b93       srai      s7, tp, 17");

  // Arithmetic
  COMPARE(add(s6, t0, t4), "01d28b33       add       s6, t0, t4");
  COMPARE(sub(s5, t1, s4), "41430ab3       sub       s5, t1, s4");
  COMPARE(sll(s4, t2, s4), "01439a33       sll       s4, t2, s4");
  COMPARE(slt(s3, fp, s4), "014429b3       slt       s3, fp, s4");
  COMPARE(sltu(s2, s3, t6), "01f9b933       sltu      s2, s3, t6");
  COMPARE(xor_(a7, s4, s4), "014a48b3       xor       a7, s4, s4");
  COMPARE(srl(a6, s5, s4), "014ad833       srl       a6, s5, s4");
  COMPARE(sra(a0, s3, s4), "4149d533       sra       a0, s3, s4");
  COMPARE(or_(a0, s3, s4), "0149e533       or        a0, s3, s4");
  COMPARE(and_(a0, s3, s4), "0149f533       and       a0, s3, s4");

  VERIFY_RUN();
}

TEST(LD_ST) {
  SET_UP();
  // Loads
  COMPARE(lb(t0, a0, 0), "00050283       lb        t0, 0(a0)");
  COMPARE(lh(t1, a1, -1024), "c0059303       lh        t1, -1024(a1)");
  COMPARE(lw(t2, a2, 100), "06462383       lw        t2, 100(a2)");
  COMPARE(lbu(fp, a3, -512), "e006c403       lbu       fp, -512(a3)");
  COMPARE(lhu(s1, a4, 258), "10275483       lhu       s1, 258(a4)");

  // Stores
  COMPARE(sb(zero_reg, a5, -4), "fe078e23       sb        zero_reg, -4(a5)");
  COMPARE(sh(a6, s2, 4), "01091223       sh        a6, 4(s2)");
  COMPARE(sw(a7, s3, 100), "0719a223       sw        a7, 100(s3)");

  VERIFY_RUN();
}

TEST(MISC) {
  SET_UP();

  COMPARE(lui(sp, 0x64), "00064137       lui       sp, 0x64");
  COMPARE(auipc(ra, 0x7fe), "007fe097       auipc     ra, 0x7fe");

  // Jumps
  COMPARE_PC_REL(jal(gp, 100), "064001ef       jal       gp, 100", 100);
  COMPARE(jalr(tp, zero_reg, 100),
          "06400267       jalr      tp, 100(zero_reg)");

  // Branches
  COMPARE_PC_REL(beq(fp, a4, -268), "eee40ae3       beq       fp, a4, -268",
                 -268);
  COMPARE_PC_REL(bne(t1, s4, -268), "ef431ae3       bne       t1, s4, -268",
                 -268);
  COMPARE_PC_REL(blt(s3, t4, -268), "efd9cae3       blt       s3, t4, -268",
                 -268);
  COMPARE_PC_REL(bge(t2, sp, -268), "ee23dae3       bge       t2, sp, -268",
                 -268);
  COMPARE_PC_REL(bltu(s6, a1, -268), "eebb6ae3       bltu      s6, a1, -268",
                 -268);
  COMPARE_PC_REL(bgeu(a1, s3, -268), "ef35fae3       bgeu      a1, s3, -268",
                 -268);

  // Memory fences
  COMPARE(fence(PSO | PSR, PSW | PSI), "0690000f       fence or, iw");
  COMPARE(fence_tso(), "8330000f       fence rw, rw");

  // Environment call / break
  COMPARE(ecall(), "00000073       ecall");
  COMPARE(ebreak(), "00100073       ebreak");

  VERIFY_RUN();
}

TEST(CSR) {
  SET_UP();

  COMPARE(csrrw(a0, csr_fflags, t3), "001e1573       fsflags   a0, t3");
  COMPARE(csrrs(a0, csr_frm, t1), "00232573       csrrs     a0, csr_frm, t1");
  COMPARE(csrrc(a0, csr_fcsr, s3), "0039b573       csrrc     a0, csr_fcsr, s3");
  COMPARE(csrrwi(a0, csr_fflags, 0x10),
          "00185573       csrrwi    a0, csr_fflags, 0x10");
  COMPARE(csrrsi(t3, csr_frm, 0x3),
          "0021ee73       csrrsi    t3, csr_frm, 0x3");
  COMPARE(csrrci(a0, csr_fflags, 0x10),
          "00187573       csrrci    a0, csr_fflags, 0x10");

  VERIFY_RUN();
}

TEST(RV64I) {
  SET_UP();

  COMPARE(lwu(a0, s3, -268), "ef49e503       lwu       a0, -268(s3)");
  COMPARE(ld(a1, s3, -268), "ef49b583       ld        a1, -268(s3)");
  COMPARE(sd(fp, sp, -268), "ee813a23       sd        fp, -268(sp)");
  COMPARE(addiw(gp, s3, -268), "ef49819b       addiw     gp, s3, -268");
  COMPARE(slliw(tp, s3, 17), "0119921b       slliw     tp, s3, 17");
  COMPARE(srliw(ra, s3, 10), "00a9d09b       srliw     ra, s3, 10");
  COMPARE(sraiw(sp, s3, 17), "4119d11b       sraiw     sp, s3, 17");
  COMPARE(addw(t1, zero_reg, s4), "0140033b       addw      t1, zero_reg, s4");
  COMPARE(subw(t2, s3, s4), "414983bb       subw      t2, s3, s4");
  COMPARE(sllw(s7, s3, s4), "01499bbb       sllw      s7, s3, s4");
  COMPARE(srlw(s10, s3, s4), "0149dd3b       srlw      s10, s3, s4");
  COMPARE(sraw(a7, s3, s4), "4149d8bb       sraw      a7, s3, s4");

  VERIFY_RUN();
}

TEST(RV32M) {
  SET_UP();

  COMPARE(mul(a0, s3, t4), "03d98533       mul       a0, s3, t4");
  COMPARE(mulh(a0, s3, t4), "03d99533       mulh      a0, s3, t4");
  COMPARE(mulhsu(a0, s3, t4), "03d9a533       mulhsu    a0, s3, t4");
  COMPARE(mulhu(a0, s3, t4), "03d9b533       mulhu     a0, s3, t4");
  COMPARE(div(a0, s3, t4), "03d9c533       div       a0, s3, t4");
  COMPARE(divu(a0, s3, t4), "03d9d533       divu      a0, s3, t4");
  COMPARE(rem(a0, s3, t4), "03d9e533       rem       a0, s3, t4");
  COMPARE(remu(a0, s3, t4), "03d9f533       remu      a0, s3, t4");

  VERIFY_RUN();
}

TEST(RV64M) {
  SET_UP();

  COMPARE(mulw(a0, s3, s4), "0349853b       mulw      a0, s3, s4");
  COMPARE(divw(a0, s3, s4), "0349c53b       divw      a0, s3, s4");
  COMPARE(divuw(a0, s3, s4), "0349d53b       divuw     a0, s3, s4");
  COMPARE(remw(a0, s3, s4), "0349e53b       remw      a0, s3, s4");
  COMPARE(remuw(a0, s3, s4), "0349f53b       remuw     a0, s3, s4");

  VERIFY_RUN();
}

TEST(RV32A) {
  SET_UP();
  // RV32A Standard Extension
  COMPARE(lr_w(true, false, a0, s3), "1409a52f       lr.w.aq    a0, (s3)");
  COMPARE(sc_w(true, true, a0, s3, s4),
          "1f49a52f       sc.w.aqrl    a0, s4, (s3)");
  COMPARE(amoswap_w(false, false, a0, s3, s4),
          "0949a52f       amoswap.w a0, s4, (s3)");
  COMPARE(amoadd_w(false, true, a0, s3, s4),
          "0349a52f       amoadd.w.rl a0, s4, (s3)");
  COMPARE(amoxor_w(true, false, a0, s3, s4),
          "2549a52f       amoxor.w.aq a0, s4, (s3)");
  COMPARE(amoand_w(false, false, a0, s3, s4),
          "6149a52f       amoand.w a0, s4, (s3)");
  COMPARE(amoor_w(true, true, a0, s3, s4),
          "4749a52f       amoor.w.aqrl a0, s4, (s3)");
  COMPARE(amomin_w(false, true, a0, s3, s4),
          "8349a52f       amomin.w.rl a0, s4, (s3)");
  COMPARE(amomax_w(true, false, a0, s3, s4),
          "a549a52f       amomax.w.aq a0, s4, (s3)");
  COMPARE(amominu_w(false, false, a0, s3, s4),
          "c149a52f       amominu.w a0, s4, (s3)");
  COMPARE(amomaxu_w(true, true, a0, s3, s4),
          "e749a52f       amomaxu.w.aqrl a0, s4, (s3)");
  VERIFY_RUN();
}

TEST(RV64A) {
  SET_UP();

  COMPARE(lr_d(true, true, a0, s3), "1609b52f       lr.d.aqrl a0, (s3)");
  COMPARE(sc_d(false, true, a0, s3, s4), "1b49b52f       sc.d.rl a0, s4, (s3)");
  COMPARE(amoswap_d(true, false, a0, s3, s4),
          "0d49b52f       amoswap.d.aq a0, s4, (s3)");
  COMPARE(amoadd_d(false, false, a0, s3, s4),
          "0149b52f       amoadd.d a0, s4, (s3)");
  COMPARE(amoxor_d(true, false, a0, s3, s4),
          "2549b52f       amoxor.d.aq a0, s4, (s3)");
  COMPARE(amoand_d(true, true, a0, s3, s4),
          "6749b52f       amoand.d.aqrl a0, s4, (s3)");
  COMPARE(amoor_d(false, true, a0, s3, s4),
          "4349b52f       amoor.d.rl a0, s4, (s3)");
  COMPARE(amomin_d(true, true, a0, s3, s4),
          "8749b52f       amomin.d.aqrl a0, s4, (s3)");
  COMPARE(amomax_d(false, true, a0, s3, s4),
          "a349b52f       amoswap.d.rl a0, s4, (s3)");
  COMPARE(amominu_d(true, false, a0, s3, s4),
          "c549b52f       amominu.d.aq a0, s4, (s3)");
  COMPARE(amomaxu_d(false, true, a0, s3, s4),
          "e349b52f       amomaxu.d.rl a0, s4, (s3)");

  VERIFY_RUN();
}

TEST(RV32F) {
  SET_UP();
  // RV32F Standard Extension
  COMPARE(flw(fa0, s3, -268), "ef49a507       flw       fa0, -268(s3)");
  COMPARE(fsw(ft7, sp, -268), "ee712a27       fsw       ft7, -268(sp)");
  COMPARE(fmadd_s(fa0, ft8, fa5, fs5),
          "a8fe0543       fmadd.s   fa0, ft8, fa5, fs5");
  COMPARE(fmsub_s(fa0, ft8, fa5, fs5),
          "a8fe0547       fmsub.s   fa0, ft8, fa5, fs5");
  COMPARE(fnmsub_s(fa0, ft8, fa5, fs5),
          "a8fe054b       fnmsub.s   fa0, ft8, fa5, fs5");
  COMPARE(fnmadd_s(fa0, ft8, fa5, fs5),
          "a8fe054f       fnmadd.s   fa0, ft8, fa5, fs5");
  COMPARE(fadd_s(fa0, ft8, fa5), "00fe0553       fadd.s    fa0, ft8, fa5");
  COMPARE(fsub_s(fa0, ft8, fa5), "08fe0553       fsub.s    fa0, ft8, fa5");
  COMPARE(fmul_s(fa0, ft8, fa5), "10fe0553       fmul.s    fa0, ft8, fa5");
  COMPARE(fdiv_s(ft0, ft8, fa5), "18fe0053       fdiv.s    ft0, ft8, fa5");
  COMPARE(fsqrt_s(ft0, ft8), "580e0053       fsqrt.s   ft0, ft8");
  COMPARE(fsgnj_s(ft0, ft8, fa5), "20fe0053       fsgnj.s   ft0, ft8, fa5");
  COMPARE(fsgnjn_s(ft0, ft8, fa5), "20fe1053       fsgnjn.s  ft0, ft8, fa5");
  COMPARE(fsgnjx_s(ft0, ft8, fa5), "20fe2053       fsgnjx.s  ft0, ft8, fa5");
  COMPARE(fmin_s(ft0, ft8, fa5), "28fe0053       fmin.s    ft0, ft8, fa5");
  COMPARE(fmax_s(ft0, ft8, fa5), "28fe1053       fmax.s    ft0, ft8, fa5");
  COMPARE(fcvt_w_s(a0, ft8, RNE), "c00e0553       fcvt.w.s  [RNE] a0, ft8");
  COMPARE(fcvt_wu_s(a0, ft8, RTZ), "c01e1553       fcvt.wu.s [RTZ] a0, ft8");
  COMPARE(fmv_x_w(a0, ft8), "e00e0553       fmv.x.w   a0, ft8");
  COMPARE(feq_s(a0, ft8, fa5), "a0fe2553       feq.s     a0, ft8, fa5");
  COMPARE(flt_s(a0, ft8, fa5), "a0fe1553       flt.s     a0, ft8, fa5");
  COMPARE(fle_s(a0, ft8, fa5), "a0fe0553       fle.s     a0, ft8, fa5");
  COMPARE(fclass_s(a0, ft8), "e00e1553       fclass.s  a0, ft8");
  COMPARE(fcvt_s_w(ft0, s3), "d0098053       fcvt.s.w  ft0, s3");
  COMPARE(fcvt_s_wu(ft0, s3), "d0198053       fcvt.s.wu ft0, s3");
  COMPARE(fmv_w_x(ft0, s3), "f0098053       fmv.w.x   ft0, s3");
  VERIFY_RUN();
}

TEST(RV64F) {
  SET_UP();
  // RV64F Standard Extension (in addition to RV32F)
  COMPARE(fcvt_l_s(a0, ft8, RNE), "c02e0553       fcvt.l.s  [RNE] a0, ft8");
  COMPARE(fcvt_lu_s(a0, ft8, RMM), "c03e4553       fcvt.lu.s [RMM] a0, ft8");
  COMPARE(fcvt_s_l(ft0, s3), "d0298053       fcvt.s.l  ft0, s3");
  COMPARE(fcvt_s_lu(ft0, s3), "d0398053       fcvt.s.lu ft0, s3");
  VERIFY_RUN();
}

TEST(RV32D) {
  SET_UP();
  // RV32D Standard Extension
  COMPARE(fld(ft0, s3, -268), "ef49b007       fld       ft0, -268(s3)");
  COMPARE(fsd(ft7, sp, -268), "ee713a27       fsd       ft7, -268(sp)");
  COMPARE(fmadd_d(ft0, ft8, fa5, fs5),
          "aafe0043       fmadd.d   ft0, ft8, fa5, fs5");
  COMPARE(fmsub_d(ft0, ft8, fa5, fs1),
          "4afe0047       fmsub.d   ft0, ft8, fa5, fs1");
  COMPARE(fnmsub_d(ft0, ft8, fa5, fs2),
          "92fe004b       fnmsub.d  ft0, ft8, fa5, fs2");
  COMPARE(fnmadd_d(ft0, ft8, fa5, fs3),
          "9afe004f       fnmadd.d  ft0, ft8, fa5, fs3");
  COMPARE(fadd_d(ft0, ft8, fa5), "02fe0053       fadd.d    ft0, ft8, fa5");
  COMPARE(fsub_d(ft0, ft8, fa5), "0afe0053       fsub.d    ft0, ft8, fa5");
  COMPARE(fmul_d(ft0, ft8, fa5), "12fe0053       fmul.d    ft0, ft8, fa5");
  COMPARE(fdiv_d(ft0, ft8, fa5), "1afe0053       fdiv.d    ft0, ft8, fa5");
  COMPARE(fsqrt_d(ft0, ft8), "5a0e0053       fsqrt.d   ft0, ft8");
  COMPARE(fsgnj_d(ft0, ft8, fa5), "22fe0053       fsgnj.d   ft0, ft8, fa5");
  COMPARE(fsgnjn_d(ft0, ft8, fa5), "22fe1053       fsgnjn.d  ft0, ft8, fa5");
  COMPARE(fsgnjx_d(ft0, ft8, fa5), "22fe2053       fsgnjx.d  ft0, ft8, fa5");
  COMPARE(fmin_d(ft0, ft8, fa5), "2afe0053       fmin.d    ft0, ft8, fa5");
  COMPARE(fmax_d(ft0, ft8, fa5), "2afe1053       fmax.d    ft0, ft8, fa5");
  COMPARE(fcvt_s_d(ft0, ft8, RDN), "401e2053       fcvt.s.d  [RDN] ft0, t3");
  COMPARE(fcvt_d_s(ft0, fa0), "42050053       fcvt.d.s  ft0, fa0");
  COMPARE(feq_d(a0, ft8, fa5), "a2fe2553       feq.d     a0, ft8, fa5");
  COMPARE(flt_d(a0, ft8, fa5), "a2fe1553       flt.d     a0, ft8, fa5");
  COMPARE(fle_d(a0, ft8, fa5), "a2fe0553       fle.d     a0, ft8, fa5");
  COMPARE(fclass_d(a0, ft8), "e20e1553       fclass.d  a0, ft8");
  COMPARE(fcvt_w_d(a0, ft8, RNE), "c20e0553       fcvt.w.d  [RNE] a0, ft8");
  COMPARE(fcvt_wu_d(a0, ft8, RUP), "c21e3553       fcvt.wu.d [RUP] a0, ft8");
  COMPARE(fcvt_d_w(ft0, s3), "d2098053       fcvt.d.w  ft0, s3");
  COMPARE(fcvt_d_wu(ft0, s3), "d2198053       fcvt.d.wu ft0, s3");

  VERIFY_RUN();
}

TEST(RV64D) {
  SET_UP();
  // RV64D Standard Extension (in addition to RV32D)
  COMPARE(fcvt_l_d(a0, ft8, RMM), "c22e4553       fcvt.l.d  [RMM] a0, ft8");
  COMPARE(fcvt_lu_d(a0, ft8, RDN), "c23e2553       fcvt.lu.d [RDN] a0, ft8");
  COMPARE(fmv_x_d(a0, ft8), "e20e0553       fmv.x.d   a0, ft8");
  COMPARE(fcvt_d_l(ft0, s3), "d2298053       fcvt.d.l  ft0, s3");
  COMPARE(fcvt_d_lu(ft0, s3), "d2398053       fcvt.d.lu ft0, s3");
  COMPARE(fmv_d_x(ft0, s3), "f2098053       fmv.d.x   ft0, s3");
  VERIFY_RUN();
}

TEST(PSEUDO) {
  SET_UP();
  // pseodu instructions according to rISCV assembly programmer's handbook
  COMPARE(nop(), "00000013       nop");
  COMPARE(RV_li(t6, -12), "ff400f93       li        t6, -12");
  COMPARE(mv(t0, a4), "00070293       mv        t0, a4");
  COMPARE(not_(t0, a5), "fff7c293       not       t0, a5");
  COMPARE(neg(ra, a6), "410000b3       neg       ra, rs2");
  COMPARE(negw(t2, fp), "408003bb       negw      t2, fp");
  COMPARE(sext_w(t0, s1), "0004829b       sext.w    t0, s1");
  COMPARE(seqz(sp, s2), "00193113       seqz      sp, s2");
  COMPARE(snez(fp, s3), "01303433       snez      fp, s3");
  COMPARE(sltz(a0, t5), "000f2533       sltz      a0, t5");
  COMPARE(sgtz(a1, t4), "01d025b3       sgtz      a1, t4");

  COMPARE(fmv_s(fa0, fs4), "214a0553       fmv.s     fa0, fs4");
  COMPARE(fabs_s(fa1, fs3), "2139a5d3       fabs.s    fa1, fs3");
  COMPARE(fneg_s(fa2, fs5), "215a9653       fneg.s    fa2, fs5");
  COMPARE(fmv_d(fa3, fs2), "232906d3       fmv.d     fa3, fs2");
  COMPARE(fabs_d(fs0, fs2), "23292453       fabs.d    fs0, fs2");
  COMPARE(fneg_d(fs1, fs1), "229494d3       fneg.d    fs1, fs1");

  COMPARE_PC_REL(j(-1024), "c01ff06f       j         -1024", -1024);
  COMPARE_PC_REL(jal(32), "020000ef       jal       32", 32);
  COMPARE(jr(a1), "00058067       jr        a1");
  COMPARE(jalr(a1), "000580e7       jalr      a1");
  COMPARE(ret(), "00008067       ret");
  // COMPARE(call(int32_t offset);

  COMPARE(rdinstret(t0), "c02022f3       rdinstret t0");
  COMPARE(rdinstreth(a0), "c8202573       rdinstreth a0");
  COMPARE(rdcycle(a4), "c0002773       rdcycle   a4");
  COMPARE(rdcycleh(a5), "c80027f3       rdcycleh  a5");
  COMPARE(rdtime(a3), "c01026f3       rdtime    a3");
  COMPARE(rdtimeh(t2), "c81023f3       rdtimeh   t2");

  COMPARE(csrr(t3, csr_cycle), "c0002e73       rdcycle   t3");
  COMPARE(csrw(csr_instret, a1), "c0259073       csrw      csr_instret, a1");
  COMPARE(csrs(csr_timeh, a2), "c8162073       csrs      csr_timeh, a2");
  COMPARE(csrc(csr_cycleh, t1), "c8033073       csrc      csr_cycleh, t1");

  COMPARE(csrwi(csr_time, 0xf), "c017d073       csrwi     csr_time, 0xf");
  COMPARE(csrsi(csr_cycleh, 0x1), "c800e073       csrsi     csr_cycleh, 0x1");
  COMPARE(csrci(csr_instreth, 0x15),
          "c82af073       csrci     csr_instreth, 0x15");

  COMPARE(frcsr(t4), "00302ef3       frcsr     t4");
  COMPARE(fscsr(t1, a1), "00359373       fscsr     t1, a1");
  COMPARE(fscsr(a4), "00371073       fscsr     a4");

  COMPARE(frrm(t2), "002023f3       frrm      t2");
  COMPARE(fsrm(t0, a1), "002592f3       fsrm      t0, a1");
  COMPARE(fsrm(a5), "00279073       fsrm      a5");

  COMPARE(frflags(s5), "00102af3       frflags   s5");
  COMPARE(fsflags(s2, t1), "00131973       fsflags   s2, t1");
  COMPARE(fsflags(s1), "00149073       fsflags   s1");

  VERIFY_RUN();
}

TEST(RV64C) {
  SET_UP();

  COMPARE(c_nop(), "00000001       nop");
  COMPARE(c_addi(s3, -25), "0000199d       addi      s3, s3, -25");
  COMPARE(c_addiw(gp, -30), "00003189       addiw     gp, gp, -30");
  COMPARE(c_addi16sp(-432), "00007161       addi      sp, sp, -432");
  COMPARE(c_addi4spn(a1, 924), "00000f6c       addi       a1, sp, 924");
  COMPARE(c_li(t6, -15), "00005fc5       li        t6, -15");
  COMPARE(c_lui(s1, 0xf4), "000074d1       lui       s1, 0xffff4");
  COMPARE(c_slli(s9, 60), "00001cf2       slli      s9, s9, 60");
  COMPARE(c_fldsp(fa1, 360), "000035b6       fld       fa1, 360(sp)");
  COMPARE(c_lwsp(s7, 244), "00005bde       lw        s7, 244(sp)");
  COMPARE(c_ldsp(s6, 344), "00006b76       ld        s6, 344(sp)");

  COMPARE(c_jr(a1), "00008582       jr        a1");
  COMPARE(c_mv(t0, a4), "000082ba       mv        t0, a4");
  COMPARE(c_ebreak(), "00009002       ebreak");
  COMPARE(c_jalr(a1), "00009582       jalr      a1");
  COMPARE(c_add(s6, t0), "00009b16       add       s6, s6, t0");
  COMPARE(c_sub(s1, a0), "00008c89       sub       s1, s1, a0");
  COMPARE(c_xor(s1, a0), "00008ca9       xor       s1, s1, a0");
  COMPARE(c_or(s1, a0), "00008cc9       or       s1, s1, a0");
  COMPARE(c_and(s1, a0), "00008ce9       and       s1, s1, a0");
  COMPARE(c_subw(s1, a0), "00009c89       subw       s1, s1, a0");
  COMPARE(c_addw(a0, a1), "00009d2d       addw       a0, a0, a1");

  COMPARE(c_fsdsp(fa4, 232), "0000b5ba       fsd       fa4, 232(sp)");
  COMPARE(c_swsp(s6, 180), "0000db5a       sw        s6, 180(sp)");
  COMPARE(c_sdsp(a4, 216), "0000edba       sd        a4, 216(sp)");

  COMPARE(c_lw(a2, s1, 24), "00004c90       lw       a2, 24(s1)");
  COMPARE(c_ld(a2, s1, 24), "00006c90       ld       a2, 24(s1)");
  COMPARE(c_fld(fa1, s1, 24), "00002c8c       fld       fa1, 24(s1)");

  COMPARE(c_sw(a2, s1, 24), "0000cc90       sw       a2, 24(s1)");
  COMPARE(c_sd(a2, s1, 24), "0000ec90       sd       a2, 24(s1)");
  COMPARE(c_fsd(fa1, s1, 24), "0000ac8c       fsd       fa1, 24(s1)");

  COMPARE(c_j(-12), "0000bfd5       j       -12");
  VERIFY_RUN();
}

/*
TEST(Previleged) {
  SET_UP();
  // Privileged
  COMPARE(uret(), "");
  COMPARE(sret(), "");
  COMPARE(mret(), "");
  COMPARE(wfi(), "");
  COMPARE(sfence_vma(s3, s4), "");
  VERIFY_RUN();
}
*/
}  // namespace internal
}  // namespace v8