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 ; z with -3 67 define void @constraint_z_0() nounwind { 68 entry: 69 ; ALL-LABEL: constraint_z_0: 70 ; ALL: #APP 71 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 72 ; ALL: #NO_APP 73 tail call i32 asm sideeffect "addiu $0, $1, ${2:z}", "=r,r,I"(i32 7, i32 -3) ; 74 ret void 75 } 76 77 ; z with 0 78 define void @constraint_z_1() nounwind { 79 entry: 80 ; ALL-LABEL: constraint_z_1: 81 ; ALL: #APP 82 ; GAS: addu ${{[0-9]+}}, ${{[0-9]+}}, $0 83 ; IAS: move ${{[0-9]+}}, ${{[0-9]+}} 84 ; ALL: #NO_APP 85 tail call i32 asm sideeffect "addu $0, $1, ${2:z}", "=r,r,I"(i32 7, i32 0) nounwind 86 ret void 87 } 88 89 ; z with non-zero and the "r"(register) and "J"(integer zero) constraints 90 define void @constraint_z_2() nounwind { 91 entry: 92 ; ALL-LABEL: constraint_z_2: 93 ; ALL: #APP 94 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 95 ; ALL: #NO_APP 96 call void asm sideeffect "mtc0 ${0:z}, $$12", "Jr"(i32 7) nounwind 97 ret void 98 } 99 100 ; z with zero and the "r"(register) and "J"(integer zero) constraints 101 define void @constraint_z_3() nounwind { 102 entry: 103 ; ALL-LABEL: constraint_z_3: 104 ; ALL: #APP 105 ; GAS: mtc0 $0, ${{[0-9]+}} 106 ; IAS: mtc0 $zero, ${{[0-9]+}}, 0 107 ; ALL: #NO_APP 108 call void asm sideeffect "mtc0 ${0:z}, $$12", "Jr"(i32 0) nounwind 109 ret void 110 } 111 112 ; z with non-zero and just the "r"(register) constraint 113 define void @constraint_z_4() nounwind { 114 entry: 115 ; ALL-LABEL: constraint_z_4: 116 ; ALL: #APP 117 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 118 ; ALL: #NO_APP 119 call void asm sideeffect "mtc0 ${0:z}, $$12", "r"(i32 7) nounwind 120 ret void 121 } 122 123 ; z with zero and just the "r"(register) constraint 124 define void @constraint_z_5() nounwind { 125 entry: 126 ; ALL-LABEL: constraint_z_5: 127 ; FIXME: Check for $0, instead of other registers. 128 ; We should be using $0 directly in this case, not real registers. 129 ; When the materialization of 0 gets fixed, this test will fail. 130 ; ALL: #APP 131 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 132 ; ALL: #NO_APP 133 call void asm sideeffect "mtc0 ${0:z}, $$12", "r"(i32 0) nounwind 134 ret void 135 } 136 137 ; A long long in 32 bit mode (use to assert) 138 define i32 @constraint_longlong() nounwind { 139 entry: 140 ; ALL-LABEL: constraint_longlong: 141 ; ALL: #APP 142 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, 3 143 ; ALL: #NO_APP 144 tail call i64 asm sideeffect "addiu $0, $1, $2 \0A\09", "=r,r,X"(i64 1229801703532086340, i64 3) nounwind 145 ret i32 0 146 } 147 148 ; In little endian the source reg will be 4 bytes into the long long 149 ; In big endian the source reg will also be 4 bytes into the long long 150 define i32 @constraint_D() nounwind { 151 entry: 152 ; ALL-LABEL: constraint_D: 153 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 154 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 155 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 156 ; ALL: #APP 157 ; LE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 158 ; BE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 159 ; ALL: #NO_APP 160 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 161 %trunc1 = trunc i64 %bosco to i32 162 tail call i32 asm sideeffect "or $0, ${1:D}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 163 ret i32 0 164 } 165 166 ; In little endian the source reg will be 0 bytes into the long long 167 ; In big endian the source reg will be 4 bytes into the long long 168 define i32 @constraint_L() nounwind { 169 entry: 170 ; ALL-LABEL: constraint_L: 171 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 172 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 173 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 174 ; ALL: #APP 175 ; LE32: or ${{[0-9]+}}, $[[FIRST]], ${{[0-9]+}} 176 ; BE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 177 ; ALL: #NO_APP 178 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 179 %trunc1 = trunc i64 %bosco to i32 180 tail call i32 asm sideeffect "or $0, ${1:L}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 181 ret i32 0 182 } 183 184 ; In little endian the source reg will be 4 bytes into the long long 185 ; In big endian the source reg will be 0 bytes into the long long 186 define i32 @constraint_M() nounwind { 187 entry: 188 ; ALL-LABEL: constraint_M: 189 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 190 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 191 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 192 ; ALL: #APP 193 ; LE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 194 ; BE32: or ${{[0-9]+}}, $[[FIRST]], ${{[0-9]+}} 195 ; ALL: #NO_APP 196 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 197 %trunc1 = trunc i64 %bosco to i32 198 tail call i32 asm sideeffect "or $0, ${1:M}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 199 ret i32 0 200 } 201