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
1229 return;1229 return;
1230 1230
1231 /* F/D extension */1231 /* 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;
1232 case TOK_ASM_fsgnj_d:1256 case TOK_ASM_fsgnj_d:
1233 asm_emit_f(token, 0x53 | (4 << 27) | (1 << 25) | (0 << 12), ops, ops + 1, ops + 2);1257 asm_emit_f(token, 0x53 | (4 << 27) | (1 << 25) | (0 << 12), ops, ops + 1, ops + 2);
1234 return;1258 return;
@@ -1549,6 +1573,14 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 314 unmodified lines
1549 case TOK_ASM_csrrw:1573 case TOK_ASM_csrrw:
1550 case TOK_ASM_csrrwi:1574 case TOK_ASM_csrrwi:
1551 /* F/D extension */1575 /* 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:
1552 case TOK_ASM_fsgnj_d:1584 case TOK_ASM_fsgnj_d:
1553 case TOK_ASM_fsgnj_s:1585 case TOK_ASM_fsgnj_s:
1554 case TOK_ASM_fmax_s:1586 case TOK_ASM_fmax_s:
riscv64-tok.h+8−0
@@ -270,6 +270,14 @@ · 269 unmodified lines
270 /* enough implemented for musl */270 /* enough implemented for musl */
271 DEF_ASM_WITH_SUFFIX(fsgnj, s)271 DEF_ASM_WITH_SUFFIX(fsgnj, s)
272 DEF_ASM_WITH_SUFFIX(fsgnj, d)272 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)
273 DEF_ASM_WITH_SUFFIX(fmadd, s)281 DEF_ASM_WITH_SUFFIX(fmadd, s)
274 DEF_ASM_WITH_SUFFIX(fmadd, d)282 DEF_ASM_WITH_SUFFIX(fmadd, d)
275 DEF_ASM_WITH_SUFFIX(fmax, s)283 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
8float 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
15float 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
22float 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
29float 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
36double 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
43double 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
50double 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
57double 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
64int 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
107int 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 @@
1PASS

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