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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_fnc_plugin/] [riscv-rv64i-user.cpp] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Base ISA implementation (extension I, user level).
6
 */
7
 
8
#include "api_utils.h"
9
#include "riscv-isa.h"
10
#include "cpu_riscv_func.h"
11
 
12
namespace debugger {
13
 
14
/**
15
 * @brief Addition. Overflows are ignored
16
 */
17
class ADD : public RiscvInstruction {
18
public:
19
    ADD(CpuRiver_Functional *icpu) :
20
        RiscvInstruction(icpu, "ADD", "0000000??????????000?????0110011") {}
21
 
22
    virtual int exec(Reg64Type *payload) {
23
        ISA_R_type u;
24
        u.value = payload->buf32[0];
25
        R[u.bits.rd] = R[u.bits.rs1] + R[u.bits.rs2];
26
        return 4;
27
    }
28
};
29
 
30
/**
31
 * @brief Add immediate
32
 *
33
 * ADDI adds the sign-extended 12-bit immediate to register rs1.
34
 * Arithmetic overflow is ignored and the result is simply the low 32-bits of
35
 * the result. ADDI rd, rs1, 0 is used to implement the MV rd, rs1 assembler
36
 * pseudo-instruction.
37
 */
38
class ADDI : public RiscvInstruction {
39
public:
40
    ADDI(CpuRiver_Functional *icpu) :
41
        RiscvInstruction(icpu, "ADDI", "?????????????????000?????0010011") {}
42
 
43
    virtual int exec(Reg64Type *payload) {
44
        ISA_I_type u;
45
        u.value = payload->buf32[0];
46
 
47
        uint64_t imm = u.bits.imm;
48
        if (imm & 0x800) {
49
            imm |= EXT_SIGN_12;
50
        }
51
        R[u.bits.rd] = R[u.bits.rs1] + imm;
52
        return 4;
53
    }
54
};
55
 
56
/**
57
 * @brief Add immediate with sign extending (RV64I)
58
 *
59
 * ADDIW is an RV64I-only instruction that adds the sign-extended 12-bit
60
 * immediate to register rs1 and produces the proper sign-extension of
61
 * a 32-bit result in rd. Overflows are ignored and the result is the low
62
 * 32 bits of the result sign-extended to 64 bits. Note, ADDIW rd, rs1, 0
63
 * writes the sign-extension of the lower 32 bits of register rs1 into
64
 * register rd (assembler pseudo-op SEXT.W).
65
 */
66
class ADDIW : public RiscvInstruction {
67
public:
68
    ADDIW(CpuRiver_Functional *icpu) :
69
        RiscvInstruction(icpu, "ADDIW", "?????????????????000?????0011011") {}
70
 
71
    virtual int exec(Reg64Type *payload) {
72
        ISA_I_type u;
73
        u.value = payload->buf32[0];
74
 
75
        uint64_t imm = u.bits.imm;
76
        if (imm & 0x800) {
77
            imm |= EXT_SIGN_12;
78
        }
79
        R[u.bits.rd] = (R[u.bits.rs1] + imm) & 0xFFFFFFFFLL;
80
        if (R[u.bits.rd] & (1LL << 31)) {
81
            R[u.bits.rd] |= EXT_SIGN_32;
82
        }
83
        return 4;
84
    }
85
};
86
 
87
/**
88
 * @brief Add registers with sign extending (RV64I)
89
 *
90
 * ADDW is RV64I-only instructions that are defined analogously to
91
 * ADD but operate on 32-bit values and produce signed 32-bit results.
92
 * Overflows are ignored, and the low 32-bits of the result is sign-extended
93
 * to 64-bits and written to the destination register.
94
 */
95
class ADDW : public RiscvInstruction {
96
public:
97
    ADDW(CpuRiver_Functional *icpu) :
98
        RiscvInstruction(icpu, "ADDW", "0000000??????????000?????0111011") {}
99
 
100
    virtual int exec(Reg64Type *payload) {
101
        ISA_R_type u;
102
        u.value = payload->buf32[0];
103
 
104
        R[u.bits.rd] = (R[u.bits.rs1] + R[u.bits.rs2]) & 0xFFFFFFFFLL;
105
        if (R[u.bits.rd] & (1LL << 31)) {
106
            R[u.bits.rd] |= EXT_SIGN_32;
107
        }
108
        return 4;
109
    }
110
};
111
 
112
/**
113
 * @brief AND bitwise logical operation.
114
 */
115
class AND : public RiscvInstruction {
116
public:
117
    AND(CpuRiver_Functional *icpu) :
118
        RiscvInstruction(icpu, "AND", "0000000??????????111?????0110011") {}
119
 
120
    virtual int exec(Reg64Type *payload) {
121
        ISA_R_type u;
122
        u.value = payload->buf32[0];
123
        R[u.bits.rd] = R[u.bits.rs1] & R[u.bits.rs2];
124
        return 4;
125
    }
126
};
127
 
128
/**
129
 * @brief ANDI logical operation with immediate.
130
 *
131
 * ANDI, ORI, XORI are logical operations that perform bitwise AND, OR,
132
 * and XOR on register rs1 and the sign-extended 12-bit immediate and place
133
 * the result in rd.
134
 */
135
class ANDI : public RiscvInstruction {
136
public:
137
    ANDI(CpuRiver_Functional *icpu) :
138
        RiscvInstruction(icpu, "ANDI", "?????????????????111?????0010011") {}
139
 
140
    virtual int exec(Reg64Type *payload) {
141
        ISA_I_type u;
142
        u.value = payload->buf32[0];
143
        uint64_t imm = u.bits.imm;
144
        if (imm & 0x800) {
145
            imm |= EXT_SIGN_12;
146
        }
147
 
148
        R[u.bits.rd] = R[u.bits.rs1] & imm;
149
        return 4;
150
    }
151
};
152
 
153
/**
154
 * @brief AUIPC (add upper immediate to pc)
155
 *
156
 * AUIPC is used to build pc-relative addresses and uses the U-type
157
 * format. AUIPC forms a 32-bit offset from the 20-bit U-immediate,
158
 * filling in the lowest 12 bits with zeros, adds this offset to the pc,
159
 * then places the result in register rd.
160
 */
161
class AUIPC : public RiscvInstruction {
162
public:
163
    AUIPC(CpuRiver_Functional *icpu) :
164
        RiscvInstruction(icpu, "AUIPC", "?????????????????????????0010111") {}
165
 
166
    virtual int exec(Reg64Type *payload) {
167
        ISA_U_type u;
168
        u.value = payload->buf32[0];
169
 
170
        uint64_t off = u.bits.imm31_12 << 12;
171
        if (off & (1LL << 31)) {
172
            off |= EXT_SIGN_32;
173
        }
174
        R[u.bits.rd] = icpu_->getPC() + off;
175
        return 4;
176
    }
177
};
178
 
179
/**
180
 * @brief The BEQ (Branch if registers are equal)
181
 */
182
class BEQ : public RiscvInstruction {
183
public:
184
    BEQ(CpuRiver_Functional *icpu) :
185
        RiscvInstruction(icpu, "BEQ", "?????????????????000?????1100011") {}
186
 
187
    virtual int exec(Reg64Type *payload) {
188
        ISA_SB_type u;
189
        u.value = payload->buf32[0];
190
 
191
        if (R[u.bits.rs1] == R[u.bits.rs2]) {
192
            uint64_t imm = (u.bits.imm12 << 12) | (u.bits.imm11 << 11)
193
                    | (u.bits.imm10_5 << 5) | (u.bits.imm4_1 << 1);
194
            if (u.bits.imm12) {
195
                imm |= EXT_SIGN_12;
196
            }
197
            icpu_->setBranch(icpu_->getPC() + imm);
198
        }
199
        return 4;
200
    }
201
};
202
 
203
/**
204
 * @brief The BGE (Branch if greater than or equal using signed comparision)
205
 *
206
 * All branch instructions use the SB-type instruction format. The 12-bit
207
 * B-immediate encodes signed offsets in multiples of 2, and is added to the
208
 * current pc to give the target address. The conditional branch range
209
 * is ±4 KiB.
210
 */
211
class BGE : public RiscvInstruction {
212
public:
213
    BGE(CpuRiver_Functional *icpu) :
214
        RiscvInstruction(icpu, "BGE", "?????????????????101?????1100011") {}
215
 
216
    virtual int exec(Reg64Type *payload) {
217
        ISA_SB_type u;
218
        u.value = payload->buf32[0];
219
 
220
        if (static_cast<int64_t>(R[u.bits.rs1]) >=
221
            static_cast<int64_t>(R[u.bits.rs2])) {
222
            uint64_t imm = (u.bits.imm12 << 12) | (u.bits.imm11 << 11)
223
                    | (u.bits.imm10_5 << 5) | (u.bits.imm4_1 << 1);
224
            if (u.bits.imm12) {
225
                imm |= EXT_SIGN_12;
226
            }
227
            icpu_->setBranch(icpu_->getPC() + imm);
228
        }
229
        return 4;
230
    }
231
};
232
 
233
 
234
/**
235
 * @brief The BGEU (Branch if greater than or equal using unsigned comparision)
236
 */
237
class BGEU : public RiscvInstruction {
238
public:
239
    BGEU(CpuRiver_Functional *icpu) :
240
        RiscvInstruction(icpu, "BGEU", "?????????????????111?????1100011") {}
241
 
242
    virtual int exec(Reg64Type *payload) {
243
        ISA_SB_type u;
244
        u.value = payload->buf32[0];
245
 
246
        if (R[u.bits.rs1] >= R[u.bits.rs2]) {
247
            uint64_t imm = (u.bits.imm12 << 12) | (u.bits.imm11 << 11)
248
                    | (u.bits.imm10_5 << 5) | (u.bits.imm4_1 << 1);
249
            if (u.bits.imm12) {
250
                imm |= EXT_SIGN_12;
251
            }
252
            icpu_->setBranch(icpu_->getPC() + imm);
253
        }
254
        return 4;
255
    }
256
};
257
 
258
/**
259
 * @brief The BLT (Branch if less than using signed comparision)
260
 */
261
class BLT : public RiscvInstruction {
262
public:
263
    BLT(CpuRiver_Functional *icpu) :
264
        RiscvInstruction(icpu, "BLT", "?????????????????100?????1100011") {}
265
 
266
    virtual int exec(Reg64Type *payload) {
267
        ISA_SB_type u;
268
        u.value = payload->buf32[0];
269
 
270
        if (static_cast<int64_t>(R[u.bits.rs1]) <
271
            static_cast<int64_t>(R[u.bits.rs2])) {
272
            uint64_t imm = (u.bits.imm12 << 12) | (u.bits.imm11 << 11)
273
                    | (u.bits.imm10_5 << 5) | (u.bits.imm4_1 << 1);
274
            if (u.bits.imm12) {
275
                imm |= EXT_SIGN_12;
276
            }
277
            icpu_->setBranch(icpu_->getPC() + imm);
278
        }
279
        return 4;
280
    }
281
};
282
 
283
/**
284
 * @brief The BLTU (Branch if less than using unsigned comparision)
285
 */
286
class BLTU : public RiscvInstruction {
287
public:
288
    BLTU(CpuRiver_Functional *icpu) :
289
        RiscvInstruction(icpu, "BLTU", "?????????????????110?????1100011") {}
290
 
291
    virtual int exec(Reg64Type *payload) {
292
        ISA_SB_type u;
293
        u.value = payload->buf32[0];
294
 
295
        if (R[u.bits.rs1] < R[u.bits.rs2]) {
296
            uint64_t imm = (u.bits.imm12 << 12) | (u.bits.imm11 << 11)
297
                    | (u.bits.imm10_5 << 5) | (u.bits.imm4_1 << 1);
298
            if (u.bits.imm12) {
299
                imm |= EXT_SIGN_12;
300
            }
301
            icpu_->setBranch(icpu_->getPC() + imm);
302
        }
303
        return 4;
304
    }
305
};
306
 
307
/**
308
 * @brief The BNE (Branch if registers are unequal)
309
 */
310
class BNE : public RiscvInstruction {
311
public:
312
    BNE(CpuRiver_Functional *icpu) :
313
        RiscvInstruction(icpu, "BNE", "?????????????????001?????1100011") {}
314
 
315
    virtual int exec(Reg64Type *payload) {
316
        ISA_SB_type u;
317
        u.value = payload->buf32[0];
318
 
319
        if (R[u.bits.rs1] != R[u.bits.rs2]) {
320
            uint64_t imm = (u.bits.imm12 << 12) | (u.bits.imm11 << 11)
321
                    | (u.bits.imm10_5 << 5) | (u.bits.imm4_1 << 1);
322
            if (u.bits.imm12) {
323
                imm |= EXT_SIGN_12;
324
            }
325
            icpu_->setBranch(icpu_->getPC() + imm);
326
        }
327
        return 4;
328
    }
329
};
330
 
331
/**
332
 * @brief JAL (Jump and link).
333
 *
334
 * Unconditional jump. The offset is sign-extended and added to the pc to form
335
 * the jump target address. Jumps can therefore target a ±1 MiB range. JAL
336
 * stores the address of the instruction following the jump (pc+4) into
337
 * register rd. The standard software calling convention uses x1 as the return
338
 * address register.
339
 *
340
 * J (pseudo-op) 0 Plain unconditional jumps are encoded as a JAL with rd=x0.
341
 */
342
class JAL : public RiscvInstruction {
343
public:
344
    JAL(CpuRiver_Functional *icpu) :
345
        RiscvInstruction(icpu, "JAL", "?????????????????????????1101111") {}
346
 
347
    virtual int exec(Reg64Type *payload) {
348
        ISA_UJ_type u;
349
        u.value = payload->buf32[0];
350
        uint64_t off = 0;
351
        if (u.bits.imm20) {
352
            off = 0xfffffffffff00000LL;
353
        }
354
        off |= (u.bits.imm19_12 << 12);
355
        off |= (u.bits.imm11 << 11);
356
        off |= (u.bits.imm10_1 << 1);
357
        if (u.bits.rd != 0) {
358
            R[u.bits.rd] = icpu_->getPC() + 4;
359
        }
360
        icpu_->setBranch(icpu_->getPC() + off);
361
        if (u.bits.rd == Reg_ra) {
362
            icpu_->pushStackTrace();
363
        }
364
        return 4;
365
    }
366
};
367
 
368
/**
369
 * @brief JALR (Jump and link register).
370
 *
371
 * The target address is obtained by adding the 12-bit signed I-immediate to
372
 * the register rs1, then setting the least-significant bit of the result to
373
 * zero. The address of the instruction following the jump (pc+4) is written
374
 * to register rd. Register x0 can be used as the destination if the result
375
 * is not required.
376
 */
377
class JALR : public RiscvInstruction {
378
public:
379
    JALR(CpuRiver_Functional *icpu) :
380
        RiscvInstruction(icpu, "JALR", "?????????????????000?????1100111") {}
381
 
382
    virtual int exec(Reg64Type *payload) {
383
        ISA_I_type u;
384
        u.value = payload->buf32[0];
385
        uint64_t off = u.bits.imm;
386
        if (u.bits.imm & 0x800) {
387
            off |= 0xfffffffffffff000LL;
388
        }
389
        off += R[u.bits.rs1];
390
        off &= ~0x1LL;
391
        if (u.bits.rd != 0) {
392
            R[u.bits.rd] = icpu_->getPC() + 4;
393
        }
394
        icpu_->setBranch(off);
395
 
396
        // Stack trace buffer:
397
        if (u.bits.rd == Reg_ra) {
398
            icpu_->pushStackTrace();
399
        } else if (u.bits.imm == 0 && u.bits.rs1 == Reg_ra) {
400
            icpu_->popStackTrace();
401
        }
402
        return 4;
403
    }
404
};
405
 
406
/**
407
 * @brief LOAD instructions (LD, LW, LH, LB) with sign extending.
408
 *
409
 * Loads copy a value from memory to register rd.
410
 * The effective byte address is obtained by adding register rs1 to the
411
 * sign-extended 12-bit offset.
412
 *   The LW instruction loads a 32-bit value from memory into rd. LH loads
413
 * a 16-bit value from memory, then sign-extends to 32-bits before storing
414
 * in rd.
415
 */
416
class LD : public RiscvInstruction {
417
public:
418
    LD(CpuRiver_Functional *icpu) :
419
        RiscvInstruction(icpu, "LD", "?????????????????011?????0000011") {}
420
 
421
    virtual int exec(Reg64Type *payload) {
422
        Axi4TransactionType trans;
423
        ISA_I_type u;
424
        u.value = payload->buf32[0];
425
        uint64_t off = u.bits.imm;
426
        if (off & 0x800) {
427
            off |= EXT_SIGN_12;
428
        }
429
        trans.action = MemAction_Read;
430
        trans.addr = R[u.bits.rs1] + off;
431
        trans.xsize = 8;
432
        if (trans.addr & 0x7) {
433
            trans.rpayload.b64[0] = 0;
434
            icpu_->raiseSignal(EXCEPTION_LoadMisalign);
435
        } else {
436
            icpu_->dma_memop(&trans);
437
        }
438
        R[u.bits.rd] = trans.rpayload.b64[0];
439
        return 4;
440
    }
441
};
442
 
443
/**
444
 * Load 32-bits with sign extending.
445
 */
446
class LW : public RiscvInstruction {
447
public:
448
    LW(CpuRiver_Functional *icpu) :
449
        RiscvInstruction(icpu, "LW", "?????????????????010?????0000011") {}
450
 
451
    virtual int exec(Reg64Type *payload) {
452
        Axi4TransactionType trans;
453
        trans.rpayload.b64[0] = 0;
454
        ISA_I_type u;
455
        u.value = payload->buf32[0];
456
        uint64_t off = u.bits.imm;
457
        if (off & 0x800) {
458
            off |= EXT_SIGN_12;
459
        }
460
        trans.action = MemAction_Read;
461
        trans.addr = R[u.bits.rs1] + off;
462
        trans.xsize = 4;
463
        if (trans.addr & 0x3) {
464
            trans.rpayload.b64[0] = 0;
465
            icpu_->raiseSignal(EXCEPTION_LoadMisalign);
466
        } else {
467
            icpu_->dma_memop(&trans);
468
        }
469
        R[u.bits.rd] = trans.rpayload.b64[0];
470
        if (R[u.bits.rd] & (1LL << 31)) {
471
            R[u.bits.rd] |= EXT_SIGN_32;
472
        }
473
        return 4;
474
    }
475
};
476
 
477
/**
478
 * Load 32-bits with zero extending.
479
 */
480
class LWU : public RiscvInstruction {
481
public:
482
    LWU(CpuRiver_Functional *icpu) :
483
        RiscvInstruction(icpu, "LWU", "?????????????????110?????0000011") {}
484
 
485
    virtual int exec(Reg64Type *payload) {
486
        Axi4TransactionType trans;
487
        trans.rpayload.b64[0] = 0;
488
        ISA_I_type u;
489
        u.value = payload->buf32[0];
490
        uint64_t off = u.bits.imm;
491
        if (off & 0x800) {
492
            off |= EXT_SIGN_12;
493
        }
494
        trans.action = MemAction_Read;
495
        trans.addr = R[u.bits.rs1] + off;
496
        trans.xsize = 4;
497
        if (trans.addr & 0x3) {
498
            trans.rpayload.b64[0] = 0;
499
            icpu_->raiseSignal(EXCEPTION_LoadMisalign);
500
        } else {
501
            icpu_->dma_memop(&trans);
502
        }
503
        R[u.bits.rd] = trans.rpayload.b64[0];
504
        return 4;
505
    }
506
};
507
 
508
/**
509
 * Load 16-bits with sign extending.
510
 */
511
class LH : public RiscvInstruction {
512
public:
513
    LH(CpuRiver_Functional *icpu) :
514
        RiscvInstruction(icpu, "LH", "?????????????????001?????0000011") {}
515
 
516
    virtual int exec(Reg64Type *payload) {
517
        Axi4TransactionType trans;
518
        trans.rpayload.b64[0] = 0;
519
        ISA_I_type u;
520
        u.value = payload->buf32[0];
521
        uint64_t off = u.bits.imm;
522
        if (off & 0x800) {
523
            off |= EXT_SIGN_12;
524
        }
525
        trans.action = MemAction_Read;
526
        trans.addr = R[u.bits.rs1] + off;
527
        trans.xsize = 2;
528
        if (trans.addr & 0x1) {
529
            trans.rpayload.b64[0] = 0;
530
            icpu_->raiseSignal(EXCEPTION_LoadMisalign);
531
        } else {
532
            icpu_->dma_memop(&trans);
533
        }
534
        R[u.bits.rd] = trans.rpayload.b16[0];
535
        if (R[u.bits.rd] & (1LL << 15)) {
536
            R[u.bits.rd] |= EXT_SIGN_16;
537
        }
538
        return 4;
539
    }
540
};
541
 
542
/**
543
 * Load 16-bits with zero extending.
544
 */
545
class LHU : public RiscvInstruction {
546
public:
547
    LHU(CpuRiver_Functional *icpu) :
548
        RiscvInstruction(icpu, "LHU", "?????????????????101?????0000011") {}
549
 
550
    virtual int exec(Reg64Type *payload) {
551
        Axi4TransactionType trans;
552
        trans.rpayload.b64[0] = 0;
553
        ISA_I_type u;
554
        u.value = payload->buf32[0];
555
        uint64_t off = u.bits.imm;
556
        if (off & 0x800) {
557
            off |= EXT_SIGN_12;
558
        }
559
        trans.action = MemAction_Read;
560
        trans.addr = R[u.bits.rs1] + off;
561
        trans.xsize = 2;
562
        if (trans.addr & 0x1) {
563
            trans.rpayload.b64[0] = 0;
564
            icpu_->raiseSignal(EXCEPTION_LoadMisalign);
565
        } else {
566
            icpu_->dma_memop(&trans);
567
        }
568
        R[u.bits.rd] = trans.rpayload.b16[0];
569
        return 4;
570
    }
571
};
572
 
573
/**
574
 * Load 8-bits with sign extending.
575
 */
576
class LB : public RiscvInstruction {
577
public:
578
    LB(CpuRiver_Functional *icpu) :
579
        RiscvInstruction(icpu, "LB", "?????????????????000?????0000011") {}
580
 
581
    virtual int exec(Reg64Type *payload) {
582
        Axi4TransactionType trans;
583
        trans.rpayload.b64[0] = 0;
584
        ISA_I_type u;
585
        u.value = payload->buf32[0];
586
        uint64_t off = u.bits.imm;
587
        if (off & 0x800) {
588
            off |= EXT_SIGN_12;
589
        }
590
        trans.action = MemAction_Read;
591
        trans.addr = R[u.bits.rs1] + off;
592
        trans.xsize = 1;
593
        icpu_->dma_memop(&trans);
594
        R[u.bits.rd] = trans.rpayload.b8[0];
595
        if (R[u.bits.rd] & (1LL << 7)) {
596
            R[u.bits.rd] |= EXT_SIGN_8;
597
        }
598
        return 4;
599
    }
600
};
601
 
602
/**
603
 * Load 8-bits with zero extending.
604
 */
605
class LBU : public RiscvInstruction {
606
public:
607
    LBU(CpuRiver_Functional *icpu) :
608
        RiscvInstruction(icpu, "LBU", "?????????????????100?????0000011") {}
609
 
610
    virtual int exec(Reg64Type *payload) {
611
        Axi4TransactionType trans;
612
        trans.rpayload.b64[0] = 0;
613
        ISA_I_type u;
614
        u.value = payload->buf32[0];
615
        uint64_t off = u.bits.imm;
616
        if (off & 0x800) {
617
            off |= EXT_SIGN_12;
618
        }
619
        trans.action = MemAction_Read;
620
        trans.addr = R[u.bits.rs1] + off;
621
        trans.xsize = 1;
622
        icpu_->dma_memop(&trans);
623
        R[u.bits.rd] = trans.rpayload.b8[0];
624
        return 4;
625
    }
626
};
627
 
628
/**
629
 * @brief LUI (load upper immediate).
630
 *
631
 * It is used to build 32-bit constants and uses the U-type format. LUI places
632
 * the U-immediate value in the top 20 bits of the destination register rd,
633
 * filling in the lowest 12 bits with zeros.
634
 */
635
class LUI : public RiscvInstruction {
636
public:
637
    LUI(CpuRiver_Functional *icpu) :
638
        RiscvInstruction(icpu, "LUI", "?????????????????????????0110111") {}
639
 
640
    virtual int exec(Reg64Type *payload) {
641
        ISA_U_type u;
642
        u.value = payload->buf32[0];
643
        uint64_t tmp = u.bits.imm31_12 << 12;
644
        if (tmp & 0x80000000) {
645
            tmp |= EXT_SIGN_32;
646
        }
647
        R[u.bits.rd] = tmp;
648
        return 4;
649
    }
650
};
651
 
652
/**
653
 * @brief OR bitwise operation
654
 */
655
class OR : public RiscvInstruction {
656
public:
657
    OR(CpuRiver_Functional *icpu) :
658
        RiscvInstruction(icpu, "OR", "0000000??????????110?????0110011") {}
659
 
660
    virtual int exec(Reg64Type *payload) {
661
        ISA_R_type u;
662
        u.value = payload->buf32[0];
663
        R[u.bits.rd] = R[u.bits.rs1] | R[u.bits.rs2];
664
        return 4;
665
    }
666
};
667
 
668
/**
669
 * @brief OR on register rs1 and the sign-extended 12-bit immediate.
670
 */
671
class ORI : public RiscvInstruction {
672
public:
673
    ORI(CpuRiver_Functional *icpu) :
674
        RiscvInstruction(icpu, "ORI", "?????????????????110?????0010011") {}
675
 
676
    virtual int exec(Reg64Type *payload) {
677
        ISA_I_type u;
678
        u.value = payload->buf32[0];
679
 
680
        uint64_t imm = u.bits.imm;
681
        if (imm & 0x800) {
682
            imm |= EXT_SIGN_12;
683
        }
684
        R[u.bits.rd] = R[u.bits.rs1] | imm;
685
        return 4;
686
    }
687
};
688
 
689
/**
690
 * @brief SLLI is a logical left shift (zeros are shifted into the lower bits)
691
 */
692
class SLLI : public RiscvInstruction {
693
public:
694
    SLLI(CpuRiver_Functional *icpu) :
695
        RiscvInstruction(icpu, "SLLI", "000000???????????001?????0010011") {}
696
 
697
    virtual int exec(Reg64Type *payload) {
698
        ISA_I_type u;
699
        u.value = payload->buf32[0];
700
        uint32_t shamt = u.bits.imm & 0x3f;
701
        R[u.bits.rd] = R[u.bits.rs1] << shamt;
702
        return 4;
703
    }
704
};
705
 
706
/**
707
 * @brief The SLT (signed comparision)
708
 *
709
 * It places the value 1 in register rd if rs1 < rs2, 0 otherwise
710
 */
711
class SLT : public RiscvInstruction {
712
public:
713
    SLT(CpuRiver_Functional *icpu) :
714
        RiscvInstruction(icpu, "SLT", "0000000??????????010?????0110011") {}
715
 
716
    virtual int exec(Reg64Type *payload) {
717
        ISA_R_type u;
718
        u.value = payload->buf32[0];
719
        if (static_cast<int64_t>(R[u.bits.rs1]) <
720
                static_cast<int64_t>(R[u.bits.rs2])) {
721
            R[u.bits.rd] = 1;
722
        } else {
723
            R[u.bits.rd] = 0;
724
        }
725
        return 4;
726
    }
727
};
728
 
729
/**
730
 * @brief The SLTI (set less than immediate)
731
 *
732
 * It places the value 1 in register rd if register rs1 is less than the
733
 * sign-extended immediate when both are treated as signed numbers, else 0
734
 * is written to rd.
735
 */
736
class SLTI : public RiscvInstruction {
737
public:
738
    SLTI(CpuRiver_Functional *icpu) :
739
        RiscvInstruction(icpu, "SLTI", "?????????????????010?????0010011") {}
740
 
741
    virtual int exec(Reg64Type *payload) {
742
        ISA_I_type u;
743
        u.value = payload->buf32[0];
744
 
745
        uint64_t imm = u.bits.imm;
746
        if (imm & 0x800) {
747
            imm |= EXT_SIGN_12;
748
        }
749
        if (static_cast<int64_t>(R[u.bits.rs1]) <
750
                static_cast<int64_t>(imm)) {
751
            R[u.bits.rd] = 1;
752
        } else {
753
            R[u.bits.rd] = 0;
754
        }
755
        return 4;
756
    }
757
};
758
 
759
/**
760
 * @brief The SLTU (unsigned comparision)
761
 *
762
 * SLTU perform unsigned compares, writing 1 to rd if rs1 < rs2, 0 otherwise.
763
 * @note SLTU rd, x0, rs2 sets rd to 1 if rs2 is not equal to zero, otherwise
764
 * sets rd to zero (assembler pseudo-op SNEZ rd, rs).
765
 */
766
class SLTU : public RiscvInstruction {
767
public:
768
    SLTU(CpuRiver_Functional *icpu) :
769
        RiscvInstruction(icpu, "SLTU", "0000000??????????011?????0110011") {}
770
 
771
    virtual int exec(Reg64Type *payload) {
772
        ISA_R_type u;
773
        u.value = payload->buf32[0];
774
        if (R[u.bits.rs1] < R[u.bits.rs2]) {
775
            R[u.bits.rd] = 1;
776
        } else {
777
            R[u.bits.rd] = 0;
778
        }
779
        return 4;
780
    }
781
};
782
 
783
/**
784
 * @brief The SLTIU (set less than immediate comparing unsgined values)
785
 *
786
 * SLTIU is similar but compares the values as unsigned numbers (i.e., the
787
 * immediate is first sign-extended to 32-bits then treated as an unsigned
788
 * number). Note, SLTIU rd, rs1, 1 sets rd to 1 if rs1 equals zero, otherwise
789
 * sets rd to 0 (assembler pseudo-op SEQZ rd, rs).
790
 */
791
class SLTIU : public RiscvInstruction {
792
public:
793
    SLTIU(CpuRiver_Functional *icpu) :
794
        RiscvInstruction(icpu, "SLTIU", "?????????????????011?????0010011") {}
795
 
796
    virtual int exec(Reg64Type *payload) {
797
        ISA_I_type u;
798
        u.value = payload->buf32[0];
799
 
800
        uint64_t imm = u.bits.imm;
801
        if (imm & 0x800) {
802
            imm |= EXT_SIGN_12;
803
        }
804
        if (R[u.bits.rs1] < imm) {
805
            R[u.bits.rd] = 1;
806
        } else {
807
            R[u.bits.rd] = 0;
808
        }
809
        return 4;
810
    }
811
};
812
 
813
/**
814
 * @brief SLL logical shift left
815
 */
816
class SLL : public RiscvInstruction {
817
public:
818
    SLL(CpuRiver_Functional *icpu) :
819
        RiscvInstruction(icpu, "SLL", "0000000??????????001?????0110011") {}
820
 
821
    virtual int exec(Reg64Type *payload) {
822
        ISA_R_type u;
823
        u.value = payload->buf32[0];
824
        R[u.bits.rd] = R[u.bits.rs1] << (R[u.bits.rs2] & 0x3F);
825
        return 4;
826
    }
827
};
828
 
829
/**
830
 * @brief SLLW is a left shifts by register defined value (RV64I).
831
 */
832
class SLLW : public RiscvInstruction {
833
public:
834
    SLLW(CpuRiver_Functional *icpu) :
835
        RiscvInstruction(icpu, "SLLW", "0000000??????????001?????0111011") {}
836
 
837
    virtual int exec(Reg64Type *payload) {
838
        ISA_R_type u;
839
        u.value = payload->buf32[0];
840
        R[u.bits.rd] = R[u.bits.rs1] << R[u.bits.rs2];
841
        R[u.bits.rd] &= 0xFFFFFFFFLL;
842
        if (R[u.bits.rd] & (1LL << 31)) {
843
            R[u.bits.rd] |= EXT_SIGN_32;
844
        }
845
        return 4;
846
    }
847
};
848
 
849
/**
850
 * @brief SLLIW is a shifts by a constant (RV64I).
851
 *
852
 * SLLIW, SRLIW, and SRAIW are RV64I-only instructions that operate on 32-bit
853
 * values and produce signed 32-bit results.
854
 * @exception Illegal_Instruction if imm[5] not equal to 0.
855
 */
856
class SLLIW : public RiscvInstruction {
857
public:
858
    SLLIW(CpuRiver_Functional *icpu) :
859
        RiscvInstruction(icpu, "SLLIW", "0000000??????????001?????0011011") {}
860
 
861
    virtual int exec(Reg64Type *payload) {
862
        ISA_I_type u;
863
        u.value = payload->buf32[0];
864
        uint32_t shamt = u.bits.imm & 0x1f;
865
        R[u.bits.rd] = R[u.bits.rs1] << shamt;
866
        R[u.bits.rd] &= 0xFFFFFFFFLL;
867
        if (R[u.bits.rd] & (1LL << 31)) {
868
            R[u.bits.rd] |= EXT_SIGN_32;
869
        }
870
        if ((u.bits.imm >> 5) & 0x1) {
871
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
872
        }
873
        return 4;
874
    }
875
};
876
 
877
/**
878
 * @brief SRA arithmetic shift right
879
 */
880
class SRA : public RiscvInstruction {
881
public:
882
    SRA(CpuRiver_Functional *icpu) :
883
        RiscvInstruction(icpu, "SRA", "0100000??????????101?????0110011") {}
884
 
885
    virtual int exec(Reg64Type *payload) {
886
        ISA_R_type u;
887
        u.value = payload->buf32[0];
888
        R[u.bits.rd] = static_cast<int64_t>(R[u.bits.rs1])
889
                                >> (R[u.bits.rs2] & 0x3F);
890
        return 4;
891
    }
892
};
893
 
894
/**
895
 * @brief SRAW 32-bits arithmetic shift right (RV64I)
896
 */
897
class SRAW : public RiscvInstruction {
898
public:
899
    SRAW(CpuRiver_Functional *icpu) :
900
        RiscvInstruction(icpu, "SRAW", "0100000??????????101?????0111011") {}
901
 
902
    virtual int exec(Reg64Type *payload) {
903
        ISA_R_type u;
904
        u.value = payload->buf32[0];
905
        int32_t t1 = static_cast<int32_t>(R[u.bits.rs1]);
906
        R[u.bits.rd] = static_cast<int64_t>(t1 >> (R[u.bits.rs2] & 0x1F));
907
        return 4;
908
    }
909
};
910
 
911
 
912
/**
913
 * @brief SRAI is an arithmetic right shift.
914
 *
915
 * The original sign bit is copied into the vacanted upper bits.
916
 */
917
class SRAI : public RiscvInstruction {
918
public:
919
    SRAI(CpuRiver_Functional *icpu) :
920
        RiscvInstruction(icpu, "SRAI", "010000???????????101?????0010011") {}
921
 
922
    virtual int exec(Reg64Type *payload) {
923
        ISA_I_type u;
924
        u.value = payload->buf32[0];
925
        uint32_t shamt = u.bits.imm & 0x3f;
926
        R[u.bits.rd] = static_cast<int64_t>(R[u.bits.rs1]) >> shamt;
927
        return 4;
928
    }
929
};
930
 
931
/**
932
 * @brief SRAIW arithmetic right shift (RV64I)
933
 */
934
class SRAIW : public RiscvInstruction {
935
public:
936
    SRAIW(CpuRiver_Functional *icpu) :
937
        RiscvInstruction(icpu, "SRAIW", "0100000??????????101?????0011011") {}
938
 
939
    virtual int exec(Reg64Type *payload) {
940
        ISA_I_type u;
941
        u.value = payload->buf32[0];
942
        int32_t t1 = static_cast<int32_t>(R[u.bits.rs1]);
943
        uint32_t shamt = u.bits.imm & 0x1f;
944
        R[u.bits.rd] = static_cast<int64_t>(t1 >> shamt);
945
        if ((u.bits.imm >> 5) & 0x1) {
946
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
947
        }
948
        return 4;
949
    }
950
};
951
 
952
 
953
/**
954
 * @brief SRL logical shift right
955
 */
956
class SRL : public RiscvInstruction {
957
public:
958
    SRL(CpuRiver_Functional *icpu) :
959
        RiscvInstruction(icpu, "SRL", "0000000??????????101?????0110011") {}
960
 
961
    virtual int exec(Reg64Type *payload) {
962
        ISA_R_type u;
963
        u.value = payload->buf32[0];
964
        R[u.bits.rd] = R[u.bits.rs1] >> (R[u.bits.rs2] & 0x3F);
965
        return 4;
966
    }
967
};
968
 
969
/**
970
 * @brief SRLI is a logical right shift (zeros are shifted into the upper bits)
971
 */
972
class SRLI : public RiscvInstruction {
973
public:
974
    SRLI(CpuRiver_Functional *icpu) :
975
        RiscvInstruction(icpu, "SRLI", "000000???????????101?????0010011") {}
976
 
977
    virtual int exec(Reg64Type *payload) {
978
        ISA_I_type u;
979
        u.value = payload->buf32[0];
980
        uint32_t shamt = u.bits.imm & 0x3f;
981
        R[u.bits.rd] = R[u.bits.rs1] >> shamt;
982
        return 4;
983
    }
984
};
985
 
986
/**
987
 * @brief SRLIW logical right shift (RV64I)
988
 */
989
class SRLIW : public RiscvInstruction {
990
public:
991
    SRLIW(CpuRiver_Functional *icpu) :
992
        RiscvInstruction(icpu, "SRLIW", "0000000??????????101?????0011011") {}
993
 
994
    virtual int exec(Reg64Type *payload) {
995
        ISA_I_type u;
996
        u.value = payload->buf32[0];
997
        uint32_t shamt = u.bits.imm & 0x1f;
998
        R[u.bits.rd] = static_cast<uint32_t>(R[u.bits.rs1]) >> shamt;
999
        if ((u.bits.imm >> 5) & 0x1) {
1000
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
1001
        }
1002
        return 4;
1003
    }
1004
};
1005
 
1006
/**
1007
 * @brief SRLW is a right shifts by register defined value (RV64I).
1008
 */
1009
class SRLW : public RiscvInstruction {
1010
public:
1011
    SRLW(CpuRiver_Functional *icpu) :
1012
        RiscvInstruction(icpu, "SRLW", "0000000??????????101?????0111011") {}
1013
 
1014
    virtual int exec(Reg64Type *payload) {
1015
        ISA_R_type u;
1016
        u.value = payload->buf32[0];
1017
        R[u.bits.rd] = R[u.bits.rs1] >> R[u.bits.rs2];
1018
        R[u.bits.rd] &= 0xFFFFFFFFLL;
1019
        if (R[u.bits.rd] & (1LL << 31)) {
1020
            R[u.bits.rd] |= EXT_SIGN_32;
1021
        }
1022
        return 4;
1023
    }
1024
};
1025
 
1026
/**
1027
 * @brief STORE instructions (SD, SW, SH, SB)
1028
 *
1029
 * This instruction copies the value in register rs2 to memory.
1030
 * The effective byte address is obtained by adding register rs1 to the
1031
 * sign-extended 12-bit offset.
1032
 *   The SW, SH, and SB instructions store 32-bit, 16-bit, and 8-bit values
1033
 * from the low bits of register rs2 to memory.
1034
 */
1035
class SD : public RiscvInstruction {
1036
public:
1037
    SD(CpuRiver_Functional *icpu) :
1038
        RiscvInstruction(icpu, "SD", "?????????????????011?????0100011") {}
1039
 
1040
    virtual int exec(Reg64Type *payload) {
1041
        Axi4TransactionType trans;
1042
        ISA_S_type u;
1043
        u.value = payload->buf32[0];
1044
        uint64_t off = (u.bits.imm11_5 << 5) | u.bits.imm4_0;
1045
        if (off & 0x800) {
1046
            off |= EXT_SIGN_12;
1047
        }
1048
        trans.action = MemAction_Write;
1049
        trans.xsize = 8;
1050
        trans.wstrb = (1 << trans.xsize) - 1;
1051
        trans.addr = R[u.bits.rs1] + off;
1052
        trans.wpayload.b64[0] = R[u.bits.rs2];
1053
        if (trans.addr & 0x7) {
1054
            icpu_->raiseSignal(EXCEPTION_StoreMisalign);
1055
        } else {
1056
            icpu_->dma_memop(&trans);
1057
        }
1058
        return 4;
1059
    }
1060
};
1061
 
1062
/**
1063
 * @brief Store rs2[31:0] to memory.
1064
 */
1065
class SW : public RiscvInstruction {
1066
public:
1067
    SW(CpuRiver_Functional *icpu) :
1068
        RiscvInstruction(icpu, "SW", "?????????????????010?????0100011") {}
1069
 
1070
    virtual int exec(Reg64Type *payload) {
1071
        Axi4TransactionType trans;
1072
        trans.wpayload.b64[0] = 0;
1073
        ISA_S_type u;
1074
        u.value = payload->buf32[0];
1075
        uint64_t off = (u.bits.imm11_5 << 5) | u.bits.imm4_0;
1076
        if (off & 0x800) {
1077
            off |= EXT_SIGN_12;
1078
        }
1079
        trans.action = MemAction_Write;
1080
        trans.xsize = 4;
1081
        trans.wstrb = (1 << trans.xsize) - 1;
1082
        trans.addr = R[u.bits.rs1] + off;
1083
        trans.wpayload.b64[0] = R[u.bits.rs2];
1084
        if (trans.addr & 0x3) {
1085
            icpu_->raiseSignal(EXCEPTION_StoreMisalign);
1086
        } else {
1087
            icpu_->dma_memop(&trans);
1088
        }
1089
        return 4;
1090
    }
1091
};
1092
 
1093
/**
1094
 * @brief Store rs2[15:0] to memory.
1095
 */
1096
class SH : public RiscvInstruction {
1097
public:
1098
    SH(CpuRiver_Functional *icpu) :
1099
        RiscvInstruction(icpu, "SH", "?????????????????001?????0100011") {}
1100
 
1101
    virtual int exec(Reg64Type *payload) {
1102
        Axi4TransactionType trans;
1103
        trans.wpayload.b64[0] = 0;
1104
        ISA_S_type u;
1105
        u.value = payload->buf32[0];
1106
        uint64_t off = (u.bits.imm11_5 << 5) | u.bits.imm4_0;
1107
        if (off & 0x800) {
1108
            off |= EXT_SIGN_12;
1109
        }
1110
        trans.action = MemAction_Write;
1111
        trans.xsize = 2;
1112
        trans.wstrb = (1 << trans.xsize) - 1;
1113
        trans.addr = R[u.bits.rs1] + off;
1114
        trans.wpayload.b64[0] = R[u.bits.rs2] & 0xFFFF;
1115
        if (trans.addr & 0x1) {
1116
            icpu_->raiseSignal(EXCEPTION_StoreMisalign);
1117
        } else {
1118
            icpu_->dma_memop(&trans);
1119
        }
1120
        return 4;
1121
    }
1122
};
1123
 
1124
/**
1125
 * @brief Store rs2[7:0] to memory.
1126
 */
1127
class SB : public RiscvInstruction {
1128
public:
1129
    SB(CpuRiver_Functional *icpu) :
1130
        RiscvInstruction(icpu, "SB", "?????????????????000?????0100011") {}
1131
 
1132
    virtual int exec(Reg64Type *payload) {
1133
        Axi4TransactionType trans;
1134
        trans.wpayload.b64[0] = 0;
1135
        ISA_S_type u;
1136
        u.value = payload->buf32[0];
1137
        uint64_t off = (u.bits.imm11_5 << 5) | u.bits.imm4_0;
1138
        if (off & 0x800) {
1139
            off |= EXT_SIGN_12;
1140
        }
1141
        trans.action = MemAction_Write;
1142
        trans.xsize = 1;
1143
        trans.wstrb = (1 << trans.xsize) - 1;
1144
        trans.addr = R[u.bits.rs1] + off;
1145
        trans.wpayload.b64[0] = R[u.bits.rs2] & 0xFF;
1146
        icpu_->dma_memop(&trans);
1147
        return 4;
1148
    }
1149
};
1150
 
1151
/**
1152
 * @brief Subtruction. Overflows are ignored
1153
 */
1154
class SUB : public RiscvInstruction {
1155
public:
1156
    SUB(CpuRiver_Functional *icpu) :
1157
        RiscvInstruction(icpu, "SUB", "0100000??????????000?????0110011") {}
1158
 
1159
    virtual int exec(Reg64Type *payload) {
1160
        ISA_R_type u;
1161
        u.value = payload->buf32[0];
1162
        R[u.bits.rd] = R[u.bits.rs1] - R[u.bits.rs2];
1163
        return 4;
1164
    }
1165
};
1166
 
1167
/**
1168
 * @brief Substruct registers with sign extending (RV64I)
1169
 *
1170
 * SUBW is RV64I-only instructions that are defined analogously to
1171
 * SUB but operate on 32-bit values and produce signed 32-bit results.
1172
 * Overflows are ignored, and the low 32-bits of the result is sign-extended
1173
 * to 64-bits and written to the destination register.
1174
 */
1175
class SUBW : public RiscvInstruction {
1176
public:
1177
    SUBW(CpuRiver_Functional *icpu) :
1178
        RiscvInstruction(icpu, "SUBW", "0100000??????????000?????0111011") {}
1179
 
1180
    virtual int exec(Reg64Type *payload) {
1181
        ISA_R_type u;
1182
        u.value = payload->buf32[0];
1183
 
1184
        R[u.bits.rd] = (R[u.bits.rs1] - R[u.bits.rs2]) & 0xFFFFFFFFLL;
1185
        if (R[u.bits.rd] & (1LL << 31)) {
1186
            R[u.bits.rd] |= EXT_SIGN_32;
1187
        }
1188
        return 4;
1189
    }
1190
};
1191
 
1192
/**
1193
 * @brief XOR bitwise operation
1194
 */
1195
class XOR : public RiscvInstruction {
1196
public:
1197
    XOR(CpuRiver_Functional *icpu) :
1198
        RiscvInstruction(icpu, "XOR", "0000000??????????100?????0110011") {}
1199
 
1200
    virtual int exec(Reg64Type *payload) {
1201
        ISA_R_type u;
1202
        u.value = payload->buf32[0];
1203
        R[u.bits.rd] = R[u.bits.rs1] ^ R[u.bits.rs2];
1204
        return 4;
1205
    }
1206
};
1207
 
1208
/**
1209
 * @brief XOR on register rs1 and the sign-extended 12-bit immediate.
1210
 *
1211
 * XORI rd, rs1, -1 performs a bitwise logical inversion of register rs1
1212
 * (assembler pseudo-instruction NOT rd, rs).
1213
 */
1214
class XORI : public RiscvInstruction {
1215
public:
1216
    XORI(CpuRiver_Functional *icpu) :
1217
        RiscvInstruction(icpu, "XORI", "?????????????????100?????0010011") {}
1218
 
1219
    virtual int exec(Reg64Type *payload) {
1220
        ISA_I_type u;
1221
        u.value = payload->buf32[0];
1222
 
1223
        uint64_t imm = u.bits.imm;
1224
        if (imm & 0x800) {
1225
            imm |= EXT_SIGN_12;
1226
        }
1227
        R[u.bits.rd] = R[u.bits.rs1] ^ imm;
1228
        return 4;
1229
    }
1230
};
1231
 
1232
void CpuRiver_Functional::addIsaUserRV64I() {
1233
    addSupportedInstruction(new ADD(this));
1234
    addSupportedInstruction(new ADDI(this));
1235
    addSupportedInstruction(new ADDIW(this));
1236
    addSupportedInstruction(new ADDW(this));
1237
    addSupportedInstruction(new AND(this));
1238
    addSupportedInstruction(new ANDI(this));
1239
    addSupportedInstruction(new AUIPC(this));
1240
    addSupportedInstruction(new BEQ(this));
1241
    addSupportedInstruction(new BGE(this));
1242
    addSupportedInstruction(new BGEU(this));
1243
    addSupportedInstruction(new BLT(this));
1244
    addSupportedInstruction(new BLTU(this));
1245
    addSupportedInstruction(new BNE(this));
1246
    addSupportedInstruction(new JAL(this));
1247
    addSupportedInstruction(new JALR(this));
1248
    addSupportedInstruction(new LD(this));
1249
    addSupportedInstruction(new LW(this));
1250
    addSupportedInstruction(new LWU(this));
1251
    addSupportedInstruction(new LH(this));
1252
    addSupportedInstruction(new LHU(this));
1253
    addSupportedInstruction(new LB(this));
1254
    addSupportedInstruction(new LBU(this));
1255
    addSupportedInstruction(new LUI(this));
1256
    addSupportedInstruction(new OR(this));
1257
    addSupportedInstruction(new ORI(this));
1258
    addSupportedInstruction(new SLL(this));
1259
    addSupportedInstruction(new SLLI(this));
1260
    addSupportedInstruction(new SLLIW(this));
1261
    addSupportedInstruction(new SLLW(this));
1262
    addSupportedInstruction(new SLT(this));
1263
    addSupportedInstruction(new SLTI(this));
1264
    addSupportedInstruction(new SLTU(this));
1265
    addSupportedInstruction(new SLTIU(this));
1266
    addSupportedInstruction(new SRA(this));
1267
    addSupportedInstruction(new SRAI(this));
1268
    addSupportedInstruction(new SRAIW(this));
1269
    addSupportedInstruction(new SRAW(this));
1270
    addSupportedInstruction(new SRL(this));
1271
    addSupportedInstruction(new SRLI(this));
1272
    addSupportedInstruction(new SRLIW(this));
1273
    addSupportedInstruction(new SRLW(this));
1274
    addSupportedInstruction(new SUB(this));
1275
    addSupportedInstruction(new SUBW(this));
1276
    addSupportedInstruction(new SD(this));
1277
    addSupportedInstruction(new SW(this));
1278
    addSupportedInstruction(new SH(this));
1279
    addSupportedInstruction(new SB(this));
1280
    addSupportedInstruction(new XOR(this));
1281
    addSupportedInstruction(new XORI(this));
1282
 
1283
  /*
1284
  def SLLI_RV32          = BitPat("b0000000??????????001?????0010011")
1285
  def SRLI_RV32          = BitPat("b0000000??????????101?????0010011")
1286
  def SRAI_RV32          = BitPat("b0100000??????????101?????0010011")
1287
  */
1288
    /** Base[XLEN-1:XLEN-2]
1289
     *      1 = 32
1290
     *      2 = 64
1291
     *      3 = 128
1292
     */
1293
    uint64_t isa = 0x8000000000000000LL;
1294
    isa |= (1LL << ('I' - 'A'));
1295
    portCSR_.write(CSR_misa, isa);
1296
}
1297
 
1298
}  // namespace debugger

powered by: WebSVN 2.1.0

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