1 /*
   2  * Copyright (c) 2011, 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 package org.graalvm.compiler.replacements.test;
  24 
  25 import org.junit.Test;
  26 
  27 import org.graalvm.compiler.api.replacements.Snippet;
  28 import org.graalvm.compiler.core.common.CompilationIdentifier;
  29 import org.graalvm.compiler.core.test.GraalCompilerTest;
  30 import org.graalvm.compiler.nodes.StructuredGraph;
  31 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  32 import org.graalvm.compiler.replacements.ReplacementsImpl;
  33 import org.graalvm.compiler.replacements.Snippets;
  34 import org.graalvm.compiler.word.Pointer;
  35 import org.graalvm.compiler.word.Unsigned;
  36 import org.graalvm.compiler.word.Word;
  37 import org.graalvm.compiler.word.WordBase;
  38 
  39 import jdk.vm.ci.meta.ResolvedJavaMethod;
  40 
  41 /**
  42  * Tests for the {@link Word} type.
  43  */
  44 public class WordTest extends GraalCompilerTest implements Snippets {
  45 
  46     private final ReplacementsImpl installer;
  47 
  48     public WordTest() {
  49         installer = (ReplacementsImpl) getReplacements();
  50     }
  51 
  52     @Override
  53     protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {
  54         // create a copy to assign a valid compilation id
  55         return installer.makeGraph(m, null, null).copyWithIdentifier(compilationId);
  56     }
  57 
  58     @Test
  59     public void construction() {
  60         long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L,
  61                         Integer.MIN_VALUE - 1L, Integer.MIN_VALUE, Integer.MIN_VALUE + 1L};
  62         for (long word : words) {
  63             test("unsignedLong", word);
  64             test("unsignedInt", (int) word);
  65             test("signedLong", word);
  66             test("signedInt", (int) word);
  67         }
  68     }
  69 
  70     @Test
  71     public void testArithmetic() {
  72         long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L,
  73                         Integer.MIN_VALUE - 1L, Integer.MIN_VALUE, Integer.MIN_VALUE + 1L};
  74         for (long word : words) {
  75             test("unsignedNot", word);
  76             test("signedNot", word);
  77             for (long addend : words) {
  78                 test("unsignedPlusInt", word, (int) addend);
  79                 test("unsignedMinusInt", word, (int) addend);
  80                 test("unsignedPlusInt", word, -((int) addend));
  81                 test("unsignedMinusInt", word, -((int) addend));
  82                 test("unsignedPlusLong", word, addend);
  83                 test("unsignedMinusLong", word, addend);
  84                 test("unsignedPlusLong", word, -addend);
  85                 test("unsignedMinusLong", word, -addend);
  86                 test("signedPlusInt", word, (int) addend);
  87                 test("signedMinusInt", word, (int) addend);
  88                 test("signedPlusInt", word, -((int) addend));
  89                 test("signedMinusInt", word, -((int) addend));
  90                 test("signedPlusLong", word, addend);
  91                 test("signedMinusLong", word, addend);
  92                 test("signedPlusLong", word, -addend);
  93                 test("signedMinusLong", word, -addend);
  94 
  95                 test("andInt", word, (int) addend);
  96                 test("orInt", word, (int) addend);
  97                 test("andInt", word, -((int) addend));
  98                 test("orInt", word, -((int) addend));
  99                 test("andLong", word, addend);
 100                 test("orLong", word, addend);
 101                 test("andLong", word, -addend);
 102                 test("orLong", word, -addend);
 103             }
 104         }
 105     }
 106 
 107     @Test
 108     public void testCompare() {
 109         long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE};
 110         for (long word1 : words) {
 111             for (long word2 : words) {
 112                 for (String method : new String[]{"aboveOrEqual", "above", "belowOrEqual", "below"}) {
 113                     test(method, word1, word2);
 114                     test(method, word2, word1);
 115                 }
 116             }
 117         }
 118     }
 119 
 120     @Test
 121     public void testCast() {
 122         test("cast", 1234L);
 123     }
 124 
 125     @Snippet
 126     public static long cast(long input) {
 127         WordBase base = Word.signed(input);
 128         Unsigned unsigned = (Unsigned) base;
 129         Pointer pointer = (Pointer) unsigned;
 130         Word word = (Word) pointer;
 131         return word.rawValue();
 132     }
 133 
 134     @Snippet
 135     public static long unsignedLong(long word) {
 136         return Word.unsigned(word).rawValue();
 137     }
 138 
 139     @Snippet
 140     public static long unsignedInt(int word) {
 141         return Word.unsigned(word).rawValue();
 142     }
 143 
 144     @Snippet
 145     public static long signedLong(long word) {
 146         return Word.signed(word).rawValue();
 147     }
 148 
 149     @Snippet
 150     public static long signedInt(int word) {
 151         return Word.signed(word).rawValue();
 152     }
 153 
 154     @Snippet
 155     public static long unsignedPlusInt(long word, int addend) {
 156         return Word.unsigned(word).add(addend).rawValue();
 157     }
 158 
 159     @Snippet
 160     public static long unsignedMinusInt(long word, int addend) {
 161         return Word.unsigned(word).subtract(addend).rawValue();
 162     }
 163 
 164     @Snippet
 165     public static long unsignedPlusLong(long word, long addend) {
 166         return Word.unsigned(word).add(Word.unsigned(addend)).rawValue();
 167     }
 168 
 169     @Snippet
 170     public static long unsignedMinusLong(long word, long addend) {
 171         return Word.unsigned(word).subtract(Word.unsigned(addend)).rawValue();
 172     }
 173 
 174     @Snippet
 175     public static long signedPlusInt(long word, int addend) {
 176         return Word.signed(word).add(addend).rawValue();
 177     }
 178 
 179     @Snippet
 180     public static long signedMinusInt(long word, int addend) {
 181         return Word.signed(word).subtract(addend).rawValue();
 182     }
 183 
 184     @Snippet
 185     public static long signedPlusLong(long word, long addend) {
 186         return Word.signed(word).add(Word.signed(addend)).rawValue();
 187     }
 188 
 189     @Snippet
 190     public static long signedMinusLong(long word, long addend) {
 191         return Word.signed(word).subtract(Word.signed(addend)).rawValue();
 192     }
 193 
 194     @Snippet
 195     public static long signedNot(long word) {
 196         return Word.signed(word).not().rawValue();
 197     }
 198 
 199     @Snippet
 200     public static long unsignedNot(long word) {
 201         return Word.unsigned(word).not().rawValue();
 202     }
 203 
 204     @Snippet
 205     public static boolean aboveOrEqual(long word1, long word2) {
 206         return Word.unsigned(word1).aboveOrEqual(Word.unsigned(word2));
 207     }
 208 
 209     @Snippet
 210     public static boolean above(long word1, long word2) {
 211         return Word.unsigned(word1).aboveThan(Word.unsigned(word2));
 212     }
 213 
 214     @Snippet
 215     public static boolean belowOrEqual(long word1, long word2) {
 216         return Word.unsigned(word1).belowOrEqual(Word.unsigned(word2));
 217     }
 218 
 219     @Snippet
 220     public static boolean below(long word1, long word2) {
 221         return Word.unsigned(word1).belowThan(Word.unsigned(word2));
 222     }
 223 
 224     @Snippet
 225     public static long andInt(long word, int addend) {
 226         return Word.unsigned(word).and(addend).rawValue();
 227     }
 228 
 229     @Snippet
 230     public static long orInt(long word, int addend) {
 231         return Word.unsigned(word).or(addend).rawValue();
 232     }
 233 
 234     @Snippet
 235     public static long andLong(long word, long addend) {
 236         return Word.unsigned(word).and(Word.unsigned(addend)).rawValue();
 237     }
 238 
 239     @Snippet
 240     public static long orLong(long word, long addend) {
 241         return Word.unsigned(word).or(Word.unsigned(addend)).rawValue();
 242     }
 243 }