This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
2nd posting: exceptions and asm() blocks on x86
- From: "John S. Yates, Jr." <jyates at netezza dot com>
- To: "gcc-help" <gcc-help at gcc dot gnu dot org>
- Date: Thu, 2 Oct 2003 17:13:25 -0400
- Subject: 2nd posting: exceptions and asm() blocks on x86
- Organization: Netezza Corporation
- Reply-to: "John S. Yates, Jr." <jyates at netezza dot com>
I originally posted this query 3 weeks ago but have
received no reply.
/john
=====
I am using gcc 2.96.
I have recently debugged an exception failure in our
multi-precision arithmetic package. The problem was
that when overflow was signaled the catch block was
never found.
// Each multi-precision operation is implemented as an
// inline function wrapping an asm() block. Overflow
// is signaled by calling a noreturn, nullary helper:
extern "C" void
signal_overflow(void) __attribute__((noreturn));
// The failing code would call the helper from within
// the asm() block:
inline static CNumeric128
operator + (CNumeric128 const& left,
CNumeric128 const& right
)
{
int hi, hl, lh, lo;
asm (" movl %4,%3\n"
" movl 4%4,%2\n"
" movl 8%4,%1\n"
" movl 12%4,%0\n"
" addl %5,%3\n"
" adcl 4%5,%2\n"
" adcl 8%5,%1\n"
" adcl 12%5,%0\n"
" jno 1f\n"
" call signal_overflow\n"
"1:\n"
:
/* %0 */ "=&r" (hi),
/* %1 */ "=&r" (hl),
/* %2 */ "=&r" (lh),
/* %3 */ "=&r" (lo)
:
/* %4 */ "o" (left),
/* %5 */ "o" (right)
:
"cc"
);
return CNumeric128(hi,hl,lh,lo);
}
// Changing the asm() block to return a materialized
// boolean and then calling the helper from a normal
// C++ context allows catch blocks to be located:
inline static CNumeric128
operator + (CNumeric128 const& left,
CNumeric128 const& right
)
{
int hi, hl, lh, lo;
unsigned char ovf;
asm (" movl %5,%4\n"
" movl 4%5,%3\n"
" movl 8%5,%2\n"
" movl 12%5,%1\n"
" addl %6,%4\n"
" adcl 4%6,%3\n"
" adcl 8%6,%2\n"
" adcl 12%6,%1\n"
" setob %0\n"
:
/* %0 */ "=g" (ovf),
/* %1 */ "=&r" (hi),
/* %2 */ "=&r" (hl),
/* %3 */ "=&r" (lh),
/* %4 */ "=&r" (lo)
:
/* %5 */ "o" (left),
/* %6 */ "o" (right)
:
"cc"
);
if (ovf)
signal_overflow();
return CNumeric128(hi,hl,lh,lo);
}
Is this a bug or an expected limitation? If the
latter, is it documented anywhere?
--
John S. Yates, Jr. 508 665-6897 (voice)
Netezza Inc 508 665-6811 (fax)
200 Crossing Blvd. Framingham, MA 01701