• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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