1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdio.h>
3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdlib.h>
4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <assert.h>
5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <malloc.h>
6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef  unsigned char           UChar;
8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef  unsigned int            UInt;
9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef  unsigned long int       UWord;
10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef  unsigned long long int  ULong;
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef  struct { UChar cs[40]; }  Block;
14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid showBlock ( char* msg, Block* b )
16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int i;
18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   printf("  %s ", msg);
19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   for (i = 0; i < 40; i++)
20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("%02x", (UInt)b->cs[i]);
21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   printf("\n");
22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
24663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengUChar randUChar ( void )
25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   static UInt seed = 80021;
27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   seed = 1103515245 * seed + 12345;
28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return (seed >> 17) & 0xFF;
29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid randBlock ( Block* b )
32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int i;
34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UChar* p = (UChar*)b;
35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   for (i = 0; i < sizeof(Block); i++)
36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p[i] = randUChar();
37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Generate a function test_NAME, that tests the given insn.
40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   The insn may only mention (%rax) and r9. */
41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GEN_test_Monly(_name, _mem_form)   \
43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    \
44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    __attribute__ ((noinline)) static void test_##_name ( void )   \
45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    { \
46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       Block* b = memalign(32, sizeof(Block)); \
47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       randBlock(b); \
48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       printf("%s\n", #_name); \
49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       showBlock("before", b); \
50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       __asm__ __volatile__( \
51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "leaq      16(%0),%%rax"  "\n\t" \
52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "movq      24(%0),%%r9"   "\n\t" \
53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          _mem_form  "\n\t" \
54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "movq      %%r9, 32(%0)"  "\n\t" \
55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          : /*OUT*/  \
56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          : /*IN*/"r"(b) \
57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          : /*TRASH*/"r9","rax","memory","cc" \
58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       ); \
59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       showBlock("after ", b); \
60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       printf("\n"); \
61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       free(b); \
62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
64663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengGEN_test_Monly( MOVBE_RtoM_64, "movbe %%r9, 1(%%rax)")
65663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengGEN_test_Monly( MOVBE_RtoM_32, "movbe %%r9d,1(%%rax)")
66663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengGEN_test_Monly( MOVBE_RtoM_16, "movbe %%r9w,1(%%rax)")
67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
68663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengGEN_test_Monly( MOVBE_MtoR_64, "movbe 1(%%rax), %%r9")
69663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengGEN_test_Monly( MOVBE_MtoR_32, "movbe 1(%%rax), %%r9d")
70663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengGEN_test_Monly( MOVBE_MtoR_16, "movbe 1(%%rax), %%r9w")
71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main ( void )
73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_MOVBE_RtoM_64();
75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_MOVBE_RtoM_32();
76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_MOVBE_RtoM_16();
77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_MOVBE_MtoR_64();
78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_MOVBE_MtoR_32();
79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_MOVBE_MtoR_16();
80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return 0;
81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
82