OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_fnc_plugin/] [srcproc/] [srcproc.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Source code processor class declaration.
6
 */
7
 
8
#include "srcproc.h"
9
#include <iostream>
10
#include <riscv-isa.h>
11
 
12
namespace debugger {
13
 
14
/** Class registration in the Core */
15
enum ESymbInfo {
16
    SymbInfo_Name,
17
    SymbInfo_Address,
18
    SymbInfo_Total,
19
};
20
 
21
const char *const *RN = IREGS_NAMES;
22
 
23
int opcode_0x00(ISourceCode *isrc, uint64_t pc, uint32_t code,
24
                AttributeType *mnemonic, AttributeType *comment);
25
int opcode_0x03(ISourceCode *isrc, uint64_t pc, uint32_t code,
26
                AttributeType *mnemonic, AttributeType *comment);
27
int opcode_0x04(ISourceCode *isrc, uint64_t pc, uint32_t code,
28
                AttributeType *mnemonic, AttributeType *comment);
29
int opcode_0x05(ISourceCode *isrc, uint64_t pc, uint32_t code,
30
                AttributeType *mnemonic, AttributeType *comment);
31
int opcode_0x06(ISourceCode *isrc, uint64_t pc, uint32_t code,
32
                AttributeType *mnemonic, AttributeType *comment);
33
int opcode_0x08(ISourceCode *isrc, uint64_t pc, uint32_t code,
34
                AttributeType *mnemonic, AttributeType *comment);
35
int opcode_0x0C(ISourceCode *isrc, uint64_t pc, uint32_t code,
36
                AttributeType *mnemonic, AttributeType *comment);
37
int opcode_0x0D(ISourceCode *isrc, uint64_t pc, uint32_t code,
38
                AttributeType *mnemonic, AttributeType *comment);
39
int opcode_0x0E(ISourceCode *isrc, uint64_t pc, uint32_t code,
40
                AttributeType *mnemonic, AttributeType *comment);
41
int opcode_0x18(ISourceCode *isrc, uint64_t pc, uint32_t code,
42
                AttributeType *mnemonic, AttributeType *comment);
43
int opcode_0x19(ISourceCode *isrc, uint64_t pc, uint32_t code,
44
                AttributeType *mnemonic, AttributeType *comment);
45
int opcode_0x1B(ISourceCode *isrc, uint64_t pc, uint32_t code,
46
                AttributeType *mnemonic, AttributeType *comment);
47
int opcode_0x1C(ISourceCode *isrc, uint64_t pc, uint32_t code,
48
                AttributeType *mnemonic, AttributeType *comment);
49
 
50
int C_ADDI16SP_LUI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
51
                AttributeType *mnemonic, AttributeType *comment);
52
int C_ADDI4SPN(ISourceCode *isrc, uint64_t pc, Reg16Type code,
53
                AttributeType *mnemonic, AttributeType *comment);
54
int C_BEQZ(ISourceCode *isrc, uint64_t pc, Reg16Type code,
55
                AttributeType *mnemonic, AttributeType *comment);
56
int C_BNEZ(ISourceCode *isrc, uint64_t pc, Reg16Type code,
57
                AttributeType *mnemonic, AttributeType *comment);
58
int C_J(ISourceCode *isrc, uint64_t pc, Reg16Type code,
59
                AttributeType *mnemonic, AttributeType *comment);
60
int C_JAL_ADDIW(ISourceCode *isrc, uint64_t pc, Reg16Type code,
61
                AttributeType *mnemonic, AttributeType *comment);
62
int C_JR_MV_EBREAK_JALR_ADD(ISourceCode *isrc, uint64_t pc, Reg16Type code,
63
                AttributeType *mnemonic, AttributeType *comment);
64
int C_LD(ISourceCode *isrc, uint64_t pc, Reg16Type code,
65
                AttributeType *mnemonic, AttributeType *comment);
66
int C_LI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
67
                AttributeType *mnemonic, AttributeType *comment);
68
int C_LDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
69
                AttributeType *mnemonic, AttributeType *comment);
70
int C_LW(ISourceCode *isrc, uint64_t pc, Reg16Type code,
71
                AttributeType *mnemonic, AttributeType *comment);
72
int C_LWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
73
                AttributeType *mnemonic, AttributeType *comment);
74
int C_MATH(ISourceCode *isrc, uint64_t pc, Reg16Type code,
75
                AttributeType *mnemonic, AttributeType *comment);
76
int C_NOP_ADDI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
77
                AttributeType *mnemonic, AttributeType *comment);
78
int C_SD(ISourceCode *isrc, uint64_t pc, Reg16Type code,
79
                AttributeType *mnemonic, AttributeType *comment);
80
int C_SDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
81
                AttributeType *mnemonic, AttributeType *comment);
82
int C_SLLI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
83
                AttributeType *mnemonic, AttributeType *comment);
84
int C_SW(ISourceCode *isrc, uint64_t pc, Reg16Type code,
85
                AttributeType *mnemonic, AttributeType *comment);
86
int C_SWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
87
                AttributeType *mnemonic, AttributeType *comment);
88
 
89
 
90
RiscvSourceService::RiscvSourceService(const char *name) : IService(name) {
91
    registerInterface(static_cast<ISourceCode *>(this));
92
    memset(tblOpcode1_, 0, sizeof(tblOpcode1_));
93
    tblOpcode1_[0x00] = &opcode_0x00;
94
    tblOpcode1_[0x03] = &opcode_0x03;
95
    tblOpcode1_[0x04] = &opcode_0x04;
96
    tblOpcode1_[0x05] = &opcode_0x05;
97
    tblOpcode1_[0x06] = &opcode_0x06;
98
    tblOpcode1_[0x08] = &opcode_0x08;
99
    tblOpcode1_[0x0C] = &opcode_0x0C;
100
    tblOpcode1_[0x0D] = &opcode_0x0D;
101
    tblOpcode1_[0x0E] = &opcode_0x0E;
102
    tblOpcode1_[0x18] = &opcode_0x18;
103
    tblOpcode1_[0x19] = &opcode_0x19;
104
    tblOpcode1_[0x1B] = &opcode_0x1B;
105
    tblOpcode1_[0x1C] = &opcode_0x1C;
106
 
107
    memset(tblCompressed_, 0, sizeof(tblCompressed_));
108
    // page 82, table 12.5 " RISC-V spec. v2.2"
109
    // Compute index as hash = {[15:13],[1:0]}
110
    tblCompressed_[0x00] = &C_ADDI4SPN;
111
    tblCompressed_[0x01] = &C_NOP_ADDI;
112
    tblCompressed_[0x02] = &C_SLLI;
113
    tblCompressed_[0x05] = &C_JAL_ADDIW;
114
    tblCompressed_[0x08] = &C_LW;
115
    tblCompressed_[0x09] = &C_LI;
116
    tblCompressed_[0x0A] = &C_LWSP;
117
    tblCompressed_[0x0C] = &C_LD;
118
    tblCompressed_[0x0D] = &C_ADDI16SP_LUI;
119
    tblCompressed_[0x0E] = &C_LDSP;
120
    tblCompressed_[0x11] = &C_MATH;
121
    tblCompressed_[0x12] = &C_JR_MV_EBREAK_JALR_ADD;
122
    tblCompressed_[0x15] = &C_J;
123
    tblCompressed_[0x18] = &C_SW;
124
    tblCompressed_[0x19] = &C_BEQZ;
125
    tblCompressed_[0x1A] = &C_SWSP;
126
    tblCompressed_[0x1C] = &C_SD;
127
    tblCompressed_[0x1D] = &C_BNEZ;
128
    tblCompressed_[0x1E] = &C_SDSP;
129
 
130
    brList_.make_list(0);
131
    symbolListSortByName_.make_list(0);
132
    symbolListSortByAddr_.make_list(0);
133
}
134
 
135
RiscvSourceService::~RiscvSourceService() {
136
}
137
 
138
void RiscvSourceService::postinitService() {
139
}
140
 
