Skip to content

Instantly share code, notes, and snippets.

@bDrwx
Created October 18, 2018 20:03
Show Gist options
  • Save bDrwx/65c7355d5b252ba4c3ff77d0728a8dee to your computer and use it in GitHub Desktop.
Save bDrwx/65c7355d5b252ba4c3ff77d0728a8dee to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <inttypes.h>
#include <x86intrin.h>
int bcd2int(int bcd)
{
static __v2di output = {0,0};
output[0]=bcd;
asm volatile(
“\tmovq\t%0, %%xmm0;\n” // use 128 bit SSE xmm registers
“\tmovq\t%%xmm0, %%xmm1;\n” // make copy “04030201”
“\tmovq\t$0x000f000f000f000f, %0;\n”
“\tmovq\t%0, %%xmm2;\n” // low nibble mask “000f”
“\tshlq\t$8, %0;\n”
“\tmovq\t%0, %%xmm3;\n” // high nibble mask “0f00”
“\tpand\t%%xmm2, %%xmm0;\n” // only low “0001”
“\tpand\t%%xmm3, %%xmm1;\n” // only hi “0200”
“\tpsrlw\t$4, %%xmm1;\n” // “0020”
“\tpaddw\t%%xmm1, %%xmm0;\n” // “0020”+“0001“ => ”0021"
“\tpackuswb\t%%xmm0, %%xmm0;\n” // “0043” “0021” => “4321”
“\tmovq\t%%xmm0, %2;\n” //stored packed bcd
“\tfbld\t%2;\n” //convert pbcd->float
“\tfistp\t%2;\n” //float->int
“\temms;\n” //free FPU
“\tmovq\t%2, %1;\n”
:“=r” (output[0])
:“0” (output[0]), “o” (output) // o instead m means try to keep memory reference short
);
return output[0];
}
int main()
{
register uint64_t t;
printf(“%d\n”, bcd2int(0x04050602));
printf(“%d\n”, bcd2int(0x0));
printf(“%d\n”, bcd2int(0x01020304));
printf(“%d\n”, bcd2int(0x01010101));
printf(“%d\n”, bcd2int(0x09090909));
printf(“%d\n”, bcd2int(0x04030201));
asm volatile(“cpuid;cpuid;cpuid”);
t=__rdtsc()+72;
for(register unsigned int i=1000000–1;i;i--) bcd2int(0x09080706);
t=__rdtsc()-t;
printf(“cycles: %ld\n”, t/1000000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment