/**************************************************************************** * * * GNAT COMPILER COMPONENTS * * * * A R I T 6 4 . C * * * * C Implementation File * * * * Copyright (C) 2009, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * * ware Foundation; either version 3, or (at your option) any later ver- * * sion. GNAT is distributed in the hope that it will be useful, but WITH- * * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * * or FITNESS FOR A PARTICULAR PURPOSE. * * * * As a special exception under Section 7 of GPL version 3, you are granted * * additional permissions described in the GCC Runtime Library Exception, * * version 3.1, as published by the Free Software Foundation. * * * * You should have received a copy of the GNU General Public License and * * a copy of the GCC Runtime Library Exception along with this program; * * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see * * . * * * * GNAT was originally developed by the GNAT team at New York University. * * Extensive contributions were provided by Ada Core Technologies Inc. * * * ****************************************************************************/ extern void __gnat_rcheck_10(char *file, int line) __attribute__ ((__noreturn__)); long long int __gnat_mulv64 (long long int x, long long int y) { unsigned neg = (x >= 0) ^ (y >= 0); long long unsigned xa = x >= 0 ? (long long unsigned) x : -(long long unsigned) x; long long unsigned ya = y >= 0 ? (long long unsigned) y : -(long long unsigned) y; unsigned xhi = (unsigned) (xa >> 32); unsigned yhi = (unsigned) (ya >> 32); unsigned xlo = (unsigned) xa; unsigned ylo = (unsigned) ya; long long unsigned mid = xhi ? (long long unsigned) xhi * (long long unsigned) ylo : (long long unsigned) yhi * (long long unsigned) xlo; long long unsigned low = (long long unsigned) xlo * (long long unsigned) ylo; if ((xhi && yhi) || mid + (low >> 32) > 0x7fffffff + neg) __gnat_rcheck_10 (__FILE__, __LINE__); low += ((long long unsigned) (unsigned) mid) << 32; return (long long int) (neg ? -low : low); }