History

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.

Meng Zhuo committed 6 months ago

Commit 3935c3b1 parent 273978b4 files · +153 −0Browse files

Unified · Split

4 files
  1. riscv64-asm.c +32 −0
  2. riscv64-tok.h +8 −0
  3. tests/tests2/143_riscv_asm_farith.c +112 −0
  4. tests/tests2/143_riscv_asm_farith.expect +1 −0
riscv64-asm.c+32−0
@@ -1229,6 +1229,30 @@ static void asm_ternary_opcode(TCCState *s1, int token) · 1228 unmodified lines
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) · 314 unmodified lines
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+8−0
@@ -270,6 +270,14 @@ · 269 unmodified lines
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)
tests/tests2/143_riscv_asm_farith.c+112−0
@@ -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
tests/tests2/143_riscv_asm_farith.expect+1−0
@@ -0,0 +1 @@
1+PASS

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t