155 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 | |
| ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
 | |
| ; RUN:   | FileCheck -check-prefix=RV32IFD %s
 | |
| 
 | |
| ; Sanity checks for calling convention lowering for RV32D. This can be
 | |
| ; somewhat error-prone for soft-float RV32D due to the fact that f64 is legal
 | |
| ; but i64 is not, and there is no instruction to move values directly between
 | |
| ; the GPRs and 64-bit FPRs.
 | |
| 
 | |
| define double @callee_double_inreg(double %a, double %b) nounwind {
 | |
| ; RV32IFD-LABEL: callee_double_inreg:
 | |
| ; RV32IFD:       # %bb.0:
 | |
| ; RV32IFD-NEXT:    addi sp, sp, -16
 | |
| ; RV32IFD-NEXT:    sw a2, 8(sp)
 | |
| ; RV32IFD-NEXT:    sw a3, 12(sp)
 | |
| ; RV32IFD-NEXT:    fld ft0, 8(sp)
 | |
| ; RV32IFD-NEXT:    sw a0, 8(sp)
 | |
| ; RV32IFD-NEXT:    sw a1, 12(sp)
 | |
| ; RV32IFD-NEXT:    fld ft1, 8(sp)
 | |
| ; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
 | |
| ; RV32IFD-NEXT:    fsd ft0, 8(sp)
 | |
| ; RV32IFD-NEXT:    lw a0, 8(sp)
 | |
| ; RV32IFD-NEXT:    lw a1, 12(sp)
 | |
| ; RV32IFD-NEXT:    addi sp, sp, 16
 | |
| ; RV32IFD-NEXT:    ret
 | |
|   %1 = fadd double %a, %b
 | |
|   ret double %1
 | |
| }
 | |
| 
 | |
| ; TODO: code quality for loading and then passing f64 constants is poor.
 | |
| 
 | |
| define double @caller_double_inreg() nounwind {
 | |
| ; RV32IFD-LABEL: caller_double_inreg:
 | |
| ; RV32IFD:       # %bb.0:
 | |
| ; RV32IFD-NEXT:    addi sp, sp, -16
 | |
| ; RV32IFD-NEXT:    sw ra, 12(sp)
 | |
| ; RV32IFD-NEXT:    lui a0, %hi(.LCPI1_0)
 | |
| ; RV32IFD-NEXT:    addi a0, a0, %lo(.LCPI1_0)
 | |
| ; RV32IFD-NEXT:    fld ft0, 0(a0)
 | |
| ; RV32IFD-NEXT:    lui a0, %hi(.LCPI1_1)
 | |
| ; RV32IFD-NEXT:    addi a0, a0, %lo(.LCPI1_1)
 | |
| ; RV32IFD-NEXT:    fld ft1, 0(a0)
 | |
| ; RV32IFD-NEXT:    fsd ft1, 0(sp)
 | |
| ; RV32IFD-NEXT:    lw a0, 0(sp)
 | |
| ; RV32IFD-NEXT:    lw a1, 4(sp)
 | |
| ; RV32IFD-NEXT:    fsd ft0, 0(sp)
 | |
| ; RV32IFD-NEXT:    lw a2, 0(sp)
 | |
| ; RV32IFD-NEXT:    lw a3, 4(sp)
 | |
| ; RV32IFD-NEXT:    call callee_double_inreg
 | |
| ; RV32IFD-NEXT:    lw ra, 12(sp)
 | |
| ; RV32IFD-NEXT:    addi sp, sp, 16
 | |
| ; RV32IFD-NEXT:    ret
 | |
|   %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00)
 | |
|   ret double %1
 | |
| }
 | |
| 
 | |
| define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, double %e) nounwind {
 | |
| ; RV32IFD-LABEL: callee_double_split_reg_stack:
 | |
| ; RV32IFD:       # %bb.0:
 | |
| ; RV32IFD-NEXT:    addi sp, sp, -16
 | |
| ; RV32IFD-NEXT:    lw a0, 16(sp)
 | |
| ; RV32IFD-NEXT:    sw a7, 8(sp)
 | |
| ; RV32IFD-NEXT:    sw a0, 12(sp)
 | |
| ; RV32IFD-NEXT:    fld ft0, 8(sp)
 | |
| ; RV32IFD-NEXT:    sw a5, 8(sp)
 | |
| ; RV32IFD-NEXT:    sw a6, 12(sp)
 | |
| ; RV32IFD-NEXT:    fld ft1, 8(sp)
 | |
| ; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
 | |
| ; RV32IFD-NEXT:    fsd ft0, 8(sp)
 | |
| ; RV32IFD-NEXT:    lw a0, 8(sp)
 | |
| ; RV32IFD-NEXT:    lw a1, 12(sp)
 | |
| ; RV32IFD-NEXT:    addi sp, sp, 16
 | |
| ; RV32IFD-NEXT:    ret
 | |
|   %1 = fadd double %d, %e
 | |
|   ret double %1
 | |
| }
 | |
| 
 | |
