root/src/gauche/arith_i386.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * arith_i386.h - i386 specific arithmetic macros
   3  *
   4  *   Copyright (c) 2000-2003 Shiro Kawai, All rights reserved.
   5  * 
   6  *   Redistribution and use in source and binary forms, with or without
   7  *   modification, are permitted provided that the following conditions
   8  *   are met:
   9  * 
  10  *   1. Redistributions of source code must retain the above copyright
  11  *      notice, this list of conditions and the following disclaimer.
  12  *
  13  *   2. Redistributions in binary form must reproduce the above copyright
  14  *      notice, this list of conditions and the following disclaimer in the
  15  *      documentation and/or other materials provided with the distribution.
  16  *
  17  *   3. Neither the name of the authors nor the names of its contributors
  18  *      may be used to endorse or promote products derived from this
  19  *      software without specific prior written permission.
  20  *
  21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  *
  33  *  $Id: arith_i386.h,v 1.6 2005/05/24 07:31:48 shirok Exp $
  34  */
  35 
  36 #ifdef __GNUC__
  37 
  38 /*-----------------------------------------------------------------
  39  * UADD(r, c, x, y)      unsigned word add with carry
  40  *  u_long : r, c, x, y;
  41  *  r <- x + y + c  mod wordsize
  42  *  c <- 1 if carry, 0 otherwise
  43  */
  44 
  45 /* NB: in some context, the compiler failed to allocate registers
  46  * for 'r' and 'c', so I can't use "r" constraint for them.
  47  * The following code assumes 'r', 'c', 'x' and 'y' are stack-allocated
  48  * and to avoid both operands from being on memory.
  49  */
  50 #define UADD(r, c, x, y)                        \
  51     asm("cmpl $1, %2;"                          \
  52         "cmc;"                                  \
  53         "movl %3, %%eax;"                       \
  54         "adcl %4, %%eax;"                       \
  55         "movl %%eax, %0;"                       \
  56         "movl $0, %%eax;"                       \
  57         "adcl $0, %%eax;"                       \
  58         "movl %%eax, %1;"                       \
  59         : "=&g" (r), "=&g" (c)                  \
  60         : "1" (c), "g"(x), "g"(y)               \
  61         : "%eax")
  62 
  63 /*-----------------------------------------------------------------
  64  * UADDOV(r, v, x, y)    unsigned word add with overflow check
  65  *  u_long : r, v, x, y;
  66  *  if x + y overflows, v = 1
  67  *  else r <- x + y, v = 0
  68  */
  69 
  70 #define UADDOV(r, v, x, y)                      \
  71     asm("movl %2, %0;"                          \
  72         "addl %3, %0;"                          \
  73         "movl $0, %1;"                          \
  74         "rcll $1, %1;"                          \
  75         : "=&r" (r), "=&r" (v)                  \
  76         : "g" (x), "g" (y))
  77 
  78 /*-----------------------------------------------------------------
  79  * SADDOV(r, v, x, y)     signed word addition with overflow check
  80  *  long : r, v, x, y;
  81  *  if x + y overflows, v = 1 or -1 depending on the sign of the result
  82  *  else r <- x + y, v = 0
  83  */
  84 
  85 #define SADDOV(r, v, x, y)                      \
  86     asm("movl $0, %1;"                          \
  87         "movl %2, %0;"                          \
  88         "addl %3, %0;"                          \
  89         "jno 0f;"                               \
  90         "jns 1f;"                               \
  91         "movl $1, %1; jmp 0f;"                  \
  92         "1: movl $-1, %1;"                      \
  93         "0:"                                    \
  94         : "=&r" (r), "=&r" (v)                  \
  95         : "g" (x), "g" (y))
  96 
  97 /*-----------------------------------------------------------------
  98  * USUB(r, c, x, y)        unsigned word subtract with borrow
  99  *  u_long : r, x, c, y;
 100  *  r <- x - y - c  mod wordsize
 101  *  c <- 1 if borrow, 0 otherwise
 102  */
 103 
 104 #define USUB(r, c, x, y)                        \
 105     asm("shrl $1, %2;"                          \
 106         "movl %3, %0;"                          \
 107         "sbbl %4, %0;"                          \
 108         "movl $0, %1;"                          \
 109         "rcll $1, %1;"                          \
 110         : "=&r" (r), "=&r"(c)                   \
 111         : "1" (c), "g" (x), "g" (y))
 112 
 113 /*-----------------------------------------------------------------
 114  * USUBOV(r, v, x, y)      unsigned word subtract with overflow check
 115  *  u_long : r, v, x, y;
 116  *  if x - y overflows, v = 1
 117  *  else r <- x - y, v = 0
 118  */
 119 
 120 #define USUBOV(r, v, x, y)                      \
 121     asm("movl %2, %0;"                          \
 122         "subl %3, %0;"                          \
 123         "movl $0, %1;"                          \
 124         "rcll $1, %1;"                          \
 125         : "=&r" (r), "=&r"(v)                   \
 126         : "g" (x), "g" (y))
 127 
 128 /*-----------------------------------------------------------------
 129  * SSUBOV(r, v, x, y)     signed word subtract without borrow
 130  *  long : r, v, x, y;
 131  *  if x - y overflows, c = 1 or -1 depending on the sign of the result
 132  *  else r <- x - y, v = 0
 133  */
 134 
 135 #define SSUBOV(r, v, x, y)                      \
 136     asm("movl $0, %1;"                          \
 137         "movl %2, %0;"                          \
 138         "subl %3, %0;"                          \
 139         "jno 0f;"                               \
 140         "jns 1f;"                               \
 141         "movl $1, %1; jmp 0f;"                  \
 142         "1: movl $-1, %1;"                      \
 143         "0:"                                    \
 144         : "=&r" (r), "=&r" (v)                  \
 145         : "g" (x), "g" (y))
 146 
 147 /*-----------------------------------------------------------------
 148  * UMUL(hi, lo, x, y)       unsigned word multiply
 149  *  u_long : hi, lo, x, y;
 150  *  [hi, lo] <- x * y
 151  */
 152 
 153 #define UMUL(hi, lo, x, y)                      \
 154     asm("movl %2, %%eax;"                       \
 155         "mull %3;"                              \
 156         "movl %%eax, %1;"                       \
 157         "movl %%edx, %0;"                       \
 158         : "=r" (hi), "=r" (lo)                  \
 159         : "g" (x), "r" (y)                      \
 160         : "%eax", "%edx")
 161 
 162 /*-----------------------------------------------------------------
 163  * UMULOV(r, v, x, y)      unsigned word multiply with overflow check
 164  *  u_long : r, x, y
 165  *  int : v
 166  *  if x * y overflows, v = 1
 167  *  else r <- x * y, v = 0
 168  */
 169 /* This and SMULOV is used in the gauche.uvector where lots of
 170    functions are inlined, and using "r" constraint sometimes makes
 171    gcc fail to allocate registers.  Thus we use "g" constraint. */
 172 
 173 #define UMULOV(r, v, x, y)                      \
 174     asm("mull %2;"                              \
 175         "rcll $1, %1;"                          \
 176         : "=a" (r), "=r" (v)                    \
 177         : "r" (y), "0" (x), "1" (0)             \
 178         : "%edx")
 179 
 180 /*-----------------------------------------------------------------
 181  * SMULOV(r, v, x, y)      signed word multiply with overflow check
 182  *  long : r, x, y
 183  *  int : v
 184  *  if x * y overflows, v = 1 or -1 depending on the sign of the result
 185  *  else r <- x * y, v = 0
 186  */
 187 
 188 #define SMULOV(r, v, x, y)                      \
 189     asm("imull %2;"                             \
 190         "jno 0f;"                               \
 191         "cmp $0, %%edx;"                        \
 192         "jl 1f;"                                \
 193         "movl $1, %1; jmp 0f;"                  \
 194         "1: movl $-1, %1;"                      \
 195         "0:"                                    \
 196         : "=a" (r), "=r" (v)                    \
 197         : "r" (y), "0" (x), "1" (0)             \
 198         : "%edx")
 199 
 200 #endif /*__GNUC__*/
 201 
 202 

/* [<][>][^][v][top][bottom][index][help] */