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