1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic | FileCheck %s --check-prefix=O32 3 ; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic | FileCheck %s --check-prefix=N64 4 ; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 | FileCheck %s --check-prefix=N32 5 ; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -O3 | FileCheck %s --check-prefix=O3O32 6 ; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -O3 | FileCheck %s --check-prefix=O3N64 7 ; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -O3 | FileCheck %s --check-prefix=O3N32 8 9 ; Test that PIC calls use the $25 register. This is an ABI requirement. 10 11 @p = external global i32 12 @q = external global i32 13 @r = external global i32 14 15 define void @f0() nounwind { 16 ; O32-LABEL: f0: 17 ; O32: # %bb.0: # %entry 18 ; O32-NEXT: lui $2, %hi(_gp_disp) 19 ; O32-NEXT: addiu $2, $2, %lo(_gp_disp) 20 ; O32-NEXT: addiu $sp, $sp, -32 21 ; O32-NEXT: sw $ra, 28($sp) # 4-byte Folded Spill 22 ; O32-NEXT: sw $17, 24($sp) # 4-byte Folded Spill 23 ; O32-NEXT: sw $16, 20($sp) # 4-byte Folded Spill 24 ; O32-NEXT: addu $16, $2, $25 25 ; O32-NEXT: lw $25, %call16(f1)($16) 26 ; O32-NEXT: jalr $25 27 ; O32-NEXT: move $gp, $16 28 ; O32-NEXT: lw $1, %got(p)($16) 29 ; O32-NEXT: lw $4, 0($1) 30 ; O32-NEXT: lw $25, %call16(f2)($16) 31 ; O32-NEXT: jalr $25 32 ; O32-NEXT: move $gp, $16 33 ; O32-NEXT: lw $1, %got(q)($16) 34 ; O32-NEXT: lw $17, 0($1) 35 ; O32-NEXT: lw $25, %call16(f2)($16) 36 ; O32-NEXT: jalr $25 37 ; O32-NEXT: move $4, $17 38 ; O32-NEXT: lw $1, %got(r)($16) 39 ; O32-NEXT: lw $5, 0($1) 40 ; O32-NEXT: lw $25, %call16(f3)($16) 41 ; O32-NEXT: move $4, $17 42 ; O32-NEXT: jalr $25 43 ; O32-NEXT: move $gp, $16 44 ; O32-NEXT: lw $16, 20($sp) # 4-byte Folded Reload 45 ; O32-NEXT: lw $17, 24($sp) # 4-byte Folded Reload 46 ; O32-NEXT: lw $ra, 28($sp) # 4-byte Folded Reload 47 ; O32-NEXT: jr $ra 48 ; O32-NEXT: addiu $sp, $sp, 32 49 ; 50 ; N64-LABEL: f0: 51 ; N64: # %bb.0: # %entry 52 ; N64-NEXT: daddiu $sp, $sp, -32 53 ; N64-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill 54 ; N64-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill 55 ; N64-NEXT: sd $16, 8($sp) # 8-byte Folded Spill 56 ; N64-NEXT: lui $1, %hi(%neg(%gp_rel(f0))) 57 ; N64-NEXT: daddu $1, $1, $25 58 ; N64-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(f0))) 59 ; N64-NEXT: ld $25, %call16(f1)($gp) 60 ; N64-NEXT: jalr $25 61 ; N64-NEXT: nop 62 ; N64-NEXT: ld $1, %got_disp(p)($gp) 63 ; N64-NEXT: ld $25, %call16(f2)($gp) 64 ; N64-NEXT: jalr $25 65 ; N64-NEXT: lw $4, 0($1) 66 ; N64-NEXT: ld $1, %got_disp(q)($gp) 67 ; N64-NEXT: lw $16, 0($1) 68 ; N64-NEXT: ld $25, %call16(f2)($gp) 69 ; N64-NEXT: jalr $25 70 ; N64-NEXT: move $4, $16 71 ; N64-NEXT: ld $1, %got_disp(r)($gp) 72 ; N64-NEXT: lw $5, 0($1) 73 ; N64-NEXT: ld $25, %call16(f3)($gp) 74 ; N64-NEXT: jalr $25 75 ; N64-NEXT: move $4, $16 76 ; N64-NEXT: ld $16, 8($sp) # 8-byte Folded Reload 77 ; N64-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload 78 ; N64-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload 79 ; N64-NEXT: jr $ra 80 ; N64-NEXT: daddiu $sp, $sp, 32 81 ; 82 ; N32-LABEL: f0: 83 ; N32: # %bb.0: # %entry 84 ; N32-NEXT: addiu $sp, $sp, -32 85 ; N32-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill 86 ; N32-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill 87 ; N32-NEXT: sd $16, 8($sp) # 8-byte Folded Spill 88 ; N32-NEXT: lui $1, %hi(%neg(%gp_rel(f0))) 89 ; N32-NEXT: addu $1, $1, $25 90 ; N32-NEXT: addiu $gp, $1, %lo(%neg(%gp_rel(f0))) 91 ; N32-NEXT: lw $25, %call16(f1)($gp) 92 ; N32-NEXT: jalr $25 93 ; N32-NEXT: nop 94 ; N32-NEXT: lw $1, %got_disp(p)($gp) 95 ; N32-NEXT: lw $25, %call16(f2)($gp) 96 ; N32-NEXT: jalr $25 97 ; N32-NEXT: lw $4, 0($1) 98 ; N32-NEXT: lw $1, %got_disp(q)($gp) 99 ; N32-NEXT: lw $16, 0($1) 100 ; N32-NEXT: lw $25, %call16(f2)($gp) 101 ; N32-NEXT: jalr $25 102 ; N32-NEXT: move $4, $16 103 ; N32-NEXT: lw $1, %got_disp(r)($gp) 104 ; N32-NEXT: lw $5, 0($1) 105 ; N32-NEXT: lw $25, %call16(f3)($gp) 106 ; N32-NEXT: jalr $25 107 ; N32-NEXT: move $4, $16 108 ; N32-NEXT: ld $16, 8($sp) # 8-byte Folded Reload 109 ; N32-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload 110 ; N32-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload 111 ; N32-NEXT: jr $ra 112 ; N32-NEXT: addiu $sp, $sp, 32 113 ; 114 ; O3O32-LABEL: f0: 115 ; O3O32: # %bb.0: # %entry 116 ; O3O32-NEXT: lui $2, %hi(_gp_disp) 117 ; O3O32-NEXT: addiu $2, $2, %lo(_gp_disp) 118 ; O3O32-NEXT: addiu $sp, $sp, -32 119 ; O3O32-NEXT: sw $ra, 28($sp) # 4-byte Folded Spill 120 ; O3O32-NEXT: sw $17, 24($sp) # 4-byte Folded Spill 121 ; O3O32-NEXT: sw $16, 20($sp) # 4-byte Folded Spill 122 ; O3O32-NEXT: addu $16, $2, $25 123 ; O3O32-NEXT: lw $25, %call16(f1)($16) 124 ; O3O32-NEXT: jalr $25 125 ; O3O32-NEXT: move $gp, $16 126 ; O3O32-NEXT: lw $1, %got(p)($16) 127 ; O3O32-NEXT: lw $25, %call16(f2)($16) 128 ; O3O32-NEXT: move $gp, $16 129 ; O3O32-NEXT: jalr $25 130 ; O3O32-NEXT: lw $4, 0($1) 131 ; O3O32-NEXT: lw $1, %got(q)($16) 132 ; O3O32-NEXT: lw $25, %call16(f2)($16) 133 ; O3O32-NEXT: lw $17, 0($1) 134 ; O3O32-NEXT: jalr $25 135 ; O3O32-NEXT: move $4, $17 136 ; O3O32-NEXT: lw $1, %got(r)($16) 137 ; O3O32-NEXT: lw $25, %call16(f3)($16) 138 ; O3O32-NEXT: move $4, $17 139 ; O3O32-NEXT: move $gp, $16 140 ; O3O32-NEXT: jalr $25 141 ; O3O32-NEXT: lw $5, 0($1) 142 ; O3O32-NEXT: lw $16, 20($sp) # 4-byte Folded Reload 143 ; O3O32-NEXT: lw $17, 24($sp) # 4-byte Folded Reload 144 ; O3O32-NEXT: lw $ra, 28($sp) # 4-byte Folded Reload 145 ; O3O32-NEXT: jr $ra 146 ; O3O32-NEXT: addiu $sp, $sp, 32 147 ; 148 ; O3N64-LABEL: f0: 149 ; O3N64: # %bb.0: # %entry 150 ; O3N64-NEXT: daddiu $sp, $sp, -32 151 ; O3N64-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill 152 ; O3N64-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill 153 ; O3N64-NEXT: sd $16, 8($sp) # 8-byte Folded Spill 154 ; O3N64-NEXT: lui $1, %hi(%neg(%gp_rel(f0))) 155 ; O3N64-NEXT: daddu $1, $1, $25 156 ; O3N64-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(f0))) 157 ; O3N64-NEXT: ld $25, %call16(f1)($gp) 158 ; O3N64-NEXT: jalr $25 159 ; O3N64-NEXT: nop 160 ; O3N64-NEXT: ld $1, %got_disp(p)($gp) 161 ; O3N64-NEXT: ld $25, %call16(f2)($gp) 162 ; O3N64-NEXT: jalr $25 163 ; O3N64-NEXT: lw $4, 0($1) 164 ; O3N64-NEXT: ld $1, %got_disp(q)($gp) 165 ; O3N64-NEXT: ld $25, %call16(f2)($gp) 166 ; O3N64-NEXT: lw $16, 0($1) 167 ; O3N64-NEXT: jalr $25 168 ; O3N64-NEXT: move $4, $16 169 ; O3N64-NEXT: ld $1, %got_disp(r)($gp) 170 ; O3N64-NEXT: ld $25, %call16(f3)($gp) 171 ; O3N64-NEXT: move $4, $16 172 ; O3N64-NEXT: jalr $25 173 ; O3N64-NEXT: lw $5, 0($1) 174 ; O3N64-NEXT: ld $16, 8($sp) # 8-byte Folded Reload 175 ; O3N64-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload 176 ; O3N64-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload 177 ; O3N64-NEXT: jr $ra 178 ; O3N64-NEXT: daddiu $sp, $sp, 32 179 ; 180 ; O3N32-LABEL: f0: 181 ; O3N32: # %bb.0: # %entry 182 ; O3N32-NEXT: addiu $sp, $sp, -32 183 ; O3N32-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill 184 ; O3N32-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill 185 ; O3N32-NEXT: sd $16, 8($sp) # 8-byte Folded Spill 186 ; O3N32-NEXT: lui $1, %hi(%neg(%gp_rel(f0))) 187 ; O3N32-NEXT: addu $1, $1, $25 188 ; O3N32-NEXT: addiu $gp, $1, %lo(%neg(%gp_rel(f0))) 189 ; O3N32-NEXT: lw $25, %call16(f1)($gp) 190 ; O3N32-NEXT: jalr $25 191 ; O3N32-NEXT: nop 192 ; O3N32-NEXT: lw $1, %got_disp(p)($gp) 193 ; O3N32-NEXT: lw $25, %call16(f2)($gp) 194 ; O3N32-NEXT: jalr $25 195 ; O3N32-NEXT: lw $4, 0($1) 196 ; O3N32-NEXT: lw $1, %got_disp(q)($gp) 197 ; O3N32-NEXT: lw $25, %call16(f2)($gp) 198 ; O3N32-NEXT: lw $16, 0($1) 199 ; O3N32-NEXT: jalr $25 200 ; O3N32-NEXT: move $4, $16 201 ; O3N32-NEXT: lw $1, %got_disp(r)($gp) 202 ; O3N32-NEXT: lw $25, %call16(f3)($gp) 203 ; O3N32-NEXT: move $4, $16 204 ; O3N32-NEXT: jalr $25 205 ; O3N32-NEXT: lw $5, 0($1) 206 ; O3N32-NEXT: ld $16, 8($sp) # 8-byte Folded Reload 207 ; O3N32-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload 208 ; O3N32-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload 209 ; O3N32-NEXT: jr $ra 210 ; O3N32-NEXT: addiu $sp, $sp, 32 211 entry: 212 tail call void @f1() nounwind 213 %tmp = load i32, i32* @p, align 4 214 tail call void @f2(i32 %tmp) nounwind 215 %tmp1 = load i32, i32* @q, align 4 216 tail call void @f2(i32 %tmp1) nounwind 217 %tmp2 = load i32, i32* @r, align 4 218 tail call void @f3(i32 %tmp1, i32 %tmp2) nounwind 219 ret void 220 } 221 222 declare void @f1() 223 224 declare void @f2(i32) 225 226 declare void @f3(i32, i32) 227 228