File:  [Qemu by Fabrice Bellard] / qemu / host-utils.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:33:54 2018 UTC (2 years, 4 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, qemu1001, qemu1000, qemu0151, qemu0150, qemu0141, qemu0140, qemu0130, qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, HEAD
qemu 0.12.0

    1: /*
    2:  * Utility compute operations used by translated code.
    3:  *
    4:  * Copyright (c) 2003 Fabrice Bellard
    5:  * Copyright (c) 2007 Aurelien Jarno
    6:  *
    7:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    8:  * of this software and associated documentation files (the "Software"), to deal
    9:  * in the Software without restriction, including without limitation the rights
   10:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   11:  * copies of the Software, and to permit persons to whom the Software is
   12:  * furnished to do so, subject to the following conditions:
   13:  *
   14:  * The above copyright notice and this permission notice shall be included in
   15:  * all copies or substantial portions of the Software.
   16:  *
   17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   18:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   22:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   23:  * THE SOFTWARE.
   24:  */
   25: 
   26: #include <stdlib.h>
   27: #include <stdint.h>
   28: #include "host-utils.h"
   29: 
   30: //#define DEBUG_MULDIV
   31: 
   32: /* Long integer helpers */
   33: #if !defined(__x86_64__)
   34: static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
   35: {
   36:     *plow += a;
   37:     /* carry test */
   38:     if (*plow < a)
   39:         (*phigh)++;
   40:     *phigh += b;
   41: }
   42: 
   43: static void neg128 (uint64_t *plow, uint64_t *phigh)
   44: {
   45:     *plow = ~*plow;
   46:     *phigh = ~*phigh;
   47:     add128(plow, phigh, 1, 0);
   48: }
   49: 
   50: static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
   51: {
   52:     uint32_t a0, a1, b0, b1;
   53:     uint64_t v;
   54: 
   55:     a0 = a;
   56:     a1 = a >> 32;
   57: 
   58:     b0 = b;
   59:     b1 = b >> 32;
   60: 
   61:     v = (uint64_t)a0 * (uint64_t)b0;
   62:     *plow = v;
   63:     *phigh = 0;
   64: 
   65:     v = (uint64_t)a0 * (uint64_t)b1;
   66:     add128(plow, phigh, v << 32, v >> 32);
   67: 
   68:     v = (uint64_t)a1 * (uint64_t)b0;
   69:     add128(plow, phigh, v << 32, v >> 32);
   70: 
   71:     v = (uint64_t)a1 * (uint64_t)b1;
   72:     *phigh += v;
   73: }
   74: 
   75: /* Unsigned 64x64 -> 128 multiplication */
   76: void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
   77: {
   78:     mul64(plow, phigh, a, b);
   79: #if defined(DEBUG_MULDIV)
   80:     printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
   81:            a, b, *phigh, *plow);
   82: #endif
   83: }
   84: 
   85: /* Signed 64x64 -> 128 multiplication */
   86: void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
   87: {
   88:     int sa, sb;
   89: 
   90:     sa = (a < 0);
   91:     if (sa)
   92:         a = -a;
   93:     sb = (b < 0);
   94:     if (sb)
   95:         b = -b;
   96:     mul64(plow, phigh, a, b);
   97:     if (sa ^ sb) {
   98:         neg128(plow, phigh);
   99:     }
  100: #if defined(DEBUG_MULDIV)
  101:     printf("muls64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
  102:            a, b, *phigh, *plow);
  103: #endif
  104: }
  105: #endif /* !defined(__x86_64__) */

unix.superglobalmegacorp.com