xref: /llvm-project/llvm/test/CodeGen/Mips/inlineasm-operand-code.ll (revision ae26f50aea4ef1a6c7058019f0db11a91bbcdade)
1; Positive test for inline register constraints
2;
3; RUN: llc -no-integrated-as -mtriple=mipsel -relocation-model=pic < %s | \
4; RUN:     FileCheck -check-prefixes=ALL,LE32,GAS %s
5; RUN: llc -no-integrated-as -mtriple=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 -mtriple=mipsel -relocation-model=pic < %s | \
10; RUN:     FileCheck -check-prefixes=ALL,LE32,IAS %s
11; RUN: llc -mtriple=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; y with 4
67define i32 @constraint_y_4() nounwind {
68entry:
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
78define void @constraint_z_0() nounwind {
79entry:
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
89define void @constraint_z_1() nounwind {
90entry:
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
101define void @constraint_z_2() nounwind {
102entry:
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
112define void @constraint_z_3() nounwind {
113entry:
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
124define void @constraint_z_4() nounwind {
125entry:
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
135define void @constraint_z_5() nounwind {
136entry:
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)
149define i32 @constraint_longlong() nounwind {
150entry:
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
161define i32 @constraint_D() nounwind {
162entry:
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, ptr @uval, 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
179define i32 @constraint_L() nounwind {
180entry:
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, ptr @uval, 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
197define i32 @constraint_M() nounwind {
198entry:
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, ptr @uval, 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