141
void RiscvSourceService::addFileSymbol(const char *name, uint64_t addr,
142
                                       int sz) {
143
    AttributeType symb(Attr_List);
144
    symb.make_list(Symbol_Total);
145
    symb[Symbol_Name].make_string(name);
146
    symb[Symbol_Addr].make_uint64(addr);
147
    symb[Symbol_Size].make_int64(sz);
148
 
149
    symbolListSortByName_.add_to_list(&symb);
150
    symbolListSortByName_.sort(Symbol_Name);
151
 
152
    symbolListSortByAddr_.add_to_list(&symb);
153
    symbolListSortByAddr_.sort(Symbol_Addr);
154
}
155
 
156
void RiscvSourceService::addFunctionSymbol(const char *name,
157
                                      uint64_t addr, int sz) {
158
    addFileSymbol(name, addr, sz);
159
}
160
 
161
void RiscvSourceService::addDataSymbol(const char *name, uint64_t addr,
162
                                       int sz) {
163
    addFileSymbol(name, addr, sz);
164
}
165
 
166
void RiscvSourceService::clearSymbols() {
167
    symbolListSortByName_.make_list(0);
168
    symbolListSortByAddr_.make_list(0);
169
}
170
 
171
void RiscvSourceService::addSymbols(AttributeType *list) {
172
    for (unsigned i = 0; i < list->size(); i++) {
173
        AttributeType &item = (*list)[i];
174
        symbolListSortByName_.add_to_list(&item);
175
        symbolListSortByAddr_.add_to_list(&item);
176
    }
177
    symbolListSortByName_.sort(Symbol_Name);
178
    symbolListSortByAddr_.sort(Symbol_Addr);
179
}
180
 
181
void RiscvSourceService::addressToSymbol(uint64_t addr, AttributeType *info) {
182
    uint64_t sadr, send;
183
    int sz = static_cast<int>(symbolListSortByAddr_.size());
184
 
185
    info->make_list(SymbInfo_Total);
186
    (*info)[SymbInfo_Name].make_string("");
187
    (*info)[SymbInfo_Address].make_uint64(0);
188
    if (sz == 0) {
189
        return;
190
    }
191
    sadr = symbolListSortByAddr_[0u][Symbol_Addr].to_uint64();
192
    if (addr < sadr) {
193
        return;
194
    }
195
 
196
    bool search = true;
197
    int dist, pos = sz / 2;
198
    dist = pos;
199
    while (search) {
200
        AttributeType &symb = symbolListSortByAddr_[pos];
201
        sadr = symb[Symbol_Addr].to_uint64();
202
        if (pos < static_cast<int>(symbolListSortByAddr_.size()) - 1) {
203
            send = symbolListSortByAddr_[pos + 1][Symbol_Addr].to_uint64();
204
        } else {
205
            send = sadr + symb[Symbol_Size].to_uint64();
206
        }
207
        if (sadr <= addr && addr < send) {
208
            (*info)[SymbInfo_Name] = symb[Symbol_Name];
209
            (*info)[SymbInfo_Address].make_uint64(addr - sadr);
210
            return;
211
        }
212
 
213
        if (addr < sadr) {
214
            if (dist == 0 || pos == 0) {
215
                search = false;
216
            } else if (dist == 1) {
217
                dist = 0;
218
                pos--;
219
            } else {
220
                int incr = dist / 2;
221
                pos -= incr;
222
                dist = (dist / 2) + (dist & 0x1);
223
                if (pos < 0) {
224
                    pos = 0;
225
                }
226
            }
227
        } else {
228
            if (dist == 0 || pos == (sz - 1)) {
229
                search = false;
230
            } else if (dist == 1) {
231
                dist = 0;
232
                pos++;
233
            } else {
234
                int incr = dist / 2;
235
                pos += incr;
236
                dist = (dist / 2) + (dist & 0x1);
237
                if (pos >= sz) {
238
                    pos = sz - 1;
239
                }
240
            }
241
        }
242
    }
243
}
244
 
245
int RiscvSourceService::symbol2Address(const char *name, uint64_t *addr) {
246
    for (unsigned i = 0; i < symbolListSortByName_.size(); i++) {
247
        AttributeType &item = symbolListSortByName_[i];
248
        if (item[Symbol_Name].is_equal(name)) {
249
            *addr = item[Symbol_Addr].to_uint64();
250
            return 0;
251
        }
252
    }
253
    return -1;
254
}
255
 
256
void RiscvSourceService::registerBreakpoint(uint64_t addr, uint64_t flags,
257
                                       uint64_t instr) {
258
    AttributeType item;
259
    item.make_list(BrkList_Total);
260
    item[BrkList_address].make_uint64(addr);
261
    item[BrkList_flags].make_uint64(flags);
262
    item[BrkList_instr].make_uint64(instr);
263
 
264
    bool not_found = true;
265
    for (unsigned i = 0; i < brList_.size(); i++) {
266
        AttributeType &br = brList_[i];
267
        if (addr == br[BrkList_address].to_uint64()) {
268
            not_found = false;
269
        }
270
    }
271
    if (not_found) {
272
        brList_.add_to_list(&item);
273
    }
274
}
275
 
276
int RiscvSourceService::unregisterBreakpoint(uint64_t addr, uint64_t *flags,
277
                                       uint64_t *instr) {
278
    for (unsigned i = 0; i < brList_.size(); i++) {
279
        AttributeType &br = brList_[i];
280
        if (addr == br[BrkList_address].to_uint64()) {
281
            *flags = br[BrkList_flags].to_uint64();
282
            *instr = br[BrkList_instr].to_uint64();
283
            brList_.remove_from_list(i);
284
            return 0;
285
        }
286
    }
287
    return 1;
288
}
289
 
290
void RiscvSourceService::getBreakpointList(AttributeType *list) {
291
    if (!list->is_list() || list->size() != brList_.size()) {
292
        list->make_list(brList_.size());
293
    }
294
 
295
    for (unsigned i = 0; i < brList_.size(); i++) {
296
        AttributeType &item = (*list)[i];
297
        AttributeType &br = brList_[i];
298
        if (!item.is_list() || item.size() != 3) {
299
            item.make_list(BrkList_Total);
300
        }
301
        item[BrkList_address] = br[BrkList_address];
302
        item[BrkList_flags] = br[BrkList_flags];
303
        item[BrkList_instr] = br[BrkList_instr];
304
    }
305
}
306
 
307
bool RiscvSourceService::isBreakpoint(uint64_t addr, AttributeType *outbr) {
308
    for (unsigned i = 0; i < brList_.size(); i++) {
309
        uint64_t bradr = brList_[i][BrkList_address].to_uint64();
310
        if (addr == bradr) {
311
            *outbr = brList_[i];
312
            return true;
313
        }
314
    }
315
    return false;
316
}
317
 
318
int RiscvSourceService::disasm(uint64_t pc,
319
                       uint8_t *data,
320
                       int offset,
321
                       AttributeType *mnemonic,
322
                       AttributeType *comment) {
323
    int oplen;
324
    if ((data[offset] & 0x3) < 3) {
325
        Reg16Type val;
326
        uint32_t hash;
327
        val.word = *reinterpret_cast<uint16_t*>(&data[offset]);
328
        hash = ((val.word >> 11) & 0x1C) | (val.word & 0x3);
329
        oplen = 2;
330
        if (tblCompressed_[hash]) {
331
            return tblCompressed_[hash](static_cast<ISourceCode *>(this),
332
                                        pc + static_cast<uint64_t>(offset),
333
                                        val,
334
                                        mnemonic,
335
                                        comment);
336
        }
337
    } else if ((data[offset] & 0x3) == 0x3) {
338
        uint32_t val = *reinterpret_cast<uint32_t*>(&data[offset]);
339
        uint32_t opcode1 = (val >> 2) & 0x1f;
340
        oplen = 4;
341
        if (tblOpcode1_[opcode1]) {
342
            return tblOpcode1_[opcode1](static_cast<ISourceCode *>(this),
343
                                        pc + static_cast<uint64_t>(offset),
344
                                        val,
345
                                        mnemonic,
346
                                        comment);
347
        }
348
    }
349
 
350
    mnemonic->make_string("unimpl");
351
    comment->make_string("");
352
    return oplen;
353
}
354
 
