1#
2# rep, repe (repz) and repne (repnz) prefixed string instructions
3#   only count as one instruction, even though they repeat many times
4# This test makes sure the bbv plugin counts these instructions properly
5# The answer is validated to hw perf counters.
6#
7
8	.globl _start
9_start:
10	cld				# we want these to happen forward
11
12
13	#===============================================
14	# Some SSE2 instructions start with 0xf2 or 0xf3
15	# Check for them, to make sure our rep detection
16	#   handles things properly.
17	# We should check this on x86 too, but then we'd
18	#   have to check for SSE2 capability somehow?
19	#===================================
20false_positives:
21
22	movdqu	%xmm1,%xmm2
23	movdqu	%xmm2,%xmm1
24	addsd	%xmm1,%xmm2
25	pause
26
27	#===================================
28	# Check varied order of the size prefix
29	#   with the rep prefix.  Older binutils
30	#   did this one way, newer binutils the other
31	#===================================
32
33size_prefix:
34	# test 16-bit load
35
36	mov	$8192, %rcx
37	mov	$buffer1, %rsi		# set source
38	.byte 0x66, 0xf3, 0xad		# lodsw
39
40	mov	$8192, %rcx
41	mov	$buffer1, %rsi		# set source
42	.byte 0xf3, 0x66, 0xad		# lodsw
43
44
45
46
47	#===================================
48	# Load and Store Instructions
49	#===================================
50loadstore:
51	xor	%rax, %rax
52	mov	$0xd, %al		# set eax to d
53
54	# test 8-bit store
55
56	mov	$16384, %rcx
57	mov	$buffer1, %rdi		# set destination
58	rep	stosb	    		# store d 16384 times, auto-increment
59
60	# test 8-bit load
61
62	mov	$16384, %rcx
63	mov	$buffer1, %rsi		# set source
64	rep	lodsb	    		# load byte 16384 times, auto-increment
65
66	cmp	$0xd,%al		# if we loaded wrong value
67	jne	print_error		# print an error
68
69	# test 16-bit store
70
71	mov    	$0x020d,%ax		# store 0x020d
72
73	mov	$8192, %rcx
74	mov	$buffer1, %rdi		# set destination
75	rep	stosw	    		# store 8192 times, auto-increment
76
77	# test 16-bit load
78
79	mov	$8192, %rcx
80	mov	$buffer1, %rsi		# set source
81	rep	lodsw	    		# load 8192 times, auto-increment
82
83	cmp	$0x020d,%ax		# if we loaded wrong value
84	jne	print_error		# print an error
85
86	# test 32-bit store
87
88	mov    	$0x0feb1378,%eax	# store 0x0feb1378
89
90	mov	$4096, %rcx
91	mov	$buffer1, %rdi		# set destination
92	rep	stosl	    		# store 4096 times, auto-increment
93
94	# test 32-bit load
95
96	mov	$4096, %rcx
97	mov	$buffer1, %rsi		# set source
98	rep	lodsl	    		# load 4096 times, auto-increment
99
100	cmp	$0x0feb1378,%eax	# if we loaded wrong value
101	jne	print_error		# print an error
102
103	# test 64-bit store
104
105	mov    	$0xfeb131978a5a5a5a,%rax
106
107	mov	$2048, %rcx
108	mov	$buffer1, %rdi		# set destination
109	rep	stosq	    		# store 2048 times, auto-increment
110
111	# test 64-bit load
112
113	mov	$2048, %rcx
114	mov	$buffer1, %rsi		# set source
115	rep	lodsq	    		# load 2048 times, auto-increment
116
117	cmp     $0x8a5a5a5a,%eax
118					# !if we loaded wrong value
119	jne	print_error		# print an error
120
121
122	#=============================
123	# Move instructions
124	#=============================
125moves:
126	# test 8-bit move
127
128	mov    $16384, %rcx
129	mov    $buffer1, %rsi
130	mov    $buffer2, %rdi
131	rep    movsb
132
133	# test 16-bit move
134
135	mov    $8192, %rcx
136	mov    $buffer2, %rsi
137	mov    $buffer1, %rdi
138	rep    movsw
139
140	# test 32-bit move
141
142	mov    $4096, %rcx
143	mov    $buffer1, %rsi
144	mov    $buffer2, %rdi
145	rep    movsl
146
147	# test 64-bit move
148
149	mov    $2048, %rcx
150	mov    $buffer1, %rsi
151	mov    $buffer2, %rdi
152	rep    movsq
153
154
155	#==================================
156	# Compare equal instructions
157	#==================================
158compare_equal:
159	# first set up the areas to compare
160
161	mov	$0xa5a5a5a5,%eax
162	mov	$buffer1, %rdi
163	mov	$4096, %rcx
164	rep	stosl
165
166	mov	$0xa5a5a5a5,%eax
167	mov	$buffer2, %rdi
168	mov	$4096, %rcx
169	rep	stosl
170
171
172	# test 8-bit
173
174	mov	$buffer1,%rsi
175	mov	$buffer2,%rdi
176	mov	$16384, %rcx
177	repe	cmpsb
178	jnz	print_error
179
180	# test 16-bit
181
182	mov	$buffer1,%rsi
183	mov	$buffer2,%rdi
184	mov	$8192, %rcx
185	repe	cmpsw
186	jnz	print_error
187
188	# test 32-bit
189
190	mov	$buffer1,%rsi
191	mov	$buffer2,%rdi
192	mov	$4096, %rcx
193	repe	cmpsl
194	jnz	print_error
195
196	# test 64-bit
197
198	mov	$buffer1,%rsi
199	mov	$buffer2,%rdi
200	mov	$2048, %rcx
201	repe	cmpsq
202	jnz	print_error
203
204
205
206	#==================================
207	# Compare not equal instructions
208	#==================================
209compare_noteq:
210	# change second buffer
211
212	mov	$0x5a5a5a5a,%eax
213	mov	$buffer2, %rdi
214	mov	$4096, %rcx
215	rep	stosl
216
217	# test 8-bit
218
219	mov	$buffer1,%rsi
220	mov	$buffer2,%rdi
221	mov	$16384, %rcx
222#	repne	cmpsb             FIXME!  Not implemented valgrind
223#	je	print_error
224
225	# test 16-bit
226
227	mov	$buffer1,%rsi
228	mov	$buffer2,%rdi
229	mov	$8192, %rcx
230#	repne	cmpsw             FIXME!  Not implemented valgrind
231#	je	print_error
232
233	# test 32-bit
234
235	mov	$buffer1,%rsi
236	mov	$buffer2,%rdi
237	mov	$4096, %rcx
238#	repne	cmpsl             FIXME!  Not implemented valgrind
239#	je	print_error
240
241	# test 64-bit
242
243	mov	$buffer1,%rsi
244	mov	$buffer2,%rdi
245	mov	$2048, %rcx
246#	repne	cmpsq             FIXME!  Not implemented valgrind
247#	je	print_error
248
249	#====================================
250	# Check scan equal instruction
251	#====================================
252scan_eq:
253	# test 8-bit
254
255	mov     $0xa5,%al
256	mov	$buffer1,%rdi
257	mov	$16384, %rcx
258	repe	scasb
259	jnz	print_error
260
261	# test 16-bit
262
263	mov     $0xa5a5,%ax
264	mov	$buffer1,%rdi
265	mov	$8192, %rcx
266	repe	scasw
267	jnz	print_error
268
269	# test 32-bit
270
271	mov	$0xa5a5a5a5,%eax
272	mov	$buffer1,%rdi
273	mov	$4096, %rcx
274	repe	scasl
275	jnz	print_error
276
277	# test 64-bit
278
279	mov	$0xa5a5a5a5a5a5a5a5,%rax
280	mov	$buffer1,%rdi
281	mov	$2048, %rcx
282	repe	scasq
283	jnz	print_error
284
285
286	#====================================
287	# Check scan not-equal instruction
288	#====================================
289
290	# test 8-bit
291scan_ne:
292	mov     $0xa5,%al
293	mov	$buffer2,%rdi
294	mov	$16384, %rcx
295	repne	scasb
296	jz	print_error
297
298	# test 16-bit
299
300	mov     $0xa5a5,%ax
301	mov	$buffer2,%rdi
302	mov	$8192, %rcx
303	repne	scasw
304	jz	print_error
305
306	# test 32-bit
307
308	mov	$0xa5a5a5a5,%eax
309	mov	$buffer2,%rdi
310	mov	$4096, %rcx
311	repne	scasl
312	jz	print_error
313
314	# test 64-bit
315
316	mov	$0xa5a5a5a5a5a5a5a5,%rax
317	mov	$buffer2,%rdi
318	mov	$2048, %rcx
319	repne	scasq
320	jz	print_error
321
322	jmp	exit			# no error, skip to exit
323
324print_error:
325
326	mov 	$1, %rax		# Write syscall
327	mov	$1, %rdi		# print to stdout
328	mov	$error_string, %rsi	# string to print
329	mov	$16, %edx      	   	# strlen
330	syscall	 			# call syscall
331
332	#================================
333	# Exit
334	#================================
335exit:
336     	mov	$60,%rax
337	xor     %rdi,%rdi		# we return 0
338	syscall             		# and exit
339
340
341.data
342error_string:	.asciz "Error detected!\n"
343
344.bss
345
346.lcomm	buffer1,	16384
347.lcomm	buffer2,	16384
348