From: David Cleaver <wraithx@mo...>  20100204 02:40:32

Hello, I'm not sure if this will be the proper place to ask this. If not, could someone suggest a better place to ask. I'm having a bit of trouble with a small function I've created. It is supposed to multiply 2 64bit numbers, divide the result (possibly up to a 128bit number) by another 64bit number, and then return the 64bit remainder after that division (mulmod64). I thought that I have compiled this successfully with Mingw64 in the past, but I can't seem to recreate that now. Now when I compile it, it silently crashes. When I run it through gdb, it tells me I am getting a SIGFPE on a "mov" instruction. If I hit continue, it just keeps repeating SIGILL after that. I guess my question is, Is my code correct? Can what I'm trying to do be done with Mingw64? Any help/advice would be greatly appreciated. David C. Here is a small sample program: #include <stdio.h> typedef unsigned long long u64_t; /***************************************************************/ static u64_t mulmod64_asm(u64_t a, u64_t b, u64_t c) { u64_t d; /* to hold the result of a*b mod c */ /* calculates a*b mod c, stores result in d */ asm ("mov %1, %%rax;" /* put a into rax */ "mul %2;" /* mul a*b > rdx:rax */ "div %3;" /* (a*b)/c > quot in rax rem in rdx */ "mov %%rdx, %0;" /* store result in d */ :"=r"(d) /* output */ :"r"(a), "r"(b), "r"(c) /* input */ :"%rax", "%rdx" /* clobbered registers */ ); return d; }/* method mulmod64_asm */ /***************************************************************/ int main(int argc, char* argv[]) { u64_t n = 0; u64_t x = 18446744073709551615ULL; u64_t y = 18446744073709551615ULL; u64_t z = 18446744073709550000ULL; /* this gives n = 2608225 */ /* u64_t z = 10000; /* with this z, n = 8225 */ printf("Testing asm code...\n"); n = mulmod64_asm(x,y,z); printf("x*y mod z = %I64u\n", n); return 0; } 
From: Daniel Verkamp <daniel@dr...>  20100204 19:14:24

On Wed, Feb 3, 2010 at 7:32 PM, David Cleaver <wraithx@...> wrote: > Hello, I'm not sure if this will be the proper place to ask this. If not, > could someone suggest a better place to ask. > > I'm having a bit of trouble with a small function I've created. It is supposed > to multiply 2 64bit numbers, divide the result (possibly up to a 128bit > number) by another 64bit number, and then return the 64bit remainder after > that division (mulmod64). > > I thought that I have compiled this successfully with Mingw64 in the past, but I > can't seem to recreate that now. Now when I compile it, it silently crashes. > When I run it through gdb, it tells me I am getting a SIGFPE on a "mov" > instruction. If I hit continue, it just keeps repeating SIGILL after that. > > I guess my question is, Is my code correct? Can what I'm trying to do be done > with Mingw64? Any help/advice would be greatly appreciated. > > David C. > > Here is a small sample program: > > #include <stdio.h> > > typedef unsigned long long u64_t; > > /***************************************************************/ > > static u64_t mulmod64_asm(u64_t a, u64_t b, u64_t c) > { > u64_t d; /* to hold the result of a*b mod c */ > > /* calculates a*b mod c, stores result in d */ > asm ("mov %1, %%rax;" /* put a into rax */ > "mul %2;" /* mul a*b > rdx:rax */ > "div %3;" /* (a*b)/c > quot in rax rem in rdx */ > "mov %%rdx, %0;" /* store result in d */ > :"=r"(d) /* output */ > :"r"(a), "r"(b), "r"(c) /* input */ > :"%rax", "%rdx" /* clobbered registers */ > ); > return d; > }/* method mulmod64_asm */ I don't have a 64bit machine handy to test this at the moment, but it could at least be more efficiently written with different constraints: static u64_t mulmod64_asm(u64_t a, u64_t b, u64_t c) { u64_t d; asm ("mul %2;" "div %3;" :"=d"(d) :"a"(a), "rm"(b), "rm"(c) ); return d; } Apologies if this doesn't really answer your question...  Daniel Verkamp 