355
void RiscvSourceService::disasm(uint64_t pc,
356
                          AttributeType *idata,
357
                          AttributeType *asmlist) {
358
    asmlist->make_list(0);
359
    if (!idata->is_data()) {
360
        return;
361
    }
362
    uint8_t *data = idata->data();
363
 
364
    AttributeType asm_item, symb_item, info, brpoint;
365
    asm_item.make_list(ASM_Total);
366
    symb_item.make_list(3);
367
    asm_item[ASM_list_type].make_int64(AsmList_disasm);
368
    symb_item[ASM_list_type].make_int64(AsmList_symbol);
369
    uint64_t off = 0;
370
    Reg64Type code;
371
    int codesz;
372
 
373
    while (static_cast<unsigned>(off) < idata->size()) {
374
        code.val = *reinterpret_cast<uint32_t*>(&data[off]);
375
 
376
        addressToSymbol(pc + off, &info);
377
        if (info[SymbInfo_Name].size() != 0 &&
378
            info[SymbInfo_Address].to_int() == 0) {
379
            symb_item[1].make_uint64(pc + off);
380
            symb_item[2].make_string(info[SymbInfo_Name].to_string());
381
            asmlist->add_to_list(&symb_item);
382
        }
383
        asm_item[ASM_addrline].make_uint64(pc + off);
384
        asm_item[ASM_breakpoint].make_boolean(false);
385
        asm_item[ASM_label].make_string("");
386
 
387
        if (isBreakpoint(pc + off, &brpoint)) {
388
            asm_item[ASM_breakpoint].make_boolean(true);
389
            if (!(brpoint[BrkList_flags].to_uint64() & BreakFlag_HW)) {
390
                code.val = brpoint[BrkList_instr].to_uint32();
391
            }
392
        }
393
        codesz = disasm(pc + off,
394
                        code.buf,
395
                        0,
396
                        &asm_item[ASM_mnemonic],
397
                        &asm_item[ASM_comment]);
398
 
399
#if 1
400
        uint64_t swap = code.val;
401
        if (codesz == 2) {
402
            swap = code.buf16[0];
403
        }
404
#else
405
        uint64_t swap = 0;
406
        for (int i = 0; i < codesz; i++) {
407
            swap = (swap << 8) | code.buf[i];
408
        }
409
#endif
410
        asm_item[ASM_code].make_uint64(swap);
411
        asm_item[ASM_codesize].make_uint64(codesz);
412
        asmlist->add_to_list(&asm_item);
413
        off += codesz;
414
    }
415
}
416
 
