| # |
| # 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 |
| |
| #=================================== |
| # 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, %ecx |
| mov $buffer1, %esi # set source |
| .byte 0x66, 0xf3, 0xad # lodsw |
| |
| mov $8192, %ecx |
| mov $buffer1, %esi # set source |
| .byte 0xf3, 0x66, 0xad # lodsw |
| |
| |
| |
| |
| #=================================== |
| # Load and Store Instructions |
| #=================================== |
| loadstore: |
| xor %eax, %eax |
| mov $0xd, %al # set eax to d |
| |
| # test 8-bit store |
| |
| mov $16384, %ecx |
| mov $buffer1, %edi # set destination |
| rep stosb # store d 16384 times, auto-increment |
| |
| # test 8-bit load |
| |
| mov $16384, %ecx |
| mov $buffer1, %esi # 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, %ecx |
| mov $buffer1, %edi # set destination |
| rep stosw # store 8192 times, auto-increment |
| |
| # test 16-bit load |
| |
| mov $8192, %ecx |
| mov $buffer1, %esi # 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, %ecx |
| mov $buffer1, %edi # set destination |
| rep stosl # store 4096 times, auto-increment |
| |
| # test 32-bit load |
| |
| mov $4096, %ecx |
| mov $buffer1, %esi # set source |
| rep lodsl # load 4096 times, auto-increment |
| |
| cmp $0x0feb1378,%eax # if we loaded wrong value |
| jne print_error # print an error |
| |
| #============================= |
| # Move instructions |
| #============================= |
| moves: |
| # test 8-bit move |
| |
| mov $16384, %ecx |
| mov $buffer1, %esi |
| mov $buffer2, %edi |
| rep movsb |
| |
| # test 16-bit move |
| |
| mov $8192, %ecx |
| mov $buffer2, %esi |
| mov $buffer1, %edi |
| rep movsw |
| |
| # test 32-bit move |
| |
| mov $4096, %ecx |
| mov $buffer1, %esi |
| mov $buffer2, %edi |
| rep movsl |
| |
| #================================== |
| # Compare equal instructions |
| #================================== |
| compare_equal: |
| # first set up the areas to compare |
| |
| mov $0xa5a5a5a5,%eax |
| mov $buffer1, %edi |
| mov $4096, %ecx |
| rep stosl |
| |
| mov $0xa5a5a5a5,%eax |
| mov $buffer2, %edi |
| mov $4096, %ecx |
| rep stosl |
| |
| # test 8-bit |
| |
| mov $buffer1,%esi |
| mov $buffer2,%edi |
| mov $16384, %ecx |
| repe cmpsb |
| jnz print_error |
| |
| # test 16-bit |
| |
| mov $buffer1,%esi |
| mov $buffer2,%edi |
| mov $8192, %ecx |
| repe cmpsw |
| jnz print_error |
| |
| # test 32-bit |
| |
| mov $buffer1,%esi |
| mov $buffer2,%edi |
| mov $4096, %ecx |
| repe cmpsl |
| jnz print_error |
| |
| #================================== |
| # Compare not equal instructions |
| #================================== |
| compare_noteq: |
| # change second buffer |
| |
| mov $0x5a5a5a5a,%eax |
| mov $buffer2, %edi |
| mov $4096, %ecx |
| rep stosl |
| |
| # test 8-bit |
| |
| mov $buffer1,%esi |
| mov $buffer2,%edi |
| mov $16384, %ecx |
| repne cmpsb |
| je print_error |
| |
| # test 16-bit |
| |
| mov $buffer1,%esi |
| mov $buffer2,%edi |
| mov $8192, %ecx |
| repne cmpsw |
| je print_error |
| |
| # test 32-bit |
| |
| mov $buffer1,%esi |
| mov $buffer2,%edi |
| mov $4096, %ecx |
| repne cmpsl |
| je print_error |
| |
| #==================================== |
| # Check scan equal instruction |
| #==================================== |
| |
| # test 8-bit |
| |
| mov $0xa5,%al |
| mov $buffer1,%edi |
| mov $16384, %ecx |
| repe scasb |
| jnz print_error |
| |
| # test 16-bit |
| |
| mov $0xa5a5,%ax |
| mov $buffer1,%edi |
| mov $8192, %ecx |
| repe scasw |
| jnz print_error |
| |
| # test 32-bit |
| |
| mov $0xa5a5a5a5,%eax |
| mov $buffer1,%edi |
| mov $4096, %ecx |
| repe scasl |
| jnz print_error |
| |
| #==================================== |
| # Check scan not-equal instruction |
| #==================================== |
| |
| # test 8-bit |
| |
| mov $0xa5,%al |
| mov $buffer2,%edi |
| mov $16384, %ecx |
| repne scasb |
| jz print_error |
| |
| # test 16-bit |
| |
| mov $0xa5a5,%ax |
| mov $buffer2,%edi |
| mov $8192, %ecx |
| repne scasw |
| jz print_error |
| |
| # test 32-bit |
| |
| mov $0xa5a5a5a5,%eax |
| mov $buffer2,%edi |
| mov $4096, %ecx |
| repne scasl |
| jz print_error |
| |
| jmp exit # no error, skip to exit |
| |
| print_error: |
| |
| mov $4, %eax # Write syscall |
| #ifdef VGO_darwin |
| pushl $1 |
| pushl $error_string |
| pushl $16 |
| #else |
| mov $1, %ebx # print to stdout |
| mov $error_string, %ecx # string to print |
| mov $16, %edx # strlen |
| #endif |
| int $0x80 # call syscall |
| |
| #================================ |
| # Exit |
| #================================ |
| exit: |
| #ifdef VGO_darwin |
| xor %ebx,%ebx # we return 0 |
| #else |
| pushl $0 # we return 0 |
| #endif |
| xor %eax,%eax |
| inc %eax # put exit syscall number (1) in eax |
| int $0x80 # and exit |
| |
| |
| .data |
| error_string: .asciz "Error detected!\n" |
| |
| #.bss |
| |
| .lcomm buffer1, 16384 |
| .lcomm buffer2, 16384 |