1; RUN: llc < %s -march=avr -mattr=movw -no-integrated-as | FileCheck %s
2; XFAIL: *
3
4; CHECK-LABEL: no_operands:
5define void @no_operands() {
6  ; CHECK: add {{r[0-9]+}}, {{r[0-9]+}}
7  call void asm sideeffect "add r24, r22", ""() nounwind
8  ret void
9}
10
11; CHECK-LABEL: input_operand:
12define void @input_operand(i8 %a) {
13  ; CHECK: add {{r[0-9]+}}, {{r[0-9]+}}
14  call void asm sideeffect "add $0, $0", "r"(i8 %a) nounwind
15  ret void
16}
17
18; CHECK-LABEL: simple_upper_regs:
19define void @simple_upper_regs(i8 %p0, i8 %p1, i8 %p2, i8 %p3,
20                               i8 %p4, i8 %p5, i8 %p6, i8 %p7) {
21  ; CHECK: some_instr {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}
22  call void asm sideeffect "some_instr $0, $1, $2, $3, $4, $5, $6, $7",
23                           "a,a,a,a,a,a,a,a" (i8 %p0, i8 %p1, i8 %p2, i8 %p3,
24                                              i8 %p4, i8 %p5, i8 %p6, i8 %p7) nounwind
25  ret void
26}
27
28; CHECK-LABEL: upper_regs:
29define void @upper_regs(i8 %p0) {
30  ; CHECK: some_instr {{r[0-9]+}}
31  call void asm sideeffect "some_instr $0", "d" (i8 %p0) nounwind
32  ret void
33}
34
35; CHECK-LABEL: lower_regs:
36define void @lower_regs(i8 %p0) {
37  ; CHECK: some_instr {{r[0-9]+}}
38  call void asm sideeffect "some_instr $0", "l" (i8 %p0) nounwind
39  ret void
40}
41
42; CHECK-LABEL: special_upper_regs:
43define void @special_upper_regs(i8 %p0, i8 %p1, i8 %p2, i8 %p3) {
44  ; CHECK: some_instr {{r[0-9]+}},{{r[0-9]+}},{{r[0-9]+}},{{r[0-9]+}}
45  call void asm sideeffect "some_instr $0,$1,$2,$3", "w,w,w,w" (i8 %p0, i8 %p1, i8 %p2, i8 %p3) nounwind
46  ret void
47}
48
49; CHECK-LABEL: xyz_reg:
50define void @xyz_reg(i16 %var) {
51  ; CHECK: some_instr {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}
52  call void asm sideeffect "some_instr $0, $1, $2", "x,y,z" (i16 %var, i16 %var, i16 %var) nounwind
53  ret void
54}
55
56;TODO
57; How to use SP reg properly in inline asm??
58; define void @sp_reg(i16 %var)
59
60; CHECK-LABEL: ptr_reg:
61define void @ptr_reg(i16 %var0, i16 %var1, i16 %var2) {
62  ; CHECK: some_instr {{r[0-9]+}}, {{r[0-9]+}}, {{r[0-9]+}}
63  call void asm sideeffect "some_instr $0, $1, $2", "e,e,e" (i16 %var0, i16 %var1, i16 %var2) nounwind
64  ret void
65}
66
67; CHECK-LABEL: base_ptr_reg:
68define void @base_ptr_reg(i16 %var0, i16 %var1) {
69  ; CHECK: some_instr r28, r30
70  call void asm sideeffect "some_instr $0, $1", "b,b" (i16 %var0, i16 %var1) nounwind
71  ret void
72}
73
74; CHECK-LABEL: input_output_operand:
75define i8 @input_output_operand(i8 %a, i8 %b) {
76  ; CHECK: add {{r[0-9]+}}, {{r[0-9]+}}
77  %1 = call i8 asm "add $0, $1", "=r,r"(i8 %a) nounwind
78  ret i8 %1
79}
80
81; CHECK-LABEL: temp_reg:
82define void @temp_reg(i8 %a) {
83  ; CHECK: some_instr {{r[0-9]+}}
84  call void asm sideeffect "some_instr $0", "t" (i8 %a) nounwind
85  ret void
86}
87
88; CHECK-LABEL: int_0_63:
89define void @int_0_63() {
90  ; CHECK: some_instr 5
91  call void asm sideeffect "some_instr $0", "I" (i8 5) nounwind
92  ret void
93}
94
95; CHECK-LABEL: int_minus63_0:
96define void @int_minus63_0() {
97  ; CHECK: some_instr -5
98  call void asm sideeffect "some_instr $0", "J" (i8 -5) nounwind
99  ret void
100}
101
102; CHECK-LABEL: int_2_2:
103define void @int_2_2() {
104  ; CHECK: some_instr 2
105  call void asm sideeffect "some_instr $0", "K" (i8 2) nounwind
106  ret void
107}
108
109; CHECK-LABEL: int_0_0:
110define void @int_0_0() {
111  ; CHECK: some_instr 0
112  call void asm sideeffect "some_instr $0", "L" (i8 0) nounwind
113  ret void
114}
115
116; CHECK-LABEL: int_0_255:
117define void @int_0_255() {
118  ; CHECK: some_instr 254
119  call void asm sideeffect "some_instr $0", "M" (i8 254) nounwind
120  ret void
121}
122
123; CHECK-LABEL: int_minus1_minus1:
124define void @int_minus1_minus1() {
125  ; CHECK: some_instr -1
126  call void asm sideeffect "some_instr $0", "N" (i8 -1) nounwind
127  ret void
128}
129
130; CHECK-LABEL: int_8_or_16_or_24:
131define void @int_8_or_16_or_24() {
132  ; CHECK: some_instr 8, 16, 24
133  call void asm sideeffect "some_instr $0, $1, $2", "O,O,O" (i8 8, i8 16, i8 24) nounwind
134  ret void
135}
136
137; CHECK-LABEL: int_1_1:
138define void @int_1_1() {
139  ; CHECK: some_instr 1
140  call void asm sideeffect "some_instr $0", "P" (i8 1) nounwind
141  ret void
142}
143
144; CHECK-LABEL: int_minus6_5:
145define void @int_minus6_5() {
146  ; CHECK: some_instr -6
147  call void asm sideeffect "some_instr $0", "R" (i8 -6) nounwind
148  ret void
149}
150
151; CHECK-LABEL: float_0_0:
152define void @float_0_0() {
153  ; CHECK: some_instr 0
154  call void asm sideeffect "some_instr $0", "G" (float 0.0) nounwind
155  ret void
156}
157
158
159; Memory constraint
160
161@a = internal global i16 0, align 4
162@b = internal global i16 0, align 4
163
164; CHECK-LABEL: mem_global:
165define void @mem_global() {
166  ; CHECK: some_instr {{X|Y|Z}}, {{X|Y|Z}}
167  call void asm "some_instr $0, $1", "=*Q,=*Q"(i16* @a, i16* @b)
168  ret void
169}
170
171; CHECK-LABEL: mem_params:
172define void @mem_params(i16* %a, i16* %b) {
173  ; CHECK: some_instr {{X|Y|Z}}, {{X|Y|Z}}
174  call void asm "some_instr $0, $1", "=*Q,=*Q"(i16* %a, i16* %b)
175  ret void
176}
177
178; CHECK-LABEL: mem_local:
179define void @mem_local() {
180  %a = alloca i16
181  %b = alloca i16
182  ; CHECK: some_instr {{X|Y|Z}}+3, {{X|Y|Z}}+1
183  call void asm "some_instr $0, $1", "=*Q,=*Q"(i16* %a, i16* %b)
184  ret void
185}
186
187; CHECK-LABEL: mem_mixed:
188define void @mem_mixed() {
189  %a = alloca i16
190  %b = alloca i16
191  ; CHECK: some_instr {{X|Y|Z}}, {{X|Y|Z}}+3, {{X|Y|Z}}+1
192  call void asm "some_instr $0, $1, $2", "=*Q,=*Q,=*Q"(i16* @a, i16* %a, i16* %b)
193  ret void
194}
195
196; CHECK-LABEL: mem_gep:
197define i8 @mem_gep(i8* %p) {
198entry:
199; CHECK: movw {{r[0-9]+}}, [[REG:r[0-9]+]]
200  %arrayidx = getelementptr inbounds i8, i8* %p, i16 1
201; CHECK: ld [[REG]], {{X|Y|Z}}+1
202  %0 = tail call i8 asm sideeffect "ld $0, $1\0A\09", "=r,*Q"(i8* %arrayidx)
203  ret i8 %0
204}
205