417
int opcode_0x00(ISourceCode *isrc, uint64_t pc, uint32_t code,
418
                AttributeType *mnemonic, AttributeType *comment) {
419
    char tstr[128] = "unimpl";
420
    char tcomm[128] = "";
421
    ISA_I_type i;
422
    int32_t imm;
423
 
424
    i.value = code;
425
    imm = static_cast<int32_t>(code) >> 20;
426
    switch (i.bits.funct3) {
427
    case 0:
428
        RISCV_sprintf(tstr, sizeof(tstr), "lb      %s,%d(%s)",
429
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
430
        break;
431
    case 1:
432
        RISCV_sprintf(tstr, sizeof(tstr), "lh      %s,%d(%s)",
433
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
434
        break;
435
    case 2:
436
        RISCV_sprintf(tstr, sizeof(tstr), "lw      %s,%d(%s)",
437
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
438
        break;
439
    case 3:
440
        RISCV_sprintf(tstr, sizeof(tstr), "ld      %s,%d(%s)",
441
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
442
        break;
443
    case 4:
444
        RISCV_sprintf(tstr, sizeof(tstr), "lbu     %s,%d(%s)",
445
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
446
        break;
447
    case 5:
448
        RISCV_sprintf(tstr, sizeof(tstr), "lhu     %s,%d(%s)",
449
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
450
        break;
451
    case 6:
452
        RISCV_sprintf(tstr, sizeof(tstr), "lwu     %s,%d(%s)",
453
            RN[i.bits.rd], imm, RN[i.bits.rs1]);
454
        break;
455
    default:;
456
    }
457
    mnemonic->make_string(tstr);
458
    comment->make_string(tcomm);
459
    return 4;
460
}
461
 
462
int opcode_0x03(ISourceCode *isrc, uint64_t pc, uint32_t code,
463
                AttributeType *mnemonic, AttributeType *comment) {
464
    char tstr[128] = "unimpl";
465
    char tcomm[128] = "";
466
    ISA_R_type r;
467
 
468
    r.value = code;
469
    switch (r.bits.funct3) {
470
    case 0:
471
        RISCV_sprintf(tstr, sizeof(tstr), "%s", "fence");
472
        break;
473
    case 1:
474
        RISCV_sprintf(tstr, sizeof(tstr), "%s", "fence_i");
475
        break;
476
    default:;
477
    }
478
    mnemonic->make_string(tstr);
479
    comment->make_string(tcomm);
480
    return 4;
481
}
482
 
483
int opcode_0x04(ISourceCode *isrc, uint64_t pc, uint32_t code,
484
                AttributeType *mnemonic, AttributeType *comment) {
485
    char tstr[128] = "unimpl";
486
    char tcomm[128] = "";
487
    ISA_I_type i;
488
    int32_t imm;
489
 
490
    i.value = code;
491
    imm = static_cast<int32_t>(code) >> 20;
492
    switch (i.bits.funct3) {
493
    case 0:
494
        if (imm == 0) {
495
            RISCV_sprintf(tstr, sizeof(tstr), "mv      %s,%s",
496
                RN[i.bits.rd], RN[i.bits.rs1]);
497
        } else if (i.bits.rs1 == 0) {
498
            RISCV_sprintf(tstr, sizeof(tstr), "li      %s,%d",
499
                RN[i.bits.rd], imm);
500
        } else {
501
            RISCV_sprintf(tstr, sizeof(tstr), "addi    %s,%s,%d",
502
                RN[i.bits.rd], RN[i.bits.rs1], imm);
503
        }
504
        break;
505
    case 1:
506
        RISCV_sprintf(tstr, sizeof(tstr), "slli    %s,%s,%d",
507
            RN[i.bits.rd], RN[i.bits.rs1], imm);
508
        break;
509
    case 2:
510
        RISCV_sprintf(tstr, sizeof(tstr), "slti    %s,%s,%d",
511
            RN[i.bits.rd], RN[i.bits.rs1], imm);
512
        break;
513
    case 3:
514
        RISCV_sprintf(tstr, sizeof(tstr), "sltiu   %s,%s,%d",
515
            RN[i.bits.rd], RN[i.bits.rs1], imm);
516
        break;
517
    case 4:
518
        RISCV_sprintf(tstr, sizeof(tstr), "xori    %s,%s,%d",
519
            RN[i.bits.rd], RN[i.bits.rs1], imm);
520
        break;
521
    case 5:
522
        if ((code >> 26) == 0) {
523
            RISCV_sprintf(tstr, sizeof(tstr), "srli    %s,%s,%d",
524
                RN[i.bits.rd], RN[i.bits.rs1], imm);
525
        } else if ((code >> 26) == 0x20) {
526
            RISCV_sprintf(tstr, sizeof(tstr), "srai    %s,%s,%d",
527
                RN[i.bits.rd], RN[i.bits.rs1], imm);
528
        }
529
        break;
530
    case 6:
531
        RISCV_sprintf(tstr, sizeof(tstr), "ori     %s,%s,%d",
532
            RN[i.bits.rd], RN[i.bits.rs1], imm);
533
        break;
534
    case 7:
535
        RISCV_sprintf(tstr, sizeof(tstr), "andi    %s,%s,%d",
536
            RN[i.bits.rd], RN[i.bits.rs1], imm);
537
        break;
538
    default:;
539
    }
540
    mnemonic->make_string(tstr);
541
    comment->make_string(tcomm);
542
    return 4;
543
}
544
 
545
int opcode_0x05(ISourceCode *isrc, uint64_t pc, uint32_t code,
546
                AttributeType *mnemonic, AttributeType *comment) {
547
    char tstr[128] = "unimpl";
548
    char tcomm[128] = "";
549
    ISA_U_type u;
550
    uint64_t imm64;
551
 
552
    u.value = code;
553
    imm64 = u.bits.imm31_12 << 12;
554
    if (imm64 & (1LL << 31)) {
555
        imm64 |= EXT_SIGN_32;
556
    }
557
    RISCV_sprintf(tstr, sizeof(tstr), "auipc   %s,0x%" RV_PRI64 "x",
558
        RN[u.bits.rd], imm64);
559
    mnemonic->make_string(tstr);
560
    comment->make_string(tcomm);
561
    return 4;
562
}
563
 
564
int opcode_0x06(ISourceCode *isrc, uint64_t pc, uint32_t code,
565
                AttributeType *mnemonic, AttributeType *comment) {
566
    char tstr[128] = "unimpl";
567
    char tcomm[128] = "";
568
    ISA_I_type i;
569
    int32_t imm;
570
 
571
    i.value = code;
572
    imm = static_cast<int32_t>(code) >> 20;
573
    switch (i.bits.funct3) {
574
    case 0:
575
        RISCV_sprintf(tstr, sizeof(tstr), "addiw   %s,%s,%d",
576
            RN[i.bits.rd], RN[i.bits.rs1], imm);
577
        break;
578
    case 1:
579
        RISCV_sprintf(tstr, sizeof(tstr), "slliw   %s,%s,%d",
580
            RN[i.bits.rd], RN[i.bits.rs1], imm);
581
        break;
582
    case 5:
583
        if ((code >> 25) == 0) {
584
            RISCV_sprintf(tstr, sizeof(tstr), "srliw   %s,%s,%d",
585
                RN[i.bits.rd], RN[i.bits.rs1], imm);
586
        } else if ((code >> 25) == 0x20) {
587
            RISCV_sprintf(tstr, sizeof(tstr), "sraiw   %s,%s,%d",
588
                RN[i.bits.rd], RN[i.bits.rs1], imm);
589
        }
590
        break;
591
    default:;
592
    }
593
    mnemonic->make_string(tstr);
594
    comment->make_string(tcomm);
595
    return 4;
596
}
597
 
598
int opcode_0x08(ISourceCode *isrc, uint64_t pc, uint32_t code,
599
                AttributeType *mnemonic, AttributeType *comment) {
600
    char tstr[128] = "unimpl";
601
    char tcomm[128] = "";
602
    ISA_S_type s;
603
    int32_t imm;
604
    s.value = code;
605
    imm = (s.bits.imm11_5 << 5) | s.bits.imm4_0;
606
    if (imm & 0x800) {
607
        imm |= EXT_SIGN_12;
608
    }
609
    switch (s.bits.funct3) {
610
    case 0:
611
        RISCV_sprintf(tstr, sizeof(tstr), "sb      %s,%d(%s)",
612
            RN[s.bits.rs2], imm, RN[s.bits.rs1]);
613
        break;
614
    case 1:
615
        RISCV_sprintf(tstr, sizeof(tstr), "sh      %s,%d(%s)",
616
            RN[s.bits.rs2], imm, RN[s.bits.rs1]);
617
        break;
618
    case 2:
619
        RISCV_sprintf(tstr, sizeof(tstr), "sw      %s,%d(%s)",
620
            RN[s.bits.rs2], imm, RN[s.bits.rs1]);
621
        break;
622
    case 3:
623
        RISCV_sprintf(tstr, sizeof(tstr), "sd      %s,%d(%s)",
624
            RN[s.bits.rs2], imm, RN[s.bits.rs1]);
625
        break;
626
    default:;
627
    }
628
    mnemonic->make_string(tstr);
629
    comment->make_string(tcomm);
630
    return 4;
631
}
632
 
633
 
634
int opcode_0x0C(ISourceCode *isrc, uint64_t pc, uint32_t code,
635
                AttributeType *mnemonic, AttributeType *comment) {
636
    char tstr[128] = "unimpl";
637
    char tcomm[128] = "";
638
    ISA_R_type r;
639
    r.value = code;
640
    switch (r.bits.funct3) {
641
    case 0:
642
        if (r.bits.funct7 == 0) {
643
            RISCV_sprintf(tstr, sizeof(tstr), "add     %s,%s,%s",
644
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
645
        } else if (r.bits.funct7 == 1) {
646
            RISCV_sprintf(tstr, sizeof(tstr), "mul     %s,%s,%s",
647
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
648
        } else if (r.bits.funct7 == 0x20) {
649
            RISCV_sprintf(tstr, sizeof(tstr), "sub     %s,%s,%s",
650
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
651
        }
652
        break;
653
    case 1:
654
        RISCV_sprintf(tstr, sizeof(tstr), "sll     %s,%s,%s",
655
            RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
656
        break;
657
    case 2:
658
        RISCV_sprintf(tstr, sizeof(tstr), "slt     %s,%s,%s",
659
            RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
660
        break;
661
    case 3:
662
        RISCV_sprintf(tstr, sizeof(tstr), "sltu     %s,%s,%s",
663
            RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
664
        break;
665
    case 4:
666
        if (r.bits.funct7 == 0) {
667
            RISCV_sprintf(tstr, sizeof(tstr), "xor     %s,%s,%s",
668
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
669
        } else if (r.bits.funct7 == 1) {
670
            RISCV_sprintf(tstr, sizeof(tstr), "div     %s,%s,%s",
671
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
672
        }
673
        break;
674
    case 5:
675
        if (r.bits.funct7 == 0) {
676
            RISCV_sprintf(tstr, sizeof(tstr), "srl     %s,%s,%s",
677
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
678
        } else if (r.bits.funct7 == 1) {
679
            RISCV_sprintf(tstr, sizeof(tstr), "divu    %s,%s,%s",
680
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
681
        } else if (r.bits.funct7 == 0x20) {
682
            RISCV_sprintf(tstr, sizeof(tstr), "sra     %s,%s,%s",
683
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
684
        }
685
        break;
686
    case 6:
687
        if (r.bits.funct7 == 0) {
688
            RISCV_sprintf(tstr, sizeof(tstr), "or      %s,%s,%s",
689
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
690
        } else if (r.bits.funct7 == 1) {
691
            RISCV_sprintf(tstr, sizeof(tstr), "rem     %s,%s,%s",
692
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
693
        }
694
        break;
695
    case 7:
696
        if (r.bits.funct7 == 0) {
697
            RISCV_sprintf(tstr, sizeof(tstr), "and     %s,%s,%s",
698
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
699
        } else if (r.bits.funct7 == 1) {
700
            RISCV_sprintf(tstr, sizeof(tstr), "remu    %s,%s,%s",
701
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
702
        }
703
        break;
704
    default:;
705
    }
706
    mnemonic->make_string(tstr);
707
    comment->make_string(tcomm);
708
    return 4;
709
}
710
 
711
int opcode_0x0D(ISourceCode *isrc, uint64_t pc, uint32_t code,
712
                AttributeType *mnemonic, AttributeType *comment) {
713
    char tstr[128] = "unimpl";
714
    char tcomm[128] = "";
715
    ISA_U_type u;
716
    u.value = code;
717
    RISCV_sprintf(tstr, sizeof(tstr), "lui     %s,0x%x",
718
        RN[u.bits.rd], u.bits.imm31_12);
719
    mnemonic->make_string(tstr);
720
    comment->make_string(tcomm);
721
    return 4;
722
}
723
 
724
int opcode_0x0E(ISourceCode *isrc, uint64_t pc, uint32_t code,
725
                AttributeType *mnemonic, AttributeType *comment) {
726
    char tstr[128] = "unimpl";
727
    char tcomm[128] = "";
728
    ISA_R_type r;
729
 
730
    r.value = code;
731
    switch (r.bits.funct3) {
732
    case 0:
733
        if (r.bits.funct7 == 0) {
734
            RISCV_sprintf(tstr, sizeof(tstr), "addw    %s,%s,%s",
735
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
736
        } else if (r.bits.funct7 == 1) {
737
            RISCV_sprintf(tstr, sizeof(tstr), "mulw    %s,%s,%s",
738
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
739
        } else if (r.bits.funct7 == 0x20) {
740
            RISCV_sprintf(tstr, sizeof(tstr), "subw    %s,%s,%s",
741
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
742
        }
743
        break;
744
    case 1:
745
        RISCV_sprintf(tstr, sizeof(tstr), "sllw    %s,%s,%s",
746
            RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
747
        break;
748
    case 4:
749
        if (r.bits.funct7 == 1) {
750
            RISCV_sprintf(tstr, sizeof(tstr), "divw    %s,%s,%s",
751
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
752
        }
753
        break;
754
    case 5:
755
        if (r.bits.funct7 == 0) {
756
            RISCV_sprintf(tstr, sizeof(tstr), "srlw    %s,%s,%s",
757
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
758
        } else if (r.bits.funct7 == 1) {
759
            RISCV_sprintf(tstr, sizeof(tstr), "divuw   %s,%s,%s",
760
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
761
        } else if (r.bits.funct7 == 0x20) {
762
            RISCV_sprintf(tstr, sizeof(tstr), "sraw    %s,%s,%s",
763
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
764
        }
765
        break;
766
    case 6:
767
        if (r.bits.funct7 == 1) {
768
            RISCV_sprintf(tstr, sizeof(tstr), "remw    %s,%s,%s",
769
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
770
        }
771
        break;
772
    case 7:
773
        if (r.bits.funct7 == 1) {
774
            RISCV_sprintf(tstr, sizeof(tstr), "remuw   %s,%s,%s",
775
                RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]);
776
        }
777
        break;
778
    default:;
779
    }
780
    mnemonic->make_string(tstr);
781
    comment->make_string(tcomm);
782
    return 4;
783
}
784
 
785
int opcode_0x18(ISourceCode *isrc, uint64_t pc, uint32_t code,
786
                AttributeType *mnemonic, AttributeType *comment) {
787
    char tstr[128] = "unimpl";
788
    char tcomm[128] = "";
789
    ISA_SB_type sb;
790
    uint64_t imm64;
791
 
792
    sb.value = code;
793
    imm64 = (sb.bits.imm12 << 12) | (sb.bits.imm11 << 11)
794
                | (sb.bits.imm10_5 << 5) | (sb.bits.imm4_1 << 1);
795
    if (sb.bits.imm12) {
796
        imm64 |= EXT_SIGN_12;
797
    }
798
    imm64 += pc;
799
    switch (sb.bits.funct3) {
800
    case 0:
801
        if (sb.bits.rs2 == 0) {
802
            RISCV_sprintf(tstr, sizeof(tstr), "beqz    %s,%08" RV_PRI64 "x",
803
                RN[sb.bits.rs1], imm64);
804
        } else {
805
            RISCV_sprintf(tstr, sizeof(tstr), "beq     %s,%s,%08" RV_PRI64 "x",
806
                RN[sb.bits.rs1], RN[sb.bits.rs2], imm64);
807
        }
808
        break;
809
    case 1:
810
        if (sb.bits.rs2 == 0) {
811
            RISCV_sprintf(tstr, sizeof(tstr), "bnez    %s,%08" RV_PRI64 "x",
812
                RN[sb.bits.rs1], imm64);
813
        } else {
814
            RISCV_sprintf(tstr, sizeof(tstr), "bne     %s,%s,%08" RV_PRI64 "x",
815
                RN[sb.bits.rs1], RN[sb.bits.rs2], imm64);
816
        }
817
        break;
818
    case 4:
819
        if (sb.bits.rs2 == 0) {
820
            RISCV_sprintf(tstr, sizeof(tstr), "bltz    %s,%08" RV_PRI64 "x",
821
                RN[sb.bits.rs1], imm64);
822
        } else {
823
            RISCV_sprintf(tstr, sizeof(tstr), "blt     %s,%s,%08" RV_PRI64 "x",
824
                RN[sb.bits.rs1], RN[sb.bits.rs2], imm64);
825
        }
826
        break;
827
    case 5:
828
        if (sb.bits.rs2 == 0) {
829
            RISCV_sprintf(tstr, sizeof(tstr), "bgez    %s,%08" RV_PRI64 "x",
830
                RN[sb.bits.rs1], imm64);
831
        } else {
832
            RISCV_sprintf(tstr, sizeof(tstr), "bge     %s,%s,%08" RV_PRI64 "x",
833
                RN[sb.bits.rs1], RN[sb.bits.rs2], imm64);
834
        }
835
        break;
836
    case 6:
837
        if (sb.bits.rs2 == 0) {
838
            RISCV_sprintf(tstr, sizeof(tstr), "bltuz   %s,%08" RV_PRI64 "x",
839
                RN[sb.bits.rs1], imm64);
840
        } else {
841
            RISCV_sprintf(tstr, sizeof(tstr), "bltu    %s,%s,%08" RV_PRI64 "x",
842
                RN[sb.bits.rs1], RN[sb.bits.rs2], imm64);
843
        }
844
        break;
845
    case 7:
846
        if (sb.bits.rs2 == 0) {
847
            RISCV_sprintf(tstr, sizeof(tstr), "bgeuz   %s,%08" RV_PRI64 "x",
848
                RN[sb.bits.rs1], imm64);
849
        } else {
850
            RISCV_sprintf(tstr, sizeof(tstr), "bgeu    %s,%s,%08" RV_PRI64 "x",
851
                RN[sb.bits.rs1], RN[sb.bits.rs2], imm64);
852
        }
853
        break;
854
    default:;
855
    }
856
 
857
    if (isrc) {
858
        AttributeType info;
859
        isrc->addressToSymbol(imm64, &info);
860
        if (info[0u].size()) {
861
            if (info[1].to_uint32() == 0) {
862
                RISCV_sprintf(tcomm, sizeof(tcomm), "%s",
863
                        info[0u].to_string());
864
            } else {
865
                RISCV_sprintf(tcomm, sizeof(tcomm), "%s+%xh",
866
                        info[0u].to_string(), info[1].to_uint32());
867
            }
868
        }
869
    }
870
    mnemonic->make_string(tstr);
871
    comment->make_string(tcomm);
872
    return 4;
873
}
874
 
875
int opcode_0x19(ISourceCode *isrc, uint64_t pc, uint32_t code,
876
                AttributeType *mnemonic, AttributeType *comment) {
877
    char tstr[128] = "unimpl";
878
    char tcomm[128] = "";
879
    ISA_I_type i;
880
    uint64_t imm64;
881
 
882
    i.value = code;
883
    imm64 = static_cast<int32_t>(code) >> 20;
884
    if (imm64 == 0) {
885
        if (i.bits.rs1 == Reg_ra) {
886
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "ret");
887
        } else if (i.bits.rd == 0) {
888
            RISCV_sprintf(tstr, sizeof(tstr), "jr      %s",
889
                RN[i.bits.rs1]);
890
        } else {
891
            RISCV_sprintf(tstr, sizeof(tstr), "jalr    %s",
892
                RN[i.bits.rs1]);
893
        }
894
    } else {
895
        RISCV_sprintf(tstr, sizeof(tstr), "jalr    %" RV_PRI64 "d,(%s)",
896
            imm64, RN[i.bits.rs1]);
897
    }
898
    mnemonic->make_string(tstr);
899
    comment->make_string(tcomm);
900
    return 4;
901
}
902
 
903
int opcode_0x1B(ISourceCode *isrc, uint64_t pc, uint32_t code,
904
                AttributeType *mnemonic, AttributeType *comment) {
905
    char tstr[128] = "unimpl";
906
    char tcomm[128] = "";
907
    ISA_UJ_type uj;
908
    uint64_t imm64;
909
 
910
    uj.value = code;
911
    imm64 = 0;
912
    if (uj.bits.imm20) {
913
        imm64 = 0xfffffffffff00000LL;
914
    }
915
    imm64 |= (uj.bits.imm19_12 << 12);
916
    imm64 |= (uj.bits.imm11 << 11);
917
    imm64 |= (uj.bits.imm10_1 << 1);
918
    if (uj.bits.rd) {
919
        RISCV_sprintf(tstr, sizeof(tstr), "jal     ra,%08" RV_PRI64 "x",
920
            pc + imm64);
921
    } else {
922
        RISCV_sprintf(tstr, sizeof(tstr), "j       %08" RV_PRI64 "x",
923
            pc + imm64);
924
    }
925
 
926
    if (isrc) {
927
        AttributeType info;
928
        isrc->addressToSymbol(pc + imm64, &info);
929
        if (info[0u].size()) {
930
            if (info[1].to_uint32() == 0) {
931
                RISCV_sprintf(tcomm, sizeof(tcomm), "%s",
932
                        info[0u].to_string());
933
            } else {
934
                RISCV_sprintf(tcomm, sizeof(tcomm), "%s+%xh",
935
                        info[0u].to_string(), info[1].to_uint32());
936
            }
937
        }
938
    }
939
    mnemonic->make_string(tstr);
940
    comment->make_string(tcomm);
941
    return 4;
942
}
943
 
944
int opcode_0x1C(ISourceCode *isrc, uint64_t pc, uint32_t code,
945
                AttributeType *mnemonic, AttributeType *comment) {
946
    char tstr[128] = "unimpl";
947
    char tcomm[128] = "";
948
    ISA_I_type i;
949
    uint32_t imm;
950
 
951
    i.value = code;
952
    imm = static_cast<int32_t>(code) >> 20;
953
 
954
    switch (i.bits.funct3) {
955
    case 0:
956
        if (code == 0x00000073) {
957
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "ecall");
958
        } else if (code == 0x00100073) {
959
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "ebreak");
960
        } else if (code == 0x00200073) {
961
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "uret");
962
        } else if (code == 0x10200073) {
963
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "sret");
964
        } else if (code == 0x20200073) {
965
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "hret");
966
        } else if (code == 0x30200073) {
967
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "mret");
968
        }
969
        break;
970
    case 1:
971
        if (i.bits.rd == 0) {
972
            RISCV_sprintf(tstr, sizeof(tstr), "csrw    0x%x,%s",
973
                imm, RN[i.bits.rs1]);
974
        } else {
975
            RISCV_sprintf(tstr, sizeof(tstr), "csrrw   %s,0x%x,%s",
976
                RN[i.bits.rd], imm, RN[i.bits.rs1]);
977
        }
978
        break;
979
    case 2:
980
        if (i.bits.rs1 == 0) {
981
            // Read
982
            RISCV_sprintf(tstr, sizeof(tstr), "csrr    %s,0x%x",
983
                RN[i.bits.rd], imm);
984
        } else if (i.bits.rd == 0) {
985
            // Set
986
            RISCV_sprintf(tstr, sizeof(tstr), "csrs    0x%x,%s",
987
                imm, RN[i.bits.rs1]);
988
        } else {
989
            // Read and set
990
            RISCV_sprintf(tstr, sizeof(tstr), "csrrs   %s,0x%x,%s",
991
                RN[i.bits.rd], imm, RN[i.bits.rs1]);
992
        }
993
        break;
994
    case 3:
995
        if (i.bits.rd == 0) {
996
            RISCV_sprintf(tstr, sizeof(tstr), "csrc    0x%x,%s",
997
                imm, RN[i.bits.rs1]);
998
        } else {
999
            RISCV_sprintf(tstr, sizeof(tstr), "csrrc   %s,0x%x,%s",
1000
                RN[i.bits.rd], imm, RN[i.bits.rs1]);
1001
        }
1002
        break;
1003
    case 5:
1004
        if (i.bits.rd == 0) {
1005
            RISCV_sprintf(tstr, sizeof(tstr), "csrwi   0x%x,0x%x",
1006
                imm, i.bits.rs1);
1007
        } else {
1008
            RISCV_sprintf(tstr, sizeof(tstr), "csrrwi  %s,0x%x,0x%x",
1009
                RN[i.bits.rd], imm, i.bits.rs1);
1010
        }
1011
        break;
1012
    case 6:
1013
        if (i.bits.rd == 0) {
1014
            RISCV_sprintf(tstr, sizeof(tstr), "csrsi   0x%x,0x%x",
1015
                imm, i.bits.rs1);
1016
        } else {
1017
            RISCV_sprintf(tstr, sizeof(tstr), "csrrsi  %s,0x%x,0x%x",
1018
                RN[i.bits.rd], imm, i.bits.rs1);
1019
        }
1020
        break;
1021
    case 7:
1022
        if (i.bits.rd == 0) {
1023
            RISCV_sprintf(tstr, sizeof(tstr), "csrci   0x%x,0x%x",
1024
                imm, i.bits.rs1);
1025
        } else {
1026
            RISCV_sprintf(tstr, sizeof(tstr), "csrrci  %s,0x%x,0x%x",
1027
                RN[i.bits.rd], imm, i.bits.rs1);
1028
        }
1029
        break;
1030
    default:;
1031
    }
1032
    mnemonic->make_string(tstr);
1033
    comment->make_string(tcomm);
1034
    return 4;
1035
}
1036
 
1037
/**
1038
 * C-extension  disassembler
1039
 */
1040
int C_JR_MV_EBREAK_JALR_ADD(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1041
                AttributeType *mnemonic, AttributeType *comment) {
1042
    char tstr[128] = "unimpl";
1043
    char tcomm[128] = "";
1044
    ISA_CR_type u;
1045
    u.value = code.word;
1046
    if (u.bits.funct4 == 0x8) {
1047
        if (u.bits.rdrs1 && !u.bits.rs2) {
1048
            if (u.bits.rdrs1 == 1) {
1049
                RISCV_sprintf(tstr, sizeof(tstr), "%s", "ret");
1050
            } else {
1051
                RISCV_sprintf(tstr, sizeof(tstr), "jr      %s",
1052
                    RN[u.bits.rdrs1]);
1053
            }
1054
        } else {
1055
            RISCV_sprintf(tstr, sizeof(tstr), "mv      %s,%s",
1056
                RN[u.bits.rdrs1], RN[u.bits.rs2]);
1057
        }
1058
    } else {
1059
        if (!u.bits.rdrs1 && !u.bits.rs2) {
1060
            RISCV_sprintf(tstr, sizeof(tstr), "%s", "ebreak");
1061
        } else if (u.bits.rdrs1 && !u.bits.rs2) {
1062
            RISCV_sprintf(tstr, sizeof(tstr), "jalr    ra,%s,0",
1063
                RN[u.bits.rdrs1]);
1064
        } else {
1065
            RISCV_sprintf(tstr, sizeof(tstr), "add     %s,%s,%s",
1066
                RN[u.bits.rdrs1], RN[u.bits.rdrs1], RN[u.bits.rs2]);
1067
        }
1068
    }
1069
 
1070
    mnemonic->make_string(tstr);
1071
    comment->make_string(tcomm);
1072
    return 2;
1073
}
1074
 
1075
int C_NOP_ADDI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1076
                AttributeType *mnemonic, AttributeType *comment) {
1077
    char tstr[128];
1078
    char tcomm[128] = "";
1079
    ISA_CI_type u;
1080
    u.value = code.word;
1081
    uint64_t imm = u.bits.imm;
1082
    if (u.bits.imm6) {
1083
        imm |= EXT_SIGN_6;
1084
    }
1085
    if (u.value == 0x1) {
1086
        RISCV_sprintf(tstr, sizeof(tstr), "%s", "nop");
1087
    } else {
1088
        RISCV_sprintf(tstr, sizeof(tstr), "addi    %s,%s,%" RV_PRI64 "d",
1089
            RN[u.bits.rdrs], RN[u.bits.rdrs], imm);
1090
    }
1091
 
1092
    mnemonic->make_string(tstr);
1093
    comment->make_string(tcomm);
1094
    return 2;
1095
}
1096
 
1097
int C_ADDI16SP_LUI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1098
                AttributeType *mnemonic, AttributeType *comment) {
1099
    char tstr[128];
1100
    char tcomm[128] = "";
1101
    ISA_CI_type u;
1102
    u.value = code.word;
1103
    if (u.spbits.sp == 0x2) {
1104
        uint64_t imm = (u.spbits.imm8_7 << 3) | (u.spbits.imm6 << 2)
1105
                    | (u.spbits.imm5 << 1) | u.spbits.imm4;
1106
        if (u.spbits.imm9) {
1107
            imm |= EXT_SIGN_6;
1108
        }
1109
        imm <<= 4;
1110
        RISCV_sprintf(tstr, sizeof(tstr), "addi    sp,sp,%" RV_PRI64 "d",
1111
            imm);
1112
    } else {
1113
        uint64_t imm = u.bits.imm;
1114
        if (u.bits.imm6) {
1115
            imm |= EXT_SIGN_6;
1116
        }
1117
        imm <<= 12;
1118
        RISCV_sprintf(tstr, sizeof(tstr), "lui     %s,0x%x",
1119
            RN[u.bits.rdrs], static_cast<uint32_t>(imm));
1120
 
1121
    }
1122
 
1123
    mnemonic->make_string(tstr);
1124
    comment->make_string(tcomm);
1125
    return 2;
1126
}
1127
 
1128
int C_ADDI4SPN(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1129
                AttributeType *mnemonic, AttributeType *comment) {
1130
    char tstr[128] = "unimp";
1131
    char tcomm[128] = "";
1132
    ISA_CIW_type u;
1133
    u.value = code.word;
1134
    uint64_t imm = (u.bits.imm9_6 << 4) | (u.bits.imm5_4 << 2)
1135
                | (u.bits.imm3 << 1) | u.bits.imm2;
1136
    imm <<= 2;
1137
    if (code.word) {
1138
        RISCV_sprintf(tstr, sizeof(tstr), "addi    %s,sp,%" RV_PRI64 "d",
1139
            RN[8 + u.bits.rd], imm);
1140
    }
1141
 
1142
    mnemonic->make_string(tstr);
1143
    comment->make_string(tcomm);
1144
    return 2;
1145
}
1146
 
1147
int C_JAL_ADDIW(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1148
                AttributeType *mnemonic, AttributeType *comment) {
1149
    char tstr[128];
1150
    char tcomm[128] = "";
1151
    ISA_CI_type u;
1152
    u.value = code.word;
1153
    int64_t imm = u.bits.imm;
1154
    if (u.bits.imm6) {
1155
        imm |= EXT_SIGN_6;
1156
    }
1157
    // JAL is th RV32C only instruction
1158
    RISCV_sprintf(tstr, sizeof(tstr), "addiw   %s,%s,%" RV_PRI64 "d",
1159
        RN[u.bits.rdrs], RN[u.bits.rdrs], imm);
1160
 
1161
    mnemonic->make_string(tstr);
1162
    comment->make_string(tcomm);
1163
    return 2;
1164
}
1165
 
1166
int C_LD(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1167
                AttributeType *mnemonic, AttributeType *comment) {
1168
    char tstr[128];
1169
    char tcomm[128] = "";
1170
    ISA_CL_type u;
1171
    u.value = code.word;
1172
    uint32_t off = (u.bits.imm27 << 4) | (u.bits.imm6 << 3) | u.bits.imm5_3;
1173
    off <<= 3;
1174
 
1175
    RISCV_sprintf(tstr, sizeof(tstr), "ld      %s,%d(%s)",
1176
        RN[8 + u.bits.rd], off, RN[8 + u.bits.rs1]);
1177
 
1178
    mnemonic->make_string(tstr);
1179
    comment->make_string(tcomm);
1180
    return 2;
1181
}
1182
 
1183
int C_LDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1184
           AttributeType *mnemonic, AttributeType *comment) {
1185
    char tstr[128];
1186
    char tcomm[128] = "";
1187
    ISA_CI_type u;
1188
    u.value = code.word;
1189
    uint32_t off = (u.ldspbits.off8_6 << 3) | (u.ldspbits.off5 << 2)
1190
                    | u.ldspbits.off4_3;
1191
    off <<= 3;
1192
 
1193
    RISCV_sprintf(tstr, sizeof(tstr), "ld      %s,%d(sp)",
1194
        RN[u.ldspbits.rd], off);
1195
 
1196
    mnemonic->make_string(tstr);
1197
    comment->make_string(tcomm);
1198
    return 2;
1199
}
1200
 
1201
int C_LI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1202
                AttributeType *mnemonic, AttributeType *comment) {
1203
    char tstr[128];
1204
    char tcomm[128] = "";
1205
    ISA_CI_type u;
1206
    u.value = code.word;
1207
    int64_t imm = u.bits.imm;
1208
    if (u.bits.imm6) {
1209
        imm |= EXT_SIGN_6;
1210
    }
1211
 
1212
    RISCV_sprintf(tstr, sizeof(tstr), "li      %s,%" RV_PRI64 "d",
1213
        RN[u.bits.rdrs], imm);
1214
 
1215
    mnemonic->make_string(tstr);
1216
    comment->make_string(tcomm);
1217
    return 2;
1218
}
1219
 
1220
int C_LW(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1221
                AttributeType *mnemonic, AttributeType *comment) {
1222
    char tstr[128];
1223
    char tcomm[128] = "";
1224
    ISA_CL_type u;
1225
    u.value = code.word;
1226
    uint32_t off = (u.bits.imm6 << 4) | (u.bits.imm5_3 << 1) | u.bits.imm27;
1227
    off <<= 2;
1228
 
1229
    RISCV_sprintf(tstr, sizeof(tstr), "lw      %s,%d(%s)",
1230
        RN[8 + u.bits.rd], off, RN[8 + u.bits.rs1]);
1231
 
1232
    mnemonic->make_string(tstr);
1233
    comment->make_string(tcomm);
1234
    return 2;
1235
}
1236
 
1237
int C_LWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1238
           AttributeType *mnemonic, AttributeType *comment) {
1239
    char tstr[128];
1240
    char tcomm[128] = "";
1241
    ISA_CI_type u;
1242
    u.value = code.word;
1243
    uint32_t off = (u.lwspbits.off7_6 << 4) | (u.lwspbits.off5 << 3)
1244
                     | u.lwspbits.off4_2;
1245
    off <<= 2;
1246
 
1247
    RISCV_sprintf(tstr, sizeof(tstr), "lw      %s,%d(sp)",
1248
        RN[u.lwspbits.rd], off);
1249
 
1250
    mnemonic->make_string(tstr);
1251
    comment->make_string(tcomm);
1252
    return 2;
1253
}
1254
 
1255
int C_MATH(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1256
           AttributeType *mnemonic, AttributeType *comment) {
1257
    char tstr[128] = "unimpl";
1258
    char tcomm[128] = "";
1259
    ISA_CB_type u;
1260
    u.value = code.word;
1261
    uint32_t shamt = (u.shbits.shamt5 << 5) | u.shbits.shamt;
1262
    uint32_t imm = (u.bits.off7_6 << 3) | (u.bits.off2_1 << 1)  | u.bits.off5;
1263
 
1264
    if (u.bits.off4_3 == 0) {
1265
        RISCV_sprintf(tstr, sizeof(tstr), "srli    %s,%s,%d",
1266
            RN[8 + u.shbits.rd], RN[8 + u.shbits.rd], shamt);
1267
    } else if (u.bits.off4_3 == 1) {
1268
        RISCV_sprintf(tstr, sizeof(tstr), "srai    %s,%s,%d",
1269
            RN[8 + u.shbits.rd], RN[8 + u.shbits.rd], shamt);
1270
    } else if (u.bits.off4_3 == 2) {
1271
        RISCV_sprintf(tstr, sizeof(tstr), "andi    %s,%s,%d",
1272
            RN[8 + u.shbits.rd], RN[8 + u.shbits.rd], imm);
1273
    } else if (u.bits.off8 == 0) {
1274
        ISA_CS_type u2;
1275
        u2.value = code.word;
1276
        switch (u.bits.off7_6) {
1277
        case 0:
1278
            RISCV_sprintf(tstr, sizeof(tstr), "sub     %s,%s,%s",
1279
                RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]);
1280
            break;
1281
        case 1:
1282
            RISCV_sprintf(tstr, sizeof(tstr), "xor     %s,%s,%s",
1283
                RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]);
1284
            break;
1285
        case 2:
1286
            RISCV_sprintf(tstr, sizeof(tstr), "or      %s,%s,%s",
1287
                RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]);
1288
            break;
1289
        default:
1290
            RISCV_sprintf(tstr, sizeof(tstr), "and     %s,%s,%s",
1291
                RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]);
1292
        }
1293
    } else {
1294
        ISA_CS_type u2;
1295
        u2.value = code.word;
1296
        switch (u.bits.off7_6) {
1297
        case 0:
1298
            RISCV_sprintf(tstr, sizeof(tstr), "subw    %s,%s,%s",
1299
                RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]);
1300
            break;
1301
        case 1:
1302
            RISCV_sprintf(tstr, sizeof(tstr), "addw    %s,%s,%s",
1303
                RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]);
1304
            break;
1305
        default:;
1306
        }
1307
    }
1308
 
1309
    mnemonic->make_string(tstr);
1310
    comment->make_string(tcomm);
1311
    return 2;
1312
}
1313
 
1314
int C_J(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1315
        AttributeType *mnemonic, AttributeType *comment) {
1316
    char tstr[128];
1317
    char tcomm[128] = "";
1318
    ISA_CJ_type u;
1319
    u.value = code.word;
1320
    uint64_t off = (u.bits.off10 << 9) | (u.bits.off9_8 << 7)
1321
                    | (u.bits.off7 << 6) | (u.bits.off6 << 5)
1322
                    | (u.bits.off5 << 4) | (u.bits.off4 << 3)
1323
                    | u.bits.off3_1;
1324
    off <<= 1;
1325
    if (u.bits.off11) {
1326
        off |= EXT_SIGN_11;
1327
    }
1328
    RISCV_sprintf(tstr, sizeof(tstr), "j       %" RV_PRI64 "x", pc + off);
1329
 
1330
    mnemonic->make_string(tstr);
1331
    comment->make_string(tcomm);
1332
    return 2;
1333
}
1334
 
1335
int C_SD(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1336
                AttributeType *mnemonic, AttributeType *comment) {
1337
    char tstr[128];
1338
    char tcomm[128] = "";
1339
    ISA_CS_type u;
1340
    u.value = code.word;
1341
    uint32_t off = (u.bits.imm27 << 4) | (u.bits.imm6 << 3) | u.bits.imm5_3;
1342
    off <<= 3;
1343
 
1344
    RISCV_sprintf(tstr, sizeof(tstr), "sd      %s,%d(%s)",
1345
        RN[8 + u.bits.rs2], off, RN[8 + u.bits.rs1]);
1346
 
1347
    mnemonic->make_string(tstr);
1348
    comment->make_string(tcomm);
1349
    return 2;
1350
}
1351
 
1352
int C_SDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1353
                AttributeType *mnemonic, AttributeType *comment) {
1354
    char tstr[128];
1355
    char tcomm[128] = "";
1356
    ISA_CSS_type u;
1357
    u.value = code.word;
1358
    uint32_t off = (u.dbits.imm8_6 << 3) | u.dbits.imm5_3;
1359
    off <<= 3;
1360
 
1361
    RISCV_sprintf(tstr, sizeof(tstr), "sd      %s,%d(sp)",
1362
        RN[u.dbits.rs2], off);
1363
 
1364
    mnemonic->make_string(tstr);
1365
    comment->make_string(tcomm);
1366
    return 2;
1367
}
1368
 
1369
int C_SW(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1370
                AttributeType *mnemonic, AttributeType *comment) {
1371
    char tstr[128];
1372
    char tcomm[128] = "";
1373
    ISA_CS_type u;
1374
    u.value = code.word;
1375
    uint32_t off = (u.bits.imm6 << 4) | (u.bits.imm5_3 << 1) | u.bits.imm27;
1376
    off <<= 2;
1377
 
1378
    RISCV_sprintf(tstr, sizeof(tstr), "sw      %s,%d(%s)",
1379
        RN[8 + u.bits.rs2], off, RN[8 + u.bits.rs1]);
1380
 
1381
    mnemonic->make_string(tstr);
1382
    comment->make_string(tcomm);
1383
    return 2;
1384
}
1385
 
1386
int C_SWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1387
                AttributeType *mnemonic, AttributeType *comment) {
1388
    char tstr[128];
1389
    char tcomm[128] = "";
1390
    ISA_CSS_type u;
1391
    u.value = code.word;
1392
    uint32_t off = (u.wbits.imm7_6 << 4) | u.wbits.imm5_2;
1393
    off <<= 2;
1394
 
1395
    RISCV_sprintf(tstr, sizeof(tstr), "sw      %s,%d(sp)",
1396
        RN[u.dbits.rs2], off);
1397
 
1398
    mnemonic->make_string(tstr);
1399
    comment->make_string(tcomm);
1400
    return 2;
1401
}
1402
 
1403
int C_BEQZ(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1404
                AttributeType *mnemonic, AttributeType *comment) {
1405
    char tstr[128];
1406
    char tcomm[128] = "";
1407
    ISA_CB_type u;
1408
    u.value = code.word;
1409
    uint64_t imm = (u.bits.off7_6 << 5) | (u.bits.off5 << 4)
1410
            | (u.bits.off4_3 << 2) | u.bits.off2_1;
1411
    imm <<= 1;
1412
    if (u.bits.off8) {
1413
        imm |= EXT_SIGN_9;
1414
    }
1415
 
1416
    RISCV_sprintf(tstr, sizeof(tstr), "beqz    %s,%" RV_PRI64 "x",
1417
        RN[8 + u.bits.rs1], pc + imm);
1418
 
1419
    mnemonic->make_string(tstr);
1420
    comment->make_string(tcomm);
1421
    return 2;
1422
}
1423
 
1424
int C_BNEZ(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1425
                AttributeType *mnemonic, AttributeType *comment) {
1426
    char tstr[128];
1427
    char tcomm[128] = "";
1428
    ISA_CB_type u;
1429
    u.value = code.word;
1430
    uint64_t imm = (u.bits.off7_6 << 5) | (u.bits.off5 << 4)
1431
            | (u.bits.off4_3 << 2) | u.bits.off2_1;
1432
    imm <<= 1;
1433
    if (u.bits.off8) {
1434
        imm |= EXT_SIGN_9;
1435
    }
1436
 
1437
    RISCV_sprintf(tstr, sizeof(tstr), "bnez    %s,%" RV_PRI64 "x",
1438
        RN[8 + u.bits.rs1], pc + imm);
1439
 
1440
    mnemonic->make_string(tstr);
1441
    comment->make_string(tcomm);
1442
    return 2;
1443
}
1444
 
1445
int C_SLLI(ISourceCode *isrc, uint64_t pc, Reg16Type code,
1446
                AttributeType *mnemonic, AttributeType *comment) {
1447
    char tstr[128];
1448
    char tcomm[128] = "";
1449
    ISA_CB_type u;
1450
    u.value = code.word;
1451
    uint32_t shamt = (u.shbits.shamt5 << 5) | u.shbits.shamt;
1452
    uint32_t idx = (u.shbits.funct2 << 3) | u.shbits.rd;
1453
    RISCV_sprintf(tstr, sizeof(tstr), "slli    %s,%s,%d",
1454
        RN[idx], RN[idx], shamt);
1455
 
1456
    mnemonic->make_string(tstr);
1457
    comment->make_string(tcomm);
1458
    return 2;
1459
}
1460
 
1461
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.