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, %hi(.LCPI1_0)
38 ; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI1_0)
39 ; RV32IFD-NEXT: fld ft0, 0(a0)
40 ; RV32IFD-NEXT: lui a0, %hi(.LCPI1_1)
41 ; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI1_1)
42 ; RV32IFD-NEXT: fld ft1, 0(a0)
43 ; RV32IFD-NEXT: fsd ft1, 0(sp)
44 ; RV32IFD-NEXT: lw a0, 0(sp)
45 ; RV32IFD-NEXT: lw a1, 4(sp)
46 ; RV32IFD-NEXT: fsd ft0, 0(sp)
47 ; RV32IFD-NEXT: lw a2, 0(sp)
48 ; RV32IFD-NEXT: lw a3, 4(sp)
49 ; RV32IFD-NEXT: call callee_double_inreg
50 ; RV32IFD-NEXT: lw ra, 12(sp)
51 ; RV32IFD-NEXT: addi sp, sp, 16
53 %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00)
57 define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, double %e) nounwind {
58 ; RV32IFD-LABEL: callee_double_split_reg_stack:
60 ; RV32IFD-NEXT: addi sp, sp, -16
61 ; RV32IFD-NEXT: lw a0, 16(sp)
62 ; RV32IFD-NEXT: sw a7, 8(sp)
63 ; RV32IFD-NEXT: sw a0, 12(sp)
64 ; RV32IFD-NEXT: fld ft0, 8(sp)
65 ; RV32IFD-NEXT: sw a5, 8(sp)
66 ; RV32IFD-NEXT: sw a6, 12(sp)
67 ; RV32IFD-NEXT: fld ft1, 8(sp)
68 ; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
69 ; RV32IFD-NEXT: fsd ft0, 8(sp)
70 ; RV32IFD-NEXT: lw a0, 8(sp)
71 ; RV32IFD-NEXT: lw a1, 12(sp)
72 ; RV32IFD-NEXT: addi sp, sp, 16
74 %1 = fadd double %d, %e
78 define double @caller_double_split_reg_stack() nounwind {
79 ; RV32IFD-LABEL: caller_double_split_reg_stack:
81 ; RV32IFD-NEXT: addi sp, sp, -32
82 ; RV32IFD-NEXT: sw ra, 28(sp)
83 ; RV32IFD-NEXT: lui a0, %hi(.LCPI3_0)
84 ; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI3_0)
85 ; RV32IFD-NEXT: fld ft0, 0(a0)
86 ; RV32IFD-NEXT: fsd ft0, 16(sp)
87 ; RV32IFD-NEXT: lw a7, 16(sp)
88 ; RV32IFD-NEXT: lw a0, 20(sp)
89 ; RV32IFD-NEXT: sw a0, 0(sp)
90 ; RV32IFD-NEXT: lui a0, %hi(.LCPI3_1)
91 ; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI3_1)
92 ; RV32IFD-NEXT: fld ft0, 0(a0)
93 ; RV32IFD-NEXT: fsd ft0, 16(sp)
94 ; RV32IFD-NEXT: lw a5, 16(sp)
95 ; RV32IFD-NEXT: lw a6, 20(sp)
96 ; RV32IFD-NEXT: addi a0, zero, 1
97 ; RV32IFD-NEXT: addi a1, zero, 2
98 ; RV32IFD-NEXT: mv a2, zero
99 ; RV32IFD-NEXT: addi a3, zero, 3
100 ; RV32IFD-NEXT: mv a4, zero
101 ; RV32IFD-NEXT: call callee_double_split_reg_stack
102 ; RV32IFD-NEXT: lw ra, 28(sp)
103 ; RV32IFD-NEXT: addi sp, sp, 32
105 %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72)
109 define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind {
110 ; RV32IFD-LABEL: callee_double_stack:
112 ; RV32IFD-NEXT: addi sp, sp, -16
113 ; RV32IFD-NEXT: fld ft0, 24(sp)
114 ; RV32IFD-NEXT: fld ft1, 16(sp)
115 ; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
116 ; RV32IFD-NEXT: fsd ft0, 8(sp)
117 ; RV32IFD-NEXT: lw a0, 8(sp)
118 ; RV32IFD-NEXT: lw a1, 12(sp)
119 ; RV32IFD-NEXT: addi sp, sp, 16
121 %1 = fadd double %e, %f
125 define double @caller_double_stack() nounwind {
126 ; RV32IFD-LABEL: caller_double_stack:
128 ; RV32IFD-NEXT: addi sp, sp, -32
129 ; RV32IFD-NEXT: sw ra, 28(sp)
130 ; RV32IFD-NEXT: lui a0, 262510
131 ; RV32IFD-NEXT: addi a0, a0, 327
132 ; RV32IFD-NEXT: sw a0, 4(sp)
133 ; RV32IFD-NEXT: lui a0, 262574
134 ; RV32IFD-NEXT: addi a0, a0, 327
135 ; RV32IFD-NEXT: sw a0, 12(sp)
136 ; RV32IFD-NEXT: lui a0, 713032
137 ; RV32IFD-NEXT: addi a0, a0, -1311
138 ; RV32IFD-NEXT: sw a0, 0(sp)
139 ; RV32IFD-NEXT: sw a0, 8(sp)
140 ; RV32IFD-NEXT: addi a0, zero, 1
141 ; RV32IFD-NEXT: mv a1, zero
142 ; RV32IFD-NEXT: addi a2, zero, 2
143 ; RV32IFD-NEXT: mv a3, zero
144 ; RV32IFD-NEXT: addi a4, zero, 3
145 ; RV32IFD-NEXT: mv a5, zero
146 ; RV32IFD-NEXT: addi a6, zero, 4
147 ; RV32IFD-NEXT: mv a7, zero
148 ; RV32IFD-NEXT: call callee_double_stack
149 ; RV32IFD-NEXT: lw ra, 28(sp)
150 ; RV32IFD-NEXT: addi sp, sp, 32
152 %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72)