[mips] Add CCValAssign::[ASZ]ExtUpper and CCPromoteToUpperBitsInType and handle struc...
[oota-llvm.git] / test / CodeGen / Mips / cconv / return-struct.ll
1 ; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static < %s | FileCheck --check-prefix=ALL --check-prefix=O32 --check-prefix=O32-BE %s
2 ; RUN: llc -mtriple=mipsel-linux-gnu -relocation-model=static < %s | FileCheck --check-prefix=ALL --check-prefix=O32 --check-prefix=O32-LE %s
3
4 ; RUN-TODO: llc -mtriple=mips64-linux-gnu -relocation-model=static -mattr=-n64,+o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
5 ; RUN-TODO: llc -mtriple=mips64el-linux-gnu -relocation-model=static -mattr=-n64,+o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
6
7 ; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -mattr=-n64,+n32 < %s | FileCheck --check-prefix=ALL --check-prefix=N32 --check-prefix=N32-BE %s
8 ; RUN: llc -mtriple=mips64el-linux-gnu -relocation-model=static -mattr=-n64,+n32 < %s | FileCheck --check-prefix=ALL --check-prefix=N32 --check-prefix=N32-LE %s
9
10 ; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -mattr=-n64,+n64 < %s | FileCheck --check-prefix=ALL --check-prefix=N64 --check-prefix=N64-BE %s
11 ; RUN: llc -mtriple=mips64el-linux-gnu -relocation-model=static -mattr=-n64,+n64 < %s | FileCheck --check-prefix=ALL --check-prefix=N64 --check-prefix=N64-LE %s
12
13 ; Test struct returns for all ABI's and byte orders.
14
15 @struct_byte = global {i8} zeroinitializer
16 @struct_2byte = global {i8,i8} zeroinitializer
17
18 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
19
20 define inreg {i8} @ret_struct_i8() nounwind {
21 entry:
22         %0 = load volatile {i8}* @struct_byte
23         ret {i8} %0
24 }
25
26 ; ALL-LABEL: ret_struct_i8:
27 ; O32-DAG:           lui [[R1:\$[0-9]+]], %hi(struct_byte)
28 ; O32-DAG:           lbu $2, %lo(struct_byte)([[R1]])
29
30 ; N32-LE-DAG:        lui [[R1:\$[0-9]+]], %hi(struct_byte)
31 ; N32-LE-DAG:        lb $2, %lo(struct_byte)([[R1]])
32
33 ; N32-BE-DAG:        lui [[R1:\$[0-9]+]], %hi(struct_byte)
34 ; N32-BE-DAG:        lb [[R2:\$[0-9]+]], %lo(struct_byte)([[R1]])
35 ; N32-BE-DAG:        dsll $2, [[R2]], 56
36
37 ; N64-LE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_byte)($1)
38 ; N64-LE-DAG:        lb $2, 0([[R1]])
39
40 ; N64-BE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_byte)($1)
41 ; N64-BE-DAG:        lb [[R2:\$[0-9]+]], 0([[R1]])
42 ; N64-BE-DAG:        dsll $2, [[R2]], 56
43
44 ; This test is based on the way clang currently lowers {i8,i8} to {i16}.
45 ; FIXME: It should probably work for without any lowering too but this doesn't
46 ;        work as expected. Each member gets mapped to a register rather than
47 ;        packed into a single register.
48 define inreg {i16} @ret_struct_i16() nounwind {
49 entry:
50         %retval = alloca {i8,i8}, align 1
51         %0 = bitcast {i8,i8}* %retval to i8*
52         call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr inbounds ({i8,i8}* @struct_2byte, i32 0, i32 0), i64 2, i32 1, i1 false)
53         %1 = bitcast {i8,i8}* %retval to {i16}*
54         %2 = load volatile {i16}* %1
55         ret {i16} %2
56 }
57
58 ; ALL-LABEL: ret_struct_i16:
59 ; O32-DAG:           lui [[R1:\$[0-9]+]], %hi(struct_2byte)
60 ; O32-DAG:           lhu [[R2:\$[0-9]+]], %lo(struct_2byte)([[R1]])
61 ; O32-DAG:           sh  [[R2]], 0([[SP:\$sp]])
62 ; O32-DAG:           lhu $2, 0([[SP:\$sp]])
63
64 ; N32-LE-DAG:        lui [[R1:\$[0-9]+]], %hi(struct_2byte)
65 ; N32-LE-DAG:        lhu [[R2:\$[0-9]+]], %lo(struct_2byte)([[R1]])
66 ; N32-LE-DAG:        sh  [[R2]], 8([[SP:\$sp]])
67 ; N32-LE-DAG:        lh  $2, 8([[SP:\$sp]])
68
69 ; N32-BE-DAG:        lui [[R1:\$[0-9]+]], %hi(struct_2byte)
70 ; N32-BE-DAG:        lhu [[R2:\$[0-9]+]], %lo(struct_2byte)([[R1]])
71 ; N32-BE-DAG:        sh  [[R2]], 8([[SP:\$sp]])
72 ; N32-BE-DAG:        lh  [[R3:\$[0-9]+]], 8([[SP:\$sp]])
73 ; N32-BE-DAG:        dsll $2, [[R3]], 48
74
75 ; N64-LE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_2byte)($1)
76 ; N64-LE-DAG:        lhu [[R2:\$[0-9]+]], 0([[R1]])
77 ; N64-LE-DAG:        sh  [[R2]], 8([[SP:\$sp]])
78 ; N64-LE-DAG:        lh  $2, 8([[SP:\$sp]])
79
80 ; N64-BE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_2byte)($1)
81 ; N64-BE-DAG:        lhu [[R2:\$[0-9]+]], 0([[R1]])
82 ; N64-BE-DAG:        sh  [[R2]], 8([[SP:\$sp]])
83 ; N64-BE-DAG:        lh  [[R3:\$[0-9]+]], 8([[SP:\$sp]])
84 ; N64-BE-DAG:        dsll $2, [[R3]], 48