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 18 define 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 27 define 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 37 define 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 47 define 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 57 define 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 67 define 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 77 define 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 87 define 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 98 define 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 113 define 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 129 define 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 148 define 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 163 define 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 177 define 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 194 define 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