1 ; Positive test for inline register constraints 2 ; 3 ; RUN: llc -no-integrated-as -march=mipsel -relocation-model=pic < %s | \ 4 ; RUN: FileCheck -check-prefixes=ALL,LE32,GAS %s 5 ; RUN: llc -no-integrated-as -march=mips -relocation-model=pic < %s | \ 6 ; RUN: FileCheck -check-prefixes=ALL,BE32,GAS %s 7 8 ; IAS might not print in the same way since it parses the assembly. 9 ; RUN: llc -march=mipsel -relocation-model=pic < %s | \ 10 ; RUN: FileCheck -check-prefixes=ALL,LE32,IAS %s 11 ; RUN: llc -march=mips -relocation-model=pic < %s | \ 12 ; RUN: FileCheck -check-prefixes=ALL,BE32,IAS %s 13 14 %union.u_tag = type { i64 } 15 %struct.anon = type { i32, i32 } 16 @uval = common global %union.u_tag zeroinitializer, align 8 17 18 ; X with -3 19 define i32 @constraint_X() nounwind { 20 entry: 21 ; ALL-LABEL: constraint_X: 22 ; ALL: #APP 23 ; GAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, 0xfffffffffffffffd 24 ; IAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 25 ; ALL: #NO_APP 26 tail call i32 asm sideeffect "addiu $0, $1, ${2:X}", "=r,r,I"(i32 7, i32 -3) ; 27 ret i32 0 28 } 29 30 ; x with -3 31 define i32 @constraint_x() nounwind { 32 entry: 33 ; ALL-LABEL: constraint_x: 34 ; ALL: #APP 35 ; GAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, 0xfffd 36 ; This is _also_ -3 because uimm16 values are silently coerced to simm16 when 37 ; it would otherwise fail to match. 38 ; IAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 39 ; ALL: #NO_APP 40 tail call i32 asm sideeffect "addiu $0, $1, ${2:x}", "=r,r,I"(i32 7, i32 -3) ; 41 ret i32 0 42 } 43 44 ; d with -3 45 define i32 @constraint_d() nounwind { 46 entry: 47 ; ALL-LABEL: constraint_d: 48 ; ALL: #APP 49 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 50 ; ALL: #NO_APP 51 tail call i32 asm sideeffect "addiu $0, $1, ${2:d}", "=r,r,I"(i32 7, i32 -3) ; 52 ret i32 0 53 } 54 55 ; m with -3 56 define i32 @constraint_m() nounwind { 57 entry: 58 ; ALL-LABEL: constraint_m: 59 ; ALL: #APP 60 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -4 61 ; ALL: #NO_APP 62 tail call i32 asm sideeffect "addiu $0, $1, ${2:m}", "=r,r,I"(i32 7, i32 -3) ; 63 ret i32 0 64 } 65 66 ; y with 4 67 define i32 @constraint_y_4() nounwind { 68 entry: 69 ; ALL-LABEL: constraint_y_4: 70 ; ALL: #APP 71 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, 2 72 ; ALL: #NO_APP 73 tail call i32 asm sideeffect "addiu $0, $1, ${2:y}", "=r,r,I"(i32 7, i32 4) ; 74 ret i32 0 75 } 76 77 ; z with -3 78 define void @constraint_z_0() nounwind { 79 entry: 80 ; ALL-LABEL: constraint_z_0: 81 ; ALL: #APP 82 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 83 ; ALL: #NO_APP 84 tail call i32 asm sideeffect "addiu $0, $1, ${2:z}", "=r,r,I"(i32 7, i32 -3) ; 85 ret void 86 } 87 88 ; z with 0 89 define void @constraint_z_1() nounwind { 90 entry: 91 ; ALL-LABEL: constraint_z_1: 92 ; ALL: #APP 93 ; GAS: addu ${{[0-9]+}}, ${{[0-9]+}}, $0 94 ; IAS: move ${{[0-9]+}}, ${{[0-9]+}} 95 ; ALL: #NO_APP 96 tail call i32 asm sideeffect "addu $0, $1, ${2:z}", "=r,r,I"(i32 7, i32 0) nounwind 97 ret void 98 } 99 100 ; z with non-zero and the "r"(register) and "J"(integer zero) constraints 101 define void @constraint_z_2() nounwind { 102 entry: 103 ; ALL-LABEL: constraint_z_2: 104 ; ALL: #APP 105 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 106 ; ALL: #NO_APP 107 call void asm sideeffect "mtc0 ${0:z}, $$12", "Jr"(i32 7) nounwind 108 ret void 109 } 110 111 ; z with zero and the "r"(register) and "J"(integer zero) constraints 112 define void @constraint_z_3() nounwind { 113 entry: 114 ; ALL-LABEL: constraint_z_3: 115 ; ALL: #APP 116 ; GAS: mtc0 $0, ${{[0-9]+}} 117 ; IAS: mtc0 $zero, ${{[0-9]+}}, 0 118 ; ALL: #NO_APP 119 call void asm sideeffect "mtc0 ${0:z}, $$12", "Jr"(i32 0) nounwind 120 ret void 121 } 122 123 ; z with non-zero and just the "r"(register) constraint 124 define void @constraint_z_4() nounwind { 125 entry: 126 ; ALL-LABEL: constraint_z_4: 127 ; ALL: #APP 128 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 129 ; ALL: #NO_APP 130 call void asm sideeffect "mtc0 ${0:z}, $$12", "r"(i32 7) nounwind 131 ret void 132 } 133 134 ; z with zero and just the "r"(register) constraint 135 define void @constraint_z_5() nounwind { 136 entry: 137 ; ALL-LABEL: constraint_z_5: 138 ; FIXME: Check for $0, instead of other registers. 139 ; We should be using $0 directly in this case, not real registers. 140 ; When the materialization of 0 gets fixed, this test will fail. 141 ; ALL: #APP 142 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 143 ; ALL: #NO_APP 144 call void asm sideeffect "mtc0 ${0:z}, $$12", "r"(i32 0) nounwind 145 ret void 146 } 147 148 ; A long long in 32 bit mode (use to assert) 149 define i32 @constraint_longlong() nounwind { 150 entry: 151 ; ALL-LABEL: constraint_longlong: 152 ; ALL: #APP 153 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, 3 154 ; ALL: #NO_APP 155 tail call i64 asm sideeffect "addiu $0, $1, $2 \0A\09", "=r,r,X"(i64 1229801703532086340, i64 3) nounwind 156 ret i32 0 157 } 158 159 ; In little endian the source reg will be 4 bytes into the long long 160 ; In big endian the source reg will also be 4 bytes into the long long 161 define i32 @constraint_D() nounwind { 162 entry: 163 ; ALL-LABEL: constraint_D: 164 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 165 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 166 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 167 ; ALL: #APP 168 ; LE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 169 ; BE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 170 ; ALL: #NO_APP 171 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 172 %trunc1 = trunc i64 %bosco to i32 173 tail call i32 asm sideeffect "or $0, ${1:D}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 174 ret i32 0 175 } 176 177 ; In little endian the source reg will be 0 bytes into the long long 178 ; In big endian the source reg will be 4 bytes into the long long 179 define i32 @constraint_L() nounwind { 180 entry: 181 ; ALL-LABEL: constraint_L: 182 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 183 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 184 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 185 ; ALL: #APP 186 ; LE32: or ${{[0-9]+}}, $[[FIRST]], ${{[0-9]+}} 187 ; BE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 188 ; ALL: #NO_APP 189 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 190 %trunc1 = trunc i64 %bosco to i32 191 tail call i32 asm sideeffect "or $0, ${1:L}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 192 ret i32 0 193 } 194 195 ; In little endian the source reg will be 4 bytes into the long long 196 ; In big endian the source reg will be 0 bytes into the long long 197 define i32 @constraint_M() nounwind { 198 entry: 199 ; ALL-LABEL: constraint_M: 200 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 201 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 202 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 203 ; ALL: #APP 204 ; LE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 205 ; BE32: or ${{[0-9]+}}, $[[FIRST]], ${{[0-9]+}} 206 ; ALL: #NO_APP 207 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 208 %trunc1 = trunc i64 %bosco to i32 209 tail call i32 asm sideeffect "or $0, ${1:M}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 210 ret i32 0 211 } 212