• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
4
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.
9
10define double @callee_double_inreg(double %a, double %b) nounwind {
11; RV32IFD-LABEL: callee_double_inreg:
12; RV32IFD:       # %bb.0:
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
25; RV32IFD-NEXT:    ret
26  %1 = fadd double %a, %b
27  ret double %1
28}
29
30; TODO: code quality for loading and then passing f64 constants is poor.
31
32define double @caller_double_inreg() nounwind {
33; RV32IFD-LABEL: caller_double_inreg:
34; RV32IFD:       # %bb.0:
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
47; RV32IFD-NEXT:    ret
48  %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00)
49  ret double %1
50}
51
52define 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:
54; RV32IFD:       # %bb.0:
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
68; RV32IFD-NEXT:    ret
69  %1 = fadd double %d, %e
70  ret double %1
71}
72
73define double @caller_double_split_reg_stack() nounwind {
74; RV32IFD-LABEL: caller_double_split_reg_stack:
75; RV32IFD:       # %bb.0:
76; RV32IFD-NEXT:    addi sp, sp, -16
77; RV32IFD-NEXT:    sw ra, 12(sp)
78; RV32IFD-NEXT:    lui a0, 262510
79; RV32IFD-NEXT:    addi a2, a0, 327
80; RV32IFD-NEXT:    lui a0, 262446
81; RV32IFD-NEXT:    addi a6, a0, 327
82; RV32IFD-NEXT:    lui a0, 713032
83; RV32IFD-NEXT:    addi a5, a0, -1311
84; RV32IFD-NEXT:    addi a0, zero, 1
85; RV32IFD-NEXT:    addi a1, zero, 2
86; RV32IFD-NEXT:    addi a3, zero, 3
87; RV32IFD-NEXT:    sw a2, 0(sp)
88; RV32IFD-NEXT:    mv a2, zero
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
94; RV32IFD-NEXT:    ret
95  %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72)
96  ret double %1
97}
98
99define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind {
100; RV32IFD-LABEL: callee_double_stack:
101; RV32IFD:       # %bb.0:
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
110; RV32IFD-NEXT:    ret
111  %1 = fadd double %e, %f
112  ret double %1
113}
114
115define double @caller_double_stack() nounwind {
116; RV32IFD-LABEL: caller_double_stack:
117; RV32IFD:       # %bb.0:
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, 713032
124; RV32IFD-NEXT:    addi a1, a0, -1311
125; RV32IFD-NEXT:    sw a1, 0(sp)
126; RV32IFD-NEXT:    lui a0, 262574
127; RV32IFD-NEXT:    addi a0, a0, 327
128; RV32IFD-NEXT:    sw a0, 12(sp)
129; RV32IFD-NEXT:    addi a0, zero, 1
130; RV32IFD-NEXT:    addi a2, zero, 2
131; RV32IFD-NEXT:    addi a4, zero, 3
132; RV32IFD-NEXT:    addi a6, zero, 4
133; RV32IFD-NEXT:    sw a1, 8(sp)
134; RV32IFD-NEXT:    mv a1, zero
135; RV32IFD-NEXT:    mv a3, zero
136; RV32IFD-NEXT:    mv a5, zero
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
141; RV32IFD-NEXT:    ret
142  %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72)
143  ret double %1
144}
145