1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32IFD %s
5 ; Sanity checks for calling convention lowering for RV32D. This can be
6 ; somewhat error-prone for soft-float RV32D due to the fact that f64 is legal
7 ; but i64 is not, and there is no instruction to move values directly between
8 ; the GPRs and 64-bit FPRs.
10 define double @callee_double_inreg(double %a, double %b) nounwind {
11 ; RV32IFD-LABEL: callee_double_inreg:
13 ; RV32IFD-NEXT: addi sp, sp, -16
14 ; RV32IFD-NEXT: sw a2, 8(sp)
15 ; RV32IFD-NEXT: sw a3, 12(sp)
16 ; RV32IFD-NEXT: fld ft0, 8(sp)
17 ; RV32IFD-NEXT: sw a0, 8(sp)
18 ; RV32IFD-NEXT: sw a1, 12(sp)
19 ; RV32IFD-NEXT: fld ft1, 8(sp)
20 ; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
21 ; RV32IFD-NEXT: fsd ft0, 8(sp)
22 ; RV32IFD-NEXT: lw a0, 8(sp)
23 ; RV32IFD-NEXT: lw a1, 12(sp)
24 ; RV32IFD-NEXT: addi sp, sp, 16
26 %1 = fadd double %a, %b
30 ; TODO: code quality for loading and then passing f64 constants is poor.
32 define double @caller_double_inreg() nounwind {
33 ; RV32IFD-LABEL: caller_double_inreg:
35 ; RV32IFD-NEXT: addi sp, sp, -16
36 ; RV32IFD-NEXT: sw ra, 12(sp)
37 ; RV32IFD-NEXT: lui a0, 262236
38 ; RV32IFD-NEXT: addi a1, a0, 655
39 ; RV32IFD-NEXT: lui a0, 377487
40 ; RV32IFD-NEXT: addi a0, a0, 1475
41 ; RV32IFD-NEXT: lui a2, 262364
42 ; RV32IFD-NEXT: addi a3, a2, 655
43 ; RV32IFD-NEXT: mv a2, a0
44 ; RV32IFD-NEXT: call callee_double_inreg
45 ; RV32IFD-NEXT: lw ra, 12(sp)
46 ; RV32IFD-NEXT: addi sp, sp, 16
48 %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00)
52 define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, double %e) nounwind {
53 ; RV32IFD-LABEL: callee_double_split_reg_stack:
55 ; RV32IFD-NEXT: addi sp, sp, -16
56 ; RV32IFD-NEXT: lw a0, 16(sp)
57 ; RV32IFD-NEXT: sw a7, 8(sp)
58 ; RV32IFD-NEXT: sw a0, 12(sp)
59 ; RV32IFD-NEXT: fld ft0, 8(sp)
60 ; RV32IFD-NEXT: sw a5, 8(sp)
61 ; RV32IFD-NEXT: sw a6, 12(sp)
62 ; RV32IFD-NEXT: fld ft1, 8(sp)
63 ; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
64 ; RV32IFD-NEXT: fsd ft0, 8(sp)
65 ; RV32IFD-NEXT: lw a0, 8(sp)
66 ; RV32IFD-NEXT: lw a1, 12(sp)
67 ; RV32IFD-NEXT: addi sp, sp, 16
69 %1 = fadd double %d, %e
73 define double @caller_double_split_reg_stack() nounwind {
74 ; RV32IFD-LABEL: caller_double_split_reg_stack:
76 ; RV32IFD-NEXT: addi sp, sp, -16
77 ; RV32IFD-NEXT: sw ra, 12(sp)
78 ; RV32IFD-NEXT: lui a0, 262510
79 ; RV32IFD-NEXT: addi a0, a0, 327
80 ; RV32IFD-NEXT: sw a0, 0(sp)
81 ; RV32IFD-NEXT: lui a0, 262446
82 ; RV32IFD-NEXT: addi a6, a0, 327
83 ; RV32IFD-NEXT: lui a0, 713032
84 ; RV32IFD-NEXT: addi a5, a0, -1311
85 ; RV32IFD-NEXT: addi a0, zero, 1
86 ; RV32IFD-NEXT: addi a1, zero, 2
87 ; RV32IFD-NEXT: mv a2, zero
88 ; RV32IFD-NEXT: addi a3, zero, 3
89 ; RV32IFD-NEXT: mv a4, zero
90 ; RV32IFD-NEXT: mv a7, a5
91 ; RV32IFD-NEXT: call callee_double_split_reg_stack
92 ; RV32IFD-NEXT: lw ra, 12(sp)
93 ; RV32IFD-NEXT: addi sp, sp, 16
95 %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72)
99 define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind {
100 ; RV32IFD-LABEL: callee_double_stack:
102 ; RV32IFD-NEXT: addi sp, sp, -16
103 ; RV32IFD-NEXT: fld ft0, 24(sp)
104 ; RV32IFD-NEXT: fld ft1, 16(sp)
105 ; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
106 ; RV32IFD-NEXT: fsd ft0, 8(sp)
107 ; RV32IFD-NEXT: lw a0, 8(sp)
108 ; RV32IFD-NEXT: lw a1, 12(sp)
109 ; RV32IFD-NEXT: addi sp, sp, 16
111 %1 = fadd double %e, %f
115 define double @caller_double_stack() nounwind {
116 ; RV32IFD-LABEL: caller_double_stack:
118 ; RV32IFD-NEXT: addi sp, sp, -32
119 ; RV32IFD-NEXT: sw ra, 28(sp)
120 ; RV32IFD-NEXT: lui a0, 262510
121 ; RV32IFD-NEXT: addi a0, a0, 327
122 ; RV32IFD-NEXT: sw a0, 4(sp)
123 ; RV32IFD-NEXT: lui a0, 262574
124 ; RV32IFD-NEXT: addi a0, a0, 327
125 ; RV32IFD-NEXT: sw a0, 12(sp)
126 ; RV32IFD-NEXT: lui a0, 713032
127 ; RV32IFD-NEXT: addi a0, a0, -1311
128 ; RV32IFD-NEXT: sw a0, 0(sp)
129 ; RV32IFD-NEXT: sw a0, 8(sp)
130 ; RV32IFD-NEXT: addi a0, zero, 1
131 ; RV32IFD-NEXT: mv a1, zero
132 ; RV32IFD-NEXT: addi a2, zero, 2
133 ; RV32IFD-NEXT: mv a3, zero
134 ; RV32IFD-NEXT: addi a4, zero, 3
135 ; RV32IFD-NEXT: mv a5, zero
136 ; RV32IFD-NEXT: addi a6, zero, 4
137 ; RV32IFD-NEXT: mv a7, zero
138 ; RV32IFD-NEXT: call callee_double_stack
139 ; RV32IFD-NEXT: lw ra, 28(sp)
140 ; RV32IFD-NEXT: addi sp, sp, 32
142 %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72)