1; RUN: llc < %s -march=mips -mcpu=mips2 -relocation-model=pic | FileCheck %s \ 2; RUN: --check-prefixes=ALL,GP32,GP32-M 3; RUN: llc < %s -march=mips -mcpu=mips32 -relocation-model=pic | FileCheck %s \ 4; RUN: --check-prefixes=ALL,GP32,GP32-M 5; RUN: llc < %s -march=mips -mcpu=mips32r6 -relocation-model=pic | FileCheck %s \ 6; RUN: --check-prefixes=ALL,GP32,GP32-M 7; RUN: llc < %s -march=mips -mcpu=mips32r2 -mattr=+micromips -relocation-model=pic | FileCheck %s \ 8; RUN: --check-prefixes=ALL,GP32,GP32-MM,GP32-MMR2 9; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ 10; RUN: --check-prefixes=ALL,GP32,GP32-MM,GP32-MMR6 11; RUN: llc < %s -march=mips64 -mcpu=mips3 -relocation-model=pic | FileCheck %s \ 12; RUN: --check-prefixes=ALL,GP64,N64 13; RUN: llc < %s -march=mips64 -mcpu=mips64 -relocation-model=pic | FileCheck %s \ 14; RUN: --check-prefixes=ALL,GP64,N64 15; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ 16; RUN: --check-prefixes=ALL,GP64,N64 17; RUN: llc < %s -march=mips64 -mcpu=mips3 -target-abi n32 -relocation-model=pic | FileCheck %s \ 18; RUN: --check-prefixes=ALL,GP64,N32 19; RUN: llc < %s -march=mips64 -mcpu=mips64 -target-abi n32 -relocation-model=pic | FileCheck %s \ 20; RUN: --check-prefixes=ALL,GP64,N32 21; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -target-abi n32 -relocation-model=pic | FileCheck %s \ 22; RUN: --check-prefixes=ALL,GP64,N32 23 24; Check dynamic stack realignment in functions without variable-sized objects. 25 26declare void @helper_01(i32, i32, i32, i32, i32*) 27 28; O32 ABI 29define void @func_01() { 30entry: 31; GP32-LABEL: func_01: 32 33 ; prologue 34 ; FIXME: We are currently over-allocating stack space. This particular case 35 ; needs a frame of up to between 16 and 512-bytes but currently 36 ; allocates between 1024 and 1536 bytes 37 ; GP32-M: addiu $sp, $sp, -1024 38 ; GP32-MMR2: addiusp -1024 39 ; GP32-MMR6: addiu $sp, $sp, -1024 40 ; GP32: sw $ra, 1020($sp) 41 ; GP32: sw $fp, 1016($sp) 42 ; 43 ; GP32: move $fp, $sp 44 ; GP32: addiu $[[T0:[0-9]+|ra|gp]], $zero, -512 45 ; GP32-NEXT: and $sp, $sp, $[[T0]] 46 47 ; body 48 ; GP32: addiu $[[T1:[0-9]+]], $sp, 512 49 ; GP32-M: sw $[[T1]], 16($sp) 50 ; GP32-MM: sw16 $[[T1]], 16(${{[0-9]+}}) 51 52 ; epilogue 53 ; GP32: move $sp, $fp 54 ; GP32: lw $fp, 1016($sp) 55 ; GP32: lw $ra, 1020($sp) 56 ; GP32-M: addiu $sp, $sp, 1024 57 ; GP32-MMR2: addiusp 1024 58 ; GP32-MMR6: addiu $sp, $sp, 1024 59 60 %a = alloca i32, align 512 61 call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) 62 ret void 63} 64 65declare void @helper_02(i32, i32, i32, i32, 66 i32, i32, i32, i32, i32*) 67 68; N32/N64 ABIs 69define void @func_02() { 70entry: 71; GP64-LABEL: func_02: 72 73 ; prologue 74 ; FIXME: We are currently over-allocating stack space. This particular case 75 ; needs a frame of up to between 16 and 512-bytes but currently 76 ; allocates between 1024 and 1536 bytes 77 ; N32: addiu $sp, $sp, -1024 78 ; N64: daddiu $sp, $sp, -1024 79 ; GP64: sd $ra, 1016($sp) 80 ; GP64: sd $fp, 1008($sp) 81 ; N32: sd $gp, 1000($sp) 82 ; 83 ; GP64: move $fp, $sp 84 ; N32: addiu $[[T0:[0-9]+|ra]], $zero, -512 85 ; N64: daddiu $[[T0:[0-9]+|ra]], $zero, -512 86 ; GP64-NEXT: and $sp, $sp, $[[T0]] 87 88 ; body 89 ; N32: addiu $[[T1:[0-9]+]], $sp, 512 90 ; N64: daddiu $[[T1:[0-9]+]], $sp, 512 91 ; GP64: sd $[[T1]], 0($sp) 92 93 ; epilogue 94 ; GP64: move $sp, $fp 95 ; N32: ld $gp, 1000($sp) 96 ; GP64: ld $fp, 1008($sp) 97 ; GP64: ld $ra, 1016($sp) 98 ; N32: addiu $sp, $sp, 1024 99 ; N64: daddiu $sp, $sp, 1024 100 101 %a = alloca i32, align 512 102 call void @helper_02(i32 0, i32 0, i32 0, i32 0, 103 i32 0, i32 0, i32 0, i32 0, i32* %a) 104 ret void 105} 106 107; Verify that we use $fp for referencing incoming arguments. 108 109declare void @helper_03(i32, i32, i32, i32, i32*, i32*) 110 111; O32 ABI 112define void @func_03(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32* %b) { 113entry: 114; GP32-LABEL: func_03: 115 116 ; body 117 ; FIXME: We are currently over-allocating stack space. 118 ; GP32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 119 ; GP32-M-DAG: sw $[[T0]], 16($sp) 120 ; GP32-MM-DAG: sw16 $[[T0]], 16(${{[0-9]+}}) 121 ; GP32-DAG: lw $[[T1:[0-9]+]], 1040($fp) 122 ; GP32-M-DAG: sw $[[T1]], 20($sp) 123 ; GP32-MM-DAG: sw16 $[[T1]], 20(${{[0-9]+}}) 124 125 %a = alloca i32, align 512 126 call void @helper_03(i32 0, i32 0, i32 0, i32 0, i32* %a, i32* %b) 127 ret void 128} 129 130declare void @helper_04(i32, i32, i32, i32, 131 i32, i32, i32, i32, i32*, i32*) 132 133; N32/N64 ABIs 134define void @func_04(i32 %p0, i32 %p1, i32 %p2, i32 %p3, 135 i32 %p4, i32 %p5, i32 %p6, i32 %p7, 136 i32* %b) { 137entry: 138; GP64-LABEL: func_04: 139 140 ; body 141 ; FIXME: We are currently over-allocating stack space. 142 ; N32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 143 ; N64-DAG: daddiu $[[T0:[0-9]+]], $sp, 512 144 ; GP64-DAG: sd $[[T0]], 0($sp) 145 ; GP64-DAG: ld $[[T1:[0-9]+]], 1024($fp) 146 ; GP64-DAG: sd $[[T1]], 8($sp) 147 148 %a = alloca i32, align 512 149 call void @helper_04(i32 0, i32 0, i32 0, i32 0, 150 i32 0, i32 0, i32 0, i32 0, i32* %a, i32* %b) 151 ret void 152} 153 154; Check dynamic stack realignment in functions with variable-sized objects. 155 156; O32 ABI 157define void @func_05(i32 %sz) { 158entry: 159; GP32-LABEL: func_05: 160 161 ; prologue 162 ; FIXME: We are currently over-allocating stack space. 163 ; GP32-M: addiu $sp, $sp, -1024 164 ; GP32-MMR2: addiusp -1024 165 ; GP32-MMR6: addiu $sp, $sp, -1024 166 ; GP32: sw $fp, 1020($sp) 167 ; GP32: sw $23, 1016($sp) 168 ; 169 ; GP32: move $fp, $sp 170 ; GP32: addiu $[[T0:[0-9]+|gp]], $zero, -512 171 ; GP32-NEXT: and $sp, $sp, $[[T0]] 172 ; GP32-NEXT: move $23, $sp 173 174 ; body 175 ; GP32: addiu $[[T1:[0-9]+]], $zero, 222 176 ; GP32: sw $[[T1]], 508($23) 177 178 ; epilogue 179 ; GP32: move $sp, $fp 180 ; GP32: lw $23, 1016($sp) 181 ; GP32: lw $fp, 1020($sp) 182 ; GP32-M: addiu $sp, $sp, 1024 183 ; GP32-MMR2: addiusp 1024 184 ; GP32-MMR6: addiu $sp, $sp, 1024 185 186 %a0 = alloca i32, i32 %sz, align 512 187 %a1 = alloca i32, align 4 188 189 store volatile i32 111, i32* %a0, align 512 190 store volatile i32 222, i32* %a1, align 4 191 192 ret void 193} 194 195; N32/N64 ABIs 196define void @func_06(i32 %sz) { 197entry: 198; GP64-LABEL: func_06: 199 200 ; prologue 201 ; FIXME: We are currently over-allocating stack space. 202 ; N32: addiu $sp, $sp, -1024 203 ; N64: daddiu $sp, $sp, -1024 204 ; GP64: sd $fp, 1016($sp) 205 ; GP64: sd $23, 1008($sp) 206 ; 207 ; GP64: move $fp, $sp 208 ; GP64: addiu $[[T0:[0-9]+|gp]], $zero, -512 209 ; GP64-NEXT: and $sp, $sp, $[[T0]] 210 ; GP64-NEXT: move $23, $sp 211 212 ; body 213 ; GP64: addiu $[[T1:[0-9]+]], $zero, 222 214 ; GP64: sw $[[T1]], 508($23) 215 216 ; epilogue 217 ; GP64: move $sp, $fp 218 ; GP64: ld $23, 1008($sp) 219 ; GP64: ld $fp, 1016($sp) 220 ; N32: addiu $sp, $sp, 1024 221 ; N64: daddiu $sp, $sp, 1024 222 223 %a0 = alloca i32, i32 %sz, align 512 224 %a1 = alloca i32, align 4 225 226 store volatile i32 111, i32* %a0, align 512 227 store volatile i32 222, i32* %a1, align 4 228 229 ret void 230} 231 232; Verify that we use $fp for referencing incoming arguments and $sp for 233; building outbound arguments for nested function calls. 234 235; O32 ABI 236define void @func_07(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %sz) { 237entry: 238; GP32-LABEL: func_07: 239 240 ; body 241 ; FIXME: We are currently over-allocating stack space. 242 ; GP32-DAG: lw $[[T0:[0-9]+]], 1040($fp) 243 ; 244 ; GP32-DAG: addiu $[[T1:[0-9]+]], $zero, 222 245 ; GP32-DAG: sw $[[T1]], 508($23) 246 ; 247 ; GP32-M-DAG: sw $[[T2:[0-9]+]], 16($sp) 248 ; GP32-MM-DAG: sw16 $[[T2:[0-9]+]], 16($[[T3:[0-9]+]]) 249 250 %a0 = alloca i32, i32 %sz, align 512 251 %a1 = alloca i32, align 4 252 253 store volatile i32 111, i32* %a0, align 512 254 store volatile i32 222, i32* %a1, align 4 255 256 call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a1) 257 258 ret void 259} 260 261; N32/N64 ABIs 262define void @func_08(i32 %p0, i32 %p1, i32 %p2, i32 %p3, 263 i32 %p4, i32 %p5, i32 %p6, i32 %p7, 264 i32 %sz) { 265entry: 266; GP64-LABEL: func_08: 267 268 ; body 269 ; FIXME: We are currently over-allocating stack space. 270 ; N32-DAG: lw $[[T0:[0-9]+]], 1028($fp) 271 ; N64-DAG: lwu $[[T0:[0-9]+]], 1028($fp) 272 ; 273 ; GP64-DAG: addiu $[[T1:[0-9]+]], $zero, 222 274 ; GP64-DAG: sw $[[T1]], 508($23) 275 ; 276 ; GP64-DAG: sd $[[T2:[0-9]+]], 0($sp) 277 278 %a0 = alloca i32, i32 %sz, align 512 279 %a1 = alloca i32, align 4 280 281 store volatile i32 111, i32* %a0, align 512 282 store volatile i32 222, i32* %a1, align 4 283 284 call void @helper_02(i32 0, i32 0, i32 0, i32 0, 285 i32 0, i32 0, i32 0, i32 0, i32* %a1) 286 ret void 287} 288 289; Check that we do not perform dynamic stack realignment in the presence of 290; the "no-realign-stack" function attribute. 291define void @func_09() "no-realign-stack" { 292entry: 293; ALL-LABEL: func_09: 294 295 ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] 296 297 %a = alloca i32, align 512 298 call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) 299 ret void 300} 301 302define void @func_10(i32 %sz) "no-realign-stack" { 303entry: 304; ALL-LABEL: func_10: 305 306 ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] 307 308 %a0 = alloca i32, i32 %sz, align 512 309 %a1 = alloca i32, align 4 310 311 store volatile i32 111, i32* %a0, align 512 312 store volatile i32 222, i32* %a1, align 4 313 314 ret void 315} 316