1 ; Positive test for inline register constraints 2 ; 3 ; RUN: llc -no-integrated-as -march=mipsel < %s | \ 4 ; RUN: FileCheck -check-prefix=ALL -check-prefix=LE32 -check-prefix=GAS %s 5 ; RUN: llc -no-integrated-as -march=mips < %s | \ 6 ; RUN: FileCheck -check-prefix=ALL -check-prefix=BE32 -check-prefix=GAS %s 7 8 %union.u_tag = type { i64 } 9 %struct.anon = type { i32, i32 } 10 @uval = common global %union.u_tag zeroinitializer, align 8 11 12 ; X with -3 13 define i32 @constraint_X() nounwind { 14 entry: 15 ; ALL-LABEL: constraint_X: 16 ; ALL: #APP 17 ; GAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, 0xfffffffffffffffd 18 ; ALL: #NO_APP 19 tail call i32 asm sideeffect "addiu $0, $1, ${2:X}", "=r,r,I"(i32 7, i32 -3) ; 20 ret i32 0 21 } 22 23 ; x with -3 24 define i32 @constraint_x() nounwind { 25 entry: 26 ; ALL-LABEL: constraint_x: 27 ; ALL: #APP 28 ; GAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, 0xfffd 29 ; ALL: #NO_APP 30 tail call i32 asm sideeffect "addiu $0, $1, ${2:x}", "=r,r,I"(i32 7, i32 -3) ; 31 ret i32 0 32 } 33 34 ; d with -3 35 define i32 @constraint_d() nounwind { 36 entry: 37 ; ALL-LABEL: constraint_d: 38 ; ALL: #APP 39 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 40 ; ALL: #NO_APP 41 tail call i32 asm sideeffect "addiu $0, $1, ${2:d}", "=r,r,I"(i32 7, i32 -3) ; 42 ret i32 0 43 } 44 45 ; m with -3 46 define i32 @constraint_m() nounwind { 47 entry: 48 ; ALL-LABEL: constraint_m: 49 ; ALL: #APP 50 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -4 51 ; ALL: #NO_APP 52 tail call i32 asm sideeffect "addiu $0, $1, ${2:m}", "=r,r,I"(i32 7, i32 -3) ; 53 ret i32 0 54 } 55 56 ; z with -3 57 define i32 @constraint_z() nounwind { 58 entry: 59 ; ALL-LABEL: constraint_z: 60 ; ALL: #APP 61 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, -3 62 ; ALL: #NO_APP 63 tail call i32 asm sideeffect "addiu $0, $1, ${2:z}", "=r,r,I"(i32 7, i32 -3) ; 64 65 ; z with 0 66 ; ALL: #APP 67 ; GAS: addiu ${{[0-9]+}}, ${{[0-9]+}}, $0 68 ; ALL: #NO_APP 69 tail call i32 asm sideeffect "addiu $0, $1, ${2:z}", "=r,r,I"(i32 7, i32 0) nounwind 70 71 ; z with non-zero and the "r"(register) and "J"(integer zero) constraints 72 ; ALL: #APP 73 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 74 ; ALL: #NO_APP 75 call void asm sideeffect "mtc0 ${0:z}, $$12", "Jr"(i32 7) nounwind 76 77 ; z with zero and the "r"(register) and "J"(integer zero) constraints 78 ; ALL: #APP 79 ; ALL: mtc0 $0, ${{[0-9]+}} 80 ; ALL: #NO_APP 81 call void asm sideeffect "mtc0 ${0:z}, $$12", "Jr"(i32 0) nounwind 82 83 ; z with non-zero and just the "r"(register) constraint 84 ; ALL: #APP 85 ; ALL: mtc0 ${{[1-9][0-9]?}}, ${{[0-9]+}} 86 ; ALL: #NO_APP 87 call void asm sideeffect "mtc0 ${0:z}, $$12", "r"(i32 7) nounwind 88 89 ; z with zero and just the "r"(register) constraint 90 ; FIXME: Check for $0, instead of other registers. 91 ; We should be using $0 directly in this case, not real registers. 92 ; When the materialization of 0 gets fixed, this test will fail. 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", "r"(i32 0) nounwind 97 ret i32 0 98 } 99 100 ; A long long in 32 bit mode (use to assert) 101 define i32 @constraint_longlong() nounwind { 102 entry: 103 ; ALL-LABEL: constraint_longlong: 104 ; ALL: #APP 105 ; ALL: addiu ${{[0-9]+}}, ${{[0-9]+}}, 3 106 ; ALL: #NO_APP 107 tail call i64 asm sideeffect "addiu $0, $1, $2 \0A\09", "=r,r,X"(i64 1229801703532086340, i64 3) nounwind 108 ret i32 0 109 } 110 111 ; In little endian the source reg will be 4 bytes into the long long 112 ; In big endian the source reg will also be 4 bytes into the long long 113 define i32 @constraint_D() nounwind { 114 entry: 115 ; ALL-LABEL: constraint_D: 116 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 117 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 118 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 119 ; ALL: #APP 120 ; LE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 121 ; BE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 122 ; ALL: #NO_APP 123 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 124 %trunc1 = trunc i64 %bosco to i32 125 tail call i32 asm sideeffect "or $0, ${1:D}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 126 ret i32 0 127 } 128 129 ; In little endian the source reg will be 0 bytes into the long long 130 ; In big endian the source reg will be 4 bytes into the long long 131 define i32 @constraint_L() nounwind { 132 entry: 133 ; ALL-LABEL: constraint_L: 134 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 135 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 136 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 137 ; ALL: #APP 138 ; LE32: or ${{[0-9]+}}, $[[FIRST]], ${{[0-9]+}} 139 ; BE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 140 ; ALL: #NO_APP 141 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 142 %trunc1 = trunc i64 %bosco to i32 143 tail call i32 asm sideeffect "or $0, ${1:L}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 144 ret i32 0 145 } 146 147 ; In little endian the source reg will be 4 bytes into the long long 148 ; In big endian the source reg will be 0 bytes into the long long 149 define i32 @constraint_M() nounwind { 150 entry: 151 ; ALL-LABEL: constraint_M: 152 ; ALL: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}}) 153 ; ALL: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}}) 154 ; ALL: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}}) 155 ; ALL: #APP 156 ; LE32: or ${{[0-9]+}}, $[[SECOND]], ${{[0-9]+}} 157 ; BE32: or ${{[0-9]+}}, $[[FIRST]], ${{[0-9]+}} 158 ; ALL: #NO_APP 159 %bosco = load i64, i64* getelementptr inbounds (%union.u_tag, %union.u_tag* @uval, i32 0, i32 0), align 8 160 %trunc1 = trunc i64 %bosco to i32 161 tail call i32 asm sideeffect "or $0, ${1:M}, $2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind 162 ret i32 0 163 } 164