Browse Source

Added RV32D extension

Eyck Jentzsch 1 year ago
parent
commit
ce98e2ad31

+ 298
- 0
riscv/gen_input/RV32D.core_desc View File

@@ -0,0 +1,298 @@
1
+import "RV32IBase.core_desc"
2
+
3
+InsructionSet RV32D extends RV32IBase{
4
+	constants {
5
+		FLEN, FFLAG_MASK
6
+	} 
7
+	registers {
8
+		[31:0]    F[FLEN],  FCSR[32]
9
+    }	
10
+	instructions{
11
+		FLD {
12
+			encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111;
13
+			args_disass:"f%rd$d, %imm%(x%rs1$d)";
14
+			val offs[XLEN] <= X[rs1]+imm;
15
+			val res[64] <= MEM[offs]{64};
16
+			if(FLEN==64)
17
+				F[rd] <= res;
18
+			else { // NaN boxing
19
+				val upper[FLEN] <= -1;
20
+				F[rd] <= (upper<<64) | res;
21
+			}
22
+		}
23
+		FSD {
24
+			encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111;
25
+			args_disass:"f%rs2$d, %imm%(x%rs1$d)";
26
+			val offs[XLEN] <= X[rs1]+imm;
27
+			MEM[offs]{64}<=F[rs2]{64};
28
+		}
29
+		FMADD.D {
30
+			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
31
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
32
+			//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
33
+			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8}));
34
+			if(FLEN==64)
35
+				F[rd] <= res;
36
+			else { // NaN boxing
37
+				val upper[FLEN] <= -1;
38
+				F[rd] <= (upper<<64) | res;
39
+			}
40
+			val flags[32] <= fdispatch_fget_flags();
41
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
42
+		}
43
+		FMSUB.D {
44
+			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
45
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
46
+			//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
47
+			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
48
+			if(FLEN==64)
49
+				F[rd] <= res;
50
+			else { // NaN boxing
51
+				val upper[FLEN] <= -1;
52
+				F[rd] <= (upper<<64) | res;
53
+			}
54
+			val flags[32] <= fdispatch_fget_flags();
55
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};	
56
+		}
57
+		FNMADD.D {
58
+			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
59
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
60
+			//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
61
+			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
62
+			if(FLEN==64)
63
+				F[rd] <= res;
64
+			else { // NaN boxing
65
+				val upper[FLEN] <= -1;
66
+				F[rd] <= (upper<<64) | res;
67
+			}
68
+			val flags[32] <= fdispatch_fget_flags();
69
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
70
+		}
71
+		FNMSUB.D {
72
+			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
73
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
74
+			//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
75
+			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
76
+			if(FLEN==64)
77
+				F[rd] <= res;
78
+			else { // NaN boxing
79
+				val upper[FLEN] <= -1;
80
+				F[rd] <= (upper<<64) | res;
81
+			}
82
+			val flags[32] <= fdispatch_fget_flags();
83
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
84
+		}
85
+		FADD.D {
86
+			encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
87
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
88
+			// F[rd]f <= F[rs1]f + F[rs2]f;
89
+			val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
90
+			if(FLEN==64)
91
+				F[rd] <= res;
92
+			else { // NaN boxing
93
+				val upper[FLEN] <= -1;
94
+				F[rd] <= (upper<<64) | res;
95
+			}
96
+			val flags[32] <= fdispatch_fget_flags();
97
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
98
+		}
99
+		FSUB.D {
100
+			encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
101
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
102
+			// F[rd]f <= F[rs1]f - F[rs2]f;
103
+			val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
104
+			if(FLEN==64)
105
+				F[rd] <= res;
106
+			else { // NaN boxing
107
+				val upper[FLEN] <= -1;
108
+				F[rd] <= (upper<<64) | res;
109
+			}
110
+			val flags[32] <= fdispatch_fget_flags();
111
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
112
+		}
113
+		FMUL.D {
114
+			encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
115
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
116
+			// F[rd]f <= F[rs1]f * F[rs2]f;
117
+			val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
118
+			if(FLEN==64)
119
+				F[rd] <= res;
120
+			else { // NaN boxing
121
+				val upper[FLEN] <= -1;
122
+				F[rd] <= (upper<<64) | res;
123
+			}
124
+			val flags[32] <= fdispatch_fget_flags();
125
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
126
+		}
127
+		FDIV.D {
128
+			encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
129
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
130
+			// F[rd]f <= F[rs1]f / F[rs2]f;
131
+			val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
132
+			if(FLEN==64)
133
+				F[rd] <= res;
134
+			else { // NaN boxing
135
+				val upper[FLEN] <= -1;
136
+				F[rd] <= (upper<<64) | res;
137
+			}
138
+			val flags[32] <= fdispatch_fget_flags();
139
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
140
+		}
141
+		FSQRT.D {
142
+			encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
143
+			args_disass:"x%rd$d, f%rs1$d";
144
+			//F[rd]f<=sqrt(F[rs1]f);
145
+			val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8}));
146
+			if(FLEN==64)
147
+				F[rd] <= res;
148
+			else { // NaN boxing
149
+				val upper[FLEN] <= -1;
150
+				F[rd] <= (upper<<64) | res;
151
+			}
152
+			val flags[32] <= fdispatch_fget_flags();
153
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
154
+		}
155
+		FSGNJ.D {
156
+			encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
157
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
158
+			val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000);
159
+			if(FLEN==64)
160
+				F[rd] <= res;
161
+			else { // NaN boxing
162
+				val upper[FLEN] <= -1;
163
+				F[rd] <= (upper<<64) | res;
164
+			}
165
+		}
166
+		FSGNJN.D {
167
+			encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
168
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
169
+			val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000);
170
+			if(FLEN==64)
171
+				F[rd] <= res;
172
+			else { // NaN boxing
173
+				val upper[FLEN] <= -1;
174
+				F[rd] <= (upper<<64) | res;
175
+			}
176
+		}
177
+		FSGNJX.D {
178
+			encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
179
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
180
+			val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000);
181
+			if(FLEN==64)
182
+				F[rd] <= res;
183
+			else { // NaN boxing
184
+				val upper[FLEN] <= -1;
185
+				F[rd] <= (upper<<64) | res;
186
+			}
187
+		}
188
+		FMIN.D  {
189
+			encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
190
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
191
+			//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
192
+			val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
193
+			if(FLEN==64)
194
+				F[rd] <= res;
195
+			else { // NaN boxing
196
+				val upper[FLEN] <= -1;
197
+				F[rd] <= (upper<<64) | res;
198
+			}
199
+			val flags[32] <= fdispatch_fget_flags();
200
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
201
+		}
202
+		FMAX.D {
203
+			encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
204
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
205
+			//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
206
+			val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
207
+			if(FLEN==64)
208
+				F[rd] <= res;
209
+			else { // NaN boxing
210
+				val upper[FLEN] <= -1;
211
+				F[rd] <= (upper<<64) | res;
212
+			}
213
+			val flags[32] <= fdispatch_fget_flags();
214
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
215
+		}
216
+		FCVT.S.D {
217
+			encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
218
+			args_disass:"f%rd$d, f%rs1$d";
219
+			val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8});
220
+			// NaN boxing
221
+			val upper[FLEN] <= -1;
222
+			F[rd] <= upper<<32 | zext(res, FLEN);
223
+		}
224
+		FCVT.D.S {
225
+			encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
226
+			args_disass:"f%rd$d, f%rs1$d";
227
+			val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8});
228
+			if(FLEN==64){
229
+				F[rd] <= res;
230
+			} else {
231
+				val upper[FLEN] <= -1;
232
+				F[rd] <= (upper<<64) | res;
233
+			}
234
+		}
235
+		FEQ.D {
236
+			encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
237
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
238
+			X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
239
+			val flags[32] <= fdispatch_fget_flags();
240
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
241
+		}
242
+		FLT.D {
243
+			encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
244
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
245
+			X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32));
246
+			val flags[32] <= fdispatch_fget_flags();
247
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
248
+		}
249
+		FLE.D {
250
+			encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
251
+			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
252
+			X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
253
+			val flags[32] <= fdispatch_fget_flags();
254
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
255
+		}
256
+		FCLASS.D {
257
+			encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
258
+			args_disass:"x%rd$d, f%rs1$d";
259
+			X[rd]<=fdispatch_fclass_d(F[rs1]{64});
260
+		}
261
+		FCVT.W.D {
262
+			encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
263
+			args_disass:"x%rd$d, f%rs1$d";
264
+			X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN);
265
+			val flags[32] <= fdispatch_fget_flags();
266
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
267
+		}
268
+		FCVT.WU.D {
269
+			encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
270
+			args_disass:"x%rd$d, f%rs1$d";
271
+			X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN);
272
+			val flags[32] <= fdispatch_fget_flags();
273
+			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
274
+		}
275
+		FCVT.D.W {
276
+			encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
277
+			args_disass:"f%rd$d, x%rs1$d";
278
+			val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8});
279
+			if(FLEN==64)
280
+				F[rd] <= res;
281
+			else { // NaN boxing
282
+				val upper[FLEN] <= -1;
283
+				F[rd] <= (upper<<64) | res;
284
+			}
285
+		}
286
+		FCVT.D.WU {
287
+			encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
288
+			args_disass:"f%rd$d, x%rs1$d";
289
+			val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8});
290
+			if(FLEN==64)
291
+				F[rd] <= res;
292
+			else { // NaN boxing
293
+				val upper[FLEN] <= -1;
294
+				F[rd] <= (upper<<64) | res;
295
+			}
296
+		}
297
+	}
298
+}

