From: Julian Seward Date: Tue, 15 Oct 2013 11:37:16 +0000 (+0000) Subject: A minimal test case for the parsing of XACQUIRE and XRELEASE prefixes. X-Git-Tag: svn/VALGRIND_3_9_0~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21e2ef83b2ebe3da93f1d7a3960b4e975f10af18;p=thirdparty%2Fvalgrind.git A minimal test case for the parsing of XACQUIRE and XRELEASE prefixes. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13645 --- diff --git a/none/tests/amd64/xacq_xrel.c b/none/tests/amd64/xacq_xrel.c new file mode 100644 index 0000000000..628d7292a2 --- /dev/null +++ b/none/tests/amd64/xacq_xrel.c @@ -0,0 +1,298 @@ + +/* This is a test program that checks the parsing of instructions with + xacquire and xrelease prefixes. The tested insns are, afaics, + exactly those listed in the Intel description for the two prefixes + ("XACQUIRE/XRELEASE -- Hardware Lock Elision Prefix Hints"). */ + +#include + +typedef unsigned long long int ULong; + +#define CAT2(_x,_y) _x##_y +#define CAT(_x,_y) CAT2(_x,_y) + +#define GEN_BINARY(_insn) \ + void CAT(do_,_insn) ( void ) \ + { \ + volatile ULong n = 0x5555555555555555ULL; \ + ULong some = 0x271831415927D459ULL; \ + __asm__ __volatile__( \ + "\t" \ + "stc" "\n\t" \ + "xacquire lock " #_insn "q $123456789, (%0)" "\n\t" \ + "xrelease lock " #_insn "q $123456789, (%0)" "\n\t" \ + "xacquire lock " #_insn "l $0x12345FE, (%0)" "\n\t" \ + "xrelease lock " #_insn "l $0x12345FE, (%0)" "\n\t" \ + "xacquire lock " #_insn "w $0x9876, (%0)" "\n\t" \ + "xrelease lock " #_insn "w $0x9876, (%0)" "\n\t" \ + "xacquire lock " #_insn "b $0x45, (%0)" "\n\t" \ + "xrelease lock " #_insn "b $0x45, (%0)" "\n\t" \ + "xacquire lock " #_insn "q %1, (%0)" "\n\t" \ + "xrelease lock " #_insn "q %1, (%0)" "\n\t" \ + "xacquire lock " #_insn "l %k1, (%0)" "\n\t" \ + "xrelease lock " #_insn "l %k1, (%0)" "\n\t" \ + "xacquire lock " #_insn "w %w1, (%0)" "\n\t" \ + "xrelease lock " #_insn "w %w1, (%0)" "\n\t" \ + "xacquire lock " #_insn "b %b1, (%0)" "\n\t" \ + "xrelease lock " #_insn "b %b1, (%0)" "\n\t" \ + : : "r"(&n), "r"(some) : "cc", "memory" \ + ); \ + printf("result for '%-3s' is %016llx\n", #_insn, n); \ + } + +GEN_BINARY(add) +GEN_BINARY(adc) +GEN_BINARY(and) +GEN_BINARY(or) +GEN_BINARY(sbb) +GEN_BINARY(sub) +GEN_BINARY(xor) + +#define GEN_UNARY(_insn) \ + void CAT(do_,_insn) ( void ) \ + { \ + volatile ULong n = 0x5555555555555555ULL; \ + __asm__ __volatile__( \ + "\t" \ + "stc" "\n\t" \ + "xacquire lock " #_insn "q (%0)" "\n\t" \ + "xrelease lock " #_insn "q (%0)" "\n\t" \ + "xacquire lock " #_insn "l (%0)" "\n\t" \ + "xrelease lock " #_insn "l (%0)" "\n\t" \ + "xacquire lock " #_insn "w (%0)" "\n\t" \ + "xrelease lock " #_insn "w (%0)" "\n\t" \ + "xacquire lock " #_insn "b (%0)" "\n\t" \ + "xrelease lock " #_insn "b (%0)" "\n\t" \ + : : "r"(&n) : "cc", "memory" \ + ); \ + printf("result for '%-3s' is %016llx\n", #_insn, n); \ + } + +GEN_UNARY(dec) +GEN_UNARY(inc) +GEN_UNARY(neg) +GEN_UNARY(not) + +void do_btc ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + __asm__ __volatile__( + "xacquire lock btcq %1, (%0)" "\n\t" + "xacquire lock btcq $57, (%0)" "\n\t" + "xrelease lock btcq %1, (%0)" "\n\t" + "xrelease lock btcq $55, (%0)" "\n\t" + "xacquire lock btcl %k1, (%0)" "\n\t" + "xacquire lock btcl $27, (%0)" "\n\t" + "xrelease lock btcl %k1, (%0)" "\n\t" + "xrelease lock btcl $25, (%0)" "\n\t" + "xacquire lock btcw %w1, (%0)" "\n\t" + "xacquire lock btcw $12, (%0)" "\n\t" + "xrelease lock btcw %w1, (%0)" "\n\t" + "xrelease lock btcw $11, (%0)" "\n\t" + : : "r"(&n), "r"(6ULL) : "cc", "memory" + ); + printf("result for '%-3s' is %016llx\n", "btc", n); \ +} + +void do_btr ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + __asm__ __volatile__( + "xacquire lock btrq %1, (%0)" "\n\t" + "xacquire lock btrq $57, (%0)" "\n\t" + "xrelease lock btrq %1, (%0)" "\n\t" + "xrelease lock btrq $55, (%0)" "\n\t" + "xacquire lock btrl %k1, (%0)" "\n\t" + "xacquire lock btrl $27, (%0)" "\n\t" + "xrelease lock btrl %k1, (%0)" "\n\t" + "xrelease lock btrl $25, (%0)" "\n\t" + "xacquire lock btrw %w1, (%0)" "\n\t" + "xacquire lock btrw $12, (%0)" "\n\t" + "xrelease lock btrw %w1, (%0)" "\n\t" + "xrelease lock btrw $11, (%0)" "\n\t" + : : "r"(&n), "r"(6ULL) : "cc", "memory" + ); + printf("result for '%-3s' is %016llx\n", "btr", n); \ +} + +void do_bts ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + __asm__ __volatile__( + "xacquire lock btsq %1, (%0)" "\n\t" + "xacquire lock btsq $57, (%0)" "\n\t" + "xrelease lock btsq %1, (%0)" "\n\t" + "xrelease lock btsq $55, (%0)" "\n\t" + "xacquire lock btsl %k1, (%0)" "\n\t" + "xacquire lock btsl $27, (%0)" "\n\t" + "xrelease lock btsl %k1, (%0)" "\n\t" + "xrelease lock btsl $25, (%0)" "\n\t" + "xacquire lock btsw %w1, (%0)" "\n\t" + "xacquire lock btsw $12, (%0)" "\n\t" + "xrelease lock btsw %w1, (%0)" "\n\t" + "xrelease lock btsw $11, (%0)" "\n\t" + : : "r"(&n), "r"(6ULL) : "cc", "memory" + ); + printf("result for '%-3s' is %016llx\n", "bts", n); \ +} + +void do_cmpxchg ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + ULong some = 0x271831415927D459ULL; + __asm__ __volatile__( + "\t" + "stc" "\n\t" + // zero out rax and get the flags in a known state + "xorq %%rax, %%rax" "\n\t" + "xacquire lock cmpxchgq %1, (%0)" "\n\t" + "xrelease lock cmpxchgq %1, (%0)" "\n\t" + "xacquire lock cmpxchgl %k1, (%0)" "\n\t" + "xrelease lock cmpxchgl %k1, (%0)" "\n\t" + "xacquire lock cmpxchgw %w1, (%0)" "\n\t" + "xrelease lock cmpxchgw %w1, (%0)" "\n\t" + "xacquire lock cmpxchgb %b1, (%0)" "\n\t" + "xrelease lock cmpxchgb %b1, (%0)" "\n\t" + : : "r"(&n), "r"(some) : "cc", "memory", "rax" + ); + printf("result for '%-3s' is %016llx\n", "cmpxchg", n); +} + +void do_cmpxchg8b ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + __asm__ __volatile__( + "xorq %%rax, %%rax" "\n\t" + "xorq %%rdx, %%rdx" "\n\t" + "xacquire lock cmpxchg8b (%0)" "\n\t" + "xrelease lock cmpxchg8b (%0)" "\n\t" + : : "r"(&n) : "cc", "memory", "rax", "rdx" + ); + printf("result for '%-3s' is %016llx\n", "cmpxchg8b", n); +} + +void do_xadd ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + ULong some = 0x271831415927D459ULL; + __asm__ __volatile__( + "\t" + "stc" "\n\t" + // zero out rax and get the flags in a known state + "xorq %%rax, %%rax" "\n\t" + "xacquire lock xaddq %1, (%0)" "\n\t" + "xrelease lock xaddq %1, (%0)" "\n\t" + "xacquire lock xaddl %k1, (%0)" "\n\t" + "xrelease lock xaddl %k1, (%0)" "\n\t" + "xacquire lock xaddw %w1, (%0)" "\n\t" + "xrelease lock xaddw %w1, (%0)" "\n\t" + "xacquire lock xaddb %b1, (%0)" "\n\t" + "xrelease lock xaddb %b1, (%0)" "\n\t" + : : "r"(&n), "r"(some) : "cc", "memory", "rax" + // not sure this constraint string is really correct, since %1 + // is written as well as read, in this case. But I can't figure + // out how to tell gcc that. + ); + printf("result for '%-3s' is %016llx\n", "xadd", n); +} + +void do_xchg ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + ULong some = 0x271831415927D459ULL; + __asm__ __volatile__( + "\t" + "stc" "\n\t" + // zero out rax and get the flags in a known state + "xorq %%rax, %%rax" "\n\t" + "xacquire lock xchgq %1, (%0)" "\n\t" + "xrelease lock xchgq %1, (%0)" "\n\t" + "xacquire lock xchgl %k1, (%0)" "\n\t" + "xrelease lock xchgl %k1, (%0)" "\n\t" + "xacquire lock xchgw %w1, (%0)" "\n\t" + "xrelease lock xchgw %w1, (%0)" "\n\t" + "xacquire lock xchgb %b1, (%0)" "\n\t" + "xrelease lock xchgb %b1, (%0)" "\n\t" + : : "r"(&n), "r"(some) : "cc", "memory", "rax" + // not sure this constraint string is really correct, since %1 + // is written as well as read, in this case. But I can't figure + // out how to tell gcc that. + ); + printf("result for '%-3s' is %016llx\n", "xchg", n); +} + +void do_xchg_no_lock ( void ) +{ + volatile ULong n = 0x5555555555555555ULL; + ULong some = 0x271831415927D459ULL; + __asm__ __volatile__( + "\t" + "stc" "\n\t" + // zero out rax and get the flags in a known state + "xorq %%rax, %%rax" "\n\t" + "xacquire xchgq %1, (%0)" "\n\t" + "xrelease xchgq %1, (%0)" "\n\t" + "xacquire xchgl %k1, (%0)" "\n\t" + "xrelease xchgl %k1, (%0)" "\n\t" + "xacquire xchgw %w1, (%0)" "\n\t" + "xrelease xchgw %w1, (%0)" "\n\t" + "xacquire xchgb %b1, (%0)" "\n\t" + "xrelease xchgb %b1, (%0)" "\n\t" + : : "r"(&n), "r"(some) : "cc", "memory", "rax" + // not sure this constraint string is really correct, since %1 + // is written as well as read, in this case. But I can't figure + // out how to tell gcc that. + ); + printf("result for '%-3s' is %016llx\n", "xchg-no-lock", n); +} + +void do_mov ( void ) +{ + // According to the Intel docs, we only need to allow xrelease here. + volatile ULong n = 0x5555555555555555ULL; + ULong some = 0x271831415927D459ULL; + __asm__ __volatile__( + "\t" + "xrelease movq %1, 0(%0)" "\n\t" + "xrelease movl %k1, 1(%0)" "\n\t" + "xrelease movw %w1, 3(%0)" "\n\t" + "xrelease movb %b1, 7(%0)" "\n\t" + : : "r"(&n), "r"(some) : "cc", "memory" + ); + printf("result for '%-3s' is %016llx\n", "mov-reg", n); + n = 0xAAAAAAAAAAAAAAAAULL; + __asm__ __volatile__( + "\t" + "xrelease movq $-0x79876543, 0(%0)" "\n\t" + "xrelease movl $0xEFCDAB89, 1(%0)" "\n\t" + "xrelease movw $0xF00D, 3(%0)" "\n\t" + "xrelease movb $0x42, 7(%0)" "\n\t" + : : "r"(&n) : "cc", "memory" + ); + printf("result for '%-3s' is %016llx\n", "mov-imm", n); +} + +int main ( void ) +{ + do_add(); + do_adc(); + do_and(); + do_or(); + do_sbb(); + do_sub(); + do_xor(); + do_dec(); + do_inc(); + do_neg(); + do_not(); + do_btc(); + do_btr(); + do_bts(); + do_cmpxchg(); + do_cmpxchg8b(); + do_xadd(); + do_xchg(); + do_xchg_no_lock(); + do_mov(); + return 0; +}