1; Test all important variants of the 'ret' instruction.
2;
3; For non-void returns it is necessary to have something to return so we also
4; test constant generation here.
5;
6; We'll test pointer returns in a separate file since the relocation model
7; affects it and it's undesirable to repeat the non-pointer returns for each
8; relocation model.
9
10; RUN: llc -march=mips   -mcpu=mips32   -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=NO-MTHC1 -check-prefix=NOT-R6
11; RUN: llc -march=mips   -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6
12; RUN: llc -march=mips   -mcpu=mips32r3 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6
13; RUN: llc -march=mips   -mcpu=mips32r5 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6
14; RUN: llc -march=mips   -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=R6
15; RUN: llc -march=mips64 -mcpu=mips4    -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
16; RUN: llc -march=mips64 -mcpu=mips64   -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
17; RUN: llc -march=mips64 -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
18; RUN: llc -march=mips64 -mcpu=mips64r3 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
19; RUN: llc -march=mips64 -mcpu=mips64r5 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
20; RUN: llc -march=mips64 -mcpu=mips64r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=R6
21
22define void @ret_void() {
23; ALL-LABEL: ret_void:
24
25; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
26; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
27
28  ret void
29}
30
31define i8 @ret_i8() {
32; ALL-LABEL: ret_i8:
33; ALL-DAG:       addiu $2, $zero, 3
34
35; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
36; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
37
38  ret i8 3
39}
40
41define i16 @ret_i16_3() {
42; ALL-LABEL: ret_i16_3:
43; ALL-DAG:       addiu $2, $zero, 3
44
45; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
46; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
47
48  ret i16 3
49}
50
51define i16 @ret_i16_256() {
52; ALL-LABEL: ret_i16_256:
53; ALL-DAG:       addiu $2, $zero, 256
54
55; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
56; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
57
58  ret i16 256
59}
60
61define i16 @ret_i16_257() {
62; ALL-LABEL: ret_i16_257:
63; ALL-DAG:       addiu $2, $zero, 257
64
65; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
66; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
67
68  ret i16 257
69}
70
71define i32 @ret_i32_257() {
72; ALL-LABEL: ret_i32_257:
73; ALL-DAG:       addiu $2, $zero, 257
74
75; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
76; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
77
78  ret i32 257
79}
80
81define i32 @ret_i32_65536() {
82; ALL-LABEL: ret_i32_65536:
83; ALL-DAG:       lui $2, 1
84
85; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
86; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
87
88  ret i32 65536
89}
90
91define i32 @ret_i32_65537() {
92; ALL-LABEL: ret_i32_65537:
93; ALL:           lui $[[T0:[0-9]+]], 1
94; ALL-DAG:       ori $2, $[[T0]], 1
95
96; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
97; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
98
99  ret i32 65537
100}
101
102define i64 @ret_i64_65537() {
103; ALL-LABEL: ret_i64_65537:
104; ALL:           lui $[[T0:[0-9]+]], 1
105
106; GPR32-DAG:     ori $3, $[[T0]], 1
107; GPR32-DAG:     addiu $2, $zero, 0
108
109; GPR64-DAG:     daddiu $2, $[[T0]], 1
110
111; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
112; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
113
114  ret i64 65537
115}
116
117define i64 @ret_i64_281479271677952() {
118; ALL-LABEL: ret_i64_281479271677952:
119; ALL-DAG:       lui $[[T0:[0-9]+]], 1
120
121; GPR32-DAG:     ori $2, $[[T0]], 1
122; GPR32-DAG:     addiu $3, $zero, 0
123
124; GPR64-DAG:     daddiu $[[T1:[0-9]+]], $[[T0]], 1
125; GPR64-DAG:     dsll $2, $[[T1]], 32
126
127; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
128; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
129
130  ret i64 281479271677952
131}
132
133define i64 @ret_i64_281479271809026() {
134; ALL-LABEL: ret_i64_281479271809026:
135; GPR32-DAG:     lui $[[T0:[0-9]+]], 1
136; GPR32-DAG:     lui $[[T1:[0-9]+]], 2
137; GPR32-DAG:     ori $2, $[[T0]], 1
138; GPR32-DAG:     ori $3, $[[T1]], 2
139
140; GPR64-DAG:     ori  $[[T0:[0-9]+]], $zero, 32769
141; GPR64-DAG:     dsll $[[T1:[0-9]+]], $[[T0]], 16
142; GPR64-DAG:     daddiu $[[T0:[0-9]+]], $[[T0]], -32767
143; GPR64-DAG:     dsll $[[T1:[0-9]+]], $[[T0]], 17
144; GPR64-DAG:     daddiu $2, $[[T1]], 2
145
146; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
147; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
148
149  ret i64 281479271809026
150}
151
152define float @ret_float_0x0() {
153; ALL-LABEL: ret_float_0x0:
154
155; NO-MTHC1-DAG:  mtc1 $zero, $f0
156
157; MTHC1-DAG:     mtc1 $zero, $f0
158
159; DMTC-DAG:      dmtc1 $zero, $f0
160
161; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
162; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
163
164  ret float 0x0000000000000000
165}
166
167define float @ret_float_0x3() {
168; ALL-LABEL: ret_float_0x3:
169
170; Use a constant pool
171; O32-DAG:       lwc1 $f0, %lo($CPI
172; N64-DAG:       lwc1 $f0, %got_ofst($CPI
173
174; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
175; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
176
177; float constants are written as double constants
178  ret float 0x36b8000000000000
179}
180
181define double @ret_double_0x0() {
182; ALL-LABEL: ret_double_0x0:
183
184; NO-MTHC1-DAG:  mtc1 $zero, $f0
185; NO-MTHC1-DAG:  mtc1 $zero, $f1
186
187; MTHC1-DAG:     mtc1 $zero, $f0
188; MTHC1-DAG:     mthc1 $zero, $f0
189
190; DMTC-DAG:      dmtc1 $zero, $f0
191
192; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
193; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
194
195  ret double 0x0000000000000000
196}
197
198define double @ret_double_0x3() {
199; ALL-LABEL: ret_double_0x3:
200
201; Use a constant pool
202; O32-DAG:       ldc1 $f0, %lo($CPI
203; N64-DAG:       ldc1 $f0, %got_ofst($CPI
204
205; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
206; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
207
208  ret double 0x0000000000000003
209}
210