1 /*
   2  * Copyright (c) 2015, 2015, 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.lir.jtt;
  24 
  25 import org.junit.Before;
  26 import org.junit.Test;
  27 
  28 import org.graalvm.compiler.core.common.LIRKind;
  29 import org.graalvm.compiler.lir.Variable;
  30 import org.graalvm.compiler.lir.VirtualStackSlot;
  31 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
  32 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  33 
  34 import jdk.vm.ci.meta.JavaKind;
  35 import jdk.vm.ci.meta.PlatformKind;
  36 import jdk.vm.ci.meta.Value;
  37 import jdk.vm.ci.meta.ValueKind;
  38 
  39 public class StackMoveTest extends LIRTest {
  40     private static PlatformKind byteKind;
  41     private static PlatformKind shortKind;
  42 
  43     @Before
  44     public void setUp() {
  45         byteKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Byte);
  46         shortKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Short);
  47     }
  48 
  49     private static class StackCopySpec extends LIRTestSpecification {
  50         @Override
  51         public void generate(LIRGeneratorTool gen, Value a) {
  52             FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
  53             ValueKind<?> valueKind = getValueKind(a);
  54 
  55             // create slots
  56             VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(valueKind);
  57             VirtualStackSlot s2 = frameMapBuilder.allocateSpillSlot(valueKind);
  58 
  59             // start emit
  60             gen.emitMove(s1, a);
  61             Value copy1 = gen.emitMove(s1);
  62             gen.append(gen.getSpillMoveFactory().createStackMove(s2, s1));
  63             Variable result = gen.emitMove(s2);
  64             // end emit
  65 
  66             // set output and result
  67             setResult(result);
  68             setOutput("slotcopy", copy1);
  69             setOutput("slot1", s1);
  70             setOutput("slot2", s2);
  71         }
  72 
  73         protected ValueKind<?> getValueKind(Value value) {
  74             return value.getValueKind();
  75         }
  76     }
  77 
  78     private static final LIRTestSpecification stackCopy = new StackCopySpec();
  79 
  80     /*
  81      * int
  82      */
  83 
  84     @SuppressWarnings("unused")
  85     @LIRIntrinsic
  86     public static int copyInt(LIRTestSpecification spec, int a) {
  87         return a;
  88     }
  89 
  90     public int[] testInt(int a, int[] out) {
  91         out[0] = copyInt(stackCopy, a);
  92         out[1] = getOutput(stackCopy, "slotcopy", a);
  93         out[2] = getOutput(stackCopy, "slot1", a);
  94         out[3] = getOutput(stackCopy, "slot2", a);
  95         return out;
  96     }
  97 
  98     @Test
  99     public void runInt() throws Throwable {
 100         runTest("testInt", Integer.MIN_VALUE, supply(() -> new int[4]));
 101         runTest("testInt", -1, supply(() -> new int[4]));
 102         runTest("testInt", 0, supply(() -> new int[4]));
 103         runTest("testInt", 1, supply(() -> new int[4]));
 104         runTest("testInt", Integer.MAX_VALUE, supply(() -> new int[4]));
 105     }
 106 
 107     /*
 108      * long
 109      */
 110 
 111     @SuppressWarnings("unused")
 112     @LIRIntrinsic
 113     public static long copyLong(LIRTestSpecification spec, long a) {
 114         return a;
 115     }
 116 
 117     public long[] testLong(long a, long[] out) {
 118         out[0] = copyLong(stackCopy, a);
 119         out[1] = getOutput(stackCopy, "slotcopy", a);
 120         out[2] = getOutput(stackCopy, "slot1", a);
 121         out[3] = getOutput(stackCopy, "slot2", a);
 122         return out;
 123     }
 124 
 125     @Test
 126     public void runLong() throws Throwable {
 127         runTest("testLong", Long.MIN_VALUE, supply(() -> new long[3]));
 128         runTest("testLong", -1L, supply(() -> new long[3]));
 129         runTest("testLong", 0L, supply(() -> new long[3]));
 130         runTest("testLong", 1L, supply(() -> new long[3]));
 131         runTest("testLong", Long.MAX_VALUE, supply(() -> new long[3]));
 132     }
 133 
 134     /*
 135      * float
 136      */
 137 
 138     @SuppressWarnings("unused")
 139     @LIRIntrinsic
 140     public static float copyFloat(LIRTestSpecification spec, float a) {
 141         return a;
 142     }
 143 
 144     public float[] testFloat(float a, float[] out) {
 145         out[0] = copyFloat(stackCopy, a);
 146         out[1] = getOutput(stackCopy, "slotcopy", a);
 147         out[2] = getOutput(stackCopy, "slot1", a);
 148         out[3] = getOutput(stackCopy, "slot2", a);
 149         return out;
 150     }
 151 
 152     @Test
 153     public void runFloat() throws Throwable {
 154         runTest("testFloat", Float.MIN_VALUE, supply(() -> new float[3]));
 155         runTest("testFloat", -1f, supply(() -> new float[3]));
 156         runTest("testFloat", -0.1f, supply(() -> new float[3]));
 157         runTest("testFloat", 0f, supply(() -> new float[3]));
 158         runTest("testFloat", 0.1f, supply(() -> new float[3]));
 159         runTest("testFloat", 1f, supply(() -> new float[3]));
 160         runTest("testFloat", Float.MAX_VALUE, supply(() -> new float[3]));
 161     }
 162 
 163     /*
 164      * double
 165      */
 166 
 167     @SuppressWarnings("unused")
 168     @LIRIntrinsic
 169     public static double copyDouble(LIRTestSpecification spec, double a) {
 170         return a;
 171     }
 172 
 173     public double[] testDouble(double a, double[] out) {
 174         out[0] = copyDouble(stackCopy, a);
 175         out[1] = getOutput(stackCopy, "slotcopy", a);
 176         out[2] = getOutput(stackCopy, "slot1", a);
 177         out[3] = getOutput(stackCopy, "slot2", a);
 178         return out;
 179     }
 180 
 181     @Test
 182     public void runDouble() throws Throwable {
 183         runTest("testDouble", Double.MIN_VALUE, supply(() -> new double[3]));
 184         runTest("testDouble", -1., supply(() -> new double[3]));
 185         runTest("testDouble", -0.1, supply(() -> new double[3]));
 186         runTest("testDouble", 0., supply(() -> new double[3]));
 187         runTest("testDouble", 0.1, supply(() -> new double[3]));
 188         runTest("testDouble", 1., supply(() -> new double[3]));
 189         runTest("testDouble", Double.MAX_VALUE, supply(() -> new double[3]));
 190     }
 191 
 192     /*
 193      * short
 194      */
 195 
 196     private static final LIRTestSpecification shortStackCopy = new StackCopySpec() {
 197         @Override
 198         protected ValueKind<?> getValueKind(Value value) {
 199             return LIRKind.value(shortKind);
 200         }
 201     };
 202 
 203     @SuppressWarnings("unused")
 204     @LIRIntrinsic
 205     public static short copyShort(LIRTestSpecification spec, short a) {
 206         return a;
 207     }
 208 
 209     public short[] testShort(short a, short[] out) {
 210         out[0] = copyShort(shortStackCopy, a);
 211         out[1] = getOutput(shortStackCopy, "slotcopy", a);
 212         out[2] = getOutput(shortStackCopy, "slot1", a);
 213         out[3] = getOutput(shortStackCopy, "slot2", a);
 214         return out;
 215     }
 216 
 217     @Test
 218     public void runShort() throws Throwable {
 219         runTest("testShort", Short.MIN_VALUE, supply(() -> new short[3]));
 220         runTest("testShort", (short) -1, supply(() -> new short[3]));
 221         runTest("testShort", (short) 0, supply(() -> new short[3]));
 222         runTest("testShort", (short) 1, supply(() -> new short[3]));
 223         runTest("testShort", Short.MAX_VALUE, supply(() -> new short[3]));
 224     }
 225 
 226     /*
 227      * byte
 228      */
 229 
 230     private static final LIRTestSpecification byteStackCopy = new StackCopySpec() {
 231         @Override
 232         protected ValueKind<?> getValueKind(Value value) {
 233             return LIRKind.value(byteKind);
 234         }
 235     };
 236 
 237     @SuppressWarnings("unused")
 238     @LIRIntrinsic
 239     public static byte copyByte(LIRTestSpecification spec, byte a) {
 240         return a;
 241     }
 242 
 243     public byte[] testByte(byte a, byte[] out) {
 244         out[0] = copyByte(byteStackCopy, a);
 245         out[1] = getOutput(byteStackCopy, "slotcopy", a);
 246         out[2] = getOutput(byteStackCopy, "slot1", a);
 247         out[3] = getOutput(byteStackCopy, "slot2", a);
 248         return out;
 249     }
 250 
 251     @Test
 252     public void runByte() throws Throwable {
 253         runTest("testByte", Byte.MIN_VALUE, supply(() -> new byte[3]));
 254         runTest("testByte", (byte) -1, supply(() -> new byte[3]));
 255         runTest("testByte", (byte) 0, supply(() -> new byte[3]));
 256         runTest("testByte", (byte) 1, supply(() -> new byte[3]));
 257         runTest("testByte", Byte.MAX_VALUE, supply(() -> new byte[3]));
 258     }
 259 }