xref: /linux/tools/testing/selftests/bpf/progs/verifier_div_mod_bounds.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
1*c9e440bfSYazhou Tang // SPDX-License-Identifier: GPL-2.0
2*c9e440bfSYazhou Tang 
3*c9e440bfSYazhou Tang #include <linux/bpf.h>
4*c9e440bfSYazhou Tang #include <limits.h>
5*c9e440bfSYazhou Tang #include <bpf/bpf_helpers.h>
6*c9e440bfSYazhou Tang #include "bpf_misc.h"
7*c9e440bfSYazhou Tang 
8*c9e440bfSYazhou Tang /* This file contains unit tests for signed/unsigned division and modulo
9*c9e440bfSYazhou Tang  * operations (with divisor as a constant), focusing on verifying whether
10*c9e440bfSYazhou Tang  * BPF verifier's range tracking module soundly and precisely computes
11*c9e440bfSYazhou Tang  * the results.
12*c9e440bfSYazhou Tang  */
13*c9e440bfSYazhou Tang 
14*c9e440bfSYazhou Tang SEC("socket")
15*c9e440bfSYazhou Tang __description("UDIV32, positive divisor")
16*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
17*c9e440bfSYazhou Tang __msg("w1 /= 3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=3,var_off=(0x0; 0x3))")
18*c9e440bfSYazhou Tang __naked void udiv32_pos_divisor(void)
19*c9e440bfSYazhou Tang {
20*c9e440bfSYazhou Tang 	asm volatile ("					\
21*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
22*c9e440bfSYazhou Tang 	w1 = w0;					\
23*c9e440bfSYazhou Tang 	w1 &= 8;					\
24*c9e440bfSYazhou Tang 	w1 |= 1;					\
25*c9e440bfSYazhou Tang 	w1 /= 3;					\
26*c9e440bfSYazhou Tang 	if w1 > 3 goto l0_%=;				\
27*c9e440bfSYazhou Tang 	r0 = 0;						\
28*c9e440bfSYazhou Tang 	exit;						\
29*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
30*c9e440bfSYazhou Tang 	exit;						\
31*c9e440bfSYazhou Tang "	:
32*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
33*c9e440bfSYazhou Tang 	: __clobber_all);
34*c9e440bfSYazhou Tang }
35*c9e440bfSYazhou Tang 
36*c9e440bfSYazhou Tang SEC("socket")
37*c9e440bfSYazhou Tang __description("UDIV32, zero divisor")
38*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
39*c9e440bfSYazhou Tang __msg("w1 /= w2 {{.*}}; R1=0 R2=0")
40*c9e440bfSYazhou Tang __naked void udiv32_zero_divisor(void)
41*c9e440bfSYazhou Tang {
42*c9e440bfSYazhou Tang 	asm volatile ("					\
43*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
44*c9e440bfSYazhou Tang 	w1 = w0;					\
45*c9e440bfSYazhou Tang 	w1 &= 8;					\
46*c9e440bfSYazhou Tang 	w1 |= 1;					\
47*c9e440bfSYazhou Tang 	w2 = 0;						\
48*c9e440bfSYazhou Tang 	w1 /= w2;					\
49*c9e440bfSYazhou Tang 	if w1 != 0 goto l0_%=;				\
50*c9e440bfSYazhou Tang 	r0 = 0;						\
51*c9e440bfSYazhou Tang 	exit;						\
52*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
53*c9e440bfSYazhou Tang 	exit;						\
54*c9e440bfSYazhou Tang "	:
55*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
56*c9e440bfSYazhou Tang 	: __clobber_all);
57*c9e440bfSYazhou Tang }
58*c9e440bfSYazhou Tang 
59*c9e440bfSYazhou Tang SEC("socket")
60*c9e440bfSYazhou Tang __description("UDIV64, positive divisor")
61*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
62*c9e440bfSYazhou Tang __msg("r1 /= 3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=3,var_off=(0x0; 0x3))")
63*c9e440bfSYazhou Tang __naked void udiv64_pos_divisor(void)
64*c9e440bfSYazhou Tang {
65*c9e440bfSYazhou Tang 	asm volatile ("					\
66*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
67*c9e440bfSYazhou Tang 	r1 = r0;					\
68*c9e440bfSYazhou Tang 	r1 &= 8;					\
69*c9e440bfSYazhou Tang 	r1 |= 1;					\
70*c9e440bfSYazhou Tang 	r1 /= 3;					\
71*c9e440bfSYazhou Tang 	if r1 > 3 goto l0_%=;				\
72*c9e440bfSYazhou Tang 	r0 = 0;						\
73*c9e440bfSYazhou Tang 	exit;						\
74*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
75*c9e440bfSYazhou Tang 	exit;						\
76*c9e440bfSYazhou Tang "	:
77*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
78*c9e440bfSYazhou Tang 	: __clobber_all);
79*c9e440bfSYazhou Tang }
80*c9e440bfSYazhou Tang 
81*c9e440bfSYazhou Tang SEC("socket")
82*c9e440bfSYazhou Tang __description("UDIV64, zero divisor")
83*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
84*c9e440bfSYazhou Tang __msg("r1 /= r2 {{.*}}; R1=0 R2=0")
85*c9e440bfSYazhou Tang __naked void udiv64_zero_divisor(void)
86*c9e440bfSYazhou Tang {
87*c9e440bfSYazhou Tang 	asm volatile ("					\
88*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
89*c9e440bfSYazhou Tang 	r1 = r0;					\
90*c9e440bfSYazhou Tang 	r1 &= 8;					\
91*c9e440bfSYazhou Tang 	r1 |= 1;					\
92*c9e440bfSYazhou Tang 	r2 = 0;						\
93*c9e440bfSYazhou Tang 	r1 /= r2;					\
94*c9e440bfSYazhou Tang 	if r1 != 0 goto l0_%=;				\
95*c9e440bfSYazhou Tang 	r0 = 0;						\
96*c9e440bfSYazhou Tang 	exit;						\
97*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
98*c9e440bfSYazhou Tang 	exit;						\
99*c9e440bfSYazhou Tang "	:
100*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
101*c9e440bfSYazhou Tang 	: __clobber_all);
102*c9e440bfSYazhou Tang }
103*c9e440bfSYazhou Tang 
104*c9e440bfSYazhou Tang SEC("socket")
105*c9e440bfSYazhou Tang __description("SDIV32, positive divisor, positive dividend")
106*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
107*c9e440bfSYazhou Tang __msg("w1 s/= 3 {{.*}}; R1=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=3,var_off=(0x2; 0x1))")
108*c9e440bfSYazhou Tang __naked void sdiv32_pos_divisor_1(void)
109*c9e440bfSYazhou Tang {
110*c9e440bfSYazhou Tang 	asm volatile ("					\
111*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
112*c9e440bfSYazhou Tang 	w1 = w0;					\
113*c9e440bfSYazhou Tang 	if w1 s< 8 goto l0_%=;				\
114*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
115*c9e440bfSYazhou Tang 	w1 s/= 3;					\
116*c9e440bfSYazhou Tang 	if w1 s< 2 goto l1_%=;				\
117*c9e440bfSYazhou Tang 	if w1 s> 3 goto l1_%=;				\
118*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
119*c9e440bfSYazhou Tang 	exit;						\
120*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
121*c9e440bfSYazhou Tang 	exit;						\
122*c9e440bfSYazhou Tang "	:
123*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
124*c9e440bfSYazhou Tang 	: __clobber_all);
125*c9e440bfSYazhou Tang }
126*c9e440bfSYazhou Tang 
127*c9e440bfSYazhou Tang SEC("socket")
128*c9e440bfSYazhou Tang __description("SDIV32, positive divisor, negative dividend")
129*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
130*c9e440bfSYazhou Tang __msg("w1 s/= 3 {{.*}}; R1=scalar(smin=umin=umin32=0xfffffffd,smax=umax=umax32=0xfffffffe,smin32=-3,smax32=-2,var_off=(0xfffffffc; 0x3))")
131*c9e440bfSYazhou Tang __naked void sdiv32_pos_divisor_2(void)
132*c9e440bfSYazhou Tang {
133*c9e440bfSYazhou Tang 	asm volatile ("					\
134*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
135*c9e440bfSYazhou Tang 	w1 = w0;					\
136*c9e440bfSYazhou Tang 	if w1 s> -8 goto l0_%=;				\
137*c9e440bfSYazhou Tang 	if w1 s< -10 goto l0_%=;			\
138*c9e440bfSYazhou Tang 	w1 s/= 3;					\
139*c9e440bfSYazhou Tang 	if w1 s< -3 goto l1_%=;				\
140*c9e440bfSYazhou Tang 	if w1 s> -2 goto l1_%=;				\
141*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
142*c9e440bfSYazhou Tang 	exit;						\
143*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
144*c9e440bfSYazhou Tang 	exit;						\
145*c9e440bfSYazhou Tang "	:
146*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
147*c9e440bfSYazhou Tang 	: __clobber_all);
148*c9e440bfSYazhou Tang }
149*c9e440bfSYazhou Tang 
150*c9e440bfSYazhou Tang SEC("socket")
151*c9e440bfSYazhou Tang __description("SDIV32, positive divisor, mixed sign dividend")
152*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
153*c9e440bfSYazhou Tang __msg("w1 s/= 3 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-2,smax32=3,var_off=(0x0; 0xffffffff))")
154*c9e440bfSYazhou Tang __naked void sdiv32_pos_divisor_3(void)
155*c9e440bfSYazhou Tang {
156*c9e440bfSYazhou Tang 	asm volatile ("					\
157*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
158*c9e440bfSYazhou Tang 	w1 = w0;					\
159*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
160*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
161*c9e440bfSYazhou Tang 	w1 s/= 3;					\
162*c9e440bfSYazhou Tang 	if w1 s< -2 goto l1_%=;				\
163*c9e440bfSYazhou Tang 	if w1 s> 3 goto l1_%=;				\
164*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
165*c9e440bfSYazhou Tang 	exit;						\
166*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
167*c9e440bfSYazhou Tang 	exit;						\
168*c9e440bfSYazhou Tang "	:
169*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
170*c9e440bfSYazhou Tang 	: __clobber_all);
171*c9e440bfSYazhou Tang }
172*c9e440bfSYazhou Tang 
173*c9e440bfSYazhou Tang SEC("socket")
174*c9e440bfSYazhou Tang __description("SDIV32, negative divisor, positive dividend")
175*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
176*c9e440bfSYazhou Tang __msg("w1 s/= -3 {{.*}}; R1=scalar(smin=umin=umin32=0xfffffffd,smax=umax=umax32=0xfffffffe,smin32=-3,smax32=-2,var_off=(0xfffffffc; 0x3))")
177*c9e440bfSYazhou Tang __naked void sdiv32_neg_divisor_1(void)
178*c9e440bfSYazhou Tang {
179*c9e440bfSYazhou Tang 	asm volatile ("					\
180*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
181*c9e440bfSYazhou Tang 	w1 = w0;					\
182*c9e440bfSYazhou Tang 	if w1 s< 8 goto l0_%=;				\
183*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
184*c9e440bfSYazhou Tang 	w1 s/= -3;					\
185*c9e440bfSYazhou Tang 	if w1 s< -3 goto l1_%=;				\
186*c9e440bfSYazhou Tang 	if w1 s> -2 goto l1_%=;				\
187*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
188*c9e440bfSYazhou Tang 	exit;						\
189*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
190*c9e440bfSYazhou Tang 	exit;						\
191*c9e440bfSYazhou Tang "	:
192*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
193*c9e440bfSYazhou Tang 	: __clobber_all);
194*c9e440bfSYazhou Tang }
195*c9e440bfSYazhou Tang 
196*c9e440bfSYazhou Tang SEC("socket")
197*c9e440bfSYazhou Tang __description("SDIV32, negative divisor, positive dividend")
198*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
199*c9e440bfSYazhou Tang __msg("w1 s/= -3 {{.*}}; R1=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=3,var_off=(0x2; 0x1))")
200*c9e440bfSYazhou Tang __naked void sdiv32_neg_divisor_2(void)
201*c9e440bfSYazhou Tang {
202*c9e440bfSYazhou Tang 	asm volatile ("					\
203*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
204*c9e440bfSYazhou Tang 	w1 = w0;					\
205*c9e440bfSYazhou Tang 	if w1 s> -8 goto l0_%=;				\
206*c9e440bfSYazhou Tang 	if w1 s< -10 goto l0_%=;			\
207*c9e440bfSYazhou Tang 	w1 s/= -3;					\
208*c9e440bfSYazhou Tang 	if w1 s< 2 goto l1_%=;				\
209*c9e440bfSYazhou Tang 	if w1 s> 3 goto l1_%=;				\
210*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
211*c9e440bfSYazhou Tang 	exit;						\
212*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
213*c9e440bfSYazhou Tang 	exit;						\
214*c9e440bfSYazhou Tang "	:
215*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
216*c9e440bfSYazhou Tang 	: __clobber_all);
217*c9e440bfSYazhou Tang }
218*c9e440bfSYazhou Tang 
219*c9e440bfSYazhou Tang SEC("socket")
220*c9e440bfSYazhou Tang __description("SDIV32, negative divisor, mixed sign dividend")
221*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
222*c9e440bfSYazhou Tang __msg("w1 s/= -3 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-3,smax32=2,var_off=(0x0; 0xffffffff))")
223*c9e440bfSYazhou Tang __naked void sdiv32_neg_divisor_3(void)
224*c9e440bfSYazhou Tang {
225*c9e440bfSYazhou Tang 	asm volatile ("					\
226*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
227*c9e440bfSYazhou Tang 	w1 = w0;					\
228*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
229*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
230*c9e440bfSYazhou Tang 	w1 s/= -3;					\
231*c9e440bfSYazhou Tang 	if w1 s< -3 goto l1_%=;				\
232*c9e440bfSYazhou Tang 	if w1 s> 2 goto l1_%=;				\
233*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
234*c9e440bfSYazhou Tang 	exit;						\
235*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
236*c9e440bfSYazhou Tang 	exit;						\
237*c9e440bfSYazhou Tang "	:
238*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
239*c9e440bfSYazhou Tang 	: __clobber_all);
240*c9e440bfSYazhou Tang }
241*c9e440bfSYazhou Tang 
242*c9e440bfSYazhou Tang SEC("socket")
243*c9e440bfSYazhou Tang __description("SDIV32, zero divisor")
244*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
245*c9e440bfSYazhou Tang __msg("w1 s/= w2 {{.*}}; R1=0 R2=0")
246*c9e440bfSYazhou Tang __naked void sdiv32_zero_divisor(void)
247*c9e440bfSYazhou Tang {
248*c9e440bfSYazhou Tang 	asm volatile ("					\
249*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
250*c9e440bfSYazhou Tang 	w1 = w0;					\
251*c9e440bfSYazhou Tang 	w1 &= 8;					\
252*c9e440bfSYazhou Tang 	w1 |= 1;					\
253*c9e440bfSYazhou Tang 	w2 = 0;						\
254*c9e440bfSYazhou Tang 	w1 s/= w2;					\
255*c9e440bfSYazhou Tang 	if w1 != 0 goto l0_%=;				\
256*c9e440bfSYazhou Tang 	r0 = 0;						\
257*c9e440bfSYazhou Tang 	exit;						\
258*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
259*c9e440bfSYazhou Tang 	exit;						\
260*c9e440bfSYazhou Tang "	:
261*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
262*c9e440bfSYazhou Tang 	: __clobber_all);
263*c9e440bfSYazhou Tang }
264*c9e440bfSYazhou Tang 
265*c9e440bfSYazhou Tang SEC("socket")
266*c9e440bfSYazhou Tang __description("SDIV32, overflow (S32_MIN/-1)")
267*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
268*c9e440bfSYazhou Tang __msg("w1 s/= -1 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff))")
269*c9e440bfSYazhou Tang __naked void sdiv32_overflow_1(void)
270*c9e440bfSYazhou Tang {
271*c9e440bfSYazhou Tang 	asm volatile ("					\
272*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
273*c9e440bfSYazhou Tang 	w1 = w0;					\
274*c9e440bfSYazhou Tang 	w2 = %[int_min];				\
275*c9e440bfSYazhou Tang 	w2 += 10;					\
276*c9e440bfSYazhou Tang 	if w1 s> w2 goto l0_%=;				\
277*c9e440bfSYazhou Tang 	w1 s/= -1;					\
278*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
279*c9e440bfSYazhou Tang 	exit;						\
280*c9e440bfSYazhou Tang "	:
281*c9e440bfSYazhou Tang 	: __imm_const(int_min, INT_MIN),
282*c9e440bfSYazhou Tang 	  __imm(bpf_get_prandom_u32)
283*c9e440bfSYazhou Tang 	: __clobber_all);
284*c9e440bfSYazhou Tang }
285*c9e440bfSYazhou Tang 
286*c9e440bfSYazhou Tang SEC("socket")
287*c9e440bfSYazhou Tang __description("SDIV32, overflow (S32_MIN/-1), constant dividend")
288*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
289*c9e440bfSYazhou Tang __msg("w1 s/= -1 {{.*}}; R1=0x80000000")
290*c9e440bfSYazhou Tang __naked void sdiv32_overflow_2(void)
291*c9e440bfSYazhou Tang {
292*c9e440bfSYazhou Tang 	asm volatile ("					\
293*c9e440bfSYazhou Tang 	w1 = %[int_min];				\
294*c9e440bfSYazhou Tang 	w1 s/= -1;					\
295*c9e440bfSYazhou Tang 	if w1 != %[int_min] goto l0_%=;			\
296*c9e440bfSYazhou Tang 	r0 = 0;						\
297*c9e440bfSYazhou Tang 	exit;						\
298*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
299*c9e440bfSYazhou Tang 	exit;						\
300*c9e440bfSYazhou Tang "	:
301*c9e440bfSYazhou Tang 	: __imm_const(int_min, INT_MIN)
302*c9e440bfSYazhou Tang 	: __clobber_all);
303*c9e440bfSYazhou Tang }
304*c9e440bfSYazhou Tang 
305*c9e440bfSYazhou Tang SEC("socket")
306*c9e440bfSYazhou Tang __description("SDIV64, positive divisor, positive dividend")
307*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
308*c9e440bfSYazhou Tang __msg("r1 s/= 3 {{.*}}; R1=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=3,var_off=(0x2; 0x1))")
309*c9e440bfSYazhou Tang __naked void sdiv64_pos_divisor_1(void)
310*c9e440bfSYazhou Tang {
311*c9e440bfSYazhou Tang 	asm volatile ("					\
312*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
313*c9e440bfSYazhou Tang 	r1 = r0;					\
314*c9e440bfSYazhou Tang 	if r1 s< 8 goto l0_%=;				\
315*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
316*c9e440bfSYazhou Tang 	r1 s/= 3;					\
317*c9e440bfSYazhou Tang 	if r1 s< 2 goto l1_%=;				\
318*c9e440bfSYazhou Tang 	if r1 s> 3 goto l1_%=;				\
319*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
320*c9e440bfSYazhou Tang 	exit;						\
321*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
322*c9e440bfSYazhou Tang 	exit;						\
323*c9e440bfSYazhou Tang "	:
324*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
325*c9e440bfSYazhou Tang 	: __clobber_all);
326*c9e440bfSYazhou Tang }
327*c9e440bfSYazhou Tang 
328*c9e440bfSYazhou Tang SEC("socket")
329*c9e440bfSYazhou Tang __description("SDIV64, positive divisor, negative dividend")
330*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
331*c9e440bfSYazhou Tang __msg("r1 s/= 3 {{.*}}; R1=scalar(smin=smin32=-3,smax=smax32=-2,umin=0xfffffffffffffffd,umax=0xfffffffffffffffe,umin32=0xfffffffd,umax32=0xfffffffe,var_off=(0xfffffffffffffffc; 0x3))")
332*c9e440bfSYazhou Tang __naked void sdiv64_pos_divisor_2(void)
333*c9e440bfSYazhou Tang {
334*c9e440bfSYazhou Tang 	asm volatile ("					\
335*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
336*c9e440bfSYazhou Tang 	r1 = r0;					\
337*c9e440bfSYazhou Tang 	if r1 s> -8 goto l0_%=;				\
338*c9e440bfSYazhou Tang 	if r1 s< -10 goto l0_%=;			\
339*c9e440bfSYazhou Tang 	r1 s/= 3;					\
340*c9e440bfSYazhou Tang 	if r1 s< -3 goto l1_%=;				\
341*c9e440bfSYazhou Tang 	if r1 s> -2 goto l1_%=;				\
342*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
343*c9e440bfSYazhou Tang 	exit;						\
344*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
345*c9e440bfSYazhou Tang 	exit;						\
346*c9e440bfSYazhou Tang "	:
347*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
348*c9e440bfSYazhou Tang 	: __clobber_all);
349*c9e440bfSYazhou Tang }
350*c9e440bfSYazhou Tang 
351*c9e440bfSYazhou Tang SEC("socket")
352*c9e440bfSYazhou Tang __description("SDIV64, positive divisor, mixed sign dividend")
353*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
354*c9e440bfSYazhou Tang __msg("r1 s/= 3 {{.*}}; R1=scalar(smin=smin32=-2,smax=smax32=3)")
355*c9e440bfSYazhou Tang __naked void sdiv64_pos_divisor_3(void)
356*c9e440bfSYazhou Tang {
357*c9e440bfSYazhou Tang 	asm volatile ("					\
358*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
359*c9e440bfSYazhou Tang 	r1 = r0;					\
360*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
361*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
362*c9e440bfSYazhou Tang 	r1 s/= 3;					\
363*c9e440bfSYazhou Tang 	if r1 s< -2 goto l1_%=;				\
364*c9e440bfSYazhou Tang 	if r1 s> 3 goto l1_%=;				\
365*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
366*c9e440bfSYazhou Tang 	exit;						\
367*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
368*c9e440bfSYazhou Tang 	exit;						\
369*c9e440bfSYazhou Tang "	:
370*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
371*c9e440bfSYazhou Tang 	: __clobber_all);
372*c9e440bfSYazhou Tang }
373*c9e440bfSYazhou Tang 
374*c9e440bfSYazhou Tang SEC("socket")
375*c9e440bfSYazhou Tang __description("SDIV64, negative divisor, positive dividend")
376*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
377*c9e440bfSYazhou Tang __msg("r1 s/= -3 {{.*}}; R1=scalar(smin=smin32=-3,smax=smax32=-2,umin=0xfffffffffffffffd,umax=0xfffffffffffffffe,umin32=0xfffffffd,umax32=0xfffffffe,var_off=(0xfffffffffffffffc; 0x3))")
378*c9e440bfSYazhou Tang __naked void sdiv64_neg_divisor_1(void)
379*c9e440bfSYazhou Tang {
380*c9e440bfSYazhou Tang 	asm volatile ("					\
381*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
382*c9e440bfSYazhou Tang 	r1 = r0;					\
383*c9e440bfSYazhou Tang 	if r1 s< 8 goto l0_%=;				\
384*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
385*c9e440bfSYazhou Tang 	r1 s/= -3;					\
386*c9e440bfSYazhou Tang 	if r1 s< -3 goto l1_%=;				\
387*c9e440bfSYazhou Tang 	if r1 s> -2 goto l1_%=;				\
388*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
389*c9e440bfSYazhou Tang 	exit;						\
390*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
391*c9e440bfSYazhou Tang 	exit;						\
392*c9e440bfSYazhou Tang "	:
393*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
394*c9e440bfSYazhou Tang 	: __clobber_all);
395*c9e440bfSYazhou Tang }
396*c9e440bfSYazhou Tang 
397*c9e440bfSYazhou Tang SEC("socket")
398*c9e440bfSYazhou Tang __description("SDIV64, negative divisor, positive dividend")
399*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
400*c9e440bfSYazhou Tang __msg("r1 s/= -3 {{.*}}; R1=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=3,var_off=(0x2; 0x1))")
401*c9e440bfSYazhou Tang __naked void sdiv64_neg_divisor_2(void)
402*c9e440bfSYazhou Tang {
403*c9e440bfSYazhou Tang 	asm volatile ("					\
404*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
405*c9e440bfSYazhou Tang 	r1 = r0;					\
406*c9e440bfSYazhou Tang 	if r1 s> -8 goto l0_%=;				\
407*c9e440bfSYazhou Tang 	if r1 s< -10 goto l0_%=;			\
408*c9e440bfSYazhou Tang 	r1 s/= -3;					\
409*c9e440bfSYazhou Tang 	if r1 s< 2 goto l1_%=;				\
410*c9e440bfSYazhou Tang 	if r1 s> 3 goto l1_%=;				\
411*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
412*c9e440bfSYazhou Tang 	exit;						\
413*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
414*c9e440bfSYazhou Tang 	exit;						\
415*c9e440bfSYazhou Tang "	:
416*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
417*c9e440bfSYazhou Tang 	: __clobber_all);
418*c9e440bfSYazhou Tang }
419*c9e440bfSYazhou Tang 
420*c9e440bfSYazhou Tang SEC("socket")
421*c9e440bfSYazhou Tang __description("SDIV64, negative divisor, mixed sign dividend")
422*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
423*c9e440bfSYazhou Tang __msg("r1 s/= -3 {{.*}}; R1=scalar(smin=smin32=-3,smax=smax32=2)")
424*c9e440bfSYazhou Tang __naked void sdiv64_neg_divisor_3(void)
425*c9e440bfSYazhou Tang {
426*c9e440bfSYazhou Tang 	asm volatile ("					\
427*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
428*c9e440bfSYazhou Tang 	r1 = r0;					\
429*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
430*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
431*c9e440bfSYazhou Tang 	r1 s/= -3;					\
432*c9e440bfSYazhou Tang 	if r1 s< -3 goto l1_%=;				\
433*c9e440bfSYazhou Tang 	if r1 s> 2 goto l1_%=;				\
434*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
435*c9e440bfSYazhou Tang 	exit;						\
436*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
437*c9e440bfSYazhou Tang 	exit;						\
438*c9e440bfSYazhou Tang "	:
439*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
440*c9e440bfSYazhou Tang 	: __clobber_all);
441*c9e440bfSYazhou Tang }
442*c9e440bfSYazhou Tang 
443*c9e440bfSYazhou Tang SEC("socket")
444*c9e440bfSYazhou Tang __description("SDIV64, zero divisor")
445*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
446*c9e440bfSYazhou Tang __msg("r1 s/= r2 {{.*}}; R1=0 R2=0")
447*c9e440bfSYazhou Tang __naked void sdiv64_zero_divisor(void)
448*c9e440bfSYazhou Tang {
449*c9e440bfSYazhou Tang 	asm volatile ("					\
450*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
451*c9e440bfSYazhou Tang 	r1 = r0;					\
452*c9e440bfSYazhou Tang 	r1 &= 8;					\
453*c9e440bfSYazhou Tang 	r1 |= 1;					\
454*c9e440bfSYazhou Tang 	r2 = 0;						\
455*c9e440bfSYazhou Tang 	r1 s/= r2;					\
456*c9e440bfSYazhou Tang 	if r1 != 0 goto l0_%=;				\
457*c9e440bfSYazhou Tang 	r0 = 0;						\
458*c9e440bfSYazhou Tang 	exit;						\
459*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
460*c9e440bfSYazhou Tang 	exit;						\
461*c9e440bfSYazhou Tang "	:
462*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
463*c9e440bfSYazhou Tang 	: __clobber_all);
464*c9e440bfSYazhou Tang }
465*c9e440bfSYazhou Tang 
466*c9e440bfSYazhou Tang SEC("socket")
467*c9e440bfSYazhou Tang __description("SDIV64, overflow (S64_MIN/-1)")
468*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
469*c9e440bfSYazhou Tang __msg("r1 s/= -1 {{.*}}; R1=scalar()")
470*c9e440bfSYazhou Tang __naked void sdiv64_overflow_1(void)
471*c9e440bfSYazhou Tang {
472*c9e440bfSYazhou Tang 	asm volatile ("					\
473*c9e440bfSYazhou Tang 	call %[bpf_ktime_get_ns];			\
474*c9e440bfSYazhou Tang 	r1 = r0;					\
475*c9e440bfSYazhou Tang 	r2 = %[llong_min] ll;				\
476*c9e440bfSYazhou Tang 	r2 += 10;					\
477*c9e440bfSYazhou Tang 	if r1 s> r2 goto l0_%=;				\
478*c9e440bfSYazhou Tang 	r1 s/= -1;					\
479*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
480*c9e440bfSYazhou Tang 	exit;						\
481*c9e440bfSYazhou Tang "	:
482*c9e440bfSYazhou Tang 	: __imm_const(llong_min, LLONG_MIN),
483*c9e440bfSYazhou Tang 	  __imm(bpf_ktime_get_ns)
484*c9e440bfSYazhou Tang 	: __clobber_all);
485*c9e440bfSYazhou Tang }
486*c9e440bfSYazhou Tang 
487*c9e440bfSYazhou Tang SEC("socket")
488*c9e440bfSYazhou Tang __description("SDIV64, overflow (S64_MIN/-1), constant dividend")
489*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
490*c9e440bfSYazhou Tang __msg("r1 s/= -1 {{.*}}; R1=0x8000000000000000")
491*c9e440bfSYazhou Tang __naked void sdiv64_overflow_2(void)
492*c9e440bfSYazhou Tang {
493*c9e440bfSYazhou Tang 	asm volatile ("					\
494*c9e440bfSYazhou Tang 	r1 = %[llong_min] ll;				\
495*c9e440bfSYazhou Tang 	r1 s/= -1;					\
496*c9e440bfSYazhou Tang 	r2 = %[llong_min] ll;				\
497*c9e440bfSYazhou Tang 	if r1 != r2 goto l0_%=;				\
498*c9e440bfSYazhou Tang 	r0 = 0;						\
499*c9e440bfSYazhou Tang 	exit;						\
500*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
501*c9e440bfSYazhou Tang 	exit;						\
502*c9e440bfSYazhou Tang "	:
503*c9e440bfSYazhou Tang 	: __imm_const(llong_min, LLONG_MIN)
504*c9e440bfSYazhou Tang 	: __clobber_all);
505*c9e440bfSYazhou Tang }
506*c9e440bfSYazhou Tang 
507*c9e440bfSYazhou Tang SEC("socket")
508*c9e440bfSYazhou Tang __description("UMOD32, positive divisor")
509*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
510*c9e440bfSYazhou Tang __msg("w1 %= 3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=2,var_off=(0x0; 0x3))")
511*c9e440bfSYazhou Tang __naked void umod32_pos_divisor(void)
512*c9e440bfSYazhou Tang {
513*c9e440bfSYazhou Tang 	asm volatile ("					\
514*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
515*c9e440bfSYazhou Tang 	w1 = w0;					\
516*c9e440bfSYazhou Tang 	w1 &= 8;					\
517*c9e440bfSYazhou Tang 	w1 |= 1;					\
518*c9e440bfSYazhou Tang 	w1 %%= 3;					\
519*c9e440bfSYazhou Tang 	if w1 > 3 goto l0_%=;				\
520*c9e440bfSYazhou Tang 	r0 = 0;						\
521*c9e440bfSYazhou Tang 	exit;						\
522*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
523*c9e440bfSYazhou Tang 	exit;						\
524*c9e440bfSYazhou Tang "	:
525*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
526*c9e440bfSYazhou Tang 	: __clobber_all);
527*c9e440bfSYazhou Tang }
528*c9e440bfSYazhou Tang 
529*c9e440bfSYazhou Tang SEC("socket")
530*c9e440bfSYazhou Tang __description("UMOD32, positive divisor, small dividend")
531*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
532*c9e440bfSYazhou Tang __msg("w1 %= 10 {{.*}}; R1=scalar(smin=umin=smin32=umin32=1,smax=umax=smax32=umax32=9,var_off=(0x1; 0x8))")
533*c9e440bfSYazhou Tang __naked void umod32_pos_divisor_unchanged(void)
534*c9e440bfSYazhou Tang {
535*c9e440bfSYazhou Tang 	asm volatile ("					\
536*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
537*c9e440bfSYazhou Tang 	w1 = w0;					\
538*c9e440bfSYazhou Tang 	w1 &= 8;					\
539*c9e440bfSYazhou Tang 	w1 |= 1;					\
540*c9e440bfSYazhou Tang 	w1 %%= 10;					\
541*c9e440bfSYazhou Tang 	if w1 < 1 goto l0_%=;				\
542*c9e440bfSYazhou Tang 	if w1 > 9 goto l0_%=;				\
543*c9e440bfSYazhou Tang 	if w1 & 1 != 1 goto l0_%=;			\
544*c9e440bfSYazhou Tang 	r0 = 0;						\
545*c9e440bfSYazhou Tang 	exit;						\
546*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
547*c9e440bfSYazhou Tang 	exit;						\
548*c9e440bfSYazhou Tang "	:
549*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
550*c9e440bfSYazhou Tang 	: __clobber_all);
551*c9e440bfSYazhou Tang }
552*c9e440bfSYazhou Tang 
553*c9e440bfSYazhou Tang SEC("socket")
554*c9e440bfSYazhou Tang __description("UMOD32, zero divisor")
555*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
556*c9e440bfSYazhou Tang __msg("w1 %= w2 {{.*}}; R1=scalar(smin=umin=smin32=umin32=1,smax=umax=smax32=umax32=9,var_off=(0x1; 0x8)) R2=0")
557*c9e440bfSYazhou Tang __naked void umod32_zero_divisor(void)
558*c9e440bfSYazhou Tang {
559*c9e440bfSYazhou Tang 	asm volatile ("					\
560*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
561*c9e440bfSYazhou Tang 	w1 = w0;					\
562*c9e440bfSYazhou Tang 	w1 &= 8;					\
563*c9e440bfSYazhou Tang 	w1 |= 1;					\
564*c9e440bfSYazhou Tang 	w2 = 0;						\
565*c9e440bfSYazhou Tang 	w1 %%= w2;					\
566*c9e440bfSYazhou Tang 	if w1 < 1 goto l0_%=;				\
567*c9e440bfSYazhou Tang 	if w1 > 9 goto l0_%=;				\
568*c9e440bfSYazhou Tang 	if w1 & 1 != 1 goto l0_%=;			\
569*c9e440bfSYazhou Tang 	r0 = 0;						\
570*c9e440bfSYazhou Tang 	exit;						\
571*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
572*c9e440bfSYazhou Tang 	exit;						\
573*c9e440bfSYazhou Tang "	:
574*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
575*c9e440bfSYazhou Tang 	: __clobber_all);
576*c9e440bfSYazhou Tang }
577*c9e440bfSYazhou Tang 
578*c9e440bfSYazhou Tang SEC("socket")
579*c9e440bfSYazhou Tang __description("UMOD64, positive divisor")
580*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
581*c9e440bfSYazhou Tang __msg("r1 %= 3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=2,var_off=(0x0; 0x3))")
582*c9e440bfSYazhou Tang __naked void umod64_pos_divisor(void)
583*c9e440bfSYazhou Tang {
584*c9e440bfSYazhou Tang 	asm volatile ("					\
585*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
586*c9e440bfSYazhou Tang 	r1 = r0;					\
587*c9e440bfSYazhou Tang 	r1 &= 8;					\
588*c9e440bfSYazhou Tang 	r1 |= 1;					\
589*c9e440bfSYazhou Tang 	r1 %%= 3;					\
590*c9e440bfSYazhou Tang 	if r1 > 3 goto l0_%=;				\
591*c9e440bfSYazhou Tang 	r0 = 0;						\
592*c9e440bfSYazhou Tang 	exit;						\
593*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
594*c9e440bfSYazhou Tang 	exit;						\
595*c9e440bfSYazhou Tang "	:
596*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
597*c9e440bfSYazhou Tang 	: __clobber_all);
598*c9e440bfSYazhou Tang }
599*c9e440bfSYazhou Tang 
600*c9e440bfSYazhou Tang SEC("socket")
601*c9e440bfSYazhou Tang __description("UMOD64, positive divisor, small dividend")
602*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
603*c9e440bfSYazhou Tang __msg("r1 %= 10 {{.*}}; R1=scalar(smin=umin=smin32=umin32=1,smax=umax=smax32=umax32=9,var_off=(0x1; 0x8))")
604*c9e440bfSYazhou Tang __naked void umod64_pos_divisor_unchanged(void)
605*c9e440bfSYazhou Tang {
606*c9e440bfSYazhou Tang 	asm volatile ("					\
607*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
608*c9e440bfSYazhou Tang 	r1 = r0;					\
609*c9e440bfSYazhou Tang 	r1 &= 8;					\
610*c9e440bfSYazhou Tang 	r1 |= 1;					\
611*c9e440bfSYazhou Tang 	r1 %%= 10;					\
612*c9e440bfSYazhou Tang 	if r1 < 1 goto l0_%=;				\
613*c9e440bfSYazhou Tang 	if r1 > 9 goto l0_%=;				\
614*c9e440bfSYazhou Tang 	if r1 & 1 != 1 goto l0_%=;			\
615*c9e440bfSYazhou Tang 	r0 = 0;						\
616*c9e440bfSYazhou Tang 	exit;						\
617*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
618*c9e440bfSYazhou Tang 	exit;						\
619*c9e440bfSYazhou Tang "	:
620*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
621*c9e440bfSYazhou Tang 	: __clobber_all);
622*c9e440bfSYazhou Tang }
623*c9e440bfSYazhou Tang 
624*c9e440bfSYazhou Tang SEC("socket")
625*c9e440bfSYazhou Tang __description("UMOD64, zero divisor")
626*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
627*c9e440bfSYazhou Tang __msg("r1 %= r2 {{.*}}; R1=scalar(smin=umin=smin32=umin32=1,smax=umax=smax32=umax32=9,var_off=(0x1; 0x8)) R2=0")
628*c9e440bfSYazhou Tang __naked void umod64_zero_divisor(void)
629*c9e440bfSYazhou Tang {
630*c9e440bfSYazhou Tang 	asm volatile ("					\
631*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
632*c9e440bfSYazhou Tang 	r1 = r0;					\
633*c9e440bfSYazhou Tang 	r1 &= 8;					\
634*c9e440bfSYazhou Tang 	r1 |= 1;					\
635*c9e440bfSYazhou Tang 	r2 = 0;						\
636*c9e440bfSYazhou Tang 	r1 %%= r2;					\
637*c9e440bfSYazhou Tang 	if r1 < 1 goto l0_%=;				\
638*c9e440bfSYazhou Tang 	if r1 > 9 goto l0_%=;				\
639*c9e440bfSYazhou Tang 	if r1 & 1 != 1 goto l0_%=;			\
640*c9e440bfSYazhou Tang 	r0 = 0;						\
641*c9e440bfSYazhou Tang 	exit;						\
642*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
643*c9e440bfSYazhou Tang 	exit;						\
644*c9e440bfSYazhou Tang "	:
645*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
646*c9e440bfSYazhou Tang 	: __clobber_all);
647*c9e440bfSYazhou Tang }
648*c9e440bfSYazhou Tang 
649*c9e440bfSYazhou Tang SEC("socket")
650*c9e440bfSYazhou Tang __description("SMOD32, positive divisor, positive dividend")
651*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
652*c9e440bfSYazhou Tang __msg("w1 s%= 3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=2,var_off=(0x0; 0x3))")
653*c9e440bfSYazhou Tang __naked void smod32_pos_divisor_1(void)
654*c9e440bfSYazhou Tang {
655*c9e440bfSYazhou Tang 	asm volatile ("					\
656*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
657*c9e440bfSYazhou Tang 	w1 = w0;					\
658*c9e440bfSYazhou Tang 	if w1 s< 8 goto l0_%=;				\
659*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
660*c9e440bfSYazhou Tang 	w1 s%%= 3;					\
661*c9e440bfSYazhou Tang 	if w1 s< 0 goto l1_%=;				\
662*c9e440bfSYazhou Tang 	if w1 s> 2 goto l1_%=;				\
663*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
664*c9e440bfSYazhou Tang 	exit;						\
665*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
666*c9e440bfSYazhou Tang 	exit;						\
667*c9e440bfSYazhou Tang "	:
668*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
669*c9e440bfSYazhou Tang 	: __clobber_all);
670*c9e440bfSYazhou Tang }
671*c9e440bfSYazhou Tang 
672*c9e440bfSYazhou Tang SEC("socket")
673*c9e440bfSYazhou Tang __description("SMOD32, positive divisor, negative dividend")
674*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
675*c9e440bfSYazhou Tang __msg("w1 s%= 3 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-2,smax32=0,var_off=(0x0; 0xffffffff))")
676*c9e440bfSYazhou Tang __naked void smod32_pos_divisor_2(void)
677*c9e440bfSYazhou Tang {
678*c9e440bfSYazhou Tang 	asm volatile ("					\
679*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
680*c9e440bfSYazhou Tang 	w1 = w0;					\
681*c9e440bfSYazhou Tang 	if w1 s> -8 goto l0_%=;				\
682*c9e440bfSYazhou Tang 	if w1 s< -10 goto l0_%=;			\
683*c9e440bfSYazhou Tang 	w1 s%%= 3;					\
684*c9e440bfSYazhou Tang 	if w1 s< -2 goto l1_%=;				\
685*c9e440bfSYazhou Tang 	if w1 s> 0 goto l1_%=;				\
686*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
687*c9e440bfSYazhou Tang 	exit;						\
688*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
689*c9e440bfSYazhou Tang 	exit;						\
690*c9e440bfSYazhou Tang "	:
691*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
692*c9e440bfSYazhou Tang 	: __clobber_all);
693*c9e440bfSYazhou Tang }
694*c9e440bfSYazhou Tang 
695*c9e440bfSYazhou Tang SEC("socket")
696*c9e440bfSYazhou Tang __description("SMOD32, positive divisor, mixed sign dividend")
697*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
698*c9e440bfSYazhou Tang __msg("w1 s%= 3 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-2,smax32=2,var_off=(0x0; 0xffffffff))")
699*c9e440bfSYazhou Tang __naked void smod32_pos_divisor_3(void)
700*c9e440bfSYazhou Tang {
701*c9e440bfSYazhou Tang 	asm volatile ("					\
702*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
703*c9e440bfSYazhou Tang 	w1 = w0;					\
704*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
705*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
706*c9e440bfSYazhou Tang 	w1 s%%= 3;					\
707*c9e440bfSYazhou Tang 	if w1 s< -2 goto l1_%=;				\
708*c9e440bfSYazhou Tang 	if w1 s> 2 goto l1_%=;				\
709*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
710*c9e440bfSYazhou Tang 	exit;						\
711*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
712*c9e440bfSYazhou Tang 	exit;						\
713*c9e440bfSYazhou Tang "	:
714*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
715*c9e440bfSYazhou Tang 	: __clobber_all);
716*c9e440bfSYazhou Tang }
717*c9e440bfSYazhou Tang 
718*c9e440bfSYazhou Tang SEC("socket")
719*c9e440bfSYazhou Tang __description("SMOD32, positive divisor, small dividend")
720*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
721*c9e440bfSYazhou Tang __msg("w1 s%= 11 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-8,smax32=10,var_off=(0x0; 0xffffffff))")
722*c9e440bfSYazhou Tang __naked void smod32_pos_divisor_unchanged(void)
723*c9e440bfSYazhou Tang {
724*c9e440bfSYazhou Tang 	asm volatile ("					\
725*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
726*c9e440bfSYazhou Tang 	w1 = w0;					\
727*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
728*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
729*c9e440bfSYazhou Tang 	w1 s%%= 11;					\
730*c9e440bfSYazhou Tang 	if w1 s< -8 goto l1_%=;				\
731*c9e440bfSYazhou Tang 	if w1 s> 10 goto l1_%=;				\
732*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
733*c9e440bfSYazhou Tang 	exit;						\
734*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
735*c9e440bfSYazhou Tang 	exit;						\
736*c9e440bfSYazhou Tang "	:
737*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
738*c9e440bfSYazhou Tang 	: __clobber_all);
739*c9e440bfSYazhou Tang }
740*c9e440bfSYazhou Tang 
741*c9e440bfSYazhou Tang SEC("socket")
742*c9e440bfSYazhou Tang __description("SMOD32, negative divisor, positive dividend")
743*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
744*c9e440bfSYazhou Tang __msg("w1 s%= -3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=2,var_off=(0x0; 0x3))")
745*c9e440bfSYazhou Tang __naked void smod32_neg_divisor_1(void)
746*c9e440bfSYazhou Tang {
747*c9e440bfSYazhou Tang 	asm volatile ("					\
748*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
749*c9e440bfSYazhou Tang 	w1 = w0;					\
750*c9e440bfSYazhou Tang 	if w1 s< 8 goto l0_%=;				\
751*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
752*c9e440bfSYazhou Tang 	w1 s%%= -3;					\
753*c9e440bfSYazhou Tang 	if w1 s< 0 goto l1_%=;				\
754*c9e440bfSYazhou Tang 	if w1 s> 2 goto l1_%=;				\
755*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
756*c9e440bfSYazhou Tang 	exit;						\
757*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
758*c9e440bfSYazhou Tang 	exit;						\
759*c9e440bfSYazhou Tang "	:
760*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
761*c9e440bfSYazhou Tang 	: __clobber_all);
762*c9e440bfSYazhou Tang }
763*c9e440bfSYazhou Tang 
764*c9e440bfSYazhou Tang SEC("socket")
765*c9e440bfSYazhou Tang __description("SMOD32, negative divisor, negative dividend")
766*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
767*c9e440bfSYazhou Tang __msg("w1 s%= -3 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-2,smax32=0,var_off=(0x0; 0xffffffff))")
768*c9e440bfSYazhou Tang __naked void smod32_neg_divisor_2(void)
769*c9e440bfSYazhou Tang {
770*c9e440bfSYazhou Tang 	asm volatile ("					\
771*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
772*c9e440bfSYazhou Tang 	w1 = w0;					\
773*c9e440bfSYazhou Tang 	if w1 s> -8 goto l0_%=;				\
774*c9e440bfSYazhou Tang 	if w1 s< -10 goto l0_%=;			\
775*c9e440bfSYazhou Tang 	w1 s%%= -3;					\
776*c9e440bfSYazhou Tang 	if w1 s< -2 goto l1_%=;				\
777*c9e440bfSYazhou Tang 	if w1 s> 0 goto l1_%=;				\
778*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
779*c9e440bfSYazhou Tang 	exit;						\
780*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
781*c9e440bfSYazhou Tang 	exit;						\
782*c9e440bfSYazhou Tang "	:
783*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
784*c9e440bfSYazhou Tang 	: __clobber_all);
785*c9e440bfSYazhou Tang }
786*c9e440bfSYazhou Tang 
787*c9e440bfSYazhou Tang SEC("socket")
788*c9e440bfSYazhou Tang __description("SMOD32, negative divisor, mixed sign dividend")
789*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
790*c9e440bfSYazhou Tang __msg("w1 s%= -3 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-2,smax32=2,var_off=(0x0; 0xffffffff))")
791*c9e440bfSYazhou Tang __naked void smod32_neg_divisor_3(void)
792*c9e440bfSYazhou Tang {
793*c9e440bfSYazhou Tang 	asm volatile ("					\
794*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
795*c9e440bfSYazhou Tang 	w1 = w0;					\
796*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
797*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
798*c9e440bfSYazhou Tang 	w1 s%%= -3;					\
799*c9e440bfSYazhou Tang 	if w1 s< -2 goto l1_%=;				\
800*c9e440bfSYazhou Tang 	if w1 s> 2 goto l1_%=;				\
801*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
802*c9e440bfSYazhou Tang 	exit;						\
803*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
804*c9e440bfSYazhou Tang 	exit;						\
805*c9e440bfSYazhou Tang "	:
806*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
807*c9e440bfSYazhou Tang 	: __clobber_all);
808*c9e440bfSYazhou Tang }
809*c9e440bfSYazhou Tang 
810*c9e440bfSYazhou Tang SEC("socket")
811*c9e440bfSYazhou Tang __description("SMOD32, negative divisor, small dividend")
812*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
813*c9e440bfSYazhou Tang __msg("w1 s%= -11 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-8,smax32=10,var_off=(0x0; 0xffffffff))")
814*c9e440bfSYazhou Tang __naked void smod32_neg_divisor_unchanged(void)
815*c9e440bfSYazhou Tang {
816*c9e440bfSYazhou Tang 	asm volatile ("					\
817*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
818*c9e440bfSYazhou Tang 	w1 = w0;					\
819*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
820*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
821*c9e440bfSYazhou Tang 	w1 s%%= -11;					\
822*c9e440bfSYazhou Tang 	if w1 s< -8 goto l1_%=;				\
823*c9e440bfSYazhou Tang 	if w1 s> 10 goto l1_%=;				\
824*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
825*c9e440bfSYazhou Tang 	exit;						\
826*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
827*c9e440bfSYazhou Tang 	exit;						\
828*c9e440bfSYazhou Tang "	:
829*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
830*c9e440bfSYazhou Tang 	: __clobber_all);
831*c9e440bfSYazhou Tang }
832*c9e440bfSYazhou Tang 
833*c9e440bfSYazhou Tang SEC("socket")
834*c9e440bfSYazhou Tang __description("SMOD32, zero divisor")
835*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
836*c9e440bfSYazhou Tang __msg("w1 s%= w2 {{.*}}; R1=scalar(smin=0,smax=umax=0xffffffff,smin32=-8,smax32=10,var_off=(0x0; 0xffffffff)) R2=0")
837*c9e440bfSYazhou Tang __naked void smod32_zero_divisor(void)
838*c9e440bfSYazhou Tang {
839*c9e440bfSYazhou Tang 	asm volatile ("					\
840*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
841*c9e440bfSYazhou Tang 	w1 = w0;					\
842*c9e440bfSYazhou Tang 	if w1 s< -8 goto l0_%=;				\
843*c9e440bfSYazhou Tang 	if w1 s> 10 goto l0_%=;				\
844*c9e440bfSYazhou Tang 	w2 = 0;						\
845*c9e440bfSYazhou Tang 	w1 s%%= w2;					\
846*c9e440bfSYazhou Tang 	if w1 s< -8 goto l1_%=;				\
847*c9e440bfSYazhou Tang 	if w1 s> 10 goto l1_%=;				\
848*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
849*c9e440bfSYazhou Tang 	exit;						\
850*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
851*c9e440bfSYazhou Tang 	exit;						\
852*c9e440bfSYazhou Tang "	:
853*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
854*c9e440bfSYazhou Tang 	: __clobber_all);
855*c9e440bfSYazhou Tang }
856*c9e440bfSYazhou Tang 
857*c9e440bfSYazhou Tang SEC("socket")
858*c9e440bfSYazhou Tang __description("SMOD32, overflow (S32_MIN%-1)")
859*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
860*c9e440bfSYazhou Tang __msg("w1 s%= -1 {{.*}}; R1=0")
861*c9e440bfSYazhou Tang __naked void smod32_overflow_1(void)
862*c9e440bfSYazhou Tang {
863*c9e440bfSYazhou Tang 	asm volatile ("					\
864*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
865*c9e440bfSYazhou Tang 	w1 = w0;					\
866*c9e440bfSYazhou Tang 	w2 = %[int_min];				\
867*c9e440bfSYazhou Tang 	w2 += 10;					\
868*c9e440bfSYazhou Tang 	if w1 s> w2 goto l0_%=;				\
869*c9e440bfSYazhou Tang 	w1 s%%= -1;					\
870*c9e440bfSYazhou Tang 	if w1 != 0 goto l1_%=;				\
871*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
872*c9e440bfSYazhou Tang 	exit;						\
873*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
874*c9e440bfSYazhou Tang 	exit;						\
875*c9e440bfSYazhou Tang "	:
876*c9e440bfSYazhou Tang 	: __imm_const(int_min, INT_MIN),
877*c9e440bfSYazhou Tang 	  __imm(bpf_get_prandom_u32)
878*c9e440bfSYazhou Tang 	: __clobber_all);
879*c9e440bfSYazhou Tang }
880*c9e440bfSYazhou Tang 
881*c9e440bfSYazhou Tang SEC("socket")
882*c9e440bfSYazhou Tang __description("SMOD32, overflow (S32_MIN%-1), constant dividend")
883*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
884*c9e440bfSYazhou Tang __msg("w1 s%= -1 {{.*}}; R1=0")
885*c9e440bfSYazhou Tang __naked void smod32_overflow_2(void)
886*c9e440bfSYazhou Tang {
887*c9e440bfSYazhou Tang 	asm volatile ("					\
888*c9e440bfSYazhou Tang 	w1 = %[int_min];				\
889*c9e440bfSYazhou Tang 	w1 s%%= -1;					\
890*c9e440bfSYazhou Tang 	if w1 != 0 goto l0_%=;				\
891*c9e440bfSYazhou Tang 	r0 = 0;						\
892*c9e440bfSYazhou Tang 	exit;						\
893*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
894*c9e440bfSYazhou Tang 	exit;						\
895*c9e440bfSYazhou Tang "	:
896*c9e440bfSYazhou Tang 	: __imm_const(int_min, INT_MIN)
897*c9e440bfSYazhou Tang 	: __clobber_all);
898*c9e440bfSYazhou Tang }
899*c9e440bfSYazhou Tang 
900*c9e440bfSYazhou Tang SEC("socket")
901*c9e440bfSYazhou Tang __description("SMOD64, positive divisor, positive dividend")
902*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
903*c9e440bfSYazhou Tang __msg("r1 s%= 3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=2,var_off=(0x0; 0x3))")
904*c9e440bfSYazhou Tang __naked void smod64_pos_divisor_1(void)
905*c9e440bfSYazhou Tang {
906*c9e440bfSYazhou Tang 	asm volatile ("					\
907*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
908*c9e440bfSYazhou Tang 	r1 = r0;					\
909*c9e440bfSYazhou Tang 	if r1 s< 8 goto l0_%=;				\
910*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
911*c9e440bfSYazhou Tang 	r1 s%%= 3;					\
912*c9e440bfSYazhou Tang 	if r1 s< 0 goto l1_%=;				\
913*c9e440bfSYazhou Tang 	if r1 s> 2 goto l1_%=;				\
914*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
915*c9e440bfSYazhou Tang 	exit;						\
916*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
917*c9e440bfSYazhou Tang 	exit;						\
918*c9e440bfSYazhou Tang "	:
919*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
920*c9e440bfSYazhou Tang 	: __clobber_all);
921*c9e440bfSYazhou Tang }
922*c9e440bfSYazhou Tang 
923*c9e440bfSYazhou Tang SEC("socket")
924*c9e440bfSYazhou Tang __description("SMOD64, positive divisor, negative dividend")
925*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
926*c9e440bfSYazhou Tang __msg("r1 s%= 3 {{.*}}; R1=scalar(smin=smin32=-2,smax=smax32=0)")
927*c9e440bfSYazhou Tang __naked void smod64_pos_divisor_2(void)
928*c9e440bfSYazhou Tang {
929*c9e440bfSYazhou Tang 	asm volatile ("					\
930*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
931*c9e440bfSYazhou Tang 	r1 = r0;					\
932*c9e440bfSYazhou Tang 	if r1 s> -8 goto l0_%=;				\
933*c9e440bfSYazhou Tang 	if r1 s< -10 goto l0_%=;			\
934*c9e440bfSYazhou Tang 	r1 s%%= 3;					\
935*c9e440bfSYazhou Tang 	if r1 s< -2 goto l1_%=;				\
936*c9e440bfSYazhou Tang 	if r1 s> 0 goto l1_%=;				\
937*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
938*c9e440bfSYazhou Tang 	exit;						\
939*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
940*c9e440bfSYazhou Tang 	exit;						\
941*c9e440bfSYazhou Tang "	:
942*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
943*c9e440bfSYazhou Tang 	: __clobber_all);
944*c9e440bfSYazhou Tang }
945*c9e440bfSYazhou Tang 
946*c9e440bfSYazhou Tang SEC("socket")
947*c9e440bfSYazhou Tang __description("SMOD64, positive divisor, mixed sign dividend")
948*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
949*c9e440bfSYazhou Tang __msg("r1 s%= 3 {{.*}}; R1=scalar(smin=smin32=-2,smax=smax32=2)")
950*c9e440bfSYazhou Tang __naked void smod64_pos_divisor_3(void)
951*c9e440bfSYazhou Tang {
952*c9e440bfSYazhou Tang 	asm volatile ("					\
953*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
954*c9e440bfSYazhou Tang 	r1 = r0;					\
955*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
956*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
957*c9e440bfSYazhou Tang 	r1 s%%= 3;					\
958*c9e440bfSYazhou Tang 	if r1 s< -2 goto l1_%=;				\
959*c9e440bfSYazhou Tang 	if r1 s> 2 goto l1_%=;				\
960*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
961*c9e440bfSYazhou Tang 	exit;						\
962*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
963*c9e440bfSYazhou Tang 	exit;						\
964*c9e440bfSYazhou Tang "	:
965*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
966*c9e440bfSYazhou Tang 	: __clobber_all);
967*c9e440bfSYazhou Tang }
968*c9e440bfSYazhou Tang 
969*c9e440bfSYazhou Tang SEC("socket")
970*c9e440bfSYazhou Tang __description("SMOD64, positive divisor, small dividend")
971*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
972*c9e440bfSYazhou Tang __msg("r1 s%= 11 {{.*}}; R1=scalar(smin=smin32=-8,smax=smax32=10)")
973*c9e440bfSYazhou Tang __naked void smod64_pos_divisor_unchanged(void)
974*c9e440bfSYazhou Tang {
975*c9e440bfSYazhou Tang 	asm volatile ("					\
976*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
977*c9e440bfSYazhou Tang 	r1 = r0;					\
978*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
979*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
980*c9e440bfSYazhou Tang 	r1 s%%= 11;					\
981*c9e440bfSYazhou Tang 	if r1 s< -8 goto l1_%=;				\
982*c9e440bfSYazhou Tang 	if r1 s> 10 goto l1_%=;				\
983*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
984*c9e440bfSYazhou Tang 	exit;						\
985*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
986*c9e440bfSYazhou Tang 	exit;						\
987*c9e440bfSYazhou Tang "	:
988*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
989*c9e440bfSYazhou Tang 	: __clobber_all);
990*c9e440bfSYazhou Tang }
991*c9e440bfSYazhou Tang 
992*c9e440bfSYazhou Tang SEC("socket")
993*c9e440bfSYazhou Tang __description("SMOD64, negative divisor, positive dividend")
994*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
995*c9e440bfSYazhou Tang __msg("r1 s%= -3 {{.*}}; R1=scalar(smin=smin32=0,smax=umax=smax32=umax32=2,var_off=(0x0; 0x3))")
996*c9e440bfSYazhou Tang __naked void smod64_neg_divisor_1(void)
997*c9e440bfSYazhou Tang {
998*c9e440bfSYazhou Tang 	asm volatile ("					\
999*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
1000*c9e440bfSYazhou Tang 	r1 = r0;					\
1001*c9e440bfSYazhou Tang 	if r1 s< 8 goto l0_%=;				\
1002*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
1003*c9e440bfSYazhou Tang 	r1 s%%= -3;					\
1004*c9e440bfSYazhou Tang 	if r1 s< 0 goto l1_%=;				\
1005*c9e440bfSYazhou Tang 	if r1 s> 2 goto l1_%=;				\
1006*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
1007*c9e440bfSYazhou Tang 	exit;						\
1008*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
1009*c9e440bfSYazhou Tang 	exit;						\
1010*c9e440bfSYazhou Tang "	:
1011*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
1012*c9e440bfSYazhou Tang 	: __clobber_all);
1013*c9e440bfSYazhou Tang }
1014*c9e440bfSYazhou Tang 
1015*c9e440bfSYazhou Tang SEC("socket")
1016*c9e440bfSYazhou Tang __description("SMOD64, negative divisor, negative dividend")
1017*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
1018*c9e440bfSYazhou Tang __msg("r1 s%= -3 {{.*}}; R1=scalar(smin=smin32=-2,smax=smax32=0)")
1019*c9e440bfSYazhou Tang __naked void smod64_neg_divisor_2(void)
1020*c9e440bfSYazhou Tang {
1021*c9e440bfSYazhou Tang 	asm volatile ("					\
1022*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
1023*c9e440bfSYazhou Tang 	r1 = r0;					\
1024*c9e440bfSYazhou Tang 	if r1 s> -8 goto l0_%=;				\
1025*c9e440bfSYazhou Tang 	if r1 s< -10 goto l0_%=;			\
1026*c9e440bfSYazhou Tang 	r1 s%%= -3;					\
1027*c9e440bfSYazhou Tang 	if r1 s< -2 goto l1_%=;				\
1028*c9e440bfSYazhou Tang 	if r1 s> 0 goto l1_%=;				\
1029*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
1030*c9e440bfSYazhou Tang 	exit;						\
1031*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
1032*c9e440bfSYazhou Tang 	exit;						\
1033*c9e440bfSYazhou Tang "	:
1034*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
1035*c9e440bfSYazhou Tang 	: __clobber_all);
1036*c9e440bfSYazhou Tang }
1037*c9e440bfSYazhou Tang 
1038*c9e440bfSYazhou Tang SEC("socket")
1039*c9e440bfSYazhou Tang __description("SMOD64, negative divisor, mixed sign dividend")
1040*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
1041*c9e440bfSYazhou Tang __msg("r1 s%= -3 {{.*}}; R1=scalar(smin=smin32=-2,smax=smax32=2)")
1042*c9e440bfSYazhou Tang __naked void smod64_neg_divisor_3(void)
1043*c9e440bfSYazhou Tang {
1044*c9e440bfSYazhou Tang 	asm volatile ("					\
1045*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
1046*c9e440bfSYazhou Tang 	r1 = r0;					\
1047*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
1048*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
1049*c9e440bfSYazhou Tang 	r1 s%%= -3;					\
1050*c9e440bfSYazhou Tang 	if r1 s< -2 goto l1_%=;				\
1051*c9e440bfSYazhou Tang 	if r1 s> 2 goto l1_%=;				\
1052*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
1053*c9e440bfSYazhou Tang 	exit;						\
1054*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
1055*c9e440bfSYazhou Tang 	exit;						\
1056*c9e440bfSYazhou Tang "	:
1057*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
1058*c9e440bfSYazhou Tang 	: __clobber_all);
1059*c9e440bfSYazhou Tang }
1060*c9e440bfSYazhou Tang 
1061*c9e440bfSYazhou Tang SEC("socket")
1062*c9e440bfSYazhou Tang __description("SMOD64, negative divisor, small dividend")
1063*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
1064*c9e440bfSYazhou Tang __msg("r1 s%= -11 {{.*}}; R1=scalar(smin=smin32=-8,smax=smax32=10)")
1065*c9e440bfSYazhou Tang __naked void smod64_neg_divisor_unchanged(void)
1066*c9e440bfSYazhou Tang {
1067*c9e440bfSYazhou Tang 	asm volatile ("					\
1068*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
1069*c9e440bfSYazhou Tang 	r1 = r0;					\
1070*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
1071*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
1072*c9e440bfSYazhou Tang 	r1 s%%= -11;					\
1073*c9e440bfSYazhou Tang 	if r1 s< -8 goto l1_%=;				\
1074*c9e440bfSYazhou Tang 	if r1 s> 10 goto l1_%=;				\
1075*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
1076*c9e440bfSYazhou Tang 	exit;						\
1077*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
1078*c9e440bfSYazhou Tang 	exit;						\
1079*c9e440bfSYazhou Tang "	:
1080*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
1081*c9e440bfSYazhou Tang 	: __clobber_all);
1082*c9e440bfSYazhou Tang }
1083*c9e440bfSYazhou Tang 
1084*c9e440bfSYazhou Tang SEC("socket")
1085*c9e440bfSYazhou Tang __description("SMOD64, zero divisor")
1086*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
1087*c9e440bfSYazhou Tang __msg("r1 s%= r2 {{.*}}; R1=scalar(smin=smin32=-8,smax=smax32=10) R2=0")
1088*c9e440bfSYazhou Tang __naked void smod64_zero_divisor(void)
1089*c9e440bfSYazhou Tang {
1090*c9e440bfSYazhou Tang 	asm volatile ("					\
1091*c9e440bfSYazhou Tang 	call %[bpf_get_prandom_u32];			\
1092*c9e440bfSYazhou Tang 	r1 = r0;					\
1093*c9e440bfSYazhou Tang 	if r1 s< -8 goto l0_%=;				\
1094*c9e440bfSYazhou Tang 	if r1 s> 10 goto l0_%=;				\
1095*c9e440bfSYazhou Tang 	r2 = 0;						\
1096*c9e440bfSYazhou Tang 	r1 s%%= r2;					\
1097*c9e440bfSYazhou Tang 	if r1 s< -8 goto l1_%=;				\
1098*c9e440bfSYazhou Tang 	if r1 s> 10 goto l1_%=;				\
1099*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
1100*c9e440bfSYazhou Tang 	exit;						\
1101*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
1102*c9e440bfSYazhou Tang 	exit;						\
1103*c9e440bfSYazhou Tang "	:
1104*c9e440bfSYazhou Tang 	: __imm(bpf_get_prandom_u32)
1105*c9e440bfSYazhou Tang 	: __clobber_all);
1106*c9e440bfSYazhou Tang }
1107*c9e440bfSYazhou Tang 
1108*c9e440bfSYazhou Tang SEC("socket")
1109*c9e440bfSYazhou Tang __description("SMOD64, overflow (S64_MIN%-1)")
1110*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
1111*c9e440bfSYazhou Tang __msg("r1 s%= -1 {{.*}}; R1=0")
1112*c9e440bfSYazhou Tang __naked void smod64_overflow_1(void)
1113*c9e440bfSYazhou Tang {
1114*c9e440bfSYazhou Tang 	asm volatile ("					\
1115*c9e440bfSYazhou Tang 	call %[bpf_ktime_get_ns];			\
1116*c9e440bfSYazhou Tang 	r1 = r0;					\
1117*c9e440bfSYazhou Tang 	r2 = %[llong_min] ll;				\
1118*c9e440bfSYazhou Tang 	r2 += 10;					\
1119*c9e440bfSYazhou Tang 	if r1 s> r2 goto l0_%=;				\
1120*c9e440bfSYazhou Tang 	r1 s%%= -1;					\
1121*c9e440bfSYazhou Tang 	if r1 != 0 goto l1_%=;				\
1122*c9e440bfSYazhou Tang l0_%=:	r0 = 0;						\
1123*c9e440bfSYazhou Tang 	exit;						\
1124*c9e440bfSYazhou Tang l1_%=:	r0 = *(u64 *)(r1 + 0);				\
1125*c9e440bfSYazhou Tang 	exit;						\
1126*c9e440bfSYazhou Tang "	:
1127*c9e440bfSYazhou Tang 	: __imm_const(llong_min, LLONG_MIN),
1128*c9e440bfSYazhou Tang 	  __imm(bpf_ktime_get_ns)
1129*c9e440bfSYazhou Tang 	: __clobber_all);
1130*c9e440bfSYazhou Tang }
1131*c9e440bfSYazhou Tang 
1132*c9e440bfSYazhou Tang SEC("socket")
1133*c9e440bfSYazhou Tang __description("SMOD64, overflow (S64_MIN%-1), constant dividend")
1134*c9e440bfSYazhou Tang __success __retval(0) __log_level(2)
1135*c9e440bfSYazhou Tang __msg("r1 s%= -1 {{.*}}; R1=0")
1136*c9e440bfSYazhou Tang __naked void smod64_overflow_2(void)
1137*c9e440bfSYazhou Tang {
1138*c9e440bfSYazhou Tang 	asm volatile ("					\
1139*c9e440bfSYazhou Tang 	r1 = %[llong_min] ll;				\
1140*c9e440bfSYazhou Tang 	r1 s%%= -1;					\
1141*c9e440bfSYazhou Tang 	if r1 != 0 goto l0_%=;				\
1142*c9e440bfSYazhou Tang 	r0 = 0;						\
1143*c9e440bfSYazhou Tang 	exit;						\
1144*c9e440bfSYazhou Tang l0_%=:	r0 = *(u64 *)(r1 + 0);				\
1145*c9e440bfSYazhou Tang 	exit;						\
1146*c9e440bfSYazhou Tang "	:
1147*c9e440bfSYazhou Tang 	: __imm_const(llong_min, LLONG_MIN)
1148*c9e440bfSYazhou Tang 	: __clobber_all);
1149*c9e440bfSYazhou Tang }
1150