This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: multi-precision in extended asm
- From: "John S. Yates, Jr." <jyates at netezza dot com>
- To: "gcc-help" <gcc-help at gcc dot gnu dot org>
- Date: Wed, 15 May 2002 12:48:24 -0400
- Subject: Re: multi-precision in extended asm
- Organization: Netezza Corporation
- Reply-to: "John S. Yates, Jr." <jyates at netezza dot com>
Still trying. This is my first brush with gcc's extended asm
feature so I am interested in any and all feedback on my efforts.
I am writing 3 x86 accumulation functions:
- i32 into i64
- i32 into i128
- i64 into i128
My current coding appears below.
The first two work because the lhs is passed as a reference and
the rhs is register-size. I am having trouble with the third.
How do I express "please load a 64 bit input operand into %eax
and %edx according to the x86-specific A constraint"?
TIA,
/john
========================================
inline void operator += (CNumeric64& lhs, int32 rhs)
{
asm(
"cltd\n\t" // replicate sign of %eax through %edx
"addl %%eax,%0\n\t" // sum: lhs.lo32+rhs; set carry
"adcl %%edx,%1" // sum: lhs.hi32+repSign(rhs)+carry
:
/* %0 */ "+o" (lhs.lo32),
/* %1 */ "+o" (lhs.hi32)
:
/* %2 */ "a" (rhs) // 32 bits in %eax
:
"cc", "edx"
);
}
inline void operator += (CNumeric128& lhs, int32 rhs)
{
asm(
"cltd\n\t" // replicate sign of %eax through %edx
"addl %%eax,%0\n\t" // sum: lhs.lo32+rhs; set carry
"adcl %%edx,%1\n\t" // sum: lhs.lh32+repSign(rhs)+carry; set carry
"adcl %%edx,%2\n\t" // sum: lhs.hl32+repSign(rhs)+carry; set carry
"adcl %%edx,%3" // sum: lhs.hi32+repSign(rhs)+carry
:
/* %0 */ "+o" (lhs.lo32),
/* %1 */ "+o" (lhs.lh32),
/* %2 */ "+o" (lhs.hl32),
/* %3 */ "+o" (lhs.hi32)
:
/* %4 */ "a" (rhs) // 32 bits in %eax
:
"cc", "edx"
);
}
inline void operator += (CNumeric128& lhs, int64 rhs)
{
asm(
"addl %%eax,%0\n\t" // sum: lhs.lo32+rhs; set carry
"movl %%edx,%%eax\n\t"// setup for sign bit replication
"adcl %%edx,%1\n\t" // sum: lhs.lh32+repSign(rhs)+carry; set carry
"cltd\n\t" // replicate sign of %eax through %edx
"adcl %%edx,%2" // sum: lhs.hl32+repSign(rhs)+carry; set carry
"adcl %%edx,%3" // sum: lhs.hi32+repSign(rhs)+carry
:
/* %0 */ "+o" (lhs.lo32),
/* %1 */ "+o" (lhs.lh32),
/* %2 */ "+o" (lhs.hl32),
/* %3 */ "+o" (lhs.hi32)
:
/* %4 */ "A" (rhs) // 64 bits: %eax = low order, %edx = high order
:
"cc", "eax", "edx"
);
}
> Given that GCC provides 64 integers across many architectures
> with only 32 bit wide registers I assume there is some general
> framework for manipulating these objects. Is there a way to
> write a constraint that says "low order 32 bits of 64 bit
> datum" or "high order 32 bits of 64 bit datum"?
>
> In particular how would I express "arithmetic shift right 31
> places the high 32 bits of a 64 bit integer to get a register
> filled with a copy of the sign bit" on the x86? on the ppc?
>
> --
> John S. Yates, Jr. 508 665-6800 x897
> Netezza Inc, Suite 100 508 665-6811 (fax)
> 1671 Worcester Rd. Framingham, MA 01701
>