Skip to content

Commit aa890fd

Browse files
committed
feat(riscv): add dobule-precision floating point conversion instructions
1 parent e695e55 commit aa890fd

4 files changed

Lines changed: 126 additions & 10 deletions

File tree

test/integration/doubles-mixed.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %config-gen-path/config-gen.rb --march rv64imfd \
2+
// RUN: --template-dir %config-gen-path/templates -o %t.yaml
3+
// RUN: riscv64-unknown-linux-gnu-clang %s -O2 -c -o %t.out -march=rv64imfd
4+
// -nostdlib -static
5+
// RUN: %bin/llvm-bleach %t.out --instructions %t.yaml -o %t.ll \
6+
// RUN: --state-struct-file=%t.state.h
7+
// RUN: sed 's|STATE|%t.state.h|g' %S/inputs/doubles-mixed-main.c > %t.main.c
8+
// RUN: clang %t.main.c %t.ll -o %t.native.out -g -fsanitize=address,undefined
9+
// RUN: %t.native.out
10+
11+
double complex_mixed(double a, double b, double c, double d) {
12+
double part1 = (a + b) * (unsigned)(c - d);
13+
double part2 = (a * d) + (int)(b * c);
14+
double part3 = (a / c) * (long long)(b / d);
15+
return part1 + part2 - part3;
16+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <STATE>
2+
#include <stdint.h>
3+
#include <stdio.h>
4+
#include <string.h>
5+
6+
struct register_state regs = {};
7+
8+
int64_t bitcast_to_int(double v) {
9+
int64_t res;
10+
memcpy(&res, &v, sizeof(double));
11+
return res;
12+
}
13+
14+
double bitcast_to_double(int64_t v) {
15+
double res;
16+
memcpy(&res, &v, sizeof(double));
17+
return res;
18+
}
19+
20+
// This should be in sync with test/integration/doubles-mixed.c
21+
// TODO: automate this
22+
double reference(double a, double b, double c, double d) {
23+
double part1 = (a + b) * (unsigned)(c - d);
24+
double part2 = (a * d) + (int)(b * c);
25+
double part3 = (a / c) * (long long)(b / d);
26+
return part1 + part2 - part3;
27+
}
28+
29+
int main() {
30+
printf("Hello from main\n");
31+
int arg_1 = 3;
32+
int arg_2 = 4;
33+
int arg_3 = 5;
34+
int arg_4 = 3;
35+
regs.FPR[10] = bitcast_to_int(arg_1);
36+
regs.FPR[11] = bitcast_to_int(arg_2);
37+
regs.FPR[12] = bitcast_to_int(arg_3);
38+
regs.FPR[13] = bitcast_to_int(arg_4);
39+
complex_mixed(&regs);
40+
double res1 = reference(arg_1, arg_2, arg_3, arg_4);
41+
double res2 = bitcast_to_double(regs.FPR[10]);
42+
printf("result: %lf\n", res2);
43+
printf("reference: %lf\n", res1);
44+
return res1 - res2 > 0.1;
45+
}
Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
// RUN: riscv64-unknown-linux-gnu-clang %s -O2 -o %t.out -march=rv64im -nostdlib
2-
// RUN: %bin/llvm-bleach %t.mir --instructions
3-
// %S/inputs/riscv-fact-instructions.yaml \ RUN: --state-struct-file
4-
// %t.state.h > %t.ll RUN: sed 's|STATE|%t.state.h|g' %S/inputs/bleached-main.c
5-
// > %t.main.c RUN: clang %t.main.c %t.ll -o %t.native.out RUN: %t.native.out |
6-
// FileCheck %s
7-
8-
// fact.c
91
__attribute__((noinline)) unsigned long long fact(unsigned long long num) {
102
unsigned long long res = 1;
113
for (unsigned long long i = 2; i <= num; ++i)
@@ -14,5 +6,3 @@ __attribute__((noinline)) unsigned long long fact(unsigned long long num) {
146
}
157

168
int main() { return fact(5); }
17-
18-
// CHECK: result: d120

tools/config-gen/templates/rv.yaml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ instructions:
1414
%7 = bitcast double %6 to i64
1515
ret i64 %7
1616
}
17+
FSUB_D:
18+
func: |
19+
define i64 @FSUB_D(i64 %0, i64 %1, i10 %rm) {
20+
%4 = bitcast i64 %0 to double
21+
%5 = bitcast i64 %1 to double
22+
%6 = fsub double %4, %5
23+
%7 = bitcast double %6 to i64
24+
ret i64 %7
25+
}
1726
FMUL_D:
1827
func: |
1928
define i64 @FMUL_D(i64 %0, i64 %1, i10 %rm) {
@@ -23,9 +32,65 @@ instructions:
2332
%7 = bitcast double %6 to i64
2433
ret i64 %7
2534
}
35+
FDIV_D:
36+
func: |
37+
define i64 @FDIV_D(i64 %0, i64 %1, i10 %rm) {
38+
%4 = bitcast i64 %0 to double
39+
%5 = bitcast i64 %1 to double
40+
%6 = fdiv double %4, %5
41+
%7 = bitcast double %6 to i64
42+
ret i64 %7
43+
}
2644
FCVT_D_LU:
2745
func: |
2846
define i64 @FCVT_D_LU(i64 %0, i10 %rm) {
47+
%3 = uitofp i64 %0 to double
48+
%4 = bitcast double %3 to i64
49+
ret i64 %4
50+
}
51+
FCVT_WU_D:
52+
func: |
53+
define i64 @FCVT_WU_D(i64 %0, i10 %rm) {
54+
%3 = bitcast i64 %0 to double
55+
%4 = fptoui double %3 to i32
56+
%5 = zext i32 %4 to i64
57+
ret i64 %5
58+
}
59+
FCVT_D_WU:
60+
func: |
61+
define i64 @FCVT_D_WU(i64 %0, i10 %rm) {
62+
%3 = trunc i64 %0 to i32
63+
%4 = uitofp i32 %3 to double
64+
%5 = bitcast double %4 to i64
65+
ret i64 %5
66+
}
67+
FCVT_D_W:
68+
func: |
69+
define i64 @FCVT_D_W(i64 %0, i10 %rm) {
70+
%3 = trunc i64 %0 to i32
71+
%4 = sitofp i32 %3 to double
72+
%5 = bitcast double %4 to i64
73+
ret i64 %5
74+
}
75+
# ggg
76+
FCVT_W_D:
77+
func: |
78+
define i64 @FCVT_W_D(i64 %0, i10 %rm) {
79+
%3 = bitcast i64 %0 to double
80+
%4 = fptosi double %3 to i32
81+
%5 = sext i32 %4 to i64
82+
ret i64 %5
83+
}
84+
FCVT_L_D:
85+
func: |
86+
define i64 @FCVT_L_D(i64 %0, i10 %rm) {
87+
%3 = bitcast i64 %0 to double
88+
%4 = fptosi double %3 to i64
89+
ret i64 %4
90+
}
91+
FCVT_D_L:
92+
func: |
93+
define i64 @FCVT_D_L(i64 %0, i10 %rm) {
2994
%3 = sitofp i64 %0 to double
3095
%4 = bitcast double %3 to i64
3196
ret i64 %4

0 commit comments

Comments
 (0)