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