#include typedef unsigned long long int ULong; ULong data; ULong xtra; ULong amt; ULong flags_in; ULong result; ULong flags_out; #define AMD64G_CC_SHIFT_O 11 #define AMD64G_CC_SHIFT_S 7 #define AMD64G_CC_SHIFT_Z 6 #define AMD64G_CC_SHIFT_A 4 #define AMD64G_CC_SHIFT_C 0 #define AMD64G_CC_SHIFT_P 2 #define AMD64G_CC_MASK_O (1 << AMD64G_CC_SHIFT_O) #define AMD64G_CC_MASK_S (1 << AMD64G_CC_SHIFT_S) #define AMD64G_CC_MASK_Z (1 << AMD64G_CC_SHIFT_Z) #define AMD64G_CC_MASK_A (1 << AMD64G_CC_SHIFT_A) #define AMD64G_CC_MASK_C (1 << AMD64G_CC_SHIFT_C) #define AMD64G_CC_MASK_P (1 << AMD64G_CC_SHIFT_P) #define MASK_OSZACP \ (AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z \ | AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P) extern void shld64 ( void ); asm("\n" "shld64:\n" "\tpushq %rsi\n" "\tpushq %r11\n" "\tpushq %rcx\n" "\tmovq data, %rsi\n" "\tmovq xtra, %r11\n" "\tmovq amt, %rcx\n" "\tpushq flags_in\n" "\tpopfq\n" "\tshldq %cl, %r11, %rsi\n" "\tmovq %rsi, result\n" "\tpushfq\n" "\tpopq flags_out\n" "\tpopq %rcx\n" "\tpopq %r11\n" "\tpopq %rsi\n" "\tret\n" ); extern void shld32 ( void ); asm("\n" "shld32:\n" "\tpushq %rsi\n" "\tpushq %r11\n" "\tpushq %rcx\n" "\tmovq data, %rsi\n" "\tmovq xtra, %r11\n" "\tmovq amt, %rcx\n" "\tpushq flags_in\n" "\tpopfq\n" "\tshldl %cl, %r11d, %esi\n" "\tmovq %rsi, result\n" "\tpushfq\n" "\tpopq flags_out\n" "\tpopq %rcx\n" "\tpopq %r11\n" "\tpopq %rsi\n" "\tret\n" ); extern void shld16 ( void ); asm("\n" "shld16:\n" "\tpushq %rsi\n" "\tpushq %r11\n" "\tpushq %rcx\n" "\tmovq data, %rsi\n" "\tmovq xtra, %r11\n" "\tmovq amt, %rcx\n" "\tpushq flags_in\n" "\tpopfq\n" "\tshldw %cl, %r11w, %si\n" "\tmovq %rsi, result\n" "\tpushfq\n" "\tpopq flags_out\n" "\tpopq %rcx\n" "\tpopq %r11\n" "\tpopq %rsi\n" "\tret\n" ); extern void shrd64 ( void ); asm("\n" "shrd64:\n" "\tpushq %rsi\n" "\tpushq %r11\n" "\tpushq %rcx\n" "\tmovq data, %rsi\n" "\tmovq xtra, %r11\n" "\tmovq amt, %rcx\n" "\tpushq flags_in\n" "\tpopfq\n" "\tshrdq %cl, %r11, %rsi\n" "\tmovq %rsi, result\n" "\tpushfq\n" "\tpopq flags_out\n" "\tpopq %rcx\n" "\tpopq %r11\n" "\tpopq %rsi\n" "\tret\n" ); extern void shrd32 ( void ); asm("\n" "shrd32:\n" "\tpushq %rsi\n" "\tpushq %r11\n" "\tpushq %rcx\n" "\tmovq data, %rsi\n" "\tmovq xtra, %r11\n" "\tmovq amt, %rcx\n" "\tpushq flags_in\n" "\tpopfq\n" "\tshrdl %cl, %r11d, %esi\n" "\tmovq %rsi, result\n" "\tpushfq\n" "\tpopq flags_out\n" "\tpopq %rcx\n" "\tpopq %r11\n" "\tpopq %rsi\n" "\tret\n" ); extern void shrd16 ( void ); asm("\n" "shrd16:\n" "\tpushq %rsi\n" "\tpushq %r11\n" "\tpushq %rcx\n" "\tmovq data, %rsi\n" "\tmovq xtra, %r11\n" "\tmovq amt, %rcx\n" "\tpushq flags_in\n" "\tpopfq\n" "\tshrdw %cl, %r11w, %si\n" "\tmovq %rsi, result\n" "\tpushfq\n" "\tpopq flags_out\n" "\tpopq %rcx\n" "\tpopq %r11\n" "\tpopq %rsi\n" "\tret\n" ); int main ( void ) { int i; ULong mask; printf("\nleft 64\n"); for (i = 0; i < 260; i++) { mask = MASK_OSZACP; if (i > 1) mask &= ~AMD64G_CC_MASK_O; if (i > 0) mask &= ~AMD64G_CC_MASK_A; data = 0x1122334455667788ULL; xtra = 0x3141592727182818ULL; flags_in = 0ULL; amt = (ULong)i; shld64(); printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask); } printf("\nleft 32\n"); for (i = 0; i < 260; i++) { mask = MASK_OSZACP; if (i > 1) mask &= ~AMD64G_CC_MASK_O; if (i > 0) mask &= ~AMD64G_CC_MASK_A; data = 0x1122334455667788ULL; xtra = 0x3141592727182818ULL; flags_in = 0ULL; amt = (ULong)i; shld32(); printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask); } printf("\n"); printf("\nleft 16\n"); for (i = 0; i < 260; i++) { mask = MASK_OSZACP; if (i > 1) mask &= ~AMD64G_CC_MASK_O; if (i > 0) mask &= ~AMD64G_CC_MASK_A; data = 0x1122334455667788ULL; xtra = 0x987654321987abcdULL; flags_in = 0ULL; amt = (ULong)i; shld16(); printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask); } printf("\n"); printf("\nright 64\n"); for (i = 0; i < 260; i++) { mask = MASK_OSZACP; if (i > 1) mask &= ~AMD64G_CC_MASK_O; if (i > 0) mask &= ~AMD64G_CC_MASK_A; data = 0x1122334455667788ULL; xtra = 0x3141592727182818ULL; flags_in = 0ULL; amt = (ULong)i; shrd64(); printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask); } printf("\nright 32\n"); for (i = 0; i < 260; i++) { mask = MASK_OSZACP; if (i > 1) mask &= ~AMD64G_CC_MASK_O; if (i > 0) mask &= ~AMD64G_CC_MASK_A; data = 0x1122334455667788ULL; xtra = 0x3141592727182818ULL; flags_in = 0ULL; amt = (ULong)i; shrd32(); printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask); } printf("\n"); printf("\nright 16\n"); for (i = 0; i < 260; i++) { mask = MASK_OSZACP; if (i > 1) mask &= ~AMD64G_CC_MASK_O; if (i > 0) mask &= ~AMD64G_CC_MASK_A; data = 0x1122334455667788ULL; xtra = 0x987654321987abcdULL; flags_in = 0ULL; amt = (ULong)i; shrd16(); printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask); } printf("\n"); return 0; }