001/*
002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.lir.jtt;
024
025import jdk.internal.jvmci.code.*;
026import jdk.internal.jvmci.meta.*;
027
028import org.junit.*;
029
030import com.oracle.graal.lir.*;
031import com.oracle.graal.lir.framemap.*;
032import com.oracle.graal.lir.gen.*;
033
034public class StackMoveTest extends LIRTest {
035    private static class StackCopySpec extends LIRTestSpecification {
036        @Override
037        public void generate(LIRGeneratorTool gen, Value a) {
038            FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
039            LIRKind lirKind = getLIRKind(a);
040
041            // create slots
042            StackSlotValue s1 = frameMapBuilder.allocateSpillSlot(lirKind);
043            StackSlotValue s2 = frameMapBuilder.allocateSpillSlot(lirKind);
044
045            // start emit
046            gen.emitMove(s1, a);
047            Value copy1 = gen.emitMove(s1);
048            gen.append(gen.getSpillMoveFactory().createStackMove(s2, s1));
049            Variable result = gen.emitMove(s2);
050            // end emit
051
052            // set output and result
053            setResult(result);
054            setOutput("slotcopy", copy1);
055            setOutput("slot1", s1);
056            setOutput("slot2", s2);
057        }
058
059        protected LIRKind getLIRKind(Value value) {
060            return value.getLIRKind();
061        }
062    }
063
064    private static final LIRTestSpecification stackCopy = new StackCopySpec();
065
066    /*
067     * int
068     */
069
070    @SuppressWarnings("unused")
071    @LIRIntrinsic
072    public static int copyInt(LIRTestSpecification spec, int a) {
073        return a;
074    }
075
076    public int[] testInt(int a, int[] out) {
077        out[0] = copyInt(stackCopy, a);
078        out[1] = getOutput(stackCopy, "slotcopy", a);
079        out[2] = getOutput(stackCopy, "slot1", a);
080        out[3] = getOutput(stackCopy, "slot2", a);
081        return out;
082    }
083
084    @Test
085    public void runInt() throws Throwable {
086        runTest("testInt", Integer.MIN_VALUE, supply(() -> new int[4]));
087        runTest("testInt", -1, supply(() -> new int[4]));
088        runTest("testInt", 0, supply(() -> new int[4]));
089        runTest("testInt", 1, supply(() -> new int[4]));
090        runTest("testInt", Integer.MAX_VALUE, supply(() -> new int[4]));
091    }
092
093    /*
094     * long
095     */
096
097    @SuppressWarnings("unused")
098    @LIRIntrinsic
099    public static long copyLong(LIRTestSpecification spec, long a) {
100        return a;
101    }
102
103    public long[] testLong(long a, long[] out) {
104        out[0] = copyLong(stackCopy, a);
105        out[1] = getOutput(stackCopy, "slotcopy", a);
106        out[2] = getOutput(stackCopy, "slot1", a);
107        out[3] = getOutput(stackCopy, "slot2", a);
108        return out;
109    }
110
111    @Test
112    public void runLong() throws Throwable {
113        runTest("testLong", Long.MIN_VALUE, supply(() -> new long[3]));
114        runTest("testLong", -1L, supply(() -> new long[3]));
115        runTest("testLong", 0L, supply(() -> new long[3]));
116        runTest("testLong", 1L, supply(() -> new long[3]));
117        runTest("testLong", Long.MAX_VALUE, supply(() -> new long[3]));
118    }
119
120    /*
121     * float
122     */
123
124    @SuppressWarnings("unused")
125    @LIRIntrinsic
126    public static float copyFloat(LIRTestSpecification spec, float a) {
127        return a;
128    }
129
130    public float[] testFloat(float a, float[] out) {
131        out[0] = copyFloat(stackCopy, a);
132        out[1] = getOutput(stackCopy, "slotcopy", a);
133        out[2] = getOutput(stackCopy, "slot1", a);
134        out[3] = getOutput(stackCopy, "slot2", a);
135        return out;
136    }
137
138    @Test
139    public void runFloat() throws Throwable {
140        runTest("testFloat", Float.MIN_VALUE, supply(() -> new float[3]));
141        runTest("testFloat", -1f, supply(() -> new float[3]));
142        runTest("testFloat", -0.1f, supply(() -> new float[3]));
143        runTest("testFloat", 0f, supply(() -> new float[3]));
144        runTest("testFloat", 0.1f, supply(() -> new float[3]));
145        runTest("testFloat", 1f, supply(() -> new float[3]));
146        runTest("testFloat", Float.MAX_VALUE, supply(() -> new float[3]));
147    }
148
149    /*
150     * double
151     */
152
153    @SuppressWarnings("unused")
154    @LIRIntrinsic
155    public static double copyDouble(LIRTestSpecification spec, double a) {
156        return a;
157    }
158
159    public double[] testDouble(double a, double[] out) {
160        out[0] = copyDouble(stackCopy, a);
161        out[1] = getOutput(stackCopy, "slotcopy", a);
162        out[2] = getOutput(stackCopy, "slot1", a);
163        out[3] = getOutput(stackCopy, "slot2", a);
164        return out;
165    }
166
167    @Test
168    public void runDouble() throws Throwable {
169        runTest("testDouble", Double.MIN_VALUE, supply(() -> new double[3]));
170        runTest("testDouble", -1., supply(() -> new double[3]));
171        runTest("testDouble", -0.1, supply(() -> new double[3]));
172        runTest("testDouble", 0., supply(() -> new double[3]));
173        runTest("testDouble", 0.1, supply(() -> new double[3]));
174        runTest("testDouble", 1., supply(() -> new double[3]));
175        runTest("testDouble", Double.MAX_VALUE, supply(() -> new double[3]));
176    }
177
178    /*
179     * short
180     */
181
182    private static final LIRTestSpecification shortStackCopy = new StackCopySpec() {
183        @Override
184        protected LIRKind getLIRKind(Value value) {
185            return LIRKind.value(Kind.Short);
186        }
187    };
188
189    @SuppressWarnings("unused")
190    @LIRIntrinsic
191    public static short copyShort(LIRTestSpecification spec, short a) {
192        return a;
193    }
194
195    public short[] testShort(short a, short[] out) {
196        out[0] = copyShort(shortStackCopy, a);
197        out[1] = getOutput(shortStackCopy, "slotcopy", a);
198        out[2] = getOutput(shortStackCopy, "slot1", a);
199        out[3] = getOutput(shortStackCopy, "slot2", a);
200        return out;
201    }
202
203    @Test
204    public void runShort() throws Throwable {
205        runTest("testShort", Short.MIN_VALUE, supply(() -> new short[3]));
206        runTest("testShort", (short) -1, supply(() -> new short[3]));
207        runTest("testShort", (short) 0, supply(() -> new short[3]));
208        runTest("testShort", (short) 1, supply(() -> new short[3]));
209        runTest("testShort", Short.MAX_VALUE, supply(() -> new short[3]));
210    }
211
212    /*
213     * byte
214     */
215
216    private static final LIRTestSpecification byteStackCopy = new StackCopySpec() {
217        @Override
218        protected LIRKind getLIRKind(Value value) {
219            return LIRKind.value(Kind.Byte);
220        }
221    };
222
223    @SuppressWarnings("unused")
224    @LIRIntrinsic
225    public static byte copyByte(LIRTestSpecification spec, byte a) {
226        return a;
227    }
228
229    public byte[] testByte(byte a, byte[] out) {
230        out[0] = copyByte(byteStackCopy, a);
231        out[1] = getOutput(byteStackCopy, "slotcopy", a);
232        out[2] = getOutput(byteStackCopy, "slot1", a);
233        out[3] = getOutput(byteStackCopy, "slot2", a);
234        return out;
235    }
236
237    @Test
238    public void runByte() throws Throwable {
239        runTest("testByte", Byte.MIN_VALUE, supply(() -> new byte[3]));
240        runTest("testByte", (byte) -1, supply(() -> new byte[3]));
241        runTest("testByte", (byte) 0, supply(() -> new byte[3]));
242        runTest("testByte", (byte) 1, supply(() -> new byte[3]));
243        runTest("testByte", Byte.MAX_VALUE, supply(() -> new byte[3]));
244    }
245}