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