1 /*
   2  * Copyright 2010 Google, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 /*
  26  * @test
  27  * @bug 6921969
  28  * @summary Tests shorter long multiply sequences when the high 32 bits of long operands are known to be zero on x86_32
  29  * @run main/othervm -Xbatch -XX:-Inline -XX:CompileOnly=.testNormal,.testLeftOptimized,.testRightOptimized,.testOptimized,.testLeftOptimized_LoadUI2L,.testRightOptimized_LoadUI2L,.testOptimized_LoadUI2L TestMultiplyLongHiZero
  30  */
  31 
  32 // This test must run without any command line arguments.
  33 
  34 public class TestMultiplyLongHiZero {
  35 
  36   private static void check(long leftFactor, long rightFactor, long optimizedProduct, long constantProduct) {
  37     long normalProduct = leftFactor * rightFactor; // unaffected by the new optimization
  38     if (optimizedProduct != constantProduct || normalProduct != constantProduct) {
  39       throw new RuntimeException("Not all three products are equal: " +
  40                                  Long.toHexString(normalProduct) + ", " +
  41                                  Long.toHexString(optimizedProduct) + ", " +
  42                                  Long.toHexString(constantProduct));
  43     }
  44   }
  45 
  46   private static int initInt(String[] args, int v) {
  47     if (args.length > 0) {
  48       try {
  49         return Integer.valueOf(args[0]);
  50       } catch (NumberFormatException e) { }
  51     }
  52     return v;
  53   }
  54 
  55   private static final long mask32 = 0x00000000FFFFFFFFL;
  56 
  57   private static void testNormal(int leftFactor, int rightFactor, long constantProduct) {
  58     check((long) leftFactor,
  59           (long) rightFactor,
  60           (long) leftFactor * (long) rightFactor, // unaffected by the new optimization
  61           constantProduct);
  62   }
  63 
  64   private static void testLeftOptimized(int leftFactor, int rightFactor, long constantProduct) {
  65     check((leftFactor & mask32),
  66           (long) rightFactor,
  67           (leftFactor & mask32) * (long) rightFactor, // left factor optimized
  68           constantProduct);
  69   }
  70 
  71   private static void testRightOptimized(int leftFactor, int rightFactor, long constantProduct) {
  72     check((long) leftFactor,
  73           (rightFactor & mask32),
  74           (long) leftFactor * (rightFactor & mask32), // right factor optimized
  75           constantProduct);
  76   }
  77 
  78   private static void testOptimized(int leftFactor, int rightFactor, long constantProduct) {
  79     check((leftFactor & mask32),
  80           (rightFactor & mask32),
  81           (leftFactor & mask32) * (rightFactor & mask32), // both factors optimized
  82           constantProduct);
  83   }
  84 
  85   private static void testLeftOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors) {
  86     check((leftFactor & mask32),
  87           (long) rightFactor,
  88           (factors[0] & mask32) * (long) rightFactor, // left factor optimized
  89           constantProduct);
  90   }
  91 
  92   private static void testRightOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors) {
  93     check((long) leftFactor,
  94           (rightFactor & mask32),
  95           (long) leftFactor * (factors[1] & mask32), // right factor optimized
  96           constantProduct);
  97   }
  98 
  99   private static void testOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors) {
 100     check((leftFactor & mask32),
 101           (rightFactor & mask32),
 102           (factors[0] & mask32) * (factors[1] & mask32), // both factors optimized
 103           constantProduct);
 104   }
 105 
 106   private static void test(int leftFactor, int rightFactor,
 107                            long normalConstantProduct,
 108                            long leftOptimizedConstantProduct,
 109                            long rightOptimizedConstantProduct,
 110                            long optimizedConstantProduct) {
 111     int[] factors = new int[2];
 112     factors[0] = leftFactor;
 113     factors[1] = rightFactor;
 114     testNormal(leftFactor, rightFactor, normalConstantProduct);
 115     testLeftOptimized(leftFactor, rightFactor, leftOptimizedConstantProduct);
 116     testRightOptimized(leftFactor, rightFactor, rightOptimizedConstantProduct);
 117     testOptimized(leftFactor, rightFactor, optimizedConstantProduct);
 118     testLeftOptimized_LoadUI2L(leftFactor, rightFactor, leftOptimizedConstantProduct, factors);
 119     testRightOptimized_LoadUI2L(leftFactor, rightFactor, rightOptimizedConstantProduct, factors);
 120     testOptimized_LoadUI2L(leftFactor, rightFactor, optimizedConstantProduct, factors);
 121   }
 122 
 123   public static void main(String[] args) {
 124     for (int i = 0; i < 100000; ++i) { // Trigger compilation
 125       int i0 = initInt(args, 1);
 126       int i1 = initInt(args, 3);
 127       int i2 = initInt(args, -1);
 128       int i3 = initInt(args, 0x7FFFFFFF);
 129       test(i0, i1, 3L, 3L, 3L, 3L);
 130       test(i0, i2, -1L, -1L, 0xFFFFFFFFL, 0xFFFFFFFFL);
 131       test(i0, i3, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL);
 132       test(i1, i2, -3L, -3L, 0x2FFFFFFFDL, 0x2FFFFFFFDL);
 133       test(i1, i3, 0x17FFFFFFDL, 0x17FFFFFFDL, 0x17FFFFFFDL, 0x17FFFFFFDL);
 134       test(i2, i3, 0xFFFFFFFF80000001L, 0x7FFFFFFE80000001L,
 135            0xFFFFFFFF80000001L, 0x7FFFFFFE80000001L);
 136     }
 137   }
 138 }