| define double @caller_double_split_reg_stack() nounwind {
 | |
| ; RV32IFD-LABEL: caller_double_split_reg_stack:
 | |
| ; RV32IFD:       # %bb.0:
 | |
| ; RV32IFD-NEXT:    addi sp, sp, -32
 | |
| ; RV32IFD-NEXT:    sw ra, 28(sp)
 | |
| ; RV32IFD-NEXT:    lui a0, %hi(.LCPI3_0)
 | |
| ; RV32IFD-NEXT:    addi a0, a0, %lo(.LCPI3_0)
 | |
| ; RV32IFD-NEXT:    fld ft0, 0(a0)
 | |
| ; RV32IFD-NEXT:    fsd ft0, 16(sp)
 | |
| ; RV32IFD-NEXT:    lw a7, 16(sp)
 | |
| ; RV32IFD-NEXT:    lw a0, 20(sp)
 | |
| ; RV32IFD-NEXT:    sw a0, 0(sp)
 | |
| ; RV32IFD-NEXT:    lui a0, %hi(.LCPI3_1)
 | |
| ; RV32IFD-NEXT:    addi a0, a0, %lo(.LCPI3_1)
 | |
| ; RV32IFD-NEXT:    fld ft0, 0(a0)
 | |
| ; RV32IFD-NEXT:    fsd ft0, 16(sp)
 | |
| ; RV32IFD-NEXT:    lw a5, 16(sp)
 | |
| ; RV32IFD-NEXT:    lw a6, 20(sp)
 | |
| ; RV32IFD-NEXT:    addi a0, zero, 1
 | |
| ; RV32IFD-NEXT:    addi a1, zero, 2
 | |
| ; RV32IFD-NEXT:    addi a3, zero, 3
 | |
| ; RV32IFD-NEXT:    mv a2, zero
 | |
| ; RV32IFD-NEXT:    mv a4, zero
 | |
| ; RV32IFD-NEXT:    call callee_double_split_reg_stack
 | |
| ; RV32IFD-NEXT:    lw ra, 28(sp)
 | |
| ; RV32IFD-NEXT:    addi sp, sp, 32
 | |
| ; RV32IFD-NEXT:    ret
 | |
|   %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72)
 | |
|   ret double %1
 | |
| }
 | |
| 
 | |
| define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind {
 | |
| ; RV32IFD-LABEL: callee_double_stack:
 | |
| ; RV32IFD:       # %bb.0:
 | |
| ; RV32IFD-NEXT:    addi sp, sp, -16
 | |
| ; RV32IFD-NEXT:    fld ft0, 24(sp)
 | |
| ; RV32IFD-NEXT:    fld ft1, 16(sp)
 | |
| ; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
 | |
| ; RV32IFD-NEXT:    fsd ft0, 8(sp)
 | |
| ; RV32IFD-NEXT:    lw a0, 8(sp)
 | |
| ; RV32IFD-NEXT:    lw a1, 12(sp)
 | |
| ; RV32IFD-NEXT:    addi sp, sp, 16
 | |
| ; RV32IFD-NEXT:    ret
 | |
|   %1 = fadd double %e, %f
 | |
|   ret double %1
 | |
| }
 | |
| 
 | |
| define double @caller_double_stack() nounwind {
 | |
| ; RV32IFD-LABEL: caller_double_stack:
 | |
| ; RV32IFD:       # %bb.0:
 | |
| ; RV32IFD-NEXT:    addi sp, sp, -32
 | |
| ; RV32IFD-NEXT:    sw ra, 28(sp)
 | |
| ; RV32IFD-NEXT:    lui a0, 262510
 | |
| ; RV32IFD-NEXT:    addi a0, a0, 327
 | |
| ; RV32IFD-NEXT:    sw a0, 4(sp)
 | |
| ; RV32IFD-NEXT:    lui a0, 262574
 | |
| ; RV32IFD-NEXT:    addi a0, a0, 327
 | |
| ; RV32IFD-NEXT:    sw a0, 12(sp)
 | |
| ; RV32IFD-NEXT:    lui a0, 713032
 | |
| ; RV32IFD-NEXT:    addi a0, a0, -1311
 | |
| ; RV32IFD-NEXT:    sw a0, 0(sp)
 | |
| ; RV32IFD-NEXT:    sw a0, 8(sp)
 | |
| ; RV32IFD-NEXT:    addi a0, zero, 1
 | |
| ; RV32IFD-NEXT:    addi a2, zero, 2
 | |
| ; RV32IFD-NEXT:    addi a4, zero, 3
 | |
| ; RV32IFD-NEXT:    addi a6, zero, 4
 | |
| ; RV32IFD-NEXT:    mv a1, zero
 | |
| ; RV32IFD-NEXT:    mv a3, zero
 | |
| ; RV32IFD-NEXT:    mv a5, zero
 | |
| ; RV32IFD-NEXT:    mv a7, zero
 | |
| ; RV32IFD-NEXT:    call callee_double_stack
 | |
| ; RV32IFD-NEXT:    lw ra, 28(sp)
 | |
| ; RV32IFD-NEXT:    addi sp, sp, 32
 | |
| ; RV32IFD-NEXT:    ret
 | |
|   %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72)
 | |
|   ret double %1
 | |
| }
 |