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.core.amd64.test;
  24 
  25 import static org.junit.Assume.assumeTrue;
  26 
  27 import org.junit.Before;
  28 import org.junit.Test;
  29 
  30 import org.graalvm.compiler.core.common.LIRKind;
  31 import org.graalvm.compiler.lir.VirtualStackSlot;
  32 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
  33 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  34 import org.graalvm.compiler.lir.jtt.LIRTest;
  35 import org.graalvm.compiler.lir.jtt.LIRTestSpecification;
  36 
  37 import jdk.vm.ci.amd64.AMD64;
  38 import jdk.vm.ci.meta.JavaConstant;
  39 import jdk.vm.ci.meta.PrimitiveConstant;
  40 
  41 public class ConstantStackMoveTest extends LIRTest {
  42     @Before
  43     public void checkAMD64() {
  44         assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
  45     }
  46 
  47     private static class LoadConstantStackSpec extends LIRTestSpecification {
  48         protected final Object primitive;
  49 
  50         LoadConstantStackSpec(Object primitive) {
  51             this.primitive = primitive;
  52         }
  53 
  54         @Override
  55         public void generate(LIRGeneratorTool gen) {
  56             FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
  57             // create slots
  58             PrimitiveConstant constantValue = JavaConstant.forBoxedPrimitive(primitive);
  59             VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(LIRKind.fromJavaKind(gen.target().arch, constantValue.getJavaKind()));
  60             // move stuff around
  61             gen.emitMoveConstant(s1, constantValue);
  62             gen.emitBlackhole(s1);
  63             setResult(gen.emitMove(s1));
  64         }
  65     }
  66 
  67     private static final class LoadConstantStackSpecByte extends LoadConstantStackSpec {
  68         LoadConstantStackSpecByte(byte primitive) {
  69             super(primitive);
  70         }
  71 
  72         byte get() {
  73             return (Byte) primitive;
  74         }
  75     }
  76 
  77     private static final class LoadConstantStackSpecShort extends LoadConstantStackSpec {
  78         LoadConstantStackSpecShort(short primitive) {
  79             super(primitive);
  80         }
  81 
  82         short get() {
  83             return (Short) primitive;
  84         }
  85     }
  86 
  87     private static final class LoadConstantStackSpecInteger extends LoadConstantStackSpec {
  88         LoadConstantStackSpecInteger(int primitive) {
  89             super(primitive);
  90         }
  91 
  92         int get() {
  93             return (Integer) primitive;
  94         }
  95     }
  96 
  97     private static final class LoadConstantStackSpecLong extends LoadConstantStackSpec {
  98         LoadConstantStackSpecLong(long primitive) {
  99             super(primitive);
 100         }
 101 
 102         long get() {
 103             return (Long) primitive;
 104         }
 105     }
 106 
 107     private static final class LoadConstantStackSpecFloat extends LoadConstantStackSpec {
 108         LoadConstantStackSpecFloat(float primitive) {
 109             super(primitive);
 110         }
 111 
 112         float get() {
 113             return (Float) primitive;
 114         }
 115     }
 116 
 117     private static final class LoadConstantStackSpecDouble extends LoadConstantStackSpec {
 118         LoadConstantStackSpecDouble(double primitive) {
 119             super(primitive);
 120         }
 121 
 122         double get() {
 123             return (Double) primitive;
 124         }
 125     }
 126 
 127     private static final LoadConstantStackSpecByte stackCopyByte = new LoadConstantStackSpecByte(Byte.MAX_VALUE);
 128     private static final LoadConstantStackSpecShort stackCopyShort = new LoadConstantStackSpecShort(Short.MAX_VALUE);
 129     private static final LoadConstantStackSpecInteger stackCopyInt = new LoadConstantStackSpecInteger(Integer.MAX_VALUE);
 130     private static final LoadConstantStackSpecLong stackCopyLong = new LoadConstantStackSpecLong(Long.MAX_VALUE);
 131     private static final LoadConstantStackSpecFloat stackCopyFloat = new LoadConstantStackSpecFloat(Float.MAX_VALUE);
 132     private static final LoadConstantStackSpecDouble stackCopyDouble = new LoadConstantStackSpecDouble(Double.MAX_VALUE);
 133 
 134     @LIRIntrinsic
 135     public static byte testCopyByte(LoadConstantStackSpecByte spec) {
 136         return spec.get();
 137     }
 138 
 139     public byte testByte() {
 140         return testCopyByte(stackCopyByte);
 141     }
 142 
 143     @Test
 144     public void runByte() throws Throwable {
 145         runTest("testByte");
 146     }
 147 
 148     @LIRIntrinsic
 149     public static short testCopyShort(LoadConstantStackSpecShort spec) {
 150         return spec.get();
 151     }
 152 
 153     public short testShort() {
 154         return testCopyShort(stackCopyShort);
 155     }
 156 
 157     @Test
 158     public void runShort() throws Throwable {
 159         runTest("testShort");
 160     }
 161 
 162     @LIRIntrinsic
 163     public static int testCopyInt(LoadConstantStackSpecInteger spec) {
 164         return spec.get();
 165     }
 166 
 167     public int testInt() {
 168         return testCopyInt(stackCopyInt);
 169     }
 170 
 171     @Test
 172     public void runInt() throws Throwable {
 173         runTest("testInt");
 174     }
 175 
 176     @LIRIntrinsic
 177     public static long testCopyLong(LoadConstantStackSpecLong spec) {
 178         return spec.get();
 179     }
 180 
 181     public long testLong() {
 182         return testCopyLong(stackCopyLong);
 183     }
 184 
 185     @Test
 186     public void runLong() throws Throwable {
 187         runTest("testLong");
 188     }
 189 
 190     @LIRIntrinsic
 191     public static float testCopyFloat(LoadConstantStackSpecFloat spec) {
 192         return spec.get();
 193     }
 194 
 195     public float testFloat() {
 196         return testCopyFloat(stackCopyFloat);
 197     }
 198 
 199     @Test
 200     public void runFloat() throws Throwable {
 201         runTest("testFloat");
 202     }
 203 
 204     @LIRIntrinsic
 205     public static double testCopyDouble(LoadConstantStackSpecDouble spec) {
 206         return spec.get();
 207     }
 208 
 209     public double testDouble() {
 210         return testCopyDouble(stackCopyDouble);
 211     }
 212 
 213     @Test
 214     public void runDouble() throws Throwable {
 215         runTest("testDouble");
 216     }
 217 
 218 }