1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "memory/allocation.hpp"
  27 #include "utilities/globalDefinitions.hpp"
  28 #include "unittest.hpp"
  29 
  30 class TestJavaArithSupport : public AllStatic {
  31 public:
  32   template<typename T> struct BinOpData { T x; T y; T r; };
  33   template<typename T> struct ShiftOpData { T x; jint shift; T r; };
  34 };
  35 
  36 typedef TestJavaArithSupport::BinOpData<jint> BinOpJintData;
  37 typedef TestJavaArithSupport::BinOpData<jlong> BinOpJlongData;
  38 
  39 typedef TestJavaArithSupport::ShiftOpData<jint> ShiftOpJintData;
  40 typedef TestJavaArithSupport::ShiftOpData<jlong> ShiftOpJlongData;
  41 
  42 const BinOpJintData add_jint_data[] = {
  43   { 0, 0, 0 },
  44   { 0, 1, 1 },
  45   { 0, -1, -1 },
  46   { max_jint, 1, min_jint },
  47   { max_jint, -1, max_jint - 1 },
  48   { min_jint, 1, min_jint + 1 },
  49   { min_jint, -1, max_jint },
  50   { max_jint, 10, min_jint + 9 },
  51   { max_jint, -10, max_jint - 10 },
  52   { min_jint, 10, min_jint + 10 },
  53   { min_jint, -10, max_jint - 9 },
  54   { max_jint, max_jint, -2 },
  55   { min_jint, min_jint, 0 }
  56 };
  57 
  58 const BinOpJlongData add_jlong_data[] = {
  59   { 0, 0, 0 },
  60   { 0, 1, 1 },
  61   { 0, -1, -1 },
  62   { max_jlong, 1, min_jlong },
  63   { max_jlong, -1, max_jlong - 1 },
  64   { min_jlong, 1, min_jlong + 1 },
  65   { min_jlong, -1, max_jlong },
  66   { max_jlong, 10, min_jlong + 9 },
  67   { max_jlong, -10, max_jlong - 10 },
  68   { min_jlong, 10, min_jlong + 10 },
  69   { min_jlong, -10, max_jlong - 9 },
  70   { max_jlong, max_jlong, -2 },
  71   { min_jlong, min_jlong, 0 }
  72 };
  73 
  74 TEST(TestJavaArithmetic, add_sub_jint) {
  75   const volatile BinOpJintData* data = add_jint_data;
  76   for (size_t i = 0; i < ARRAY_SIZE(add_jint_data); ++i) {
  77     ASSERT_EQ(data[i].r, java_add(data[i].x, data[i].y));
  78     ASSERT_EQ(data[i].r, java_add(data[i].y, data[i].x));
  79     ASSERT_EQ(data[i].x, java_subtract(data[i].r, data[i].y));
  80     ASSERT_EQ(data[i].y, java_subtract(data[i].r, data[i].x));
  81   }
  82 }
  83 
  84 TEST(TestJavaArithmetic, add_sub_jlong) {
  85   const volatile BinOpJlongData* data = add_jlong_data;
  86   for (size_t i = 0; i < ARRAY_SIZE(add_jlong_data); ++i) {
  87     ASSERT_EQ(data[i].r, java_add(data[i].x, data[i].y));
  88     ASSERT_EQ(data[i].r, java_add(data[i].y, data[i].x));
  89     ASSERT_EQ(data[i].x, java_subtract(data[i].r, data[i].y));
  90     ASSERT_EQ(data[i].y, java_subtract(data[i].r, data[i].x));
  91   }
  92 }
  93 
  94 static const BinOpJintData mul_jint_data[] = {
  95   { 0, 0, 0 },
  96   { 0, 1, 0 },
  97   { 0, max_jint, 0 },
  98   { 0, min_jint, 0 },
  99   { 1, 1, 1 },
 100   { 1, max_jint, max_jint },
 101   { 1, min_jint, min_jint },
 102   { -1, 1, -1 },
 103   { -1, max_jint, min_jint + 1 },
 104   { 5, max_jint, max_jint - 4 },
 105   { -5, max_jint, min_jint + 5 },
 106   { max_jint, max_jint, 1 },
 107   { max_jint, min_jint, min_jint },
 108   { min_jint, min_jint, 0 }
 109 };
 110 
 111 static const BinOpJlongData mul_jlong_data[] = {
 112   { 0, 0, 0 },
 113   { 0, 1, 0 },
 114   { 0, max_jlong, 0 },
 115   { 0, min_jlong, 0 },
 116   { 1, 1, 1 },
 117   { 1, max_jlong, max_jlong },
 118   { 1, min_jlong, min_jlong },
 119   { -1, 1, -1 },
 120   { -1, max_jlong, min_jlong + 1 },
 121   { 5, max_jlong, max_jlong - 4 },
 122   { -5, max_jlong, min_jlong + 5 },
 123   { max_jlong, max_jlong, 1 },
 124   { max_jlong, min_jlong, min_jlong },
 125   { min_jlong, min_jlong, 0 }
 126 };
 127 
 128 TEST(TestJavaArithmetic, mul_jint) {
 129   const volatile BinOpJintData* data = mul_jint_data;
 130   for (size_t i = 0; i < ARRAY_SIZE(mul_jint_data); ++i) {
 131     ASSERT_EQ(data[i].r, java_multiply(data[i].x, data[i].y));
 132     ASSERT_EQ(data[i].r, java_multiply(data[i].y, data[i].x));
 133   }
 134 }
 135 
 136 TEST(TestJavaArithmetic, mul_jlong) {
 137   const volatile BinOpJlongData* data = mul_jlong_data;
 138   for (size_t i = 0; i < ARRAY_SIZE(mul_jlong_data); ++i) {
 139     ASSERT_EQ(data[i].r, java_multiply(data[i].x, data[i].y));
 140     ASSERT_EQ(data[i].r, java_multiply(data[i].y, data[i].x));
 141   }
 142 }
 143 
 144 static const ShiftOpJintData asl_jint_data[] = {
 145   { 0, 0, 0 },
 146   { 0, 10, 0 },
 147   { 0, 50, 0 },
 148   { 1, 0, 1 },
 149   { 1, 10, (jint)1 << 10 },
 150   { 1, 50, (jint)1 << 18 },
 151   { 5, 0, 5 },
 152   { 5, 10, (jint)5 << 10 },
 153   { 5, 50, (jint)5 << 18 },
 154   { -1, 0, -1 },
 155   { -1, 10, (jint)-1 * (1 << 10) },
 156   { -1, 50, (jint)-1 * (1 << 18) },
 157   { -5, 0, -5 },
 158   { -5, 10, (jint)-5 * (1 << 10) },
 159   { -5, 50, (jint)-5 * (1 << 18) },
 160   { max_jint, 0, max_jint },
 161   { max_jint, 10, (jint)0xFFFFFC00 },
 162   { max_jint, 50, (jint)0xFFFC0000 },
 163   { min_jint, 0, min_jint },
 164   { min_jint, 10, 0 },
 165   { min_jint, 50, 0 }
 166 };
 167 
 168 static const ShiftOpJlongData asl_jlong_data[] = {
 169   { 0, 0, 0 },
 170   { 0, 10, 0 },
 171   { 0, 82, 0 },
 172   { 1, 0, 1 },
 173   { 1, 10, (jlong)1 << 10 },
 174   { 1, 82, (jlong)1 << 18 },
 175   { 5, 0, 5 },
 176   { 5, 10, (jlong)5 << 10 },
 177   { 5, 82, (jlong)5 << 18 },
 178   { -1, 0, -1 },
 179   { -1, 10, (jlong)-1 * (1 << 10) },
 180   { -1, 82, (jlong)-1 * (1 << 18) },
 181   { -5, 0, -5 },
 182   { -5, 10, (jlong)-5 * (1 << 10) },
 183   { -5, 82, (jlong)-5 * (1 << 18) },
 184   { max_jlong, 0, max_jlong },
 185   { max_jlong, 10, (jlong)0xFFFFFFFFFFFFFC00 },
 186   { max_jlong, 82, (jlong)0xFFFFFFFFFFFC0000 },
 187   { min_jlong, 0, min_jlong },
 188   { min_jlong, 10, 0 },
 189   { min_jlong, 82, 0 }
 190 };
 191 
 192 TEST(TestJavaArithmetic, shift_left_jint) {
 193   const volatile ShiftOpJintData* data = asl_jint_data;
 194   for (size_t i = 0; i < ARRAY_SIZE(asl_jint_data); ++i) {
 195     ASSERT_EQ(data[i].r, java_shift_left(data[i].x, data[i].shift));
 196   }
 197 }
 198 
 199 TEST(TestJavaArithmetic, shift_left_jlong) {
 200   const volatile ShiftOpJlongData* data = asl_jlong_data;
 201   for (size_t i = 0; i < ARRAY_SIZE(asl_jlong_data); ++i) {
 202     ASSERT_EQ(data[i].r, java_shift_left(data[i].x, data[i].shift));
 203   }
 204 }
 205 
 206 static const ShiftOpJintData asr_jint_data[] = {
 207   { 0, 0, 0 },
 208   { 0, 10, 0 },
 209   { 0, 50, 0 },
 210   { 1, 0, 1 },
 211   { 1, 10, 0 },
 212   { 1, 50, 0 },
 213   { 5, 0, 5 },
 214   { 5, 1, 2 },
 215   { 5, 10, 0 },
 216   { 5, 33, 2 },
 217   { 5, 50, 0 },
 218   { -1, 0, -1 },
 219   { -1, 10, -1 },
 220   { -1, 50, -1 },
 221   { -5, 0, -5 },
 222   { -5, 1, -3 },
 223   { -5, 10, -1 },
 224   { -5, 33, -3 },
 225   { -5, 50, -1 },
 226   { max_jint, 0, max_jint },
 227   { max_jint, 10, (jint)0x001FFFFF },
 228   { max_jint, 50, (jint)0x00001FFF },
 229   { min_jint, 0, min_jint },
 230   { min_jint, 10, (jint)0xFFE00000 },
 231   { min_jint, 50, (jint)0xFFFFE000 }
 232 };
 233 
 234 static const ShiftOpJlongData asr_jlong_data[] = {
 235   { 0, 0, 0 },
 236   { 0, 10, 0 },
 237   { 0, 82, 0 },
 238   { 1, 0, 1 },
 239   { 1, 10, 0 },
 240   { 1, 82, 0 },
 241   { 5, 0, 5 },
 242   { 5, 1, 2 },
 243   { 5, 10, 0 },
 244   { 5, 65, 2 },
 245   { 5, 82, 0 },
 246   { -1, 0, -1 },
 247   { -1, 10, -1 },
 248   { -1, 82, -1 },
 249   { -5, 0, -5 },
 250   { -5, 1, -3 },
 251   { -5, 10, -1 },
 252   { -5, 65, -3 },
 253   { -5, 82, -1 },
 254   { max_jlong, 0, max_jlong },
 255   { max_jlong, 10, (jlong)0x001FFFFFFFFFFFFF },
 256   { max_jlong, 82, (jlong)0x00001FFFFFFFFFFF },
 257   { min_jlong, 0, min_jlong },
 258   { min_jlong, 10, (jlong)0xFFE0000000000000 },
 259   { min_jlong, 82, (jlong)0xFFFFE00000000000 }
 260 };
 261 
 262 TEST(TestJavaArithmetic, shift_right_jint) {
 263   const volatile ShiftOpJintData* data = asr_jint_data;
 264   for (size_t i = 0; i < ARRAY_SIZE(asr_jint_data); ++i) {
 265     ASSERT_EQ(data[i].r, java_shift_right(data[i].x, data[i].shift));
 266   }
 267 }
 268 
 269 TEST(TestJavaArithmetic, shift_right_jlong) {
 270   const volatile ShiftOpJlongData* data = asr_jlong_data;
 271   for (size_t i = 0; i < ARRAY_SIZE(asr_jlong_data); ++i) {
 272     ASSERT_EQ(data[i].r, java_shift_right(data[i].x, data[i].shift));
 273   }
 274 }
 275 
 276 static const ShiftOpJintData lsr_jint_data[] = {
 277   { 0, 0, 0 },
 278   { 0, 10, 0 },
 279   { 0, 50, 0 },
 280   { 1, 0, 1 },
 281   { 1, 10, 0 },
 282   { 1, 50, 0 },
 283   { 5, 0, 5 },
 284   { 5, 1, 2 },
 285   { 5, 10, 0 },
 286   { 5, 33, 2 },
 287   { 5, 50, 0 },
 288   { -1, 0, -1 },
 289   { -1, 10, (jint)0x003FFFFF },
 290   { -1, 50, (jint)0x00003FFF },
 291   { -5, 0, -5 },
 292   { -5, 1, (jint)0x7FFFFFFD },
 293   { -5, 10, (jint)0x003FFFFF },
 294   { -5, 50, (jint)0x00003FFF },
 295   { max_jint, 0, max_jint },
 296   { max_jint, 1, (jint)0x3FFFFFFF },
 297   { max_jint, 10, (jint)0x001FFFFF },
 298   { max_jint, 50, (jint)0x00001FFF },
 299   { min_jint, 0, min_jint },
 300   { min_jint, 1, (jint)0x40000000 },
 301   { min_jint, 10, (jint)0x00200000 },
 302   { min_jint, 50, (jint)0x00002000 }
 303 };
 304 
 305 static const ShiftOpJlongData lsr_jlong_data[] = {
 306   { 0, 0, 0 },
 307   { 0, 10, 0 },
 308   { 0, 82, 0 },
 309   { 1, 0, 1 },
 310   { 1, 10, 0 },
 311   { 1, 82, 0 },
 312   { 5, 0, 5 },
 313   { 5, 1, 2 },
 314   { 5, 10, 0 },
 315   { 5, 65, 2 },
 316   { 5, 82, 0 },
 317   { -1, 0, -1 },
 318   { -1, 10, (jlong)0x003FFFFFFFFFFFFF },
 319   { -1, 82, (jlong)0x00003FFFFFFFFFFF },
 320   { -5, 0, -5 },
 321   { -5, 1, (jlong)0x7FFFFFFFFFFFFFFD },
 322   { -5, 10, (jlong)0x003FFFFFFFFFFFFF },
 323   { -5, 82, (jlong)0x00003FFFFFFFFFFF },
 324   { max_jlong, 0, max_jlong },
 325   { max_jlong, 1, (jlong)0x3FFFFFFFFFFFFFFF },
 326   { max_jlong, 10, (jlong)0x001FFFFFFFFFFFFF },
 327   { max_jlong, 82, (jlong)0x00001FFFFFFFFFFF },
 328   { min_jlong, 0, min_jlong },
 329   { min_jlong, 1, (jlong)0x4000000000000000 },
 330   { min_jlong, 10, (jlong)0x0020000000000000 },
 331   { min_jlong, 82, (jlong)0x0000200000000000 }
 332 };
 333 
 334 TEST(TestJavaArithmetic, shift_right_unsigned_jint) {
 335   const volatile ShiftOpJintData* data = lsr_jint_data;
 336   for (size_t i = 0; i < ARRAY_SIZE(lsr_jint_data); ++i) {
 337     ASSERT_EQ(data[i].r, java_shift_right_unsigned(data[i].x, data[i].shift));
 338   }
 339 }
 340 
 341 TEST(TestJavaArithmetic, shift_right_unsigned_jlong) {
 342   const volatile ShiftOpJlongData* data = lsr_jlong_data;
 343   for (size_t i = 0; i < ARRAY_SIZE(lsr_jlong_data); ++i) {
 344     ASSERT_EQ(data[i].r, java_shift_right_unsigned(data[i].x, data[i].shift));
 345   }
 346 }