1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// See LICENSE for license details.
#ifndef _RISCV_DECODE_H
#define _RISCV_DECODE_H
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <string.h>
#include "pcr.h"
#include "config.h"
#include "common.h"
typedef int int128_t __attribute__((mode(TI)));
typedef unsigned int uint128_t __attribute__((mode(TI)));
typedef int64_t sreg_t;
typedef uint64_t reg_t;
typedef uint64_t freg_t;
const int NXPR = 32;
const int NFPR = 32;
#define FP_RD_NE 0
#define FP_RD_0 1
#define FP_RD_DN 2
#define FP_RD_UP 3
#define FP_RD_NMM 4
#define FSR_RD_SHIFT 5
#define FSR_RD (0x7 << FSR_RD_SHIFT)
#define FPEXC_NX 0x01
#define FPEXC_UF 0x02
#define FPEXC_OF 0x04
#define FPEXC_DZ 0x08
#define FPEXC_NV 0x10
#define FSR_AEXC_SHIFT 0
#define FSR_NVA (FPEXC_NV << FSR_AEXC_SHIFT)
#define FSR_OFA (FPEXC_OF << FSR_AEXC_SHIFT)
#define FSR_UFA (FPEXC_UF << FSR_AEXC_SHIFT)
#define FSR_DZA (FPEXC_DZ << FSR_AEXC_SHIFT)
#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
#define FSR_ZERO ~(FSR_RD | FSR_AEXC)
class insn_t
{
public:
uint32_t bits() { return b; }
reg_t i_imm() { return x(11, 11) | (imm_sign() << 11); }
reg_t s_imm() { return x(11, 6) | (x(27, 5) << 6) | (imm_sign() << 11); }
reg_t sb_imm() { return (x(12, 5) << 1) | (x(27, 5) << 6) | (x(11, 1) << 11) | (imm_sign() << 12); }
reg_t u_imm() { return (x(22, 5) << 12) | (x(7, 3) << 17) | (x(11, 11) << 20) | (imm_sign() << 31); }
reg_t uj_imm() { return (x(12, 10) << 1) | (x(11, 1) << 11) | (x(22, 5) << 12) | (x(7, 3) << 17) | (imm_sign() << 20); }
uint32_t rd() { return x(27, 5); }
uint32_t rs1() { return x(22, 5); }
uint32_t rs2() { return x(17, 5); }
uint32_t rs3() { return x(12, 5); }
uint32_t rm() { return x(9, 3); }
private:
uint32_t b;
reg_t x(int lo, int len) { return b << (32-lo-len) >> (32-len); }
reg_t imm_sign() { return -x(10, 1); }
};
template <class T>
class write_port_t
{
public:
write_port_t(T& _t) : t(_t) {}
T& operator = (const T& rhs)
{
return t = rhs;
}
operator T()
{
return t;
}
private:
T& t;
};
template <class T, size_t N, bool zero_reg>
class regfile_t
{
public:
void reset()
{
memset(data, 0, sizeof(data));
}
write_port_t<T> write_port(size_t i)
{
if (zero_reg)
const_cast<T&>(data[0]) = 0;
return write_port_t<T>(data[i]);
}
const T& operator [] (size_t i) const
{
if (zero_reg)
const_cast<T&>(data[0]) = 0;
return data[i];
}
private:
T data[N];
};
// helpful macros, etc
#define MMU (*p->get_mmu())
#define RS1 p->get_state()->XPR[insn.rs1()]
#define RS2 p->get_state()->XPR[insn.rs2()]
#define RD p->get_state()->XPR.write_port(insn.rd())
#define FRS1 p->get_state()->FPR[insn.rs1()]
#define FRS2 p->get_state()->FPR[insn.rs2()]
#define FRS3 p->get_state()->FPR[insn.rs3()]
#define FRD p->get_state()->FPR.write_port(insn.rd())
#define SHAMT (insn.i_imm() & 0x3F)
#define BRANCH_TARGET (pc + insn.sb_imm())
#define JUMP_TARGET (pc + insn.uj_imm())
#define RM ({ int rm = insn.rm(); \
if(rm == 7) rm = (p->get_state()->fsr & FSR_RD) >> FSR_RD_SHIFT; \
if(rm > 4) throw trap_illegal_instruction(); \
rm; })
#define xpr64 (xprlen == 64)
#define require_supervisor if(unlikely(!(p->get_state()->sr & SR_S))) throw trap_privileged_instruction()
#define require_xpr64 if(unlikely(!xpr64)) throw trap_illegal_instruction()
#define require_xpr32 if(unlikely(xpr64)) throw trap_illegal_instruction()
#ifndef RISCV_ENABLE_FPU
# define require_fp throw trap_illegal_instruction()
#else
# define require_fp if(unlikely(!(p->get_state()->sr & SR_EF))) throw trap_fp_disabled()
#endif
#define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
#define set_fp_exceptions ({ p->set_fsr(p->get_state()->fsr | \
(softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
softfloat_exceptionFlags = 0; })
#define sext32(x) ((sreg_t)(int32_t)(x))
#define zext32(x) ((reg_t)(uint32_t)(x))
#define sext_xprlen(x) (((sreg_t)(x) << (64-xprlen)) >> (64-xprlen))
#define zext_xprlen(x) (((reg_t)(x) << (64-xprlen)) >> (64-xprlen))
#define insn_length(x) \
(((x) & 0x03) < 0x03 ? 2 : \
((x) & 0x1f) < 0x1f ? 4 : \
((x) & 0x3f) < 0x3f ? 6 : \
8)
#define set_pc(x) \
do { if ((x) & 3 /* For now... */) \
throw trap_instruction_address_misaligned(); \
npc = (x); \
} while(0)
#endif
|