+ 59
- 59
riscv/gen_input/RV32F.core_desc View File

@@ -15,9 +15,9 @@ InsructionSet RV32F extends RV32IBase{
15 15
 			val res[32] <= MEM[offs]{32};
16 16
 			if(FLEN==32)
17 17
 				F[rd] <= res;
18
-			else {
19
-				val upper[FLEN] <= (-1<<31);
20
-				F[rd] <= upper*2 | res;
18
+			else { // NaN boxing
19
+				val upper[FLEN] <= -1;
20
+				F[rd] <= (upper<<32) | zext(res, FLEN);
21 21
 			}
22 22
 		}
23 23
 		FSW {
@@ -33,9 +33,9 @@ InsructionSet RV32F extends RV32IBase{
33 33
 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
34 34
 			if(FLEN==32)
35 35
 				F[rd] <= res;
36
-			else {
37
-				val upper[FLEN] <= (-1<<31);
38
-				F[rd] <= upper*2 | res;
36
+			else { // NaN boxing
37
+				val upper[FLEN] <= -1;
38
+				F[rd] <= (upper<<32) | zext(res, FLEN);
39 39
 			}
40 40
 			val flags[32] <= fdispatch_fget_flags();
41 41
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
@@ -47,9 +47,9 @@ InsructionSet RV32F extends RV32IBase{
47 47
 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
48 48
 			if(FLEN==32)
49 49
 				F[rd] <= res;
50
-			else {
51
-				val upper[FLEN] <= (-1<<31);
52
-				F[rd] <= upper*2 | res;
50
+			else { // NaN boxing
51
+				val upper[FLEN] <= -1;
52
+				F[rd] <= (upper<<32) | zext(res, FLEN);
53 53
 			}
54 54
 			val flags[32] <= fdispatch_fget_flags();
55 55
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};	
@@ -61,9 +61,9 @@ InsructionSet RV32F extends RV32IBase{
61 61
 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
62 62
 			if(FLEN==32)
63 63
 				F[rd] <= res;
64
-			else {
65
-				val upper[FLEN] <= (-1<<31);
66
-				F[rd] <= upper*2 | res;
64
+			else { // NaN boxing
65
+				val upper[FLEN] <= -1;
66
+				F[rd] <= (upper<<32) | zext(res, FLEN);
67 67
 			}
68 68
 			val flags[32] <= fdispatch_fget_flags();
69 69
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
@@ -75,79 +75,79 @@ InsructionSet RV32F extends RV32IBase{
75 75
 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
76 76
 			if(FLEN==32)
77 77
 				F[rd] <= res;
78
-			else {
79
-				val upper[FLEN] <= (-1<<31);
80
-				F[rd] <= upper*2 | res;
78
+			else { // NaN boxing
79
+				val upper[FLEN] <= -1;
80
+				F[rd] <= (upper<<32) | zext(res, FLEN);
81 81
 			}
82 82
 			val flags[32] <= fdispatch_fget_flags();
83 83
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
84 84
 		}
85 85
 		FADD.S {
86 86
 			encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
87
-			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
87
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
88 88
 			// F[rd]f <= F[rs1]f + F[rs2]f;
89 89
 			val res[32] <= fdispatch_fadd_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
90 90
 			if(FLEN==32)
91 91
 				F[rd] <= res;
92
-			else {
93
-				val upper[FLEN] <= (-1<<31);
94
-				F[rd] <= upper*2 | res;
92
+			else { // NaN boxing
93
+				val upper[FLEN] <= -1;
94
+				F[rd] <= (upper<<32) | zext(res, FLEN);
95 95
 			}
96 96
 			val flags[32] <= fdispatch_fget_flags();
97 97
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
98 98
 		}
99 99
 		FSUB.S {
100 100
 			encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
101
-			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
101
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
102 102
 			// F[rd]f <= F[rs1]f - F[rs2]f;
103 103
 			val res[32] <= fdispatch_fsub_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
104 104
 			if(FLEN==32)
105 105
 				F[rd] <= res;
106
-			else {
107
-				val upper[FLEN] <= -1<<31;
108
-				F[rd] <= upper*2 | res;
106
+			else { // NaN boxing
107
+				val upper[FLEN] <= -1;
108
+				F[rd] <= (upper<<32) | zext(res, FLEN);
109 109
 			}
110 110
 			val flags[32] <= fdispatch_fget_flags();
111 111
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
112 112
 		}
113 113
 		FMUL.S {
114 114
 			encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
115
-			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
115
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
116 116
 			// F[rd]f <= F[rs1]f * F[rs2]f;
117 117
 			val res[32] <= fdispatch_fmul_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
118 118
 			if(FLEN==32)
119 119
 				F[rd] <= res;
120
-			else {
121
-				val upper[FLEN] <= -1<<31;
122
-				F[rd] <= upper*2 | res;
120
+			else { // NaN boxing
121
+				val upper[FLEN] <= -1;
122
+				F[rd] <= (upper<<32) | zext(res, FLEN);
123 123
 			}
124 124
 			val flags[32] <= fdispatch_fget_flags();
125 125
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
126 126
 		}
127 127
 		FDIV.S {
128 128
 			encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
129
-			args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
129
+			args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
130 130
 			// F[rd]f <= F[rs1]f / F[rs2]f;
131 131
 			val res[32] <= fdispatch_fdiv_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
132 132
 			if(FLEN==32)
133 133
 				F[rd] <= res;
134
-			else {
135
-				val upper[FLEN] <= -1<<31;
136
-				F[rd] <= upper*2 | res;
134
+			else { // NaN boxing
135
+				val upper[FLEN] <= -1;
136
+				F[rd] <= (upper<<32) | zext(res, FLEN);
137 137
 			}
138 138
 			val flags[32] <= fdispatch_fget_flags();
139 139
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
140 140
 		}
141 141
 		FSQRT.S {
142 142
 			encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
143
-			args_disass:"x%rd$d, f%rs1$d";
143
+			args_disass:"f%rd$d, f%rs1$d";
144 144
 			//F[rd]f<=sqrt(F[rs1]f);
145 145
 			val res[32] <= fdispatch_fsqrt_s(F[rs1]{32}, choose(rm<7, rm{8}, FCSR{8}));
146 146
 			if(FLEN==32)
147 147
 				F[rd] <= res;
148
-			else {
149
-				val upper[FLEN] <= -1<<31;
150
-				F[rd] <= upper*2 | res;
148
+			else { // NaN boxing
149
+				val upper[FLEN] <= -1;
150
+				F[rd] <= (upper<<32) | zext(res, FLEN);
151 151
 			}
152 152
 			val flags[32] <= fdispatch_fget_flags();
153 153
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
@@ -158,9 +158,9 @@ InsructionSet RV32F extends RV32IBase{
158 158
 			val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000);
159 159
 			if(FLEN==32)
160 160
 				F[rd] <= res;
161
-			else {
162
-				val upper[FLEN] <= -1<<31;
163
-				F[rd] <= upper*2 | res;
161
+			else { // NaN boxing
162
+				val upper[FLEN] <= -1;
163
+				F[rd] <= (upper<<32) | zext(res, FLEN);
164 164
 			}
165 165
 		}
166 166
 		FSGNJN.S {
@@ -169,9 +169,9 @@ InsructionSet RV32F extends RV32IBase{
169 169
 			val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000);
170 170
 			if(FLEN==32)
171 171
 				F[rd] <= res;
172
-			else {
173
-				val upper[FLEN] <= -1<<31;
174
-				F[rd] <= upper*2 | res;
172
+			else { // NaN boxing
173
+				val upper[FLEN] <= -1;
174
+				F[rd] <= (upper<<32) | zext(res, FLEN);
175 175
 			}
176 176
 		}
177 177
 		FSGNJX.S {
@@ -180,9 +180,9 @@ InsructionSet RV32F extends RV32IBase{
180 180
 			val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000);
181 181
 			if(FLEN==32)
182 182
 				F[rd] <= res;
183
-			else {
184
-				val upper[FLEN] <= -1<<31;
185
-				F[rd] <= upper*2 | res;
183
+			else { // NaN boxing
184
+				val upper[FLEN] <= -1;
185
+				F[rd] <= (upper<<32) | zext(res, FLEN);
186 186
 			}
187 187
 		}
188 188
 		FMIN.S  {
@@ -192,9 +192,9 @@ InsructionSet RV32F extends RV32IBase{
192 192
 			val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32));
193 193
 			if(FLEN==32)
194 194
 				F[rd] <= res;
195
-			else {
196
-				val upper[FLEN] <= -1<<31;
197
-				F[rd] <= upper*2 | res;
195
+			else { // NaN boxing
196
+				val upper[FLEN] <= -1;
197
+				F[rd] <= (upper<<32) | zext(res, FLEN);
198 198
 			}
199 199
 			val flags[32] <= fdispatch_fget_flags();
200 200
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
@@ -206,9 +206,9 @@ InsructionSet RV32F extends RV32IBase{
206 206
 			val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32));
207 207
 			if(FLEN==32)
208 208
 				F[rd] <= res;
209
-			else {
210
-				val upper[FLEN] <= -1<<31;
211
-				F[rd] <= upper*2 | res;
209
+			else { // NaN boxing
210
+				val upper[FLEN] <= -1;
211
+				F[rd] <= (upper<<32) | zext(res, FLEN);
212 212
 			}
213 213
 			val flags[32] <= fdispatch_fget_flags();
214 214
 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
@@ -259,9 +259,9 @@ InsructionSet RV32F extends RV32IBase{
259 259
 			val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8});
260 260
 			if(FLEN==32)
261 261
 				F[rd] <= res;
262
-			else {
263
-				val upper[FLEN] <= -1<<31;
264
-				F[rd] <= upper*2 | res;
262
+			else { // NaN boxing
263
+				val upper[FLEN] <= -1;
264
+				F[rd] <= (upper<<32) | zext(res, FLEN);
265 265
 			}
266 266
 		}
267 267
 		FCVT.S.WU {
@@ -270,9 +270,9 @@ InsructionSet RV32F extends RV32IBase{
270 270
 			val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8});
271 271
 			if(FLEN==32)
272 272
 				F[rd] <= res;
273
-			else {
274
-				val upper[FLEN] <= -1<<31;
275
-				F[rd] <= upper*2 | res;
273
+			else { // NaN boxing
274
+				val upper[FLEN] <= -1;
275
+				F[rd] <= (upper<<32) | zext(res, FLEN);
276 276
 			}
277 277
 		}
278 278
 		FMV.X.W {
@@ -285,9 +285,9 @@ InsructionSet RV32F extends RV32IBase{
285 285
 			args_disass:"f%rd$d, x%rs1$d";
286 286
 			if(FLEN==32)
287 287
 				F[rd] <= X[rs1];
288
-			else {
289
-				val upper[FLEN] <= -1<<31;
290
-				F[rd] <= upper*2 | X[rs1];
288
+			else { // NaN boxing
289
+				val upper[FLEN] <= -1;
290
+				F[rd] <= (upper<<32) | zext(X[rs1], FLEN);
291 291
 			}
292 292
 		}
293 293
 	}

+ 3
- 2
riscv/gen_input/minres_rv.core_desc View File

@@ -3,6 +3,7 @@ import "RV32M.core_desc"
3 3
 import "RV32A.core_desc"
4 4
 import "RV32C.core_desc"
5 5
 import "RV32F.core_desc"
6
+import "RV32D.core_desc"
6 7
 import "RV64IBase.core_desc"
7 8
 //import "RV64M.core_desc"
8 9
 import "RV64A.core_desc"
@@ -26,10 +27,10 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC {
26 27
     }
27 28
 }
28 29
 
29
-Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC {
30
+Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D {
30 31
     constants {
31 32
         XLEN:=32;
32
-        FLEN:=32;
33
+        FLEN:=64;
33 34
         XLEN2:=64;
34 35
         XLEN_BIT_MASK:=0x1f;
35 36
         PCLEN:=32;

+ 2
- 3
riscv/gen_input/templates/incl-CORENAME.h.gtl View File

@@ -56,6 +56,8 @@ struct traits<${coreDef.name.toLowerCase()}> {
56 56
     
57 57
     enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}};
58 58
 
59
+    constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0};
60
+
59 61
     enum reg_e {<%
60 62
      	allRegs.each { reg -> 
61 63
     		if( reg instanceof RegisterFile) {
@@ -99,9 +101,6 @@ struct traits<${coreDef.name.toLowerCase()}> {
99 101
     enum sreg_flag_e {FLAGS};
100 102
 
101 103
     enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}};
102
-
103
-	constexpr static bool has_fp_regs = ${allRegs.find {it.name=='FCSR'}!= null ?'true':'false'};
104
-    
105 104
 };
106 105
 
107 106
 struct ${coreDef.name.toLowerCase()}: public arch_if {

+ 2
- 2
riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl View File

@@ -50,7 +50,7 @@
50 50
 namespace iss {
51 51
 namespace vm {
52 52
 namespace fp_impl{
53
-void add_fp_functions_2_module(llvm::Module *mod);
53
+void add_fp_functions_2_module(llvm::Module *, unsigned);
54 54
 }
55 55
 }
56 56
 
@@ -89,7 +89,7 @@ protected:
89 89
 
90 90
     void setup_module(llvm::Module* m) override {
91 91
         super::setup_module(m);
92
-        vm::fp_impl::add_fp_functions_2_module(m);
92
+        vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
93 93
     }
94 94
 
95 95
     inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,

+ 37
- 38
riscv/incl/iss/arch/rv32gc.h View File

@@ -48,7 +48,9 @@ struct traits<rv32gc> {
48 48
 
49 49
 	constexpr static char const* const core_type = "RV32GC";
50 50
     
51
-    enum constants {XLEN=32, FLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095, FFLAG_MASK=31};
51
+    enum constants {XLEN=32, FLEN=64, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095, FFLAG_MASK=31};
52
+
53
+    constexpr static unsigned FP_REGS_SIZE = 64;
52 54
 
53 55
     enum reg_e {
54 56
         X0,
@@ -136,12 +138,12 @@ struct traits<rv32gc> {
136 138
     using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
137 139
 
138 140
     constexpr static unsigned reg_bit_width(unsigned r) {
139
-        constexpr std::array<const uint32_t, 71> RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}};
141
+        constexpr std::array<const uint32_t, 71> RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,64}};
140 142
         return RV32GC_reg_size[r];
141 143
     }
142 144
 
143 145
     constexpr static unsigned reg_byte_offset(unsigned r) {
144
-    	constexpr std::array<const uint32_t, 72> RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,288}};
146
+    	constexpr std::array<const uint32_t, 72> RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,416,424}};
145 147
         return RV32GC_reg_byte_offset[r];
146 148
     }
147 149
 
@@ -150,9 +152,6 @@ struct traits<rv32gc> {
150 152
     enum sreg_flag_e {FLAGS};
151 153
 
152 154
     enum mem_type_e {MEM, CSR, FENCE, RES};
153
-
154
-	constexpr static bool has_fp_regs = true;
155
-    
156 155
 };
157 156
 
158 157
 struct rv32gc: public arch_if {
@@ -227,38 +226,38 @@ protected:
227 226
         uint32_t X30 = 0;
228 227
         uint32_t X31 = 0;
229 228
         uint32_t PC = 0;
230
-        uint32_t F0 = 0;
231
-        uint32_t F1 = 0;
232
-        uint32_t F2 = 0;
233
-        uint32_t F3 = 0;
234
-        uint32_t F4 = 0;
235
-        uint32_t F5 = 0;
236
-        uint32_t F6 = 0;
237
-        uint32_t F7 = 0;
238
-        uint32_t F8 = 0;
239
-        uint32_t F9 = 0;
240
-        uint32_t F10 = 0;
241
-        uint32_t F11 = 0;
242
-        uint32_t F12 = 0;
243
-        uint32_t F13 = 0;
244
-        uint32_t F14 = 0;
245
-        uint32_t F15 = 0;
246
-        uint32_t F16 = 0;
247
-        uint32_t F17 = 0;
248
-        uint32_t F18 = 0;
249
-        uint32_t F19 = 0;
250
-        uint32_t F20 = 0;
251
-        uint32_t F21 = 0;
252
-        uint32_t F22 = 0;
253
-        uint32_t F23 = 0;
254
-        uint32_t F24 = 0;
255
-        uint32_t F25 = 0;
256
-        uint32_t F26 = 0;
257
-        uint32_t F27 = 0;
258
-        uint32_t F28 = 0;
259
-        uint32_t F29 = 0;
260
-        uint32_t F30 = 0;
261
-        uint32_t F31 = 0;
229
+        uint64_t F0 = 0;
230
+        uint64_t F1 = 0;
231
+        uint64_t F2 = 0;
232
+        uint64_t F3 = 0;
233
+        uint64_t F4 = 0;
234
+        uint64_t F5 = 0;
235
+        uint64_t F6 = 0;
236
+        uint64_t F7 = 0;
237
+        uint64_t F8 = 0;
238
+        uint64_t F9 = 0;
239
+        uint64_t F10 = 0;
240
+        uint64_t F11 = 0;
241
+        uint64_t F12 = 0;
242
+        uint64_t F13 = 0;
243
+        uint64_t F14 = 0;
244
+        uint64_t F15 = 0;
245
+        uint64_t F16 = 0;
246
+        uint64_t F17 = 0;
247
+        uint64_t F18 = 0;
248
+        uint64_t F19 = 0;
249
+        uint64_t F20 = 0;
250
+        uint64_t F21 = 0;
251
+        uint64_t F22 = 0;
252
+        uint64_t F23 = 0;
253
+        uint64_t F24 = 0;
254
+        uint64_t F25 = 0;
255
+        uint64_t F26 = 0;
256
+        uint64_t F27 = 0;
257
+        uint64_t F28 = 0;
258
+        uint64_t F29 = 0;
259
+        uint64_t F30 = 0;
260
+        uint64_t F31 = 0;
262 261
         uint32_t FCSR = 0;
263 262
         uint32_t NEXT_PC = 0;
264 263
         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0;

+ 2
- 3
riscv/incl/iss/arch/rv32imac.h View File

@@ -50,6 +50,8 @@ struct traits<rv32imac> {
50 50
     
51 51
     enum constants {XLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095};
52 52
 
53
+    constexpr static unsigned FP_REGS_SIZE = 0;
54
+
53 55
     enum reg_e {
54 56
         X0,
55 57
         X1,
@@ -117,9 +119,6 @@ struct traits<rv32imac> {
117 119
     enum sreg_flag_e {FLAGS};
118 120
 
119 121
     enum mem_type_e {MEM, CSR, FENCE, RES};
120
-
121
-	constexpr static bool has_fp_regs = false;
122
-    
123 122
 };
124 123
 
125 124
 struct rv32imac: public arch_if {

+ 2
- 3
riscv/incl/iss/arch/rv64ia.h View File

@@ -50,6 +50,8 @@ struct traits<rv64ia> {
50 50
     
51 51
     enum constants {XLEN=64, XLEN2=128, XLEN_BIT_MASK=63, PCLEN=64, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=2147746049, PGSIZE=4096, PGMASK=4095};
52 52
 
53
+    constexpr static unsigned FP_REGS_SIZE = 0;
54
+
53 55
     enum reg_e {
54 56
         X0,
55 57
         X1,
@@ -117,9 +119,6 @@ struct traits<rv64ia> {
117 119
     enum sreg_flag_e {FLAGS};
118 120
 
119 121
     enum mem_type_e {MEM, CSR, FENCE, RES};
120
-
121
-	constexpr static bool has_fp_regs = false;
122
-    
123 122
 };
124 123
 
125 124
 struct rv64ia: public arch_if {

+ 183
- 15
riscv/src/internal/fp_functions.cpp View File

@@ -41,6 +41,8 @@ extern "C" {
41 41
 #include "specialize.h"
42 42
 }
43 43
 
44
+#include <limits>
45
+
44 46
 namespace iss {
45 47
 namespace vm {
46 48
 namespace fp_impl {
@@ -68,18 +70,34 @@ using namespace std;
68 70
 
69 71
 using namespace llvm;
70 72
 
71
-void add_fp_functions_2_module(Module *mod) {
72
-    FDECL(fget_flags, INT_TYPE(32));
73
-    FDECL(fadd_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
74
-    FDECL(fsub_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
75
-    FDECL(fmul_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
76
-    FDECL(fdiv_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
77
-    FDECL(fsqrt_s,    INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
78
-    FDECL(fcmp_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
79
-    FDECL(fcvt_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
80
-    FDECL(fmadd_s,    INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
81
-    FDECL(fsel_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
82
-    FDECL(fclass_s,   INT_TYPE(32), INT_TYPE(32));
73
+void add_fp_functions_2_module(Module *mod, uint32_t flen) {
74
+    if(flen){
75
+        FDECL(fget_flags, INT_TYPE(32));
76
+        FDECL(fadd_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
77
+        FDECL(fsub_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
78
+        FDECL(fmul_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
79
+        FDECL(fdiv_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
80
+        FDECL(fsqrt_s,    INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
81
+        FDECL(fcmp_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
82
+        FDECL(fcvt_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
83
+        FDECL(fmadd_s,    INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
84
+        FDECL(fsel_s,     INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
85
+        FDECL(fclass_s,   INT_TYPE(32), INT_TYPE(32));
86
+        if(flen>32){
87
+            FDECL(fconv_d2f,  INT_TYPE(32), INT_TYPE(64), INT_TYPE(8));
88
+            FDECL(fconv_f2d,  INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
89
+            FDECL(fadd_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
90
+            FDECL(fsub_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
91
+            FDECL(fmul_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
92
+            FDECL(fdiv_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
93
+            FDECL(fsqrt_d,    INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
94
+            FDECL(fcmp_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32));
95
+            FDECL(fcvt_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
96
+            FDECL(fmadd_d,    INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
97
+            FDECL(fsel_d,     INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32));
98
+            FDECL(fclass_d,   INT_TYPE(64), INT_TYPE(64));
99
+        }
100
+    }
83 101
 }
84 102
 
85 103
 }
@@ -202,14 +220,14 @@ uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mod
202 220
     softfloat_roundingMode=rmm_map[mode&0x7];
203 221
     softfloat_exceptionFlags=0;
204 222
     float32_t res = softfloat_mulAddF32(v1, v2, v3, op&0x1);
205
-    if(op>1) res.v ^= 0x80000000UL;
223
+    if(op>1) res.v ^= 1ULL<<31;
206 224
     return res.v;
207 225
 }
208 226
 
209 227
 uint32_t fsel_s(uint32_t v1, uint32_t v2, uint32_t op) {
210 228
     softfloat_exceptionFlags = 0;
211
-    bool v1_nan = (v1 & defaultNaNF32UI) == quiet_nan32;
212
-    bool v2_nan = (v2 & defaultNaNF32UI) == quiet_nan32;
229
+    bool v1_nan = (v1 & defaultNaNF32UI) == defaultNaNF32UI;
230
+    bool v2_nan = (v2 & defaultNaNF32UI) == defaultNaNF32UI;
213 231
     bool v1_snan = softfloat_isSigNaNF32UI(v1);
214 232
     bool v2_snan = softfloat_isSigNaNF32UI(v2);
215 233
     if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid);
@@ -257,6 +275,156 @@ uint32_t fclass_s( uint32_t v1 ){
257 275
         ( isNaN && !isSNaN )                       << 9;
258 276
 }
259 277
 
278
+uint32_t fconv_d2f(uint64_t v1, uint8_t mode){
279
+    softfloat_roundingMode=rmm_map[mode&0x7];
280
+    bool nan = (v1 & defaultNaNF64UI)==defaultNaNF64UI;
281
+    if(nan){
282
+        return defaultNaNF32UI;
283
+    } else {
284
+        float32_t res = f64_to_f32(float64_t{v1});
285
+        return res.v;
286
+    }
287
+}
288
+
289
+uint64_t fconv_f2d(uint32_t v1, uint8_t mode){
290
+    bool nan = (v1 & defaultNaNF32UI)==defaultNaNF32UI;
291
+    if(nan){
292
+        return defaultNaNF64UI;
293
+    } else {
294
+        softfloat_roundingMode=rmm_map[mode&0x7];
295
+        float64_t res = f32_to_f64(float32_t{v1});
296
+        return res.v;
297
+    }
298
+}
299
+
300
+uint64_t fadd_d(uint64_t v1, uint64_t v2, uint8_t mode) {
301
+    bool nan = (v1&defaultNaNF32UI)==quiet_nan32;
302
+    bool snan = softfloat_isSigNaNF32UI(v1);
303
+   float64_t v1f{v1},v2f{v2};
304
+    softfloat_roundingMode=rmm_map[mode&0x7];
305
+    softfloat_exceptionFlags=0;
306
+    float64_t r =f64_add(v1f, v2f);
307
+    return r.v;
308
+}
309
+
310
+uint64_t fsub_d(uint64_t v1, uint64_t v2, uint8_t mode) {
311
+    float64_t v1f{v1},v2f{v2};
312
+    softfloat_roundingMode=rmm_map[mode&0x7];
313
+    softfloat_exceptionFlags=0;
314
+    float64_t r=f64_sub(v1f, v2f);
315
+    return r.v;
316
+}
317
+
318
+uint64_t fmul_d(uint64_t v1, uint64_t v2, uint8_t mode) {
319
+    float64_t v1f{v1},v2f{v2};
320
+    softfloat_roundingMode=rmm_map[mode&0x7];
321
+    softfloat_exceptionFlags=0;
322
+    float64_t r=f64_mul(v1f, v2f);
323
+    return r.v;
324
+}
325
+
326
+uint64_t fdiv_d(uint64_t v1, uint64_t v2, uint8_t mode) {
327
+    float64_t v1f{v1},v2f{v2};
328
+    softfloat_roundingMode=rmm_map[mode&0x7];
329
+    softfloat_exceptionFlags=0;
330
+    float64_t r=f64_div(v1f, v2f);
331
+    return r.v;
332
+}
333
+
334
+uint64_t fsqrt_d(uint64_t v1, uint8_t mode) {
335
+    float64_t v1f{v1};
336
+    softfloat_roundingMode=rmm_map[mode&0x7];
337
+    softfloat_exceptionFlags=0;
338
+    float64_t r=f64_sqrt(v1f);
339
+    return r.v;
340
+}
341
+
342
+uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) {
343
+    float64_t v1f{v1},v2f{v2};
344
+    softfloat_exceptionFlags=0;
345
+    bool nan = (v1&defaultNaNF64UI)==quiet_nan32 || (v2&defaultNaNF64UI)==quiet_nan32;
346
+    bool snan = softfloat_isSigNaNF64UI(v1) || softfloat_isSigNaNF64UI(v2);
347
+    switch(op){
348
+    case 0:
349
+        if(nan | snan){
350
+            if(snan) softfloat_raiseFlags(softfloat_flag_invalid);
351
+            return 0;
352
+        } else
353
+            return f64_eq(v1f,v2f )?1:0;
354
+    case 1:
355
+        if(nan | snan){
356
+            softfloat_raiseFlags(softfloat_flag_invalid);
357
+            return 0;
358
+        } else
359
+            return f64_le(v1f,v2f )?1:0;
360
+    case 2:
361
+        if(nan | snan){
362
+            softfloat_raiseFlags(softfloat_flag_invalid);
363
+            return 0;
364
+        } else
365
+            return f64_lt(v1f,v2f )?1:0;
366
+    default:
367
+        break;
368
+    }
369
+    return -1;
370
+}
371
+
372
+uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) {
373
+    float64_t v1f{v1};
374
+    softfloat_exceptionFlags=0;
375
+    float64_t r;
376
+    int32_t res;
377
+    switch(op){
378
+    case 0: //w->s, fp to int32
379
+        res = f64_to_i64(v1f,rmm_map[mode&0x7],true);
380
+        return (uint64_t)res;
381
+    case 1: //wu->s
382
+        return f64_to_ui64(v1f,rmm_map[mode&0x7],true);
383
+    case 2: //s->w
384
+        r=i64_to_f64(v1);
385
+        return r.v;
386
+    case 3: //s->wu
387
+        r=ui64_to_f64(v1);
388
+        return r.v;
389
+    }
390
+    return 0;
391
+}
392
+
393
+uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode) {
394
+    // op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
395
+    softfloat_roundingMode=rmm_map[mode&0x7];
396
+    softfloat_exceptionFlags=0;
397
+    float64_t res = softfloat_mulAddF64(v1, v2, v3, op&0x1);
398
+    if(op>1) res.v ^= 1ULL<<63;
399
+    return res.v;
400
+}
401
+
402
+uint64_t fsel_d(uint64_t v1, uint64_t v2, uint32_t op) {
403
+    softfloat_exceptionFlags = 0;
404
+    bool v1_nan = (v1 & defaultNaNF64UI) == defaultNaNF64UI;
405
+    bool v2_nan = (v2 & defaultNaNF64UI) == defaultNaNF64UI;
406
+    bool v1_snan = softfloat_isSigNaNF64UI(v1);
407
+    bool v2_snan = softfloat_isSigNaNF64UI(v2);
408
+    if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid);
409
+    if (v1_nan || v1_snan)
410
+        return (v2_nan || v2_snan) ? defaultNaNF64UI : v2;
411
+    else
412
+        if (v2_nan || v2_snan)
413
+            return v1;
414
+        else {
415
+            if ((v1 & std::numeric_limits<int64_t>::max()) == 0 && (v2 & std::numeric_limits<int64_t>::max()) == 0) {
416
+                return op == 0 ?
417
+                        ((v1 & std::numeric_limits<int64_t>::min()) ? v1 : v2) :
418
+                        ((v1 & std::numeric_limits<int64_t>::min()) ? v2 : v1);
419
+            } else {
420
+                float64_t v1f{ v1 }, v2f{ v2 };
421
+                return op == 0 ?
422
+                        (f64_lt(v1f, v2f) ? v1 : v2) :
423
+                        (f64_lt(v1f, v2f) ? v2 : v1);
424
+            }
425
+        }
426
+}
427
+
260 428
 uint64_t fclass_d(uint64_t v1  ){
261 429
 
262 430
     float64_t a{v1};

+ 1848
- 135
riscv/src/internal/vm_rv32gc.cpp
File diff suppressed because it is too large
View File


+ 2
- 2
riscv/src/internal/vm_rv32imac.cpp View File

@@ -50,7 +50,7 @@
50 50
 namespace iss {
51 51
 namespace vm {
52 52
 namespace fp_impl{
53
-void add_fp_functions_2_module(llvm::Module *mod);
53
+void add_fp_functions_2_module(llvm::Module *, unsigned);
54 54
 }
55 55
 }
56 56
 
@@ -89,7 +89,7 @@ protected:
89 89
 
90 90
     void setup_module(llvm::Module* m) override {
91 91
         super::setup_module(m);
92
-        vm::fp_impl::add_fp_functions_2_module(m);
92
+        vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
93 93
     }
94 94
 
95 95
     inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,

+ 2
- 2
riscv/src/internal/vm_rv64ia.cpp View File

@@ -50,7 +50,7 @@
50 50
 namespace iss {
51 51
 namespace vm {
52 52
 namespace fp_impl{
53
-void add_fp_functions_2_module(llvm::Module *mod);
53
+void add_fp_functions_2_module(llvm::Module *, unsigned);
54 54
 }
55 55
 }
56 56
 
@@ -89,7 +89,7 @@ protected:
89 89
 
90 90
     void setup_module(llvm::Module* m) override {
91 91
         super::setup_module(m);
92
-        vm::fp_impl::add_fp_functions_2_module(m);
92
+        vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
93 93
     }
94 94
 
95 95
     inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,

+ 12
- 12
softfloat/source/RISCV/specialize.h View File

@@ -51,23 +51,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 51
 | The values to return on conversions to 32-bit integer formats that raise an
52 52
 | invalid exception.
53 53
 *----------------------------------------------------------------------------*/
54
-#define ui32_fromPosOverflow 0xFFFFFFFF
55
-#define ui32_fromNegOverflow 0x0
56
-#define ui32_fromNaN         0xFFFFFFFF
57
-#define i32_fromPosOverflow  (0x7FFFFFFF)
58
-#define i32_fromNegOverflow  (-0x7FFFFFFF - 1)
59
-#define i32_fromNaN          (0x7FFFFFFF)
54
+#define ui32_fromPosOverflow UINT32_C(0xFFFFFFFF)
55
+#define ui32_fromNegOverflow UINT32_C(0x0)
56
+#define ui32_fromNaN         UINT32_C(0xFFFFFFFF)
57
+#define i32_fromPosOverflow   INT64_C(0x7FFFFFFF)
58
+#define i32_fromNegOverflow  (-INT64_C(0x7FFFFFFF)-1)
59
+#define i32_fromNaN           INT64_C(0x7FFFFFFF)
60 60
 
61 61
 /*----------------------------------------------------------------------------
62 62
 | The values to return on conversions to 64-bit integer formats that raise an
63 63
 | invalid exception.
64 64
 *----------------------------------------------------------------------------*/
65 65
 #define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
66
-#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
67
-#define ui64_fromNaN         UINT64_C( 0xFFFFFFFFFFFFFFFF )
68
-#define i64_fromPosOverflow  (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
69
-#define i64_fromNegOverflow  (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
70
-#define i64_fromNaN          (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
66
+#define ui64_fromNegOverflow UINT64_C( 0x0 )
67
+#define ui64_fromNaN         UINT64_C( 0xFFFFFFFFFFFFFFFF)
68
+#define i64_fromPosOverflow   INT64_C( 0x7FFFFFFFFFFFFFFF)
69
+#define i64_fromNegOverflow  (-INT64_C( 0x7FFFFFFFFFFFFFFF)-1)
70
+#define i64_fromNaN           INT64_C( 0x7FFFFFFFFFFFFFFF)
71 71
 
72 72
 /*----------------------------------------------------------------------------
73 73
 | "Common NaN" structure, used to transfer NaN representations from one format
@@ -155,7 +155,7 @@ uint_fast32_t
155 155
 /*----------------------------------------------------------------------------
156 156
 | The bit pattern for a default generated 64-bit floating-point NaN.
157 157
 *----------------------------------------------------------------------------*/
158
-#define defaultNaNF64UI UINT64_C( 0xFFF8000000000000 )
158
+#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 )
159 159
 
160 160
 /*----------------------------------------------------------------------------
161 161
 | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a