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 19define i32 @constraint_X() nounwind { 20entry: 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 31define i32 @constraint_x() nounwind { 32entry: 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 45define i32 @constraint_d() nounwind { 46entry: 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 56define i32 @constraint_m() nounwind { 57entry: 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 67define void @constraint_z_0() nounwind { 68entry: 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 78define void @constraint_z_1() nounwind { 79entry: 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 90define void @constraint_z_2() nounwind { 91entry: 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 101define void @constraint_z_3() nounwind { 102entry: 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 113define void @constraint_z_4() nounwind { 114entry: 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 124define void @constraint_z_5() nounwind { 125entry: 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) 138define i32 @constraint_longlong() nounwind { 139entry: 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 150define i32 @constraint_D() nounwind { 151entry: 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 168define i32 @constraint_L() nounwind { 169entry: 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 186define i32 @constraint_M() nounwind { 187entry: 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