mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
351fbaf236
To do this: 1. Change GlobalAddress SDNode to TargetGlobalAddress to avoid legalizer split the symbol. 2. Change ExternalSymbol SDNode to TargetExternalSymbol to avoid legalizer split the symbol. 3. Let PseudoCALL match direct call with target operand TargetGlobalAddress and TargetExternalSymbol. Differential Revision: https://reviews.llvm.org/D44885 llvm-svn: 330827
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
|
|
}
|