Skip to content

Commit 3935c3b

Browse files
committed
riscv64-asm: add basic F/D extension instructions (fadd/fsub/fmul/fdiv)
Adds the 8 most essential floating-point arithmetic instructions: fadd.s/d, fsub.s/d, fmul.s/d, fdiv.s/d, for both single and double precision. These complement the existing fsgnj/fmax/fmin/fsqrt set. Comparison (feq/flt/fle) and conversion (fcvt) instructions remain as future work.
1 parent 273978b commit 3935c3b

4 files changed

Lines changed: 153 additions & 0 deletions

File tree

riscv64-asm.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,30 @@ static void asm_ternary_opcode(TCCState *s1, int token)
12291229
return;
12301230

12311231
/* F/D extension */
1232+
case TOK_ASM_fadd_d:
1233+
asm_emit_f(token, 0x53 | (0 << 27) | (1 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1234+
return;
1235+
case TOK_ASM_fadd_s:
1236+
asm_emit_f(token, 0x53 | (0 << 27) | (0 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1237+
return;
1238+
case TOK_ASM_fsub_d:
1239+
asm_emit_f(token, 0x53 | (1 << 27) | (1 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1240+
return;
1241+
case TOK_ASM_fsub_s:
1242+
asm_emit_f(token, 0x53 | (1 << 27) | (0 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1243+
return;
1244+
case TOK_ASM_fmul_d:
1245+
asm_emit_f(token, 0x53 | (2 << 27) | (1 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1246+
return;
1247+
case TOK_ASM_fmul_s:
1248+
asm_emit_f(token, 0x53 | (2 << 27) | (0 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1249+
return;
1250+
case TOK_ASM_fdiv_d:
1251+
asm_emit_f(token, 0x53 | (3 << 27) | (1 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1252+
return;
1253+
case TOK_ASM_fdiv_s:
1254+
asm_emit_f(token, 0x53 | (3 << 27) | (0 << 25) | (7 << 12), ops, ops + 1, ops + 2);
1255+
return;
12321256
case TOK_ASM_fsgnj_d:
12331257
asm_emit_f(token, 0x53 | (4 << 27) | (1 << 25) | (0 << 12), ops, ops + 1, ops + 2);
12341258
return;
@@ -1549,6 +1573,14 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
15491573
case TOK_ASM_csrrw:
15501574
case TOK_ASM_csrrwi:
15511575
/* F/D extension */
1576+
case TOK_ASM_fadd_s:
1577+
case TOK_ASM_fadd_d:
1578+
case TOK_ASM_fsub_s:
1579+
case TOK_ASM_fsub_d:
1580+
case TOK_ASM_fmul_s:
1581+
case TOK_ASM_fmul_d:
1582+
case TOK_ASM_fdiv_s:
1583+
case TOK_ASM_fdiv_d:
15521584
case TOK_ASM_fsgnj_d:
15531585
case TOK_ASM_fsgnj_s:
15541586
case TOK_ASM_fmax_s:

riscv64-tok.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@
270270
/* enough implemented for musl */
271271
DEF_ASM_WITH_SUFFIX(fsgnj, s)
272272
DEF_ASM_WITH_SUFFIX(fsgnj, d)
273+
DEF_ASM_WITH_SUFFIX(fadd, s)
274+
DEF_ASM_WITH_SUFFIX(fadd, d)
275+
DEF_ASM_WITH_SUFFIX(fsub, s)
276+
DEF_ASM_WITH_SUFFIX(fsub, d)
277+
DEF_ASM_WITH_SUFFIX(fmul, s)
278+
DEF_ASM_WITH_SUFFIX(fmul, d)
279+
DEF_ASM_WITH_SUFFIX(fdiv, s)
280+
DEF_ASM_WITH_SUFFIX(fdiv, d)
273281
DEF_ASM_WITH_SUFFIX(fmadd, s)
274282
DEF_ASM_WITH_SUFFIX(fmadd, d)
275283
DEF_ASM_WITH_SUFFIX(fmax, s)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include <stdio.h>
2+
3+
/* P1.3: riscv64 F/D extension arithmetic instructions.
4+
Tests fadd/fsub/fmul/fdiv for both single and double precision. */
5+
6+
#ifdef __riscv
7+
8+
float test_fadd_s(float a, float b)
9+
{
10+
float r;
11+
asm("fadd.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
12+
return r;
13+
}
14+
15+
float test_fsub_s(float a, float b)
16+
{
17+
float r;
18+
asm("fsub.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
19+
return r;
20+
}
21+
22+
float test_fmul_s(float a, float b)
23+
{
24+
float r;
25+
asm("fmul.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
26+
return r;
27+
}
28+
29+
float test_fdiv_s(float a, float b)
30+
{
31+
float r;
32+
asm("fdiv.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
33+
return r;
34+
}
35+
36+
double test_fadd_d(double a, double b)
37+
{
38+
double r;
39+
asm("fadd.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
40+
return r;
41+
}
42+
43+
double test_fsub_d(double a, double b)
44+
{
45+
double r;
46+
asm("fsub.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
47+
return r;
48+
}
49+
50+
double test_fmul_d(double a, double b)
51+
{
52+
double r;
53+
asm("fmul.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
54+
return r;
55+
}
56+
57+
double test_fdiv_d(double a, double b)
58+
{
59+
double r;
60+
asm("fdiv.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
61+
return r;
62+
}
63+
64+
int main(void)
65+
{
66+
int ok = 1;
67+
68+
if (test_fadd_s(1.5f, 2.5f) != 4.0f) {
69+
printf("FAIL: fadd.s\n");
70+
ok = 0;
71+
}
72+
if (test_fsub_s(5.0f, 2.0f) != 3.0f) {
73+
printf("FAIL: fsub.s\n");
74+
ok = 0;
75+
}
76+
if (test_fmul_s(3.0f, 4.0f) != 12.0f) {
77+
printf("FAIL: fmul.s\n");
78+
ok = 0;
79+
}
80+
if (test_fdiv_s(12.0f, 4.0f) != 3.0f) {
81+
printf("FAIL: fdiv.s\n");
82+
ok = 0;
83+
}
84+
85+
if (test_fadd_d(1.5, 2.5) != 4.0) {
86+
printf("FAIL: fadd.d\n");
87+
ok = 0;
88+
}
89+
if (test_fsub_d(5.0, 2.0) != 3.0) {
90+
printf("FAIL: fsub.d\n");
91+
ok = 0;
92+
}
93+
if (test_fmul_d(3.0, 4.0) != 12.0) {
94+
printf("FAIL: fmul.d\n");
95+
ok = 0;
96+
}
97+
if (test_fdiv_d(12.0, 4.0) != 3.0) {
98+
printf("FAIL: fdiv.d\n");
99+
ok = 0;
100+
}
101+
102+
printf("%s\n", ok ? "PASS" : "FAIL");
103+
return ok ? 0 : 1;
104+
}
105+
106+
#else
107+
int main(void)
108+
{
109+
printf("SKIP\n");
110+
return 0;
111+
}
112+
#endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PASS

0 commit comments

Comments
 (0)