This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Changing the treatment of the MIPS HI and LO registers
- From: Maxim Kuvyrkov <maxim at codesourcery dot com>
- To: "Maciej W. Rozycki" <macro at linux-mips dot org>, Ralf Baechle <ralf at linux-mips dot org>, gcc-patches at gcc dot gnu dot org, linux-mips at linux-mips dot org, rdsandiford at googlemail dot com
- Date: Wed, 11 Jun 2008 22:41:25 +0400
- Subject: Re: Changing the treatment of the MIPS HI and LO registers
- References: <87tzgj4nh6.fsf@firetop.home> <Pine.LNX.4.55.0805272134540.18833@cliff.in.clinika.pl> <87abib4d9t.fsf@firetop.home> <Pine.LNX.4.55.0805272357020.18833@cliff.in.clinika.pl> <87r6bm1ebd.fsf@firetop.home> <Pine.LNX.4.55.0805290213140.29522@cliff.in.clinika.pl> <878wxtvarg.fsf@firetop.home> <8763stz2p3.fsf@firetop.home> <87zlpuxqfb.fsf@firetop.home>
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