Home | History | Annotate | Download | only in RISCV
      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 
     10 define 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 
     32 define 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, %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
     52 ; RV32IFD-NEXT:    ret
     53   %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00)
     54   ret double %1
     55 }
     56 
     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:
     59 ; RV32IFD:       # %bb.0:
     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
     73 ; RV32IFD-NEXT:    ret
     74   %1 = fadd double %d, %e
     75   ret double %1
     76 }
     77 
     78 define double @caller_double_split_reg_stack() nounwind {
     79 ; RV32IFD-LABEL: caller_double_split_reg_stack:
     80 ; RV32IFD:       # %bb.0:
     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:    addi a3, zero, 3
     99 ; RV32IFD-NEXT:    mv a2, zero
    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
    104 ; RV32IFD-NEXT:    ret
    105   %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72)
    106   ret double %1
    107 }
    108 
    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:
    111 ; RV32IFD:       # %bb.0:
    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
    120 ; RV32IFD-NEXT:    ret
    121   %1 = fadd double %e, %f
    122   ret double %1
    123 }
    124 
    125 define double @caller_double_stack() nounwind {
    126 ; RV32IFD-LABEL: caller_double_stack:
    127 ; RV32IFD:       # %bb.0:
    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:    addi a2, zero, 2
    142 ; RV32IFD-NEXT:    addi a4, zero, 3
    143 ; RV32IFD-NEXT:    addi a6, zero, 4
    144 ; RV32IFD-NEXT:    mv a1, zero
    145 ; RV32IFD-NEXT:    mv a3, zero
    146 ; RV32IFD-NEXT:    mv a5, zero
    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
    151 ; RV32IFD-NEXT:    ret
    152   %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72)
    153   ret double %1
    154 }
    155