blob: 6fe8ac39eae59631cc727c309ffa76d0eef09b40 [file] [log] [blame]
#
# rep, repe (repz) and repne (repnz) prefixed string instructions
# only count as one instruction, even though they repeat many times
# This test makes sure the bbv plugin counts these instructions properly
# The answer is validated to hw perf counters.
#
.globl _start
_start:
cld # we want these to happen forward
#===============================================
# Some SSE2 instructions start with 0xf2 or 0xf3
# Check for them, to make sure our rep detection
# handles things properly.
# We should check this on x86 too, but then we'd
# have to check for SSE2 capability somehow?
#===================================
false_positives:
movdqu %xmm1,%xmm2
movdqu %xmm2,%xmm1
addsd %xmm1,%xmm2
pause
#===================================
# Check varied order of the size prefix
# with the rep prefix. Older binutils
# did this one way, newer binutils the other
#===================================
size_prefix:
# test 16-bit load
mov $8192, %rcx
mov $buffer1, %rsi # set source
.byte 0x66, 0xf3, 0xad # lodsw
mov $8192, %rcx
mov $buffer1, %rsi # set source
.byte 0xf3, 0x66, 0xad # lodsw
#===================================
# Load and Store Instructions
#===================================
loadstore:
xor %rax, %rax
mov $0xd, %al # set eax to d
# test 8-bit store
mov $16384, %rcx
mov $buffer1, %rdi # set destination
rep stosb # store d 16384 times, auto-increment
# test 8-bit load
mov $16384, %rcx
mov $buffer1, %rsi # set source
rep lodsb # load byte 16384 times, auto-increment
cmp $0xd,%al # if we loaded wrong value
jne print_error # print an error
# test 16-bit store
mov $0x020d,%ax # store 0x020d
mov $8192, %rcx
mov $buffer1, %rdi # set destination
rep stosw # store 8192 times, auto-increment
# test 16-bit load
mov $8192, %rcx
mov $buffer1, %rsi # set source
rep lodsw # load 8192 times, auto-increment
cmp $0x020d,%ax # if we loaded wrong value
jne print_error # print an error
# test 32-bit store
mov $0x0feb1378,%eax # store 0x0feb1378
mov $4096, %rcx
mov $buffer1, %rdi # set destination
rep stosl # store 4096 times, auto-increment
# test 32-bit load
mov $4096, %rcx
mov $buffer1, %rsi # set source
rep lodsl # load 4096 times, auto-increment
cmp $0x0feb1378,%eax # if we loaded wrong value
jne print_error # print an error
# test 64-bit store
mov $0xfeb131978a5a5a5a,%rax
mov $2048, %rcx
mov $buffer1, %rdi # set destination
rep stosq # store 2048 times, auto-increment
# test 64-bit load
mov $2048, %rcx
mov $buffer1, %rsi # set source
rep lodsq # load 2048 times, auto-increment
cmp $0x8a5a5a5a,%eax
# !if we loaded wrong value
jne print_error # print an error
#=============================
# Move instructions
#=============================
moves:
# test 8-bit move
mov $16384, %rcx
mov $buffer1, %rsi
mov $buffer2, %rdi
rep movsb
# test 16-bit move
mov $8192, %rcx
mov $buffer2, %rsi
mov $buffer1, %rdi
rep movsw
# test 32-bit move
mov $4096, %rcx
mov $buffer1, %rsi
mov $buffer2, %rdi
rep movsl
# test 64-bit move
mov $2048, %rcx
mov $buffer1, %rsi
mov $buffer2, %rdi
rep movsq
#==================================
# Compare equal instructions
#==================================
compare_equal:
# first set up the areas to compare
mov $0xa5a5a5a5,%eax
mov $buffer1, %rdi
mov $4096, %rcx
rep stosl
mov $0xa5a5a5a5,%eax
mov $buffer2, %rdi
mov $4096, %rcx
rep stosl
# test 8-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $16384, %rcx
repe cmpsb
jnz print_error
# test 16-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $8192, %rcx
repe cmpsw
jnz print_error
# test 32-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $4096, %rcx
repe cmpsl
jnz print_error
# test 64-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $2048, %rcx
repe cmpsq
jnz print_error
#==================================
# Compare not equal instructions
#==================================
compare_noteq:
# change second buffer
mov $0x5a5a5a5a,%eax
mov $buffer2, %rdi
mov $4096, %rcx
rep stosl
# test 8-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $16384, %rcx
# repne cmpsb FIXME! Not implemented valgrind
# je print_error
# test 16-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $8192, %rcx
# repne cmpsw FIXME! Not implemented valgrind
# je print_error
# test 32-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $4096, %rcx
# repne cmpsl FIXME! Not implemented valgrind
# je print_error
# test 64-bit
mov $buffer1,%rsi
mov $buffer2,%rdi
mov $2048, %rcx
# repne cmpsq FIXME! Not implemented valgrind
# je print_error
#====================================
# Check scan equal instruction
#====================================
scan_eq:
# test 8-bit
mov $0xa5,%al
mov $buffer1,%rdi
mov $16384, %rcx
repe scasb
jnz print_error
# test 16-bit
mov $0xa5a5,%ax
mov $buffer1,%rdi
mov $8192, %rcx
repe scasw
jnz print_error
# test 32-bit
mov $0xa5a5a5a5,%eax
mov $buffer1,%rdi
mov $4096, %rcx
repe scasl
jnz print_error
# test 64-bit
mov $0xa5a5a5a5a5a5a5a5,%rax
mov $buffer1,%rdi
mov $2048, %rcx
repe scasq
jnz print_error
#====================================
# Check scan not-equal instruction
#====================================
# test 8-bit
scan_ne:
mov $0xa5,%al
mov $buffer2,%rdi
mov $16384, %rcx
repne scasb
jz print_error
# test 16-bit
mov $0xa5a5,%ax
mov $buffer2,%rdi
mov $8192, %rcx
repne scasw
jz print_error
# test 32-bit
mov $0xa5a5a5a5,%eax
mov $buffer2,%rdi
mov $4096, %rcx
repne scasl
jz print_error
# test 64-bit
mov $0xa5a5a5a5a5a5a5a5,%rax
mov $buffer2,%rdi
mov $2048, %rcx
repne scasq
jz print_error
jmp exit # no error, skip to exit
print_error:
mov $1, %rax # Write syscall
mov $1, %rdi # print to stdout
mov $error_string, %rsi # string to print
mov $16, %edx # strlen
syscall # call syscall
#================================
# Exit
#================================
exit:
mov $60,%rax
xor %rdi,%rdi # we return 0
syscall # and exit
.data
error_string: .asciz "Error detected!\n"
.bss
.lcomm buffer1, 16384
.lcomm buffer2, 16384