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