1// RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck %s --check-prefix=VI
2// RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOVI
3
4//===----------------------------------------------------------------------===//
5// Floating-point expressions are not supported
6//===----------------------------------------------------------------------===//
7
8s_sub_u32 s0, s0, -1.0 + 10000000000
9// NOVI: error: invalid operand for instruction
10
11t=10000000000
12s_sub_u32 s0, s0, 1.0 + t
13// NOVI: error: invalid operand for instruction
14
15v_ceil_f32 v1, 1.0 + 1.0
16// NOVI: error: invalid operand for instruction
17
18v_ceil_f32 v1, -1.0 + 1.0
19// NOVI: error: invalid operand for instruction
20
21//===----------------------------------------------------------------------===//
22// Constant expressions may be used with SP3 'abs' modifiers |...|
23// These expressions must be primary expressions to avoid incorrect
24// interpretation of closing "|".
25//===----------------------------------------------------------------------===//
26
27i1=1
28fm1=0xBF800000 // -1.0f
29hm1=0xBC00     // -1.0h
30
31v_ceil_f32 v1, |i1|
32// VI: v_ceil_f32_e32 v1, 1            ; encoding: [0x81,0x3a,0x02,0x7e]
33
34v_ceil_f32 v1, |(i1+1)|
35// VI: v_ceil_f32_e32 v1, 2            ; encoding: [0x82,0x3a,0x02,0x7e]
36
37v_ceil_f32 v1, |-(i1+1)|
38// VI: v_ceil_f32_e32 v1, 0x7ffffffe   ; encoding: [0xff,0x3a,0x02,0x7e,0xfe,0xff,0xff,0x7f]
39
40v_ceil_f32 v1, |fm1|
41// VI: v_ceil_f32_e32 v1, 1.0          ; encoding: [0xf2,0x3a,0x02,0x7e]
42
43v_mad_f16 v5, v1, v2, |i1|
44// VI: v_mad_f16 v5, v1, v2, |1|       ; encoding: [0x05,0x04,0xea,0xd1,0x01,0x05,0x06,0x02]
45
46v_mad_f16 v5, v1, v2, |(i1+1)|
47// VI: v_mad_f16 v5, v1, v2, |2|       ; encoding: [0x05,0x04,0xea,0xd1,0x01,0x05,0x0a,0x02]
48
49v_mad_f16 v5, v1, v2, |hm1|
50// VI: v_mad_f16 v5, v1, v2, |-1.0|    ; encoding: [0x05,0x04,0xea,0xd1,0x01,0x05,0xce,0x03]
51
52// Only primary expressions are allowed
53
54v_ceil_f32 v1, |1+i1|
55// NOVI: failed parsing operand
56
57v_ceil_f32 v1, |i1+1|
58// NOVI: failed parsing operand
59
60//===----------------------------------------------------------------------===//
61// Constant expressions may be used with 'abs' and 'neg' modifiers.
62//===----------------------------------------------------------------------===//
63
64v_ceil_f32 v1, abs(i1)
65// VI: v_ceil_f32_e32 v1, 1            ; encoding: [0x81,0x3a,0x02,0x7e]
66
67v_ceil_f32 v1, abs(i1+1)
68// VI: v_ceil_f32_e32 v1, 2            ; encoding: [0x82,0x3a,0x02,0x7e]
69
70v_ceil_f32 v1, abs(-(i1+1))
71// VI: v_ceil_f32_e32 v1, 0x7ffffffe   ; encoding: [0xff,0x3a,0x02,0x7e,0xfe,0xff,0xff,0x7f]
72
73v_ceil_f32 v1, abs(fm1)
74// VI: v_ceil_f32_e32 v1, 1.0          ; encoding: [0xf2,0x3a,0x02,0x7e]
75
76v_mad_f16 v5, v1, v2, abs(i1)
77// VI: v_mad_f16 v5, v1, v2, |1|       ; encoding: [0x05,0x04,0xea,0xd1,0x01,0x05,0x06,0x02]
78
79v_mad_f16 v5, v1, v2, abs(i1+1)
80// VI: v_mad_f16 v5, v1, v2, |2|       ; encoding: [0x05,0x04,0xea,0xd1,0x01,0x05,0x0a,0x02]
81
82v_mad_f16 v5, v1, v2, abs(hm1)
83// VI: v_mad_f16 v5, v1, v2, |-1.0|    ; encoding: [0x05,0x04,0xea,0xd1,0x01,0x05,0xce,0x03]
84
85v_ceil_f32 v1, neg(i1+1)
86// VI: v_ceil_f32_e32 v1, 0x80000002   ; encoding: [0xff,0x3a,0x02,0x7e,0x02,0x00,0x00,0x80]
87
88v_ceil_f32 v1, neg(1+i1)
89// VI: v_ceil_f32_e32 v1, 0x80000002   ; encoding: [0xff,0x3a,0x02,0x7e,0x02,0x00,0x00,0x80]
90
91v_ceil_f32 v1, neg(-i1+3)
92// VI: v_ceil_f32_e32 v1, 0x80000002   ; encoding: [0xff,0x3a,0x02,0x7e,0x02,0x00,0x00,0x80]
93
94v_ceil_f32 v1, neg(-(i1+1))
95// VI: v_ceil_f32_e32 v1, 0x7ffffffe   ; encoding: [0xff,0x3a,0x02,0x7e,0xfe,0xff,0xff,0x7f]
96
97v_ceil_f32 v1, neg(fm1)
98// VI: v_ceil_f32_e32 v1, 1.0          ; encoding: [0xf2,0x3a,0x02,0x7e]
99
100v_mad_f16 v5, v1, v2, neg(hm1)
101// VI: v_mad_f16 v5, v1, v2, neg(-1.0) ; encoding: [0x05,0x00,0xea,0xd1,0x01,0x05,0xce,0x83]
102
103//===----------------------------------------------------------------------===//
104// Constant expressions may be used where inline constants are accepted.
105//===----------------------------------------------------------------------===//
106
107v_ceil_f64 v[0:1], i1+1
108// VI: v_ceil_f64_e32 v[0:1], 2        ; encoding: [0x82,0x30,0x00,0x7e]
109
110v_and_b32 v0, i1+1, v0
111// VI: v_and_b32_e32 v0, 2, v0         ; encoding: [0x82,0x00,0x00,0x26]
112
113v_and_b32 v0, 1+i1, v0
114// VI: v_and_b32_e32 v0, 2, v0         ; encoding: [0x82,0x00,0x00,0x26]
115
116v_and_b32 v0, -i1+3, v0
117// VI: v_and_b32_e32 v0, 2, v0         ; encoding: [0x82,0x00,0x00,0x26]
118
119v_and_b32 v0, -(i1+1), v0
120// VI: v_and_b32_e32 v0, -2, v0        ; encoding: [0xc2,0x00,0x00,0x26]
121
122v_add_u16 v0, (i1+4)/2, v1
123// VI: v_add_u16_e32 v0, 2, v1         ; encoding: [0x82,0x02,0x00,0x4c]
124
125buffer_atomic_inc v1, off, s[8:11], i1+1 glc
126// VI: buffer_atomic_inc v1, off, s[8:11], 2 glc ; encoding: [0x00,0x40,0x2c,0xe1,0x00,0x01,0x02,0x82]
127
128s_addk_i32 s2, i1+1
129// VI: s_addk_i32 s2, 0x2              ; encoding: [0x02,0x00,0x02,0xb7]
130
131s_cmpk_eq_i32 s2, i1+1
132// VI: s_cmpk_eq_i32 s2, 0x2           ; encoding: [0x02,0x00,0x02,0xb1]
133
134s_setreg_imm32_b32 0x6, i1+1
135// VI: s_setreg_imm32_b32 hwreg(HW_REG_LDS_ALLOC, 0, 1), 2 ; encoding: [0x06,0x00,0x00,0xba,0x02,0x00,0x00,0x00]
136
137v_madak_f16 v1, v2, v3, i1+1
138// VI: v_madak_f16 v1, v2, v3, 0x2     ; encoding: [0x02,0x07,0x02,0x4a,0x02,0x00,0x00,0x00]
139
140s_set_gpr_idx_on s0, i1+1
141// VI: s_set_gpr_idx_on s0, gpr_idx(SRC1) ; encoding: [0x00,0x02,0x11,0xbf]
142
143s_atc_probe i1-1, s[4:5], i1+1
144// VI: s_atc_probe 0, s[4:5], 0x2      ; encoding: [0x02,0x00,0x9a,0xc0,0x02,0x00,0x00,0x00]
145
146s_load_dword s1, s[2:3], i1+1 glc
147// VI: s_load_dword s1, s[2:3], 0x2 glc ; encoding: [0x41,0x00,0x03,0xc0,0x02,0x00,0x00,0x00]
148
149//===----------------------------------------------------------------------===//
150// Constant expressions may be used where literals are accepted.
151//===----------------------------------------------------------------------===//
152
153v_ceil_f64 v[0:1], i1+100
154// VI: v_ceil_f64_e32 v[0:1], 0x65     ; encoding: [0xff,0x30,0x00,0x7e,0x65,0x00,0x00,0x00]
155
156v_and_b32 v0, i1+100, v0
157// VI: v_and_b32_e32 v0, 0x65, v0      ; encoding: [0xff,0x00,0x00,0x26,0x65,0x00,0x00,0x00]
158
159v_and_b32 v0, -i1+102, v0
160// VI: v_and_b32_e32 v0, 0x65, v0      ; encoding: [0xff,0x00,0x00,0x26,0x65,0x00,0x00,0x00]
161
162v_add_u16 v0, (i1+100)*2, v0
163// VI: v_add_u16_e32 v0, 0xca, v0      ; encoding: [0xff,0x00,0x00,0x4c,0xca,0x00,0x00,0x00]
164
165//===----------------------------------------------------------------------===//
166// Constant expressions may be used with Name:Value modifiers.
167//===----------------------------------------------------------------------===//
168
169buffer_load_dword v1, off, s[4:7], s1 offset:-1+1
170// VI: buffer_load_dword v1, off, s[4:7], s1 ; encoding: [0x00,0x00,0x50,0xe0,0x00,0x01,0x01,0x01]
171
172buffer_load_dword v1, off, s[4:7], s1 offset:i1+4
173// VI: buffer_load_dword v1, off, s[4:7], s1 offset:5 ; encoding: [0x05,0x00,0x50,0xe0,0x00,0x01,0x01,0x01]
174
175buffer_load_dword v1, off, s[4:7], s1 offset:4+i1
176// VI: buffer_load_dword v1, off, s[4:7], s1 offset:5 ; encoding: [0x05,0x00,0x50,0xe0,0x00,0x01,0x01,0x01]
177
178buffer_load_dword v1, off, s[4:7], s1 offset:-i1+4
179// VI: buffer_load_dword v1, off, s[4:7], s1 offset:3 ; encoding: [0x03,0x00,0x50,0xe0,0x00,0x01,0x01,0x01]
180
181//===----------------------------------------------------------------------===//
182// Relocatable expressions can be used with 32-bit instructions.
183//===----------------------------------------------------------------------===//
184
185v_ceil_f32 v1, -u
186// VI: v_ceil_f32_e32 v1, -u           ; encoding: [0xff,0x3a,0x02,0x7e,A,A,A,A]
187// VI-NEXT: ; fixup A - offset: 4, value: -u, kind: FK_PCRel_4
188
189v_and_b32 v0, u+1, v0
190// VI: v_and_b32_e32 v0, u+1, v0       ; encoding: [0xff,0x00,0x00,0x26,A,A,A,A]
191// VI-NEXT: ;   fixup A - offset: 4, value: u+1, kind: FK_PCRel_4
192
193//===----------------------------------------------------------------------===//
194// Relocatable expressions cannot be used as 16/20/21/64-bit operands.
195//===----------------------------------------------------------------------===//
196
197v_ceil_f64 v[0:1], u
198// NOVI: error: invalid operand for instruction
199
200v_add_u16 v0, u, v0
201// NOVI: error: invalid operand for instruction
202
203s_addk_i32 s2, u
204// NOVI: error: invalid operand for instruction
205
206s_load_dword s1, s[2:3], u glc
207// NOVI: error: invalid operand for instruction
208
209//===----------------------------------------------------------------------===//
210// Relocatable expressions cannot be used with VOP3 modifiers.
211//===----------------------------------------------------------------------===//
212
213v_ceil_f32 v1, |u|
214// NOVI: error: expected an absolute expression
215
216v_ceil_f32 v1, neg(u)
217// NOVI: error: expected an absolute expression
218
219v_ceil_f32 v1, abs(u)
220// NOVI: error: expected an absolute expression
221
222//===----------------------------------------------------------------------===//
223// Misc tests with symbols.
224//===----------------------------------------------------------------------===//
225
226.globl global
227.globl gds
228
229// Parse a global expression
230s_mov_b32 s0, global
231// VI: s_mov_b32 s0, global ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
232// VI-NEXT: ;   fixup A - offset: 4, value: global, kind: FK_PCRel_4
233
234// Use a token with the same name as a global
235ds_gws_init v2 gds
236// VI: ds_gws_init v2 gds ; encoding: [0x00,0x00,0x33,0xd9,0x02,0x00,0x00,0x00]
237
238// Use a global with the same name as a token
239s_mov_b32 s0, gds
240// VI: s_mov_b32 s0, gds ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
241// VI-NEXT: ;   fixup A - offset: 4, value: gds, kind: FK_PCRel_4
242
243// Use a binary expression
244s_mov_b32 s0, gds+4
245// VI: s_mov_b32 s0, gds+4 ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
246// VI-NEXT: ;   fixup A - offset: 4, value: gds+4, kind: FK_PCRel_4
247
248// Consecutive instructions with no blank line in between to make sure we
249// don't call Lex() too many times.
250s_add_u32 s0, s0, global+4
251s_addc_u32 s1, s1, 0
252// VI: s_add_u32 s0, s0, global+4
253// VI: s_addc_u32 s1, s1, 0
254
255// Use a computed expression that results in an inline immediate.
256.set foo, 4
257s_mov_b32 s0, foo+2
258// VI: s_mov_b32 s0, 6 ; encoding: [0x86,0x00,0x80,0xbe]
259
260// Use a computed expression that results in a non-inline immediate.
261.set foo, 512
262s_mov_b32 s0, foo+2
263// VI: s_mov_b32 s0, 0x202 ; encoding: [0xff,0x00,0x80,0xbe,0x02,0x02,0x00,0x00]
264
265v_mul_f32 v0, foo+2, v2
266// VI: v_mul_f32_e32 v0, 0x202, v2 ; encoding: [0xff,0x04,0x00,0x0a,0x02,0x02,0x00,0x00]
267
268BB1:
269v_nop_e64
270BB2:
271s_sub_u32 vcc_lo, vcc_lo, (BB2+4)-BB1
272// VI: s_sub_u32 vcc_lo, vcc_lo, (BB2+4)-BB1 ; encoding: [0x6a,0xff,0xea,0x80,A,A,A,A]
273// VI-NEXT: ;   fixup A - offset: 4, value: (BB2+4)-BB1, kind: FK_Data_4
274
275t=1
276s_sub_u32 s0, s0, -t
277// VI: s_sub_u32 s0, s0, -1            ; encoding: [0x00,0xc1,0x80,0x80]
278
279t=-1
280s_sub_u32 s0, s0, -t
281// VI: s_sub_u32 s0, s0, 1             ; encoding: [0x00,0x81,0x80,0x80]
282
283s_sub_u32 s0, s0, -2+1
284// VI: s_sub_u32 s0, s0, -1            ; encoding: [0x00,0xc1,0x80,0x80]
285
286t=1
287s_sub_u32 s0, s0, -2+t
288// VI: s_sub_u32 s0, s0, -1            ; encoding: [0x00,0xc1,0x80,0x80]
289
290//===----------------------------------------------------------------------===//
291// Symbols may look like registers.
292// They should be allowed in expressions if there is no ambiguity.
293//===----------------------------------------------------------------------===//
294
295v=1
296v_sin_f32 v0, -v
297// VI: v_sin_f32_e32 v0, -1            ; encoding: [0xc1,0x52,0x00,0x7e]
298
299s=1
300s_not_b32 s0, -s
301// VI: s_not_b32 s0, -1                ; encoding: [0xc1,0x04,0x80,0xbe]
302
303ttmp=1
304s_not_b32 s0, -ttmp
305// VI: s_not_b32 s0, -1                ; encoding: [0xc1,0x04,0x80,0xbe]
306
307//===----------------------------------------------------------------------===//
308// Registers have priority over symbols.
309//===----------------------------------------------------------------------===//
310
311v=1
312v_sin_f32 v0, -v[0]
313// VI: v_sin_f32_e64 v0, -v0           ; encoding: [0x00,0x00,0x69,0xd1,0x00,0x01,0x00,0x20]
314
315s0=1
316v_sin_f32 v0, -s0
317// VI: v_sin_f32_e64 v0, -s0           ; encoding: [0x00,0x00,0x69,0xd1,0x00,0x00,0x00,0x20]
318
319ttmp0=1
320v_sin_f32 v0, -[ttmp0]
321// VI: v_sin_f32_e64 v0, -ttmp0        ; encoding: [0x00,0x00,0x69,0xd1,0x70,0x00,0x00,0x20]
322
323//===----------------------------------------------------------------------===//
324// Incorrect register names and unsupported registers should not be interpreted
325// as expressions, rather they should trigger errors.
326//===----------------------------------------------------------------------===//
327
328s1000=1
329v_sin_f32 v0, -s1000
330// NOVI: failed parsing operand
331
332xnack_mask_lo=1
333v_sin_f32 v0, xnack_mask_lo
334// NOVI: failed parsing operand
335