Richard Sandiford wrote: ...
+ <li>The MIPS port no longer recognizes the <code>h</code> + <code>asm</code> constraint. It was necessary to remove + this constraint in order to avoid generating unpredictable + code sequences. + + <p>One of the main uses of the <code>h</code> constraint + was to extract the high part of a multiplication on + 64-bit targets. For example:</p> + <pre> + asm ("dmultu\t%1,%2" : "=h" (result) : "r" (x), "r" (y));</pre> + <p>You can now achieve the same effect using 128-bit types:</p> + <pre> + typedef unsigned int uint128_t __attribute__((mode(TI))); + result = ((uint128_t) x * y) >> 64;</pre> + <p>The second sequence is better in many ways. For example, + if <code>x</code> and <code>y</code> are constants, the + compiler can perform the multiplication at compile time. + If <code>x</code> and <code>y</code> are not constants, + the compiler can schedule the runtime multiplication + better than it can schedule an <code>asm</code> statement.</p> + </li> </ul>
Hi, GLIBC contains the following code in stdlib/longlong.h: <snip> #if defined (__mips__) && W_TYPE_SIZE == 32 #define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ : "=l" ((USItype) (w0)), \ "=h" ((USItype) (w1)) \ : "d" ((USItype) (u)), \ "d" ((USItype) (v))) #define UMUL_TIME 10 #define UDIV_TIME 100 #endif /* __mips__ */ </snip> What would be a correct fix in this case? Something like this: <snip> #define umul_ppmm(w1, w0, u, v) \ ({unsigned int __attribute__((mode(DI))) __xx; \ __xx = (unsigned int __attribute__((mode(DI)))) u * v; \ w0 = __xx & ((1 << 32) - 1); \ w1 = __xx >> 32;}) </snip> Or is there a better way? Thanks, Maxim