Home | History | Annotate | Download | only in amd64
      1 
      2 #include <stdio.h>
      3 
      4 typedef unsigned long long int ULong;
      5 
      6 ULong data;
      7 ULong xtra;
      8 ULong amt;
      9 ULong flags_in;
     10 ULong result;
     11 ULong flags_out;
     12 
     13 #define AMD64G_CC_SHIFT_O   11
     14 #define AMD64G_CC_SHIFT_S   7
     15 #define AMD64G_CC_SHIFT_Z   6
     16 #define AMD64G_CC_SHIFT_A   4
     17 #define AMD64G_CC_SHIFT_C   0
     18 #define AMD64G_CC_SHIFT_P   2
     19 
     20 #define AMD64G_CC_MASK_O    (1 << AMD64G_CC_SHIFT_O)
     21 #define AMD64G_CC_MASK_S    (1 << AMD64G_CC_SHIFT_S)
     22 #define AMD64G_CC_MASK_Z    (1 << AMD64G_CC_SHIFT_Z)
     23 #define AMD64G_CC_MASK_A    (1 << AMD64G_CC_SHIFT_A)
     24 #define AMD64G_CC_MASK_C    (1 << AMD64G_CC_SHIFT_C)
     25 #define AMD64G_CC_MASK_P    (1 << AMD64G_CC_SHIFT_P)
     26 
     27 #define MASK_OSZACP  \
     28    (AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z \
     29     | AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P)
     30 
     31 extern void shld64 ( void );
     32 asm("\n"
     33 "shld64:\n"
     34 "\tpushq %rsi\n"
     35 "\tpushq %r11\n"
     36 "\tpushq %rcx\n"
     37 "\tmovq data, %rsi\n"
     38 "\tmovq xtra, %r11\n"
     39 "\tmovq amt, %rcx\n"
     40 "\tpushq flags_in\n"
     41 "\tpopfq\n"
     42 "\tshldq %cl, %r11, %rsi\n"
     43 "\tmovq %rsi, result\n"
     44 "\tpushfq\n"
     45 "\tpopq flags_out\n"
     46 "\tpopq %rcx\n"
     47 "\tpopq %r11\n"
     48 "\tpopq %rsi\n"
     49 "\tret\n"
     50 );
     51 
     52 extern void shld32 ( void );
     53 asm("\n"
     54 "shld32:\n"
     55 "\tpushq %rsi\n"
     56 "\tpushq %r11\n"
     57 "\tpushq %rcx\n"
     58 "\tmovq data, %rsi\n"
     59 "\tmovq xtra, %r11\n"
     60 "\tmovq amt, %rcx\n"
     61 "\tpushq flags_in\n"
     62 "\tpopfq\n"
     63 "\tshldl %cl, %r11d, %esi\n"
     64 "\tmovq %rsi, result\n"
     65 "\tpushfq\n"
     66 "\tpopq flags_out\n"
     67 "\tpopq %rcx\n"
     68 "\tpopq %r11\n"
     69 "\tpopq %rsi\n"
     70 "\tret\n"
     71 );
     72 
     73 extern void shld16 ( void );
     74 asm("\n"
     75 "shld16:\n"
     76 "\tpushq %rsi\n"
     77 "\tpushq %r11\n"
     78 "\tpushq %rcx\n"
     79 "\tmovq data, %rsi\n"
     80 "\tmovq xtra, %r11\n"
     81 "\tmovq amt, %rcx\n"
     82 "\tpushq flags_in\n"
     83 "\tpopfq\n"
     84 "\tshldw %cl, %r11w, %si\n"
     85 "\tmovq %rsi, result\n"
     86 "\tpushfq\n"
     87 "\tpopq flags_out\n"
     88 "\tpopq %rcx\n"
     89 "\tpopq %r11\n"
     90 "\tpopq %rsi\n"
     91 "\tret\n"
     92 );
     93 
     94 
     95 extern void shrd64 ( void );
     96 asm("\n"
     97 "shrd64:\n"
     98 "\tpushq %rsi\n"
     99 "\tpushq %r11\n"
    100 "\tpushq %rcx\n"
    101 "\tmovq data, %rsi\n"
    102 "\tmovq xtra, %r11\n"
    103 "\tmovq amt, %rcx\n"
    104 "\tpushq flags_in\n"
    105 "\tpopfq\n"
    106 "\tshrdq %cl, %r11, %rsi\n"
    107 "\tmovq %rsi, result\n"
    108 "\tpushfq\n"
    109 "\tpopq flags_out\n"
    110 "\tpopq %rcx\n"
    111 "\tpopq %r11\n"
    112 "\tpopq %rsi\n"
    113 "\tret\n"
    114 );
    115 
    116 extern void shrd32 ( void );
    117 asm("\n"
    118 "shrd32:\n"
    119 "\tpushq %rsi\n"
    120 "\tpushq %r11\n"
    121 "\tpushq %rcx\n"
    122 "\tmovq data, %rsi\n"
    123 "\tmovq xtra, %r11\n"
    124 "\tmovq amt, %rcx\n"
    125 "\tpushq flags_in\n"
    126 "\tpopfq\n"
    127 "\tshrdl %cl, %r11d, %esi\n"
    128 "\tmovq %rsi, result\n"
    129 "\tpushfq\n"
    130 "\tpopq flags_out\n"
    131 "\tpopq %rcx\n"
    132 "\tpopq %r11\n"
    133 "\tpopq %rsi\n"
    134 "\tret\n"
    135 );
    136 
    137 extern void shrd16 ( void );
    138 asm("\n"
    139 "shrd16:\n"
    140 "\tpushq %rsi\n"
    141 "\tpushq %r11\n"
    142 "\tpushq %rcx\n"
    143 "\tmovq data, %rsi\n"
    144 "\tmovq xtra, %r11\n"
    145 "\tmovq amt, %rcx\n"
    146 "\tpushq flags_in\n"
    147 "\tpopfq\n"
    148 "\tshrdw %cl, %r11w, %si\n"
    149 "\tmovq %rsi, result\n"
    150 "\tpushfq\n"
    151 "\tpopq flags_out\n"
    152 "\tpopq %rcx\n"
    153 "\tpopq %r11\n"
    154 "\tpopq %rsi\n"
    155 "\tret\n"
    156 );
    157 
    158 
    159 int main ( void )
    160 {
    161   int i;
    162   ULong mask;
    163 
    164   printf("\nleft 64\n");
    165   for (i = 0; i < 260; i++) {
    166     mask = MASK_OSZACP;
    167     if (i > 1) mask &= ~AMD64G_CC_MASK_O;
    168     if (i > 0) mask &= ~AMD64G_CC_MASK_A;
    169     data = 0x1122334455667788ULL;
    170     xtra = 0x3141592727182818ULL;
    171     flags_in = 0ULL;
    172     amt = (ULong)i;
    173     shld64();
    174     printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
    175   }
    176 
    177   printf("\nleft 32\n");
    178   for (i = 0; i < 260; i++) {
    179     mask = MASK_OSZACP;
    180     if (i > 1) mask &= ~AMD64G_CC_MASK_O;
    181     if (i > 0) mask &= ~AMD64G_CC_MASK_A;
    182     data = 0x1122334455667788ULL;
    183     xtra = 0x3141592727182818ULL;
    184     flags_in = 0ULL;
    185     amt = (ULong)i;
    186     shld32();
    187     printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
    188   }
    189   printf("\n");
    190 
    191   printf("\nleft 16\n");
    192   for (i = 0; i < 260; i++) {
    193     mask = MASK_OSZACP;
    194     if (i > 1) mask &= ~AMD64G_CC_MASK_O;
    195     if (i > 0) mask &= ~AMD64G_CC_MASK_A;
    196     data = 0x1122334455667788ULL;
    197     xtra = 0x987654321987abcdULL;
    198     flags_in = 0ULL;
    199     amt = (ULong)i;
    200     shld16();
    201     printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
    202   }
    203   printf("\n");
    204 
    205   printf("\nright 64\n");
    206   for (i = 0; i < 260; i++) {
    207     mask = MASK_OSZACP;
    208     if (i > 1) mask &= ~AMD64G_CC_MASK_O;
    209     if (i > 0) mask &= ~AMD64G_CC_MASK_A;
    210     data = 0x1122334455667788ULL;
    211     xtra = 0x3141592727182818ULL;
    212     flags_in = 0ULL;
    213     amt = (ULong)i;
    214     shrd64();
    215     printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
    216   }
    217 
    218   printf("\nright 32\n");
    219   for (i = 0; i < 260; i++) {
    220     mask = MASK_OSZACP;
    221     if (i > 1) mask &= ~AMD64G_CC_MASK_O;
    222     if (i > 0) mask &= ~AMD64G_CC_MASK_A;
    223     data = 0x1122334455667788ULL;
    224     xtra = 0x3141592727182818ULL;
    225     flags_in = 0ULL;
    226     amt = (ULong)i;
    227     shrd32();
    228     printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
    229   }
    230   printf("\n");
    231 
    232   printf("\nright 16\n");
    233   for (i = 0; i < 260; i++) {
    234     mask = MASK_OSZACP;
    235     if (i > 1) mask &= ~AMD64G_CC_MASK_O;
    236     if (i > 0) mask &= ~AMD64G_CC_MASK_A;
    237     data = 0x1122334455667788ULL;
    238     xtra = 0x987654321987abcdULL;
    239     flags_in = 0ULL;
    240     amt = (ULong)i;
    241     shrd16();
    242     printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
    243   }
    244   printf("\n");
    245 
    246   return 0;
    247 }
    248