/* * Copyright (c) 2016, Oracle and/or its affiliates. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used to * endorse or promote products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.oracle.truffle.llvm.nodes.asm.support; /* * This functionality is in the standard class library since Java 9: * https://bugs.openjdk.java.net/browse/JDK-5100935 */ public class LongMultiplication { private static final long MASK32 = 0xFFFFFFFFL; private static final int SHIFT32 = 32; /** * Returns as a {@code long} the most significant 64 bits of the 128-bit product of two 64-bit * factors. * * @param x the first value * @param y the second value * @return the result */ public static long multiplyHigh(long x, long y) { if (x < 0 || y < 0) { // Use technique from section 8-2 of Henry S. Warren, Jr., // Hacker's Delight (2nd ed.) (Addison Wesley, 2013), 173-174. long x1 = x >> SHIFT32; long x2 = x & MASK32; long y1 = y >> SHIFT32; long y2 = y & MASK32; long z2 = x2 * y2; long t = x1 * y2 + (z2 >>> SHIFT32); long z1 = t & MASK32; long z0 = t >> SHIFT32; z1 += x2 * y1; return x1 * y1 + z0 + (z1 >> SHIFT32); } else { // Use Karatsuba technique with two base 2^32 digits. long x1 = x >>> SHIFT32; long y1 = y >>> SHIFT32; long x2 = x & MASK32; long y2 = y & MASK32; long a = x1 * y1; long b = x2 * y2; long c = (x1 + x2) * (y1 + y2); long k = c - a - b; return (((b >>> SHIFT32) + k) >>> SHIFT32) + a; } } }