Files
ftmemsim-valgrind/none/tests/amd64/shrld.c
Mark Wielaard fe6805efc1 x86 and amd64 tests: Use .text and .previous around all top-level asm.
GCC10 defaults to -fno-common which exposes some latent bugs in
some of the top-level asm code in various .c test files. Some of the
tests started to segfault (even if not run under valgrind). Such code
needs to be wrapped inside a .text and a .previous asm statement to
make sure the code is generated in the .text code section and to
make sure the compiler doesn't lose track of the section currently
being used to generate data or code in. Without it code might be
generated inside a data section or the other way around.
2020-01-25 18:34:58 +01:00

260 lines
5.2 KiB
C

#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"
".text\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"
".previous\n"
);
extern void shld32 ( void );
asm("\n"
".text\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"
".previous\n"
);
extern void shld16 ( void );
asm("\n"
".text\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"
".previous\n"
);
extern void shrd64 ( void );
asm("\n"
".text\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"
".previous\n"
);
extern void shrd32 ( void );
asm("\n"
".text\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"
".previous\n"
);
extern void shrd16 ( void );
asm("\n"
".text\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"
".previous\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;
}