exceptions and asm() blocks on x86

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
--
John S. Yates, Jr.   508 665-6897 (voice)
Netezza Inc          508 665-6811 (fax)
200 Crossing Blvd.   Framingham, MA 01701


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux