| # |
| # 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 |