Skip to content

Commit 76e0fa9

Browse files
BrunoASMauricioclaziss
authored andcommitted
Feature: Add FPUv2 instructions
Decoder: Renamed FPUv2 instruction mnemonics There are instructions for FPU that have the same mnemonic and base functionality in ARCv2 and ARCv3 but differ in operand amount (i.e. FDMADD) This requires internal renaming of mnemonics as the semantic function mapping is shared between all versions. Structure: Separated base FPU from ARCv3 FPU FPU for ARCv2 shares some functionality with ARCv3, so it makes sense to create a shared fpu.c/h for that. TCG: Added semantic function support for ARCv2 FPU instructions Signed-off-by: Bruno Mauricio <[email protected]>
1 parent e03e6a4 commit 76e0fa9

18 files changed

+1331
-287
lines changed

target/arc/cpu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static void arc_cpu_reset(DeviceState *dev)
123123

124124
/* FPU init */
125125
/* TODO: Make init_fpu parameters based on options. */
126-
init_fpu(env, true, true, true);
126+
init_fpu(cpu, true, true, true);
127127

128128
arc_resetTIMER(cpu);
129129
arc_resetIRQ(cpu);

target/arc/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ struct ArchCPU {
381381
uint32_t norm_build; /* Normalize instruction configuration register. */
382382
uint32_t barrel_build; /* Barrel shifter configuration register. */
383383
uint32_t isa_config; /* Instruction Set Configuration Register. */
384+
uint32_t fpu_build_config; /* FPU build register */
384385

385386
uint8_t core_id; /* Core id holder. */
386387

target/arc/decoder_fragments/arc-tbl.h

Lines changed: 80 additions & 80 deletions
Large diffs are not rendered by default.

target/arc/fpu-helper-v2.c

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
/*
2+
* QEMU ARC CPU
3+
*
4+
* Copyright (c) 2023 Synopsys Inc.
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, see
18+
* http://www.gnu.org/licenses/lgpl-2.1.html
19+
*/
20+
21+
#include "qemu/osdep.h"
22+
#include "cpu.h"
23+
#include "exec/exec-all.h"
24+
#include "exec/helper-proto.h"
25+
#include "fpu/softfloat.h"
26+
#include "fpu.h"
27+
#include "qemu/log.h"
28+
29+
enum arc_fcvt32 {
30+
ARC_FCVT32_FS2INT = 0b000011,
31+
ARC_FCVT32_FS2INT_RZ = 0b001011,
32+
ARC_FCVT32_FINT2S = 0b000010,
33+
ARC_FCVT32_FS2UINT = 0b000001,
34+
ARC_FCVT32_FS2UINT_RZ = 0b001001,
35+
ARC_FCVT32_FUINT2S = 0b000000,
36+
ARC_FCVT32_FH2S = 0b010101,
37+
ARC_FCVT32_FS2H = 0b010100
38+
};
39+
40+
enum arc_fcvt32_64 {
41+
ARC_FCVT32_64_FS2L = 0b000011,
42+
ARC_FCVT32_64_FS2L_RZ = 0b001011,
43+
ARC_FCVT32_64_FS2UL = 0b000001,
44+
ARC_FCVT32_64_FS2UL_RZ = 0b001001,
45+
ARC_FCVT32_64_FINT2D = 0b000010,
46+
ARC_FCVT32_64_FUINT2D = 0b000000,
47+
ARC_FCVT32_64_FS2D = 0b000100
48+
};
49+
50+
enum arc_fcvt64 {
51+
ARC_FCVT64_FD2L = 0b000011,
52+
ARC_FCVT64_FD2L_RZ = 0b001011,
53+
ARC_FCVT64_FL2D = 0b000010,
54+
ARC_FCVT64_FD2UL = 0b000001,
55+
ARC_FCVT64_FD2UL_RZ = 0b001001,
56+
ARC_FCVT64_FUL2D = 0b000000
57+
};
58+
59+
enum arc_fcvt64_32 {
60+
ARC_FCVT64_32_FD2INT = 0b000011,
61+
ARC_FCVT64_32_FD2INT_RZ = 0b001011,
62+
ARC_FCVT64_32_FD2UINT = 0b000001,
63+
ARC_FCVT64_32_FD2UINT_RZ = 0b001001,
64+
ARC_FCVT64_32_FL2S = 0b000010,
65+
ARC_FCVT64_32_FUL2S = 0b000000,
66+
ARC_FCVT64_32_FD2S = 0b000100
67+
};
68+
69+
/* Soft fpu helper of type floatSIZE_operation */
70+
#define FLOAT_INST3_HELPERS(NAME, HELPER, SIZE) \
71+
uint32_t helper_##NAME(CPUARCState *env, uint32_t frs1, uint32_t frs2) \
72+
{ \
73+
uint32_t ret = float##SIZE##_##HELPER(frs1, frs2, &env->fp_status); \
74+
check_fpu_raise_exception(env); \
75+
return ret; \
76+
}
77+
78+
FLOAT_INST3_HELPERS(fsadd32, add, 32)
79+
FLOAT_INST3_HELPERS(fssub32, sub, 32)
80+
FLOAT_INST3_HELPERS(fsmul32, mul, 32)
81+
FLOAT_INST3_HELPERS(fsdiv32, div, 32)
82+
FLOAT_INST3_HELPERS(fsmin32, minnum, 32)
83+
FLOAT_INST3_HELPERS(fsmax32, maxnum, 32)
84+
85+
/* Helper for the 32 bit Single precision floating point square root */
86+
uint32_t helper_fssqrt32(CPUARCState *env, uint32_t src) {
87+
uint32_t ret = float32_sqrt(src, &env->fp_status);
88+
check_fpu_raise_exception(env);
89+
return ret;
90+
}
91+
92+
/* Helper for the 32 bit - 32 bit conversions */
93+
uint32_t helper_fcvt32(CPUARCState *env, uint32_t src, uint32_t operation) {
94+
uint32_t ret = 0;
95+
96+
switch (operation) {
97+
98+
case ARC_FCVT32_FS2INT:
99+
ret = float32_to_int32(src, &env->fp_status);
100+
break;
101+
102+
case ARC_FCVT32_FS2INT_RZ:
103+
ret = float32_to_int32_round_to_zero(src, &env->fp_status);
104+
break;
105+
106+
case ARC_FCVT32_FINT2S:
107+
ret = int32_to_float32(src, &env->fp_status);
108+
break;
109+
110+
case ARC_FCVT32_FS2UINT:
111+
ret = float32_to_uint32(src, &env->fp_status);
112+
break;
113+
114+
case ARC_FCVT32_FS2UINT_RZ:
115+
ret = float32_to_uint32_round_to_zero(src, &env->fp_status);
116+
break;
117+
118+
case ARC_FCVT32_FUINT2S:
119+
ret = uint32_to_float32(src, &env->fp_status);
120+
break;
121+
122+
case ARC_FCVT32_FH2S:
123+
error_report("Half-precision (FH2S) not implemented for arcv2!");
124+
exit(EXIT_FAILURE);
125+
break;
126+
127+
case ARC_FCVT32_FS2H:
128+
error_report("Half-precision (FS2H) not implemented for arcv2!");
129+
exit(EXIT_FAILURE);
130+
break;
131+
132+
default:
133+
error_report("FCVT32 operation not supported!");
134+
exit(EXIT_FAILURE);
135+
}
136+
137+
check_fpu_raise_exception(env);
138+
139+
return ret;
140+
}
141+
142+
/* Helper for the 32 bit - 64 bit conversions */
143+
uint64_t helper_fcvt32_64(CPUARCState *env, uint32_t src, uint32_t operation) {
144+
uint64_t ret = 0;
145+
146+
switch (operation) {
147+
148+
case ARC_FCVT32_64_FS2L:
149+
ret = float32_to_int64(src, &env->fp_status);
150+
break;
151+
152+
case ARC_FCVT32_64_FS2L_RZ:
153+
ret = float32_to_int64_round_to_zero(src, &env->fp_status);
154+
break;
155+
156+
case ARC_FCVT32_64_FS2UL:
157+
ret = float32_to_uint64(src, &env->fp_status);
158+
break;
159+
160+
case ARC_FCVT32_64_FS2UL_RZ:
161+
ret = float32_to_uint64_round_to_zero(src, &env->fp_status);
162+
break;
163+
164+
case ARC_FCVT32_64_FINT2D:
165+
ret = int32_to_float64(src, &env->fp_status);
166+
break;
167+
168+
case ARC_FCVT32_64_FUINT2D:
169+
ret = uint32_to_float64(src, &env->fp_status);
170+
break;
171+
172+
case ARC_FCVT32_64_FS2D:
173+
ret = float32_to_float64(src, &env->fp_status);
174+
break;
175+
176+
default:
177+
178+
error_report("FCVT32_64 operation not supported!");
179+
exit(EXIT_FAILURE);
180+
}
181+
182+
check_fpu_raise_exception(env);
183+
184+
return ret;
185+
}
186+
187+
/* Helper for the 64 bit - 64 bit conversions */
188+
uint64_t helper_fcvt64(CPUARCState *env, uint64_t src, uint32_t operation) {
189+
uint64_t ret = 0;
190+
191+
switch (operation) {
192+
193+
case ARC_FCVT64_FD2L:
194+
ret = float64_to_int64(src, &env->fp_status);
195+
break;
196+
197+
case ARC_FCVT64_FD2L_RZ:
198+
ret = float64_to_int64_round_to_zero(src, &env->fp_status);
199+
break;
200+
201+
case ARC_FCVT64_FL2D:
202+
ret = int64_to_float64(src, &env->fp_status);
203+
break;
204+
205+
case ARC_FCVT64_FD2UL:
206+
ret = float64_to_uint64(src, &env->fp_status);
207+
break;
208+
209+
case ARC_FCVT64_FD2UL_RZ:
210+
ret = float64_to_uint64_round_to_zero(src, &env->fp_status);
211+
break;
212+
213+
case ARC_FCVT64_FUL2D:
214+
ret = uint64_to_float64(src, &env->fp_status);
215+
break;
216+
217+
default:
218+
error_report("FCVT64 operation not supported!");
219+
exit(EXIT_FAILURE);
220+
}
221+
222+
check_fpu_raise_exception(env);
223+
224+
return ret;
225+
}
226+
227+
/* Helper for the 64 bit - 32 bit conversions */
228+
uint32_t helper_fcvt64_32(CPUARCState *env, uint64_t src, uint32_t operation) {
229+
uint32_t ret = 0;
230+
231+
switch (operation) {
232+
233+
case ARC_FCVT64_32_FD2INT:
234+
ret = float64_to_int32(src, &env->fp_status);
235+
break;
236+
237+
case ARC_FCVT64_32_FD2INT_RZ:
238+
ret = float64_to_int32_round_to_zero(src, &env->fp_status);
239+
break;
240+
241+
case ARC_FCVT64_32_FD2UINT:
242+
ret = float64_to_uint32(src, &env->fp_status);
243+
break;
244+
245+
case ARC_FCVT64_32_FD2UINT_RZ:
246+
ret = float64_to_uint32_round_to_zero(src, &env->fp_status);
247+
break;
248+
249+
case ARC_FCVT64_32_FL2S:
250+
ret = int64_to_float32(src, &env->fp_status);
251+
break;
252+
253+
case ARC_FCVT64_32_FUL2S:
254+
ret = uint64_to_float32(src, &env->fp_status);
255+
break;
256+
257+
case ARC_FCVT64_32_FD2S:
258+
ret = float64_to_float32(src, &env->fp_status);
259+
break;
260+
261+
default:
262+
error_report("FCVT64_32 operation not supported!");
263+
exit(EXIT_FAILURE);
264+
}
265+
266+
check_fpu_raise_exception(env);
267+
268+
return ret;
269+
}
270+

0 commit comments

Comments
 (0)