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