mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
ba0a393451
This adds support for the MCU psABI in a way different from r251223 and r251224, basically reverting most of these two patches. The problem with the approach taken in r251223/4 is that it only handled libcalls that originated from the backend. However, the mid-end also inserts quite a few libcalls and assumes these use the platform's default calling convention. The previous patch tried to insert inregs when necessary both in the FE and, somewhat hackily, in the CG. Instead, we now define a new default calling convention for the MCU, which doesn't use inreg marking at all, similarly to what x86-64 does. Differential Revision: http://reviews.llvm.org/D15054 llvm-svn: 256494
113 lines
3.0 KiB
LLVM
113 lines
3.0 KiB
LLVM
; RUN: llc < %s -mtriple=i686-pc-elfiamcu | FileCheck %s
|
|
|
|
%struct.st12_t = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
|
|
|
|
; CHECK-LABEL: test_ints:
|
|
; CHECK: addl %edx, %eax
|
|
; CHECK-NEXT: imull %ecx, %eax
|
|
; CHECK-NEXT: addl 4(%esp), %eax
|
|
; CHECK-NEXT: retl
|
|
define i32 @test_ints(i32 %a, i32 %b, i32 %c, i32 %d) #0 {
|
|
entry:
|
|
%r1 = add i32 %b, %a
|
|
%r2 = mul i32 %c, %r1
|
|
%r3 = add i32 %d, %r2
|
|
ret i32 %r3
|
|
}
|
|
|
|
; CHECK-LABEL: test_floats:
|
|
; CHECK: addl %edx, %eax
|
|
; CHECK-NEXT: imull %ecx, %eax
|
|
; CHECK-NEXT: addl 4(%esp), %eax
|
|
; CHECK-NEXT: retl
|
|
define i32 @test_floats(i32 %a, i32 %b, float %c, float %d) #0 {
|
|
entry:
|
|
%ci = bitcast float %c to i32
|
|
%di = bitcast float %d to i32
|
|
%r1 = add i32 %b, %a
|
|
%r2 = mul i32 %ci, %r1
|
|
%r3 = add i32 %di, %r2
|
|
ret i32 %r3
|
|
}
|
|
|
|
; CHECK-LABEL: test_doubles:
|
|
; CHECK: addl 4(%esp), %eax
|
|
; CHECK-NEXT: adcl 8(%esp), %edx
|
|
; CHECK-NEXT: retl
|
|
define double @test_doubles(double %d1, double %d2) #0 {
|
|
entry:
|
|
%d1i = bitcast double %d1 to i64
|
|
%d2i = bitcast double %d2 to i64
|
|
%r = add i64 %d1i, %d2i
|
|
%rd = bitcast i64 %r to double
|
|
ret double %rd
|
|
}
|
|
|
|
; CHECK-LABEL: test_mixed_doubles:
|
|
; CHECK: addl %ecx, %eax
|
|
; CHECK-NEXT: adcl $0, %edx
|
|
; CHECK-NEXT: retl
|
|
define double @test_mixed_doubles(double %d2, i32 %i) #0 {
|
|
entry:
|
|
%iext = zext i32 %i to i64
|
|
%d2i = bitcast double %d2 to i64
|
|
%r = add i64 %iext, %d2i
|
|
%rd = bitcast i64 %r to double
|
|
ret double %rd
|
|
}
|
|
|
|
; CHECK-LABEL: ret_large_struct:
|
|
; CHECK: pushl %esi
|
|
; CHECK-NEXT: movl %eax, %esi
|
|
; CHECK-NEXT: leal 8(%esp), %edx
|
|
; CHECK-NEXT: movl $48, %ecx
|
|
; CHECK-NEXT: calll memcpy
|
|
; CHECK-NEXT: movl %esi, %eax
|
|
; CHECK-NEXT: popl %esi
|
|
; CHECK-NOT: retl $4
|
|
; CHECK-NEXT: retl
|
|
define void @ret_large_struct(%struct.st12_t* noalias nocapture sret %agg.result, %struct.st12_t* byval nocapture readonly align 4 %r) #0 {
|
|
entry:
|
|
%0 = bitcast %struct.st12_t* %agg.result to i8*
|
|
%1 = bitcast %struct.st12_t* %r to i8*
|
|
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 48, i32 1, i1 false)
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: var_args:
|
|
; CHECK: movl 4(%esp), %eax
|
|
; CHECK-NEXT: retl
|
|
define i32 @var_args(i32 %i1, ...) #0 {
|
|
entry:
|
|
ret i32 %i1
|
|
}
|
|
|
|
; CHECK-LABEL: test_lib_args:
|
|
; CHECK: movl %edx, %eax
|
|
; CHECK: calll __fixsfsi
|
|
define i32 @test_lib_args(float %a, float %b) #0 {
|
|
%ret = fptosi float %b to i32
|
|
ret i32 %ret
|
|
}
|
|
|
|
; CHECK-LABEL: test_fp128:
|
|
; CHECK: movl (%eax), %e[[CX:..]]
|
|
; CHECK-NEXT: movl 4(%eax), %e[[DX:..]]
|
|
; CHECK-NEXT: movl 8(%eax), %e[[SI:..]]
|
|
; CHECK-NEXT: movl 12(%eax), %e[[AX:..]]
|
|
; CHECK-NEXT: movl %e[[AX]], 12(%esp)
|
|
; CHECK-NEXT: movl %e[[SI]], 8(%esp)
|
|
; CHECK-NEXT: movl %e[[DX]], 4(%esp)
|
|
; CHECK-NEXT: movl %e[[CX]], (%esp)
|
|
; CHECK-NEXT: calll __fixtfsi
|
|
define i32 @test_fp128(fp128* %ptr) #0 {
|
|
%v = load fp128, fp128* %ptr
|
|
%ret = fptosi fp128 %v to i32
|
|
ret i32 %ret
|
|
}
|
|
|
|
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #1
|
|
|
|
attributes #0 = { nounwind "use-soft-float"="true"}
|
|
attributes #1 = { nounwind argmemonly }
|