#include <stdio.h>
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;
}