changeset 22912:3c00f45259b6

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 30 Oct 2015 20:56:28 +0100
parents 9aadd8e4e5aa 6a508ee4c7ef
children 102b099df9dd
files graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeAccess.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/util/CollectionsAccess.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeAccess.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/ConvertJTT.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArithmeticLIRGenerator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TracePerformanceWarningsListener.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java
diffstat 997 files changed, 13510 insertions(+), 8781 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Oct 30 20:55:32 2015 +0100
+++ b/.hgignore	Fri Oct 30 20:56:28 2015 +0100
@@ -30,6 +30,7 @@
 \.dot$
 \.pyc$
 \.hprof$
+\.json$
 \javafilelist.*\.txt$
 \.hprof\.txt$
 ^doc/.*/dot_temp_
--- a/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/ControlFlowAnchorDirectiveTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/ControlFlowAnchorDirectiveTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -31,7 +31,7 @@
 import java.util.Collections;
 import java.util.List;
 
-import jdk.internal.jvmci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 import org.junit.Assert;
 import org.junit.Test;
--- a/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/DeoptimizeDirectiveTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/DeoptimizeDirectiveTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.api.directives.test;
 
-import jdk.internal.jvmci.code.InstalledCode;
-import jdk.internal.jvmci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 import org.junit.Assert;
 import org.junit.Test;
--- a/graal/com.oracle.graal.api.directives/src/com/oracle/graal/api/directives/GraalDirectives.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.api.directives/src/com/oracle/graal/api/directives/GraalDirectives.java	Fri Oct 30 20:56:28 2015 +0100
@@ -328,6 +328,14 @@
     }
 
     /**
+     * Ensures that the instrumentation is valid only if it is associated with an Invoke node.
+     *
+     * See {@link #instrumentationBegin(int)}.
+     */
+    public static void instrumentationToInvokeBegin(@SuppressWarnings("unused") int offset) {
+    }
+
+    /**
      * Marks the end of the instrumentation boundary. See {@link #instrumentationBegin(int)}.
      */
     public static void instrumentationEnd() {
--- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java	Fri Oct 30 20:56:28 2015 +0100
@@ -27,7 +27,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-import jdk.internal.jvmci.meta.Signature;
+import jdk.vm.ci.meta.Signature;
 
 /**
  * Denotes a substitute method. A substitute method can call the original/substituted method by
--- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java	Fri Oct 30 20:56:28 2015 +0100
@@ -29,12 +29,12 @@
 import java.lang.reflect.Method;
 import java.util.Objects;
 
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaField;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.JavaType;
-import jdk.internal.jvmci.meta.ResolvedJavaMethod;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 /**
  * Reflection operations on values represented as {@linkplain JavaConstant constants} for the
--- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java	Fri Oct 30 20:55:32 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.runtime;
-
-import java.util.Formatter;
-
-import jdk.internal.jvmci.service.Services;
-
-/**
- * Access point for {@linkplain #getRuntime() retrieving} the single {@link GraalRuntime} instance.
- */
-public class Graal {
-
-    private static final class Lazy {
-        private static final GraalRuntime runtime = initializeRuntime();
-
-        private static GraalRuntime initializeRuntime() {
-            GraalRuntimeAccess access = Services.loadSingle(GraalRuntimeAccess.class, false);
-            if (access != null) {
-                GraalRuntime rt = access.getRuntime();
-                assert rt != null;
-                return rt;
-            }
-            return new InvalidGraalRuntime();
-        }
-    }
-
-    /**
-     * Gets the singleton {@link GraalRuntime} instance available to the application.
-     */
-    public static GraalRuntime getRuntime() {
-        return Lazy.runtime;
-    }
-
-    /**
-     * Gets a capability provided by the {@link GraalRuntime} instance available to the application.
-     *
-     * @throws UnsupportedOperationException if the capability is not available
-     */
-    public static <T> T getRequiredCapability(Class<T> clazz) {
-        T t = getRuntime().getCapability(clazz);
-        if (t == null) {
-            String javaHome = System.getProperty("java.home");
-            String vmName = System.getProperty("java.vm.name");
-            Formatter errorMessage = new Formatter();
-            if (getRuntime().getClass() == InvalidGraalRuntime.class) {
-                errorMessage.format("The VM does not support the Graal API.%n");
-            } else {
-                errorMessage.format("The VM does not expose required Graal capability %s.%n", clazz.getName());
-            }
-            errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
-            errorMessage.format("Currently used VM configuration is: %s", vmName);
-            throw new UnsupportedOperationException(errorMessage.toString());
-        }
-        return t;
-    }
-
-    private static final class InvalidGraalRuntime implements GraalRuntime {
-
-        @Override
-        public String getName() {
-            return "";
-        }
-
-        @Override
-        public <T> T getCapability(Class<T> clazz) {
-            return null;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalJVMCICompiler.java	Fri Oct 30 20:56:28 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.runtime;
+
+import jdk.vm.ci.runtime.JVMCICompiler;
+
+/**
+ * Graal specific extension of the {@link JVMCICompiler} interface.
+ */
+public interface GraalJVMCICompiler extends JVMCICompiler {
+
+    GraalRuntime getGraalRuntime();
+}
--- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeAccess.java	Fri Oct 30 20:55:32 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.runtime;
-
-/**
- * A service that provides access to a {@link GraalRuntime} implementation.
- */
-public interface GraalRuntimeAccess {
-
-    /**
-     * Gets the {@link GraalRuntime} implementation available via this access object.
-     */
-    GraalRuntime getRuntime();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.test/src/com/oracle/graal/api/test/Graal.java	Fri Oct 30 20:56:28 2015 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.test;
+
+import java.util.Formatter;
+
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.vm.ci.runtime.JVMCICompiler;
+
+import com.oracle.graal.api.runtime.GraalJVMCICompiler;
+import com.oracle.graal.api.runtime.GraalRuntime;
+
+/**
+ * Access point for {@linkplain #getRuntime() retrieving} the {@link GraalRuntime} instance of the
+ * system compiler from unit tests.
+ */
+public class Graal {
+
+    private static final GraalRuntime runtime = initializeRuntime();
+
+    private static GraalRuntime initializeRuntime() {
+        JVMCICompiler compiler = JVMCI.getRuntime().getCompiler();
+        if (compiler instanceof GraalJVMCICompiler) {
+            GraalJVMCICompiler graal = (GraalJVMCICompiler) compiler;
+            return graal.getGraalRuntime();
+        } else {
+            return new InvalidGraalRuntime();
+        }
+    }
+
+    /**
+     * Gets the singleton {@link GraalRuntime} instance available to unit tests.
+     */
+    public static GraalRuntime getRuntime() {
+        return runtime;
+    }
+
+    /**
+     * Gets a capability provided by the {@link GraalRuntime} instance available to the application.
+     *
+     * @throws UnsupportedOperationException if the capability is not available
+     */
+    public static <T> T getRequiredCapability(Class<T> clazz) {
+        T t = getRuntime().getCapability(clazz);
+        if (t == null) {
+            String javaHome = System.getProperty("java.home");
+            String vmName = System.getProperty("java.vm.name");
+            Formatter errorMessage = new Formatter();
+            if (getRuntime().getClass() == InvalidGraalRuntime.class) {
+                errorMessage.format("The VM does not support the Graal API.%n");
+            } else {
+                errorMessage.format("The VM does not expose required Graal capability %s.%n", clazz.getName());
+            }
+            errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
+            errorMessage.format("Currently used VM configuration is: %s", vmName);
+            throw new UnsupportedOperationException(errorMessage.toString());
+        }
+        return t;
+    }
+
+    private static final class InvalidGraalRuntime implements GraalRuntime {
+
+        @Override
+        public String getName() {
+            return "";
+        }
+
+        @Override
+        public <T> T getCapability(Class<T> clazz) {
+            return null;
+        }
+    }
+}
--- a/graal/com.oracle.graal.api.test/src/com/oracle/graal/api/test/GraalAPITest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.api.test/src/com/oracle/graal/api/test/GraalAPITest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
 
 import org.junit.Test;
 
-import com.oracle.graal.api.runtime.Graal;
-
 public class GraalAPITest {
 
     @Test
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/BitOpsTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/BitOpsTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -27,20 +27,20 @@
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TZCNT;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
-import static jdk.internal.jvmci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static org.junit.Assume.assumeTrue;
 
 import java.lang.reflect.Field;
 import java.util.EnumSet;
 
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.amd64.AMD64.CPUFeature;
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.JavaKind;
 
 import org.junit.Before;
 import org.junit.Test;
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,18 +22,18 @@
  */
 package com.oracle.graal.asm.amd64.test;
 
-import static jdk.internal.jvmci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static org.junit.Assume.assumeTrue;
 
 import java.lang.reflect.Field;
 
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.JavaKind;
 
 import org.junit.Before;
 import org.junit.Test;
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -27,17 +27,17 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.code.CompilationResult.DataSectionReference;
-import jdk.internal.jvmci.code.DataSection.Data;
-import jdk.internal.jvmci.code.DataSection.DataBuilder;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.CompilationResult.DataSectionReference;
+import jdk.vm.ci.code.DataSection.Data;
+import jdk.vm.ci.code.DataSection.DataBuilder;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 
 import org.junit.Before;
 import org.junit.Test;
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.asm.amd64;
 
-import jdk.internal.jvmci.code.Register;
+import jdk.vm.ci.code.Register;
 
 import com.oracle.graal.asm.AbstractAddress;
 
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Fri Oct 30 20:56:28 2015 +0100
@@ -42,20 +42,20 @@
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.WORD;
-import static jdk.internal.jvmci.amd64.AMD64.CPU;
-import static jdk.internal.jvmci.amd64.AMD64.XMM;
-import static jdk.internal.jvmci.amd64.AMD64.r12;
-import static jdk.internal.jvmci.amd64.AMD64.r13;
-import static jdk.internal.jvmci.amd64.AMD64.rbp;
-import static jdk.internal.jvmci.amd64.AMD64.rip;
-import static jdk.internal.jvmci.amd64.AMD64.rsp;
-import static jdk.internal.jvmci.code.MemoryBarriers.STORE_LOAD;
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.amd64.AMD64.CPUFeature;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.Register.RegisterCategory;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
+import static jdk.vm.ci.amd64.AMD64.CPU;
+import static jdk.vm.ci.amd64.AMD64.XMM;
+import static jdk.vm.ci.amd64.AMD64.r12;
+import static jdk.vm.ci.amd64.AMD64.r13;
+import static jdk.vm.ci.amd64.AMD64.rbp;
+import static jdk.vm.ci.amd64.AMD64.rip;
+import static jdk.vm.ci.amd64.AMD64.rsp;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.Register.RegisterCategory;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
 
 import com.oracle.graal.asm.Assembler;
 import com.oracle.graal.asm.Label;
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Fri Oct 30 20:56:28 2015 +0100
@@ -25,11 +25,11 @@
 import static com.oracle.graal.asm.amd64.AMD64AsmOptions.UseIncDec;
 import static com.oracle.graal.asm.amd64.AMD64AsmOptions.UseXmmLoadAndClearUpper;
 import static com.oracle.graal.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll;
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.amd64.AMD64Kind;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
 
 import com.oracle.graal.asm.NumUtil;
 
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.asm.sparc;
 
-import static jdk.internal.jvmci.sparc.SPARC.STACK_BIAS;
-import static jdk.internal.jvmci.sparc.SPARC.fp;
-import static jdk.internal.jvmci.sparc.SPARC.sp;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.sparc.SPARC;
+import static jdk.vm.ci.sparc.SPARC.STACK_BIAS;
+import static jdk.vm.ci.sparc.SPARC.fp;
+import static jdk.vm.ci.sparc.SPARC.sp;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.sparc.SPARC;
 
 import com.oracle.graal.asm.AbstractAddress;
 
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Fri Oct 30 20:56:28 2015 +0100
@@ -119,28 +119,28 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Ops.ArithOp;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Ops.LdstOp;
 import static java.lang.String.format;
-import static jdk.internal.jvmci.sparc.SPARC.INSTRUCTION_SIZE;
-import static jdk.internal.jvmci.sparc.SPARC.g0;
-import static jdk.internal.jvmci.sparc.SPARC.isCPURegister;
-import static jdk.internal.jvmci.sparc.SPARC.isDoubleFloatRegister;
-import static jdk.internal.jvmci.sparc.SPARC.isSingleFloatRegister;
-import static jdk.internal.jvmci.sparc.SPARC.r15;
-import static jdk.internal.jvmci.sparc.SPARC.r2;
-import static jdk.internal.jvmci.sparc.SPARC.r5;
+import static jdk.vm.ci.sparc.SPARC.CPU;
+import static jdk.vm.ci.sparc.SPARC.FPUd;
+import static jdk.vm.ci.sparc.SPARC.FPUs;
+import static jdk.vm.ci.sparc.SPARC.g0;
+import static jdk.vm.ci.sparc.SPARC.g2;
+import static jdk.vm.ci.sparc.SPARC.g5;
+import static jdk.vm.ci.sparc.SPARC.g7;
+import static jdk.vm.ci.sparc.SPARC.o7;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.PlatformKind;
-import jdk.internal.jvmci.sparc.SPARC;
-import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
-import jdk.internal.jvmci.sparc.SPARCKind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.sparc.SPARC;
+import jdk.vm.ci.sparc.SPARC.CPUFeature;
+import jdk.vm.ci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.Assembler;
 import com.oracle.graal.asm.Label;
@@ -163,6 +163,16 @@
         super(target);
     }
 
+    /**
+     * Size of an SPARC assembler instruction in Bytes.
+     */
+    public static final int INSTRUCTION_SIZE = 4;
+
+    /**
+     * Size in bytes which are cleared by stxa %g0, [%rd] ASI_ST_BLKINIT_PRIMARY.
+     */
+    public static final int BLOCK_ZERO_LENGTH = 64;
+
     public static final int CCR_ICC_SHIFT = 0;
     public static final int CCR_XCC_SHIFT = 4;
     public static final int CCR_V_SHIFT = 1;
@@ -621,7 +631,7 @@
         }
 
         public static CC forKind(PlatformKind kind) {
-            if (kind.equals(SPARCKind.DWORD)) {
+            if (kind.equals(SPARCKind.XWORD)) {
                 return Xcc;
             } else if (kind.equals(SPARCKind.WORD)) {
                 return Icc;
@@ -1630,6 +1640,31 @@
         }
     }
 
+    public static boolean isCPURegister(Register... regs) {
+        for (Register reg : regs) {
+            if (!isCPURegister(reg)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isCPURegister(Register r) {
+        return r.getRegisterCategory().equals(CPU);
+    }
+
+    public static boolean isGlobalRegister(Register r) {
+        return isCPURegister(r) && g0.number <= r.number && r.number <= g7.number;
+    }
+
+    public static boolean isSingleFloatRegister(Register r) {
+        return r.getRegisterCategory().equals(FPUs);
+    }
+
+    public static boolean isDoubleFloatRegister(Register r) {
+        return r.getRegisterCategory().equals(FPUd);
+    }
+
     public boolean hasFeature(CPUFeature feature) {
         return ((SPARC) this.target.arch).features.contains(feature);
     }
@@ -2309,7 +2344,7 @@
     // A.44 Read State Register
 
     public void rdpc(Register rd) {
-        op3(Rd, r5, g0, rd);
+        op3(Rd, g5, g0, rd);
     }
 
     public void restore(Register rs1, Register rs2, Register rd) {
@@ -2423,11 +2458,11 @@
     }
 
     public void wrccr(Register rs1, Register rs2) {
-        op3(Wr, rs1, rs2, r2);
+        op3(Wr, rs1, rs2, g2);
     }
 
     public void wrccr(Register rs1, int simm13) {
-        op3(Wr, rs1, simm13, r2);
+        op3(Wr, rs1, simm13, g2);
     }
 
     public void xor(Register rs1, Register rs2, Register rd) {
@@ -2499,7 +2534,7 @@
     }
 
     public void ld(SPARCAddress src, Register dst, int bytes, boolean signExtend) {
-        if (SPARC.isCPURegister(dst)) {
+        if (isCPURegister(dst)) {
             if (signExtend) {
                 switch (bytes) {
                     case 1:
@@ -2535,10 +2570,10 @@
                         throw new InternalError();
                 }
             }
-        } else if (SPARC.isDoubleFloatRegister(dst) && bytes == 8) {
+        } else if (isDoubleFloatRegister(dst) && bytes == 8) {
             assert !signExtend;
             ld(Lddf, src, dst);
-        } else if (SPARC.isSingleFloatRegister(dst) && bytes == 4) {
+        } else if (isSingleFloatRegister(dst) && bytes == 4) {
             assert !signExtend;
             ld(Ldf, src, dst);
         } else {
@@ -2547,7 +2582,7 @@
     }
 
     public void st(Register src, SPARCAddress dst, int bytes) {
-        if (SPARC.isCPURegister(src)) {
+        if (isCPURegister(src)) {
             switch (bytes) {
                 case 1:
                     st(Stb, src, dst);
@@ -2564,9 +2599,9 @@
                 default:
                     throw new InternalError(Integer.toString(bytes));
             }
-        } else if (SPARC.isDoubleFloatRegister(src) && bytes == 8) {
+        } else if (isDoubleFloatRegister(src) && bytes == 8) {
             st(Stdf, src, dst);
-        } else if (SPARC.isSingleFloatRegister(src) && bytes == 4) {
+        } else if (isSingleFloatRegister(src) && bytes == 4) {
             st(Stf, src, dst);
         } else {
             throw new InternalError(String.format("src: %s dst: %s bytes: %d", src, dst, bytes));
@@ -2599,17 +2634,17 @@
     }
 
     public void ldxa(Register rs1, Register rs2, Register rd, Asi asi) {
-        assert SPARC.isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
+        assert isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
         ld(Ldxa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
     public void lduwa(Register rs1, Register rs2, Register rd, Asi asi) {
-        assert SPARC.isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
+        assert isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
         ld(Lduwa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
     public void stxa(Register rd, Register rs1, Register rs2, Asi asi) {
-        assert SPARC.isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
+        assert isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
         ld(Stxa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
@@ -2648,7 +2683,7 @@
     }
 
     public void membar(int barriers) {
-        op3(Membar, r15, barriers, g0);
+        op3(Membar, o7, barriers, g0);
     }
 
     public void casa(Register rs1, Register rs2, Register rd, Asi asi) {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Fri Oct 30 20:56:28 2015 +0100
@@ -29,19 +29,14 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.Always;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.Equal;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.Rc_z;
-import static jdk.internal.jvmci.sparc.SPARC.g0;
-import static jdk.internal.jvmci.sparc.SPARC.g3;
-import static jdk.internal.jvmci.sparc.SPARC.i7;
-import static jdk.internal.jvmci.sparc.SPARC.isCPURegister;
-import static jdk.internal.jvmci.sparc.SPARC.o7;
-
-import java.util.function.Consumer;
-
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.sparc.SPARC;
-import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
+import static jdk.vm.ci.sparc.SPARC.g0;
+import static jdk.vm.ci.sparc.SPARC.g3;
+import static jdk.vm.ci.sparc.SPARC.i7;
+import static jdk.vm.ci.sparc.SPARC.o7;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.sparc.SPARC.CPUFeature;
 
 import com.oracle.graal.asm.AbstractAddress;
 import com.oracle.graal.asm.Label;
@@ -191,182 +186,74 @@
     }
 
     /**
-     * This instruction is like sethi but for 64-bit values.
+     * Generates sethi hi22(value), dst; or dst, lo10(value), dst; code.
      */
-    public static class Sethix {
-
-        private static final int INSTRUCTION_SIZE = 7;
-
-        private long value;
-        private Register dst;
-        private boolean forceRelocatable;
-        private boolean delayed = false;
-        private Consumer<SPARCAssembler> delayedInstructionEmitter;
-
-        public Sethix(long value, Register dst, boolean forceRelocatable, boolean delayed) {
-            this(value, dst, forceRelocatable);
-            assert !(forceRelocatable && delayed) : "Relocatable sethix cannot be delayed";
-            this.delayed = delayed;
-        }
-
-        public Sethix(long value, Register dst, boolean forceRelocatable) {
-            this.value = value;
-            this.dst = dst;
-            this.forceRelocatable = forceRelocatable;
-        }
-
-        public Sethix(long value, Register dst) {
-            this(value, dst, false);
-        }
-
-        private void emitInstruction(Consumer<SPARCAssembler> cb, SPARCMacroAssembler masm) {
-            if (delayed) {
-                if (this.delayedInstructionEmitter != null) {
-                    delayedInstructionEmitter.accept(masm);
-                }
-                delayedInstructionEmitter = cb;
-            } else {
-                cb.accept(masm);
-            }
-        }
-
-        public void emit(SPARCMacroAssembler masm) {
-            final int hi = (int) (value >> 32);
-            final int lo = (int) (value & ~0);
-
-            // This is the same logic as MacroAssembler::internal_set.
-            final int startPc = masm.position();
-
-            if (hi == 0 && lo >= 0) {
-                Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(lo), dst);
-                emitInstruction(cb, masm);
-            } else if (hi == -1) {
-                Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(~lo), dst);
-                emitInstruction(cb, masm);
-                cb = eMasm -> eMasm.xor(dst, ~lo10(~0), dst);
-                emitInstruction(cb, masm);
-            } else {
-                final int shiftcnt;
-                final int shiftcnt2;
-                Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(hi), dst);
-                emitInstruction(cb, masm);
-                if ((hi & 0x3ff) != 0) {                                  // Any bits?
-                    // msb 32-bits are now in lsb 32
-                    cb = eMasm -> eMasm.or(dst, hi & 0x3ff, dst);
-                    emitInstruction(cb, masm);
-                }
-                if ((lo & 0xFFFFFC00) != 0) {                             // done?
-                    if (((lo >> 20) & 0xfff) != 0) {                      // Any bits set?
-                        // Make room for next 12 bits
-                        cb = eMasm -> eMasm.sllx(dst, 12, dst);
-                        emitInstruction(cb, masm);
-                        // Or in next 12
-                        cb = eMasm -> eMasm.or(dst, (lo >> 20) & 0xfff, dst);
-                        emitInstruction(cb, masm);
-                        shiftcnt = 0;                                     // We already shifted
-                    } else {
-                        shiftcnt = 12;
-                    }
-                    if (((lo >> 10) & 0x3ff) != 0) {
-                        // Make room for last 10 bits
-                        cb = eMasm -> eMasm.sllx(dst, shiftcnt + 10, dst);
-                        emitInstruction(cb, masm);
-                        // Or in next 10
-                        cb = eMasm -> eMasm.or(dst, (lo >> 10) & 0x3ff, dst);
-                        emitInstruction(cb, masm);
-                        shiftcnt2 = 0;
-                    } else {
-                        shiftcnt2 = 10;
-                    }
-                    // Shift leaving disp field 0'd
-                    cb = eMasm -> eMasm.sllx(dst, shiftcnt2 + 10, dst);
-                    emitInstruction(cb, masm);
-                } else {
-                    cb = eMasm -> eMasm.sllx(dst, 32, dst);
-                    emitInstruction(cb, masm);
-                }
-            }
-            // Pad out the instruction sequence so it can be patched later.
-            if (forceRelocatable) {
-                while (masm.position() < (startPc + (INSTRUCTION_SIZE * 4))) {
-                    Consumer<SPARCAssembler> cb = eMasm -> eMasm.nop();
-                    emitInstruction(cb, masm);
-                }
-            }
-        }
-
-        public void emitDelayed(SPARCMacroAssembler masm) {
-            assert delayedInstructionEmitter != null;
-            delayedInstructionEmitter.accept(masm);
+    public void setw(int value, Register dst, boolean forceRelocatable) {
+        if (!forceRelocatable && isSimm13(value)) {
+            or(g0, value, dst);
+        } else {
+            sethi(hi22(value), dst);
+            or(dst, lo10(value), dst);
         }
     }
 
-    public static class Setx {
+    public void setx(long value, Register dst, boolean forceRelocatable) {
+        int lo = (int) (value & ~0);
+        sethix(value, dst, forceRelocatable);
+        if (lo10(lo) != 0 || forceRelocatable) {
+            add(dst, lo10(lo), dst);
+        }
+    }
 
-        private long value;
-        private Register dst;
-        private boolean forceRelocatable;
-        private boolean delayed = false;
-        private boolean delayedFirstEmitted = false;
-        private Sethix sethix;
-        private Consumer<SPARCMacroAssembler> delayedAdd;
+    public void sethix(long value, Register dst, boolean forceRelocatable) {
+        final int hi = (int) (value >> 32);
+        final int lo = (int) (value & ~0);
 
-        public Setx(long value, Register dst, boolean forceRelocatable, boolean delayed) {
-            assert !(forceRelocatable && delayed) : "Cannot use relocatable setx as delayable";
-            this.value = value;
-            this.dst = dst;
-            this.forceRelocatable = forceRelocatable;
-            this.delayed = delayed;
-        }
-
-        public Setx(long value, Register dst, boolean forceRelocatable) {
-            this(value, dst, forceRelocatable, false);
-        }
-
-        public Setx(long value, Register dst) {
-            this(value, dst, false);
-        }
-
-        public void emit(SPARCMacroAssembler masm) {
-            assert !delayed;
-            doEmit(masm);
-        }
-
-        private void doEmit(SPARCMacroAssembler masm) {
-            sethix = new Sethix(value, dst, forceRelocatable, delayed);
-            sethix.emit(masm);
-            int lo = (int) (value & ~0);
-            if (lo10(lo) != 0 || forceRelocatable) {
-                Consumer<SPARCMacroAssembler> add = eMasm -> eMasm.add(dst, lo10(lo), dst);
-                if (delayed) {
-                    sethix.emitDelayed(masm);
-                    sethix = null;
-                    delayedAdd = add;
+        // This is the same logic as MacroAssembler::internal_set.
+        final int startPc = position();
+        if (hi == 0 && lo >= 0) {
+            sethi(hi22(lo), dst);
+        } else if (hi == -1) {
+            sethi(hi22(~lo), dst);
+            xor(dst, ~lo10(~0), dst);
+        } else {
+            final int shiftcnt;
+            final int shiftcnt2;
+            sethi(hi22(hi), dst);
+            if ((hi & 0x3ff) != 0) {                                  // Any bits?
+                // msb 32-bits are now in lsb 32
+                or(dst, hi & 0x3ff, dst);
+            }
+            if ((lo & 0xFFFFFC00) != 0) {                             // done?
+                if (((lo >> 20) & 0xfff) != 0) {                      // Any bits set?
+                    // Make room for next 12 bits
+                    sllx(dst, 12, dst);
+                    // Or in next 12
+                    or(dst, (lo >> 20) & 0xfff, dst);
+                    shiftcnt = 0;                                     // We already shifted
                 } else {
-                    sethix = null;
-                    add.accept(masm);
+                    shiftcnt = 12;
                 }
+                if (((lo >> 10) & 0x3ff) != 0) {
+                    // Make room for last 10 bits
+                    sllx(dst, shiftcnt + 10, dst);
+                    // Or in next 10
+                    or(dst, (lo >> 10) & 0x3ff, dst);
+                    shiftcnt2 = 0;
+                } else {
+                    shiftcnt2 = 10;
+                }
+                // Shift leaving disp field 0'd
+                sllx(dst, shiftcnt2 + 10, dst);
+            } else {
+                sllx(dst, 32, dst);
             }
         }
-
-        public void emitFirstPartOfDelayed(SPARCMacroAssembler masm) {
-            assert !forceRelocatable : "Cannot use delayed mode with relocatable setx";
-            assert delayed : "Can only be used in delayed mode";
-            doEmit(masm);
-            delayedFirstEmitted = true;
-        }
-
-        public void emitSecondPartOfDelayed(SPARCMacroAssembler masm) {
-            assert !forceRelocatable : "Cannot use delayed mode with relocatable setx";
-            assert delayed : "Can only be used in delayed mode";
-            assert delayedFirstEmitted : "First part has not been emitted so far.";
-            assert delayedAdd == null && sethix != null || delayedAdd != null && sethix == null : "Either add or sethix must be set";
-            if (delayedAdd != null) {
-                delayedAdd.accept(masm);
-            } else {
-                sethix.emitDelayed(masm);
+        // Pad out the instruction sequence so it can be patched later.
+        if (forceRelocatable) {
+            while (position() < (startPc + (INSTRUCTION_SIZE * 7))) {
+                nop();
             }
-
         }
     }
 
@@ -423,7 +310,7 @@
                 int positionBefore = position();
                 delaySlotInstruction.run();
                 int positionAfter = position();
-                assert positionBefore - positionAfter > SPARC.INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot";
+                assert positionBefore - positionAfter > INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot";
             } else {
                 nop();
             }
@@ -449,7 +336,7 @@
                 int positionBefore = position();
                 delaySlotInstruction.run();
                 int positionAfter = position();
-                assert positionBefore - positionAfter > SPARC.INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot";
+                assert positionBefore - positionAfter > INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot";
             } else {
                 nop();
             }
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -24,19 +24,19 @@
 
 import java.lang.reflect.Method;
 
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.CodeCacheProvider;
-import jdk.internal.jvmci.code.CodeUtil;
-import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.code.InstalledCode;
-import jdk.internal.jvmci.code.InvalidInstalledCodeException;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaMethod;
-import jdk.internal.jvmci.runtime.JVMCI;
-import jdk.internal.jvmci.runtime.JVMCIBackend;
-import jdk.internal.jvmci.service.Services;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.vm.ci.runtime.JVMCIBackend;
+import jdk.vm.ci.service.Services;
 
 import org.junit.Assert;
 
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,15 +22,14 @@
  */
 package com.oracle.graal.asm;
 
-import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.StackSlot;
-import jdk.internal.jvmci.code.TargetDescription;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.TargetDescription;
 
 /**
  * The platform-independent base class for the assembler.
@@ -47,11 +46,7 @@
 
     public Assembler(TargetDescription target) {
         this.target = target;
-        if (target.arch.getByteOrder() == ByteOrder.BIG_ENDIAN) {
-            this.codeBuffer = new Buffer.BigEndian();
-        } else {
-            this.codeBuffer = new Buffer.LittleEndian();
-        }
+        this.codeBuffer = new Buffer(target.arch.getByteOrder());
     }
 
     /**
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,39 +22,46 @@
  */
 package com.oracle.graal.asm;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Arrays;
 
 /**
- * Code buffer management for the assembler. Support for little endian and big endian architectures
- * is implemented using subclasses.
+ * Code buffer management for the assembler.
  */
-abstract class Buffer {
+final class Buffer {
 
-    protected byte[] data;
-    protected int position;
+    protected ByteBuffer data;
 
-    public Buffer() {
-        data = new byte[AsmOptions.InitialCodeBufferSize];
+    public Buffer(ByteOrder order) {
+        data = ByteBuffer.allocate(AsmOptions.InitialCodeBufferSize);
+        data.order(order);
     }
 
     public int position() {
-        return position;
+        return data.position();
     }
 
     public void setPosition(int position) {
-        assert position >= 0 && position <= data.length;
-        this.position = position;
+        assert position >= 0 && position <= data.limit();
+        data.position(position);
     }
 
     /**
-     * Closes this buffer. No extra data can be written to this buffer after this call.
+     * Closes this buffer. Any further operations on a closed buffer will result in a
+     * {@link NullPointerException}.
      *
      * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not
      *            including) {@code position()} is returned
      * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true}
      */
     public byte[] close(boolean trimmedCopy) {
-        byte[] result = trimmedCopy ? Arrays.copyOf(data, position()) : data;
+        byte[] result = data.array();
+        if (trimmedCopy) {
+            // Make a copy even if result.length == data.position() since
+            // the API for trimmedCopy states a copy is always made
+            result = Arrays.copyOf(result, data.position());
+        }
         data = null;
         return result;
     }
@@ -63,7 +70,7 @@
         if (data == null) {
             return null;
         }
-        return Arrays.copyOfRange(data, start, end);
+        return Arrays.copyOfRange(data.array(), start, end);
     }
 
     /**
@@ -74,166 +81,91 @@
      * @param len number of bytes to copy
      */
     public void copyInto(byte[] dst, int off, int len) {
-        System.arraycopy(data, 0, dst, off, len);
+        System.arraycopy(data.array(), 0, dst, off, len);
     }
 
     protected void ensureSize(int length) {
-        if (length >= data.length) {
-            data = Arrays.copyOf(data, length * 4);
+        if (length >= data.limit()) {
+            byte[] newBuf = Arrays.copyOf(data.array(), length * 4);
+            ByteBuffer newData = ByteBuffer.wrap(newBuf);
+            newData.order(data.order());
+            newData.position(data.position());
+            data = newData;
         }
     }
 
     public void emitBytes(byte[] arr, int off, int len) {
-        ensureSize(position + len);
-        System.arraycopy(arr, off, data, position, len);
-        position += len;
+        ensureSize(data.position() + len);
+        data.put(arr, off, len);
     }
 
     public void emitByte(int b) {
-        position = emitByte(b, position);
+        assert NumUtil.isUByte(b) || NumUtil.isByte(b);
+        ensureSize(data.position() + 1);
+        data.put((byte) (b & 0xFF));
     }
 
     public void emitShort(int b) {
-        position = emitShort(b, position);
+        assert NumUtil.isUShort(b) || NumUtil.isShort(b);
+        ensureSize(data.position() + 2);
+        data.putShort((short) b);
     }
 
     public void emitInt(int b) {
-        position = emitInt(b, position);
+        ensureSize(data.position() + 4);
+        data.putInt(b);
     }
 
     public void emitLong(long b) {
-        position = emitLong(b, position);
+        ensureSize(data.position() + 8);
+        data.putLong(b);
     }
 
-    public int emitBytes(byte[] arr, int pos) {
+    public void emitBytes(byte[] arr, int pos) {
         final int len = arr.length;
-        final int newPos = pos + len;
-        ensureSize(newPos);
-        System.arraycopy(arr, 0, data, pos, len);
-        return newPos;
+        ensureSize(pos + len);
+        // Write directly into the underlying array so as to not
+        // change the ByteBuffer's position
+        System.arraycopy(arr, 0, data.array(), pos, len);
     }
 
-    public int emitByte(int b, int pos) {
+    public void emitByte(int b, int pos) {
         assert NumUtil.isUByte(b) || NumUtil.isByte(b);
-        int newPos = pos + 1;
-        ensureSize(newPos);
-        data[pos] = (byte) (b & 0xFF);
-        return newPos;
+        ensureSize(pos + 1);
+        data.put(pos, (byte) (b & 0xFF));
     }
 
-    public abstract int emitShort(int b, int pos);
+    public void emitShort(int b, int pos) {
+        assert NumUtil.isUShort(b) || NumUtil.isShort(b);
+        ensureSize(pos + 2);
+        data.putShort(pos, (short) b).position();
+    }
 
-    public abstract int emitInt(int b, int pos);
+    public void emitInt(int b, int pos) {
+        ensureSize(pos + 4);
+        data.putInt(pos, b).position();
+    }
 
-    public abstract int emitLong(long b, int pos);
+    public void emitLong(long b, int pos) {
+        ensureSize(pos + 8);
+        data.putLong(pos, b).position();
+    }
 
     public int getByte(int pos) {
-        return data[pos] & 0xff;
+        int b = data.get(pos);
+        return b & 0xff;
     }
 
-    public abstract int getShort(int pos);
-
-    public abstract int getInt(int pos);
-
-    public static final class BigEndian extends Buffer {
-
-        @Override
-        public int emitShort(int b, int pos) {
-            assert NumUtil.isUShort(b) || NumUtil.isShort(b);
-            int newPos = pos + 2;
-            ensureSize(pos + 2);
-            data[pos] = (byte) ((b >> 8) & 0xFF);
-            data[pos + 1] = (byte) (b & 0xFF);
-            return newPos;
-        }
-
-        @Override
-        public int emitInt(int b, int pos) {
-            int newPos = pos + 4;
-            ensureSize(newPos);
-            data[pos] = (byte) ((b >> 24) & 0xFF);
-            data[pos + 1] = (byte) ((b >> 16) & 0xFF);
-            data[pos + 2] = (byte) ((b >> 8) & 0xFF);
-            data[pos + 3] = (byte) (b & 0xFF);
-            return newPos;
-        }
-
-        @Override
-        public int emitLong(long b, int pos) {
-            int newPos = pos + 8;
-            ensureSize(newPos);
-            data[pos] = (byte) ((b >> 56) & 0xFF);
-            data[pos + 1] = (byte) ((b >> 48) & 0xFF);
-            data[pos + 2] = (byte) ((b >> 40) & 0xFF);
-            data[pos + 3] = (byte) ((b >> 32) & 0xFF);
-            data[pos + 4] = (byte) ((b >> 24) & 0xFF);
-            data[pos + 5] = (byte) ((b >> 16) & 0xFF);
-            data[pos + 6] = (byte) ((b >> 8) & 0xFF);
-            data[pos + 7] = (byte) (b & 0xFF);
-            return newPos;
-        }
-
-        @Override
-        public int getShort(int pos) {
-            return (data[pos + 0] & 0xff) << 8 | (data[pos + 1] & 0xff) << 0;
-        }
-
-        @Override
-        public int getInt(int pos) {
-            return (data[pos + 0] & 0xff) << 24 | (data[pos + 1] & 0xff) << 16 | (data[pos + 2] & 0xff) << 8 | (data[pos + 3] & 0xff) << 0;
-        }
+    public int getShort(int pos) {
+        short s = data.getShort(pos);
+        return s & 0xffff;
     }
 
-    public static final class LittleEndian extends Buffer {
-
-        @Override
-        public int emitShort(int b, int pos) {
-            assert NumUtil.isUShort(b) || NumUtil.isShort(b);
-            int newPos = pos + 2;
-            ensureSize(newPos);
-            data[pos] = (byte) (b & 0xFF);
-            data[pos + 1] = (byte) ((b >> 8) & 0xFF);
-            return newPos;
-        }
-
-        @Override
-        public int emitInt(int b, int pos) {
-            int newPos = pos + 4;
-            ensureSize(newPos);
-            data[pos] = (byte) (b & 0xFF);
-            data[pos + 1] = (byte) ((b >> 8) & 0xFF);
-            data[pos + 2] = (byte) ((b >> 16) & 0xFF);
-            data[pos + 3] = (byte) ((b >> 24) & 0xFF);
-            return newPos;
-        }
-
-        @Override
-        public int emitLong(long b, int pos) {
-            int newPos = pos + 8;
-            ensureSize(newPos);
-            data[pos] = (byte) (b & 0xFF);
-            data[pos + 1] = (byte) ((b >> 8) & 0xFF);
-            data[pos + 2] = (byte) ((b >> 16) & 0xFF);
-            data[pos + 3] = (byte) ((b >> 24) & 0xFF);
-            data[pos + 4] = (byte) ((b >> 32) & 0xFF);
-            data[pos + 5] = (byte) ((b >> 40) & 0xFF);
-            data[pos + 6] = (byte) ((b >> 48) & 0xFF);
-            data[pos + 7] = (byte) ((b >> 56) & 0xFF);
-            return newPos;
-        }
-
-        @Override
-        public int getShort(int pos) {
-            return (data[pos + 1] & 0xff) << 8 | (data[pos + 0] & 0xff) << 0;
-        }
-
-        @Override
-        public int getInt(int pos) {
-            return (data[pos + 3] & 0xff) << 24 | (data[pos + 2] & 0xff) << 16 | (data[pos + 1] & 0xff) << 8 | (data[pos + 0] & 0xff) << 0;
-        }
+    public int getInt(int pos) {
+        return data.getInt(pos);
     }
 
     public void reset() {
-        position = 0;
+        data.clear();
     }
 }
--- a/graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.code;
 
-import jdk.internal.jvmci.code.CodeCacheProvider;
-import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.code.InstalledCode;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.InstalledCode;
 
 /**
  * Interface providing capability for disassembling machine code.
--- a/graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFile.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFile.java	Fri Oct 30 20:56:28 2015 +0100
@@ -32,10 +32,10 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import jdk.internal.jvmci.code.CodeUtil;
-import jdk.internal.jvmci.code.CompilationResult.CodeAnnotation;
-import jdk.internal.jvmci.code.CompilationResult.CodeComment;
-import jdk.internal.jvmci.code.CompilationResult.JumpTable;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.CompilationResult.CodeAnnotation;
+import jdk.vm.ci.code.CompilationResult.CodeComment;
+import jdk.vm.ci.code.CompilationResult.JumpTable;
 
 /**
  * A HexCodeFile is a textual format for representing a chunk of machine code along with extra
--- a/graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFileDisassemblerProvider.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFileDisassemblerProvider.java	Fri Oct 30 20:56:28 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,20 +26,20 @@
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
 
-import jdk.internal.jvmci.code.CodeCacheProvider;
-import jdk.internal.jvmci.code.CodeUtil;
-import jdk.internal.jvmci.code.CodeUtil.DefaultRefMapFormatter;
-import jdk.internal.jvmci.code.CodeUtil.RefMapFormatter;
-import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.code.CompilationResult.Call;
-import jdk.internal.jvmci.code.CompilationResult.DataPatch;
-import jdk.internal.jvmci.code.CompilationResult.Infopoint;
-import jdk.internal.jvmci.code.CompilationResult.Mark;
-import jdk.internal.jvmci.code.InstalledCode;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.TargetDescription;
-import jdk.internal.jvmci.service.ServiceProvider;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.CodeUtil.DefaultRefMapFormatter;
+import jdk.vm.ci.code.CodeUtil.RefMapFormatter;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.CompilationResult.Call;
+import jdk.vm.ci.code.CompilationResult.DataPatch;
+import jdk.vm.ci.code.CompilationResult.Infopoint;
+import jdk.vm.ci.code.CompilationResult.Mark;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.service.ServiceProvider;
 
 /**
  * {@link HexCodeFile} based implementation of {@link DisassemblerProvider}.
@@ -77,7 +77,7 @@
             HexCodeFile.addAnnotations(hcf, compResult.getAnnotations());
             addExceptionHandlersComment(compResult, hcf);
             Register fp = regConfig.getFrameRegister();
-            RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.arch, target.wordSize, fp, 0);
+            RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.wordSize, fp, 0);
             for (Infopoint infopoint : compResult.getInfopoints()) {
                 if (infopoint instanceof Call) {
                     Call call = (Call) infopoint;
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -25,7 +25,7 @@
 import static com.oracle.graal.compiler.common.BackendOptions.UserOptions.TraceRA;
 import static com.oracle.graal.compiler.common.GraalOptions.RegisterPressure;
 import static org.junit.Assume.assumeTrue;
-import jdk.internal.jvmci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64;
 
 import org.junit.Before;
 import org.junit.Ignore;
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/ConstantStackMoveTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/ConstantStackMoveTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,14 +23,14 @@
 package com.oracle.graal.compiler.amd64.test;
 
 import static org.junit.Assume.assumeTrue;
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.code.StackSlotValue;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.PrimitiveConstant;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.PrimitiveConstant;
 
 import org.junit.Before;
 import org.junit.Test;
 
+import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.gen.LIRGeneratorTool;
 import com.oracle.graal.lir.jtt.LIRTest;
@@ -54,7 +54,7 @@
             FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
             // create slots
             PrimitiveConstant constantValue = JavaConstant.forBoxedPrimitive(primitive);
-            StackSlotValue s1 = frameMapBuilder.allocateSpillSlot(gen.target().getLIRKind(constantValue.getJavaKind()));
+            VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(gen.target().getLIRKind(constantValue.getJavaKind()));
             // move stuff around
             gen.emitMoveConstant(s1, constantValue);
             gen.emitBlackhole(s1);
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/StackStoreTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/StackStoreTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,16 +23,16 @@
 package com.oracle.graal.compiler.amd64.test;
 
 import static org.junit.Assume.assumeTrue;
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.amd64.AMD64Kind;
-import jdk.internal.jvmci.code.StackSlotValue;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.Value;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.Value;
 
 import org.junit.Before;
 import org.junit.Test;
 
+import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.gen.LIRGeneratorTool;
 import com.oracle.graal.lir.jtt.LIRTest;
@@ -49,8 +49,8 @@
         public void generate(LIRGeneratorTool gen, Value a) {
             FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
             // create slots
-            StackSlotValue s1 = frameMapBuilder.allocateSpillSlot(a.getLIRKind());
-            StackSlotValue s2 = frameMapBuilder.allocateSpillSlot(LIRKind.value(AMD64Kind.WORD));
+            VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(a.getLIRKind());
+            VirtualStackSlot s2 = frameMapBuilder.allocateSpillSlot(LIRKind.value(AMD64Kind.WORD));
             // move stuff around
             gen.emitMove(s1, a);
             gen.emitMoveConstant(s2, JavaConstant.forShort(Short.MIN_VALUE));
@@ -65,8 +65,8 @@
         public void generate(LIRGeneratorTool gen, Value a) {
             FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
             // create slots
-            StackSlotValue s1 = frameMapBuilder.allocateSpillSlot(a.getLIRKind());
-            StackSlotValue s2 = frameMapBuilder.allocateSpillSlot(LIRKind.value(AMD64Kind.WORD));
+            VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(a.getLIRKind());
+            VirtualStackSlot s2 = frameMapBuilder.allocateSpillSlot(LIRKind.value(AMD64Kind.WORD));
             // move stuff around
             gen.emitMove(s1, a);
             Value v = gen.emitLoadConstant(LIRKind.value(AMD64Kind.WORD), JavaConstant.forShort(Short.MIN_VALUE));
@@ -82,8 +82,8 @@
         public void generate(LIRGeneratorTool gen, Value a) {
             FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
             // create slots
-            StackSlotValue s1 = frameMapBuilder.allocateSpillSlot(a.getLIRKind());
-            StackSlotValue s2 = frameMapBuilder.allocateSpillSlot(LIRKind.value(AMD64Kind.WORD));
+            VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(a.getLIRKind());
+            VirtualStackSlot s2 = frameMapBuilder.allocateSpillSlot(LIRKind.value(AMD64Kind.WORD));
             // move stuff around
             gen.emitMoveConstant(s2, JavaConstant.forShort(Short.MIN_VALUE));
             gen.emitMove(s1, a);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,8 +23,8 @@
 
 package com.oracle.graal.compiler.amd64;
 
-import jdk.internal.jvmci.code.CodeCacheProvider;
-import jdk.internal.jvmci.meta.JavaConstant;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.meta.JavaConstant;
 
 import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.asm.amd64.AMD64Address.Scale;
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressNode.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressNode.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,9 +23,9 @@
 
 package com.oracle.graal.compiler.amd64;
 
-import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.Value;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.Value;
 
 import com.oracle.graal.asm.amd64.AMD64Address.Scale;
 import com.oracle.graal.graph.NodeClass;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64ArithmeticLIRGenerator.java	Fri Oct 30 20:56:28 2015 +0100
@@ -0,0 +1,896 @@
+/*
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.compiler.amd64;
+
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NEG;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NOT;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSF;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.LZCNT;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOV;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZX;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZXB;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.POPCNT;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TZCNT;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROL;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SAR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHL;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PS;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS;
+import static com.oracle.graal.lir.LIRValueUtil.asConstantValue;
+import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
+import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
+import static com.oracle.graal.lir.amd64.AMD64Arithmetic.DREM;
+import static com.oracle.graal.lir.amd64.AMD64Arithmetic.FREM;
+import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.COS;
+import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG;
+import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG10;
+import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.SIN;
+import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.TAN;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
+
+import com.oracle.graal.asm.NumUtil;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift;
+import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
+import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp;
+import com.oracle.graal.compiler.common.calc.FloatConvert;
+import com.oracle.graal.lir.ConstantValue;
+import com.oracle.graal.lir.LIRFrameState;
+import com.oracle.graal.lir.Variable;
+import com.oracle.graal.lir.amd64.AMD64AddressValue;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp;
+import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
+import com.oracle.graal.lir.amd64.AMD64Binary;
+import com.oracle.graal.lir.amd64.AMD64ClearRegisterOp;
+import com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp;
+import com.oracle.graal.lir.amd64.AMD64MulDivOp;
+import com.oracle.graal.lir.amd64.AMD64ShiftOp;
+import com.oracle.graal.lir.amd64.AMD64SignExtendOp;
+import com.oracle.graal.lir.amd64.AMD64Unary;
+import com.oracle.graal.lir.gen.ArithmeticLIRGenerator;
+
+/**
+ * This class implements the AMD64 specific portion of the LIR generator.
+ */
+public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AMD64ArithmeticLIRGeneratorTool {
+
+    private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD));
+
+    @Override
+    public Variable emitNegate(Value inputVal) {
+        AllocatableValue input = getLIRGen().asAllocatable(inputVal);
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        switch ((AMD64Kind) input.getPlatformKind()) {
+            case DWORD:
+                getLIRGen().append(new AMD64Unary.MOp(NEG, DWORD, result, input));
+                break;
+            case QWORD:
+                getLIRGen().append(new AMD64Unary.MOp(NEG, QWORD, result, input));
+                break;
+            case SINGLE:
+                getLIRGen().append(new AMD64Binary.DataOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16));
+                break;
+            case DOUBLE:
+                getLIRGen().append(new AMD64Binary.DataOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitNot(Value inputVal) {
+        AllocatableValue input = getLIRGen().asAllocatable(inputVal);
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        switch ((AMD64Kind) input.getPlatformKind()) {
+            case DWORD:
+                getLIRGen().append(new AMD64Unary.MOp(NOT, DWORD, result, input));
+                break;
+            case QWORD:
+                getLIRGen().append(new AMD64Unary.MOp(NOT, QWORD, result, input));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    private Variable emitBinary(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, Value a, Value b, boolean setFlags) {
+        if (isJavaConstant(b)) {
+            return emitBinaryConst(resultKind, op, size, commutative, getLIRGen().asAllocatable(a), asConstantValue(b), setFlags);
+        } else if (commutative && isJavaConstant(a)) {
+            return emitBinaryConst(resultKind, op, size, commutative, getLIRGen().asAllocatable(b), asConstantValue(a), setFlags);
+        } else {
+            return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, getLIRGen().asAllocatable(a), getLIRGen().asAllocatable(b));
+        }
+    }
+
+    private Variable emitBinary(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, Value a, Value b) {
+        if (isJavaConstant(b)) {
+            return emitBinaryConst(resultKind, op, size, getLIRGen().asAllocatable(a), asJavaConstant(b));
+        } else if (commutative && isJavaConstant(a)) {
+            return emitBinaryConst(resultKind, op, size, getLIRGen().asAllocatable(b), asJavaConstant(a));
+        } else {
+            return emitBinaryVar(resultKind, op, size, commutative, getLIRGen().asAllocatable(a), getLIRGen().asAllocatable(b));
+        }
+    }
+
+    private Variable emitBinaryConst(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, ConstantValue b, boolean setFlags) {
+        long value = b.getJavaConstant().asLong();
+        if (NumUtil.isInt(value)) {
+            Variable result = getLIRGen().newVariable(resultKind);
+            int constant = (int) value;
+
+            if (!setFlags) {
+                AMD64MOp mop = getMOp(op, constant);
+                if (mop != null) {
+                    getLIRGen().append(new AMD64Unary.MOp(mop, size, result, a));
+                    return result;
+                }
+            }
+
+            getLIRGen().append(new AMD64Binary.ConstOp(op, size, result, a, constant));
+            return result;
+        } else {
+            return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, a, getLIRGen().asAllocatable(b));
+        }
+    }
+
+    private static AMD64MOp getMOp(AMD64BinaryArithmetic op, int constant) {
+        if (constant == 1) {
+            if (op.equals(AMD64BinaryArithmetic.ADD)) {
+                return AMD64MOp.INC;
+            }
+            if (op.equals(AMD64BinaryArithmetic.SUB)) {
+                return AMD64MOp.DEC;
+            }
+        } else if (constant == -1) {
+            if (op.equals(AMD64BinaryArithmetic.ADD)) {
+                return AMD64MOp.DEC;
+            }
+            if (op.equals(AMD64BinaryArithmetic.SUB)) {
+                return AMD64MOp.INC;
+            }
+        }
+        return null;
+    }
+
+    private Variable emitBinaryConst(LIRKind resultKind, AMD64RMOp op, OperandSize size, AllocatableValue a, JavaConstant b) {
+        Variable result = getLIRGen().newVariable(resultKind);
+        getLIRGen().append(new AMD64Binary.DataOp(op, size, result, a, b));
+        return result;
+    }
+
+    private Variable emitBinaryVar(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) {
+        Variable result = getLIRGen().newVariable(resultKind);
+        if (commutative) {
+            getLIRGen().append(new AMD64Binary.CommutativeOp(op, size, result, a, b));
+        } else {
+            getLIRGen().append(new AMD64Binary.Op(op, size, result, a, b));
+        }
+        return result;
+    }
+
+    @Override
+    protected boolean isNumericInteger(PlatformKind kind) {
+        return ((AMD64Kind) kind).isInteger();
+    }
+
+    @Override
+    public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags);
+            case QWORD:
+                return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags);
+            case SINGLE:
+                return emitBinary(resultKind, SSEOp.ADD, SS, true, a, b);
+            case DOUBLE:
+                return emitBinary(resultKind, SSEOp.ADD, SD, true, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitBinary(resultKind, SUB, DWORD, false, a, b, setFlags);
+            case QWORD:
+                return emitBinary(resultKind, SUB, QWORD, false, a, b, setFlags);
+            case SINGLE:
+                return emitBinary(resultKind, SSEOp.SUB, SS, false, a, b);
+            case DOUBLE:
+                return emitBinary(resultKind, SSEOp.SUB, SD, false, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    private Variable emitIMULConst(OperandSize size, AllocatableValue a, ConstantValue b) {
+        long value = b.getJavaConstant().asLong();
+        if (NumUtil.isInt(value)) {
+            int imm = (int) value;
+            AMD64RMIOp op;
+            if (NumUtil.isByte(imm)) {
+                op = AMD64RMIOp.IMUL_SX;
+            } else {
+                op = AMD64RMIOp.IMUL;
+            }
+
+            Variable ret = getLIRGen().newVariable(LIRKind.combine(a, b));
+            getLIRGen().append(new AMD64Binary.RMIOp(op, size, ret, a, imm));
+            return ret;
+        } else {
+            return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, a, getLIRGen().asAllocatable(b));
+        }
+    }
+
+    private Variable emitIMUL(OperandSize size, Value a, Value b) {
+        if (isJavaConstant(b)) {
+            return emitIMULConst(size, getLIRGen().asAllocatable(a), asConstantValue(b));
+        } else if (isJavaConstant(a)) {
+            return emitIMULConst(size, getLIRGen().asAllocatable(b), asConstantValue(a));
+        } else {
+            return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, getLIRGen().asAllocatable(a), getLIRGen().asAllocatable(b));
+        }
+    }
+
+    @Override
+    public Variable emitMul(Value a, Value b, boolean setFlags) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitIMUL(DWORD, a, b);
+            case QWORD:
+                return emitIMUL(QWORD, a, b);
+            case SINGLE:
+                return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SS, true, a, b);
+            case DOUBLE:
+                return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SD, true, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    private RegisterValue moveToReg(Register reg, Value v) {
+        RegisterValue ret = reg.asValue(v.getLIRKind());
+        getLIRGen().emitMove(ret, v);
+        return ret;
+    }
+
+    private Value emitMulHigh(AMD64MOp opcode, OperandSize size, Value a, Value b) {
+        AMD64MulDivOp mulHigh = getLIRGen().append(new AMD64MulDivOp(opcode, size, LIRKind.combine(a, b), moveToReg(AMD64.rax, a), getLIRGen().asAllocatable(b)));
+        return getLIRGen().emitMove(mulHigh.getHighResult());
+    }
+
+    @Override
+    public Value emitMulHigh(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitMulHigh(AMD64MOp.IMUL, DWORD, a, b);
+            case QWORD:
+                return emitMulHigh(AMD64MOp.IMUL, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Value emitUMulHigh(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitMulHigh(AMD64MOp.MUL, DWORD, a, b);
+            case QWORD:
+                return emitMulHigh(AMD64MOp.MUL, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(a));
+        getLIRGen().append(new AMD64Binary.MemoryOp(op, size, result, a, location, state));
+        return result;
+    }
+
+    protected Value emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, AMD64AddressValue address, LIRFrameState state) {
+        Variable result = getLIRGen().newVariable(LIRKind.value(kind));
+        getLIRGen().append(new AMD64Unary.MemoryOp(op, size, result, address, state));
+        return result;
+    }
+
+    protected Value emitZeroExtendMemory(AMD64Kind memoryKind, int resultBits, AMD64AddressValue address, LIRFrameState state) {
+        // Issue a zero extending load of the proper bit size and set the result to
+        // the proper kind.
+        Variable result = getLIRGen().newVariable(LIRKind.value(resultBits == 32 ? AMD64Kind.DWORD : AMD64Kind.QWORD));
+        switch (memoryKind) {
+            case BYTE:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOVZXB, DWORD, result, address, state));
+                break;
+            case WORD:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOVZX, DWORD, result, address, state));
+                break;
+            case DWORD:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOV, DWORD, result, address, state));
+                break;
+            case QWORD:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOV, QWORD, result, address, state));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    private AMD64MulDivOp emitIDIV(OperandSize size, Value a, Value b, LIRFrameState state) {
+        LIRKind kind = LIRKind.combine(a, b);
+
+        AMD64SignExtendOp sx = getLIRGen().append(new AMD64SignExtendOp(size, kind, moveToReg(AMD64.rax, a)));
+        return getLIRGen().append(new AMD64MulDivOp(AMD64MOp.IDIV, size, kind, sx.getHighResult(), sx.getLowResult(), getLIRGen().asAllocatable(b), state));
+    }
+
+    private AMD64MulDivOp emitDIV(OperandSize size, Value a, Value b, LIRFrameState state) {
+        LIRKind kind = LIRKind.combine(a, b);
+
+        RegisterValue rax = moveToReg(AMD64.rax, a);
+        RegisterValue rdx = AMD64.rdx.asValue(kind);
+        getLIRGen().append(new AMD64ClearRegisterOp(size, rdx));
+        return getLIRGen().append(new AMD64MulDivOp(AMD64MOp.DIV, size, kind, rdx, rax, getLIRGen().asAllocatable(b), state));
+    }
+
+    public Value[] emitIntegerDivRem(Value a, Value b, LIRFrameState state) {
+        AMD64MulDivOp op;
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                op = emitIDIV(DWORD, a, b, state);
+                break;
+            case QWORD:
+                op = emitIDIV(QWORD, a, b, state);
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return new Value[]{getLIRGen().emitMove(op.getQuotient()), getLIRGen().emitMove(op.getRemainder())};
+    }
+
+    @Override
+    public Value emitDiv(Value a, Value b, LIRFrameState state) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                AMD64MulDivOp op = emitIDIV(DWORD, a, b, state);
+                return getLIRGen().emitMove(op.getQuotient());
+            case QWORD:
+                AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state);
+                return getLIRGen().emitMove(lop.getQuotient());
+            case SINGLE:
+                return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SS, false, a, b);
+            case DOUBLE:
+                return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SD, false, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Value emitRem(Value a, Value b, LIRFrameState state) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                AMD64MulDivOp op = emitIDIV(DWORD, a, b, state);
+                return getLIRGen().emitMove(op.getRemainder());
+            case QWORD:
+                AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state);
+                return getLIRGen().emitMove(lop.getRemainder());
+            case SINGLE: {
+                Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
+                getLIRGen().append(new FPDivRemOp(FREM, result, getLIRGen().load(a), getLIRGen().load(b)));
+                return result;
+            }
+            case DOUBLE: {
+                Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
+                getLIRGen().append(new FPDivRemOp(DREM, result, getLIRGen().load(a), getLIRGen().load(b)));
+                return result;
+            }
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitUDiv(Value a, Value b, LIRFrameState state) {
+        AMD64MulDivOp op;
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                op = emitDIV(DWORD, a, b, state);
+                break;
+            case QWORD:
+                op = emitDIV(QWORD, a, b, state);
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return getLIRGen().emitMove(op.getQuotient());
+    }
+
+    @Override
+    public Variable emitURem(Value a, Value b, LIRFrameState state) {
+        AMD64MulDivOp op;
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                op = emitDIV(DWORD, a, b, state);
+                break;
+            case QWORD:
+                op = emitDIV(QWORD, a, b, state);
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return getLIRGen().emitMove(op.getRemainder());
+    }
+
+    @Override
+    public Variable emitAnd(Value a, Value b) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitBinary(resultKind, AND, DWORD, true, a, b, false);
+            case QWORD:
+                return emitBinary(resultKind, AND, QWORD, true, a, b, false);
+            case SINGLE:
+                return emitBinary(resultKind, SSEOp.AND, PS, true, a, b);
+            case DOUBLE:
+                return emitBinary(resultKind, SSEOp.AND, PD, true, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitOr(Value a, Value b) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitBinary(resultKind, OR, DWORD, true, a, b, false);
+            case QWORD:
+                return emitBinary(resultKind, OR, QWORD, true, a, b, false);
+            case SINGLE:
+                return emitBinary(resultKind, SSEOp.OR, PS, true, a, b);
+            case DOUBLE:
+                return emitBinary(resultKind, SSEOp.OR, PD, true, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitXor(Value a, Value b) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitBinary(resultKind, XOR, DWORD, true, a, b, false);
+            case QWORD:
+                return emitBinary(resultKind, XOR, QWORD, true, a, b, false);
+            case SINGLE:
+                return emitBinary(resultKind, SSEOp.XOR, PS, true, a, b);
+            case DOUBLE:
+                return emitBinary(resultKind, SSEOp.XOR, PD, true, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    private Variable emitShift(AMD64Shift op, OperandSize size, Value a, Value b) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(a, b).changeType(a.getPlatformKind()));
+        AllocatableValue input = getLIRGen().asAllocatable(a);
+        if (isJavaConstant(b)) {
+            JavaConstant c = asJavaConstant(b);
+            if (c.asLong() == 1) {
+                getLIRGen().append(new AMD64Unary.MOp(op.m1Op, size, result, input));
+            } else {
+                /*
+                 * c is implicitly masked to 5 or 6 bits by the CPU, so casting it to (int) is
+                 * always correct, even without the NumUtil.is32bit() test.
+                 */
+                getLIRGen().append(new AMD64Binary.ConstOp(op.miOp, size, result, input, (int) c.asLong()));
+            }
+        } else {
+            getLIRGen().emitMove(RCX_I, b);
+            getLIRGen().append(new AMD64ShiftOp(op.mcOp, size, result, input, RCX_I));
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitShl(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitShift(SHL, DWORD, a, b);
+            case QWORD:
+                return emitShift(SHL, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitShr(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitShift(SAR, DWORD, a, b);
+            case QWORD:
+                return emitShift(SAR, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitUShr(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitShift(SHR, DWORD, a, b);
+            case QWORD:
+                return emitShift(SHR, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    public Variable emitRol(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitShift(ROL, DWORD, a, b);
+            case QWORD:
+                return emitShift(ROL, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    public Variable emitRor(Value a, Value b) {
+        switch ((AMD64Kind) a.getPlatformKind()) {
+            case DWORD:
+                return emitShift(ROR, DWORD, a, b);
+            case QWORD:
+                return emitShift(ROR, QWORD, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) {
+        Variable result = getLIRGen().newVariable(kind);
+        getLIRGen().append(new AMD64Unary.RMOp(op, size, result, getLIRGen().asAllocatable(input)));
+        return result;
+    }
+
+    private AllocatableValue emitConvertOp(LIRKind kind, AMD64MROp op, OperandSize size, Value input) {
+        Variable result = getLIRGen().newVariable(kind);
+        getLIRGen().append(new AMD64Unary.MROp(op, size, result, getLIRGen().asAllocatable(input)));
+        return result;
+    }
+
+    @Override
+    public Value emitReinterpret(LIRKind to, Value inputVal) {
+        LIRKind from = inputVal.getLIRKind();
+        if (to.equals(from)) {
+            return inputVal;
+        }
+
+        AllocatableValue input = getLIRGen().asAllocatable(inputVal);
+        /*
+         * Conversions between integer to floating point types require moves between CPU and FPU
+         * registers.
+         */
+        AMD64Kind fromKind = (AMD64Kind) from.getPlatformKind();
+        switch ((AMD64Kind) to.getPlatformKind()) {
+            case DWORD:
+                switch (fromKind) {
+                    case SINGLE:
+                        return emitConvertOp(to, AMD64MROp.MOVD, DWORD, input);
+                }
+                break;
+            case QWORD:
+                switch (fromKind) {
+                    case DOUBLE:
+                        return emitConvertOp(to, AMD64MROp.MOVQ, QWORD, input);
+                }
+                break;
+            case SINGLE:
+                switch (fromKind) {
+                    case DWORD:
+                        return emitConvertOp(to, AMD64RMOp.MOVD, DWORD, input);
+                }
+                break;
+            case DOUBLE:
+                switch (fromKind) {
+                    case QWORD:
+                        return emitConvertOp(to, AMD64RMOp.MOVQ, QWORD, input);
+                }
+                break;
+        }
+        throw JVMCIError.shouldNotReachHere();
+    }
+
+    public Value emitFloatConvert(FloatConvert op, Value input) {
+        switch (op) {
+            case D2F:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSD2SS, SD, input);
+            case D2I:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSD2SI, DWORD, input);
+            case D2L:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSD2SI, QWORD, input);
+            case F2D:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSS2SD, SS, input);
+            case F2I:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSS2SI, DWORD, input);
+            case F2L:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSS2SI, QWORD, input);
+            case I2D:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, DWORD, input);
+            case I2F:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, DWORD, input);
+            case L2D:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, QWORD, input);
+            case L2F:
+                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, QWORD, input);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Value emitNarrow(Value inputVal, int bits) {
+        if (inputVal.getPlatformKind() == AMD64Kind.QWORD && bits <= 32) {
+            // TODO make it possible to reinterpret Long as Int in LIR without move
+            return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), AMD64RMOp.MOV, DWORD, inputVal);
+        } else {
+            return inputVal;
+        }
+    }
+
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (toBits > 32) {
+            // sign extend to 64 bits
+            switch (fromBits) {
+                case 8:
+                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXB, QWORD, inputVal);
+                case 16:
+                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSX, QWORD, inputVal);
+                case 32:
+                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXD, QWORD, inputVal);
+                default:
+                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        } else {
+            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
+            switch (fromBits) {
+                case 8:
+                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSXB, DWORD, inputVal);
+                case 16:
+                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSX, DWORD, inputVal);
+                case 32:
+                    return inputVal;
+                default:
+                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        }
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (fromBits > 32) {
+            assert inputVal.getPlatformKind() == AMD64Kind.QWORD;
+            Variable result = getLIRGen().newVariable(LIRKind.combine(inputVal));
+            long mask = CodeUtil.mask(fromBits);
+            getLIRGen().append(new AMD64Binary.DataOp(AND.getRMOpcode(QWORD), QWORD, result, getLIRGen().asAllocatable(inputVal), JavaConstant.forLong(mask)));
+            return result;
+        } else {
+            LIRKind resultKind = LIRKind.combine(inputVal);
+            if (toBits > 32) {
+                resultKind = resultKind.changeType(AMD64Kind.QWORD);
+            } else {
+                resultKind = resultKind.changeType(AMD64Kind.DWORD);
+            }
+
+            /*
+             * Always emit DWORD operations, even if the resultKind is Long. On AMD64, all DWORD
+             * operations implicitly set the upper half of the register to 0, which is what we want
+             * anyway. Compared to the QWORD oparations, the encoding of the DWORD operations is
+             * sometimes one byte shorter.
+             */
+            switch (fromBits) {
+                case 8:
+                    return emitConvertOp(resultKind, MOVZXB, DWORD, inputVal);
+                case 16:
+                    return emitConvertOp(resultKind, MOVZX, DWORD, inputVal);
+                case 32:
+                    return emitConvertOp(resultKind, MOV, DWORD, inputVal);
+            }
+
+            // odd bit count, fall back on manual masking
+            Variable result = getLIRGen().newVariable(resultKind);
+            JavaConstant mask;
+            if (toBits > 32) {
+                mask = JavaConstant.forLong(CodeUtil.mask(fromBits));
+            } else {
+                mask = JavaConstant.forInt((int) CodeUtil.mask(fromBits));
+            }
+            getLIRGen().append(new AMD64Binary.DataOp(AND.getRMOpcode(DWORD), DWORD, result, getLIRGen().asAllocatable(inputVal), mask));
+            return result;
+        }
+    }
+
+    @Override
+    public Variable emitBitCount(Value value) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
+        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
+        if (value.getPlatformKind() == AMD64Kind.QWORD) {
+            getLIRGen().append(new AMD64Unary.RMOp(POPCNT, QWORD, result, getLIRGen().asAllocatable(value)));
+        } else {
+            getLIRGen().append(new AMD64Unary.RMOp(POPCNT, DWORD, result, getLIRGen().asAllocatable(value)));
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitBitScanForward(Value value) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
+        getLIRGen().append(new AMD64Unary.RMOp(BSF, QWORD, result, getLIRGen().asAllocatable(value)));
+        return result;
+    }
+
+    @Override
+    public Variable emitBitScanReverse(Value value) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
+        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
+        if (value.getPlatformKind() == AMD64Kind.QWORD) {
+            getLIRGen().append(new AMD64Unary.RMOp(BSR, QWORD, result, getLIRGen().asAllocatable(value)));
+        } else {
+            getLIRGen().append(new AMD64Unary.RMOp(BSR, DWORD, result, getLIRGen().asAllocatable(value)));
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitCountLeadingZeros(Value value) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
+        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
+        if (value.getPlatformKind() == AMD64Kind.QWORD) {
+            getLIRGen().append(new AMD64Unary.RMOp(LZCNT, QWORD, result, getLIRGen().asAllocatable(value)));
+        } else {
+            getLIRGen().append(new AMD64Unary.RMOp(LZCNT, DWORD, result, getLIRGen().asAllocatable(value)));
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitCountTrailingZeros(Value value) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
+        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
+        if (value.getPlatformKind() == AMD64Kind.QWORD) {
+            getLIRGen().append(new AMD64Unary.RMOp(TZCNT, QWORD, result, getLIRGen().asAllocatable(value)));
+        } else {
+            getLIRGen().append(new AMD64Unary.RMOp(TZCNT, DWORD, result, getLIRGen().asAllocatable(value)));
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitMathAbs(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        switch ((AMD64Kind) input.getPlatformKind()) {
+            case SINGLE:
+                getLIRGen().append(new AMD64Binary.DataOp(SSEOp.AND, PS, result, getLIRGen().asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)), 16));
+                break;
+            case DOUBLE:
+                getLIRGen().append(new AMD64Binary.DataOp(SSEOp.AND, PD, result, getLIRGen().asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)), 16));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitMathSqrt(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        switch ((AMD64Kind) input.getPlatformKind()) {
+            case SINGLE:
+                getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, getLIRGen().asAllocatable(input)));
+                break;
+            case DOUBLE:
+                getLIRGen().append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, getLIRGen().asAllocatable(input)));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitMathLog(Value input, boolean base10) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        getLIRGen().append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, getLIRGen().asAllocatable(input)));
+        return result;
+    }
+
+    @Override
+    public Value emitMathCos(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        getLIRGen().append(new AMD64MathIntrinsicOp(COS, result, getLIRGen().asAllocatable(input)));
+        return result;
+    }
+
+    @Override
+    public Value emitMathSin(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        getLIRGen().append(new AMD64MathIntrinsicOp(SIN, result, getLIRGen().asAllocatable(input)));
+        return result;
+    }
+
+    @Override
+    public Value emitMathTan(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        getLIRGen().append(new AMD64MathIntrinsicOp(TAN, result, getLIRGen().asAllocatable(input)));
+        return result;
+    }
+}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,34 +23,14 @@
 
 package com.oracle.graal.compiler.amd64;
 
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.CMP;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NEG;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.NOT;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSF;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.LZCNT;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOV;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSS;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZX;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVZXB;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.POPCNT;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TEST;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TESTB;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TZCNT;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROL;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.ROR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SAR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHL;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHR;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.BYTE;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PD;
@@ -62,52 +42,37 @@
 import static com.oracle.graal.lir.LIRValueUtil.asConstantValue;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static com.oracle.graal.lir.amd64.AMD64Arithmetic.DREM;
-import static com.oracle.graal.lir.amd64.AMD64Arithmetic.FREM;
-import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.COS;
-import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG;
-import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.LOG10;
-import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.SIN;
-import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.TAN;
-import static jdk.internal.jvmci.code.ValueUtil.isAllocatableValue;
-import static jdk.internal.jvmci.code.ValueUtil.isRegister;
-import static jdk.internal.jvmci.code.ValueUtil.isStackSlotValue;
+import static com.oracle.graal.lir.LIRValueUtil.isStackSlotValue;
+import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
 
 import java.util.HashMap;
 import java.util.Map;
 
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.amd64.AMD64Kind;
-import jdk.internal.jvmci.code.Architecture;
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.CodeUtil;
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.code.RegisterValue;
-import jdk.internal.jvmci.code.StackSlotValue;
-import jdk.internal.jvmci.code.VirtualStackSlot;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.PlatformKind;
-import jdk.internal.jvmci.meta.Value;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
 
 import com.oracle.graal.asm.NumUtil;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift;
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
 import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp;
 import com.oracle.graal.compiler.common.calc.Condition;
-import com.oracle.graal.compiler.common.calc.FloatConvert;
 import com.oracle.graal.compiler.common.spi.ForeignCallLinkage;
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 import com.oracle.graal.compiler.common.util.Util;
@@ -119,15 +84,12 @@
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.SwitchStrategy;
 import com.oracle.graal.lir.Variable;
+import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.amd64.AMD64AddressValue;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp;
-import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGenerator;
 import com.oracle.graal.lir.amd64.AMD64ArrayEqualsOp;
-import com.oracle.graal.lir.amd64.AMD64Binary;
 import com.oracle.graal.lir.amd64.AMD64BinaryConsumer;
 import com.oracle.graal.lir.amd64.AMD64ByteSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Call;
-import com.oracle.graal.lir.amd64.AMD64ClearRegisterOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
@@ -136,7 +98,6 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
 import com.oracle.graal.lir.amd64.AMD64LIRInstruction;
-import com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp;
 import com.oracle.graal.lir.amd64.AMD64Move;
 import com.oracle.graal.lir.amd64.AMD64Move.AMD64PushPopStackMove;
 import com.oracle.graal.lir.amd64.AMD64Move.AMD64StackMove;
@@ -148,9 +109,6 @@
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
-import com.oracle.graal.lir.amd64.AMD64MulDivOp;
-import com.oracle.graal.lir.amd64.AMD64ShiftOp;
-import com.oracle.graal.lir.amd64.AMD64SignExtendOp;
 import com.oracle.graal.lir.amd64.AMD64Unary;
 import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
@@ -161,18 +119,16 @@
 /**
  * This class implements the AMD64 specific portion of the LIR generator.
  */
-public abstract class AMD64LIRGenerator extends LIRGenerator implements AMD64ArithmeticLIRGenerator {
-
-    private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD));
+public abstract class AMD64LIRGenerator extends LIRGenerator {
 
     private AMD64SpillMoveFactory moveFactory;
     private Map<PlatformKind.Key, RegisterBackupPair> categorized;
 
     private static class RegisterBackupPair {
         public final Register register;
-        public final StackSlotValue backupSlot;
+        public final VirtualStackSlot backupSlot;
 
-        RegisterBackupPair(Register register, StackSlotValue backupSlot) {
+        RegisterBackupPair(Register register, VirtualStackSlot backupSlot) {
             this.register = register;
             this.backupSlot = backupSlot;
         }
@@ -196,8 +152,8 @@
         }
     }
 
-    public AMD64LIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        super(lirKindTool, providers, cc, lirGenRes);
+    public AMD64LIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
+        super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes);
     }
 
     public SpillMoveFactory getSpillMoveFactory() {
@@ -287,12 +243,12 @@
             default:
                 RegisterBackupPair backup = getScratchRegister(input.getPlatformKind());
                 Register scratchRegister = backup.register;
-                StackSlotValue backupSlot = backup.backupSlot;
+                VirtualStackSlot backupSlot = backup.backupSlot;
                 return createStackMove(result, input, scratchRegister, backupSlot);
         }
     }
 
-    protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input, Register scratchRegister, StackSlotValue backupSlot) {
+    protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input, Register scratchRegister, AllocatableValue backupSlot) {
         return new AMD64StackMove(result, input, scratchRegister, backupSlot);
     }
 
@@ -354,9 +310,9 @@
     }
 
     @Override
-    public Variable emitAddress(StackSlotValue address) {
+    public Variable emitAddress(AllocatableValue stackslot) {
         Variable result = newVariable(LIRKind.value(target().arch.getWordKind()));
-        append(new StackLeaOp(result, address));
+        append(new StackLeaOp(result, stackslot));
         return result;
     }
 
@@ -727,679 +683,6 @@
     }
 
     @Override
-    public Variable emitNegate(Value inputVal) {
-        AllocatableValue input = asAllocatable(inputVal);
-        Variable result = newVariable(LIRKind.combine(input));
-        switch ((AMD64Kind) input.getPlatformKind()) {
-            case DWORD:
-                append(new AMD64Unary.MOp(NEG, DWORD, result, input));
-                break;
-            case QWORD:
-                append(new AMD64Unary.MOp(NEG, QWORD, result, input));
-                break;
-            case SINGLE:
-                append(new AMD64Binary.DataOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16));
-                break;
-            case DOUBLE:
-                append(new AMD64Binary.DataOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitNot(Value inputVal) {
-        AllocatableValue input = asAllocatable(inputVal);
-        Variable result = newVariable(LIRKind.combine(input));
-        switch ((AMD64Kind) input.getPlatformKind()) {
-            case DWORD:
-                append(new AMD64Unary.MOp(NOT, DWORD, result, input));
-                break;
-            case QWORD:
-                append(new AMD64Unary.MOp(NOT, QWORD, result, input));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    private Variable emitBinary(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, Value a, Value b, boolean setFlags) {
-        if (isJavaConstant(b)) {
-            return emitBinaryConst(resultKind, op, size, commutative, asAllocatable(a), asConstantValue(b), setFlags);
-        } else if (commutative && isJavaConstant(a)) {
-            return emitBinaryConst(resultKind, op, size, commutative, asAllocatable(b), asConstantValue(a), setFlags);
-        } else {
-            return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, asAllocatable(a), asAllocatable(b));
-        }
-    }
-
-    private Variable emitBinary(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, Value a, Value b) {
-        if (isJavaConstant(b)) {
-            return emitBinaryConst(resultKind, op, size, asAllocatable(a), asJavaConstant(b));
-        } else if (commutative && isJavaConstant(a)) {
-            return emitBinaryConst(resultKind, op, size, asAllocatable(b), asJavaConstant(a));
-        } else {
-            return emitBinaryVar(resultKind, op, size, commutative, asAllocatable(a), asAllocatable(b));
-        }
-    }
-
-    private Variable emitBinaryConst(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, ConstantValue b, boolean setFlags) {
-        long value = b.getJavaConstant().asLong();
-        if (NumUtil.isInt(value)) {
-            Variable result = newVariable(resultKind);
-            int constant = (int) value;
-
-            if (!setFlags) {
-                AMD64MOp mop = getMOp(op, constant);
-                if (mop != null) {
-                    append(new AMD64Unary.MOp(mop, size, result, a));
-                    return result;
-                }
-            }
-
-            append(new AMD64Binary.ConstOp(op, size, result, a, constant));
-            return result;
-        } else {
-            return emitBinaryVar(resultKind, op.getRMOpcode(size), size, commutative, a, asAllocatable(b));
-        }
-    }
-
-    private static AMD64MOp getMOp(AMD64BinaryArithmetic op, int constant) {
-        if (constant == 1) {
-            if (op.equals(AMD64BinaryArithmetic.ADD)) {
-                return AMD64MOp.INC;
-            }
-            if (op.equals(AMD64BinaryArithmetic.SUB)) {
-                return AMD64MOp.DEC;
-            }
-        } else if (constant == -1) {
-            if (op.equals(AMD64BinaryArithmetic.ADD)) {
-                return AMD64MOp.DEC;
-            }
-            if (op.equals(AMD64BinaryArithmetic.SUB)) {
-                return AMD64MOp.INC;
-            }
-        }
-        return null;
-    }
-
-    private Variable emitBinaryConst(LIRKind resultKind, AMD64RMOp op, OperandSize size, AllocatableValue a, JavaConstant b) {
-        Variable result = newVariable(resultKind);
-        append(new AMD64Binary.DataOp(op, size, result, a, b));
-        return result;
-    }
-
-    private Variable emitBinaryVar(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) {
-        Variable result = newVariable(resultKind);
-        if (commutative) {
-            append(new AMD64Binary.CommutativeOp(op, size, result, a, b));
-        } else {
-            append(new AMD64Binary.Op(op, size, result, a, b));
-        }
-        return result;
-    }
-
-    @Override
-    protected boolean isNumericInteger(PlatformKind kind) {
-        return ((AMD64Kind) kind).isInteger();
-    }
-
-    @Override
-    public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags);
-            case QWORD:
-                return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags);
-            case SINGLE:
-                return emitBinary(resultKind, SSEOp.ADD, SS, true, a, b);
-            case DOUBLE:
-                return emitBinary(resultKind, SSEOp.ADD, SD, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitBinary(resultKind, SUB, DWORD, false, a, b, setFlags);
-            case QWORD:
-                return emitBinary(resultKind, SUB, QWORD, false, a, b, setFlags);
-            case SINGLE:
-                return emitBinary(resultKind, SSEOp.SUB, SS, false, a, b);
-            case DOUBLE:
-                return emitBinary(resultKind, SSEOp.SUB, SD, false, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    private Variable emitIMULConst(OperandSize size, AllocatableValue a, ConstantValue b) {
-        long value = b.getJavaConstant().asLong();
-        if (NumUtil.isInt(value)) {
-            int imm = (int) value;
-            AMD64RMIOp op;
-            if (NumUtil.isByte(imm)) {
-                op = AMD64RMIOp.IMUL_SX;
-            } else {
-                op = AMD64RMIOp.IMUL;
-            }
-
-            Variable ret = newVariable(LIRKind.combine(a, b));
-            append(new AMD64Binary.RMIOp(op, size, ret, a, imm));
-            return ret;
-        } else {
-            return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, a, asAllocatable(b));
-        }
-    }
-
-    private Variable emitIMUL(OperandSize size, Value a, Value b) {
-        if (isJavaConstant(b)) {
-            return emitIMULConst(size, asAllocatable(a), asConstantValue(b));
-        } else if (isJavaConstant(a)) {
-            return emitIMULConst(size, asAllocatable(b), asConstantValue(a));
-        } else {
-            return emitBinaryVar(LIRKind.combine(a, b), AMD64RMOp.IMUL, size, true, asAllocatable(a), asAllocatable(b));
-        }
-    }
-
-    @Override
-    public Variable emitMul(Value a, Value b, boolean setFlags) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitIMUL(DWORD, a, b);
-            case QWORD:
-                return emitIMUL(QWORD, a, b);
-            case SINGLE:
-                return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SS, true, a, b);
-            case DOUBLE:
-                return emitBinary(LIRKind.combine(a, b), SSEOp.MUL, SD, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    private RegisterValue moveToReg(Register reg, Value v) {
-        RegisterValue ret = reg.asValue(v.getLIRKind());
-        emitMove(ret, v);
-        return ret;
-    }
-
-    private Value emitMulHigh(AMD64MOp opcode, OperandSize size, Value a, Value b) {
-        AMD64MulDivOp mulHigh = append(new AMD64MulDivOp(opcode, size, LIRKind.combine(a, b), moveToReg(AMD64.rax, a), asAllocatable(b)));
-        return emitMove(mulHigh.getHighResult());
-    }
-
-    @Override
-    public Value emitMulHigh(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitMulHigh(AMD64MOp.IMUL, DWORD, a, b);
-            case QWORD:
-                return emitMulHigh(AMD64MOp.IMUL, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Value emitUMulHigh(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitMulHigh(AMD64MOp.MUL, DWORD, a, b);
-            case QWORD:
-                return emitMulHigh(AMD64MOp.MUL, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
-        Variable result = newVariable(LIRKind.combine(a));
-        append(new AMD64Binary.MemoryOp(op, size, result, a, location, state));
-        return result;
-    }
-
-    protected Value emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, AMD64AddressValue address, LIRFrameState state) {
-        Variable result = newVariable(LIRKind.value(kind));
-        append(new AMD64Unary.MemoryOp(op, size, result, address, state));
-        return result;
-    }
-
-    protected Value emitZeroExtendMemory(AMD64Kind memoryKind, int resultBits, AMD64AddressValue address, LIRFrameState state) {
-        // Issue a zero extending load of the proper bit size and set the result to
-        // the proper kind.
-        Variable result = newVariable(LIRKind.value(resultBits == 32 ? AMD64Kind.DWORD : AMD64Kind.QWORD));
-        switch (memoryKind) {
-            case BYTE:
-                append(new AMD64Unary.MemoryOp(MOVZXB, DWORD, result, address, state));
-                break;
-            case WORD:
-                append(new AMD64Unary.MemoryOp(MOVZX, DWORD, result, address, state));
-                break;
-            case DWORD:
-                append(new AMD64Unary.MemoryOp(MOV, DWORD, result, address, state));
-                break;
-            case QWORD:
-                append(new AMD64Unary.MemoryOp(MOV, QWORD, result, address, state));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    private AMD64MulDivOp emitIDIV(OperandSize size, Value a, Value b, LIRFrameState state) {
-        LIRKind kind = LIRKind.combine(a, b);
-
-        AMD64SignExtendOp sx = append(new AMD64SignExtendOp(size, kind, moveToReg(AMD64.rax, a)));
-        return append(new AMD64MulDivOp(AMD64MOp.IDIV, size, kind, sx.getHighResult(), sx.getLowResult(), asAllocatable(b), state));
-    }
-
-    private AMD64MulDivOp emitDIV(OperandSize size, Value a, Value b, LIRFrameState state) {
-        LIRKind kind = LIRKind.combine(a, b);
-
-        RegisterValue rax = moveToReg(AMD64.rax, a);
-        RegisterValue rdx = AMD64.rdx.asValue(kind);
-        append(new AMD64ClearRegisterOp(size, rdx));
-        return append(new AMD64MulDivOp(AMD64MOp.DIV, size, kind, rdx, rax, asAllocatable(b), state));
-    }
-
-    public Value[] emitIntegerDivRem(Value a, Value b, LIRFrameState state) {
-        AMD64MulDivOp op;
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                op = emitIDIV(DWORD, a, b, state);
-                break;
-            case QWORD:
-                op = emitIDIV(QWORD, a, b, state);
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return new Value[]{emitMove(op.getQuotient()), emitMove(op.getRemainder())};
-    }
-
-    @Override
-    public Value emitDiv(Value a, Value b, LIRFrameState state) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                AMD64MulDivOp op = emitIDIV(DWORD, a, b, state);
-                return emitMove(op.getQuotient());
-            case QWORD:
-                AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state);
-                return emitMove(lop.getQuotient());
-            case SINGLE:
-                return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SS, false, a, b);
-            case DOUBLE:
-                return emitBinary(LIRKind.combine(a, b), SSEOp.DIV, SD, false, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Value emitRem(Value a, Value b, LIRFrameState state) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                AMD64MulDivOp op = emitIDIV(DWORD, a, b, state);
-                return emitMove(op.getRemainder());
-            case QWORD:
-                AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state);
-                return emitMove(lop.getRemainder());
-            case SINGLE: {
-                Variable result = newVariable(LIRKind.combine(a, b));
-                append(new FPDivRemOp(FREM, result, load(a), load(b)));
-                return result;
-            }
-            case DOUBLE: {
-                Variable result = newVariable(LIRKind.combine(a, b));
-                append(new FPDivRemOp(DREM, result, load(a), load(b)));
-                return result;
-            }
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitUDiv(Value a, Value b, LIRFrameState state) {
-        AMD64MulDivOp op;
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                op = emitDIV(DWORD, a, b, state);
-                break;
-            case QWORD:
-                op = emitDIV(QWORD, a, b, state);
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return emitMove(op.getQuotient());
-    }
-
-    @Override
-    public Variable emitURem(Value a, Value b, LIRFrameState state) {
-        AMD64MulDivOp op;
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                op = emitDIV(DWORD, a, b, state);
-                break;
-            case QWORD:
-                op = emitDIV(QWORD, a, b, state);
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return emitMove(op.getRemainder());
-    }
-
-    @Override
-    public Variable emitAnd(Value a, Value b) {
-        LIRKind resultKind = LIRKind.combine(a, b);
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitBinary(resultKind, AND, DWORD, true, a, b, false);
-            case QWORD:
-                return emitBinary(resultKind, AND, QWORD, true, a, b, false);
-            case SINGLE:
-                return emitBinary(resultKind, SSEOp.AND, PS, true, a, b);
-            case DOUBLE:
-                return emitBinary(resultKind, SSEOp.AND, PD, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitOr(Value a, Value b) {
-        LIRKind resultKind = LIRKind.combine(a, b);
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitBinary(resultKind, OR, DWORD, true, a, b, false);
-            case QWORD:
-                return emitBinary(resultKind, OR, QWORD, true, a, b, false);
-            case SINGLE:
-                return emitBinary(resultKind, SSEOp.OR, PS, true, a, b);
-            case DOUBLE:
-                return emitBinary(resultKind, SSEOp.OR, PD, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitXor(Value a, Value b) {
-        LIRKind resultKind = LIRKind.combine(a, b);
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitBinary(resultKind, XOR, DWORD, true, a, b, false);
-            case QWORD:
-                return emitBinary(resultKind, XOR, QWORD, true, a, b, false);
-            case SINGLE:
-                return emitBinary(resultKind, SSEOp.XOR, PS, true, a, b);
-            case DOUBLE:
-                return emitBinary(resultKind, SSEOp.XOR, PD, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    private Variable emitShift(AMD64Shift op, OperandSize size, Value a, Value b) {
-        Variable result = newVariable(LIRKind.combine(a, b).changeType(a.getPlatformKind()));
-        AllocatableValue input = asAllocatable(a);
-        if (isJavaConstant(b)) {
-            JavaConstant c = asJavaConstant(b);
-            if (c.asLong() == 1) {
-                append(new AMD64Unary.MOp(op.m1Op, size, result, input));
-            } else {
-                /*
-                 * c is implicitly masked to 5 or 6 bits by the CPU, so casting it to (int) is
-                 * always correct, even without the NumUtil.is32bit() test.
-                 */
-                append(new AMD64Binary.ConstOp(op.miOp, size, result, input, (int) c.asLong()));
-            }
-        } else {
-            emitMove(RCX_I, b);
-            append(new AMD64ShiftOp(op.mcOp, size, result, input, RCX_I));
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitShl(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitShift(SHL, DWORD, a, b);
-            case QWORD:
-                return emitShift(SHL, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitShr(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitShift(SAR, DWORD, a, b);
-            case QWORD:
-                return emitShift(SAR, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitUShr(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitShift(SHR, DWORD, a, b);
-            case QWORD:
-                return emitShift(SHR, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    public Variable emitRol(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitShift(ROL, DWORD, a, b);
-            case QWORD:
-                return emitShift(ROL, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    public Variable emitRor(Value a, Value b) {
-        switch ((AMD64Kind) a.getPlatformKind()) {
-            case DWORD:
-                return emitShift(ROR, DWORD, a, b);
-            case QWORD:
-                return emitShift(ROR, QWORD, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) {
-        Variable result = newVariable(kind);
-        append(new AMD64Unary.RMOp(op, size, result, asAllocatable(input)));
-        return result;
-    }
-
-    private AllocatableValue emitConvertOp(LIRKind kind, AMD64MROp op, OperandSize size, Value input) {
-        Variable result = newVariable(kind);
-        append(new AMD64Unary.MROp(op, size, result, asAllocatable(input)));
-        return result;
-    }
-
-    @Override
-    public Value emitReinterpret(LIRKind to, Value inputVal) {
-        LIRKind from = inputVal.getLIRKind();
-        if (to.equals(from)) {
-            return inputVal;
-        }
-
-        AllocatableValue input = asAllocatable(inputVal);
-        /*
-         * Conversions between integer to floating point types require moves between CPU and FPU
-         * registers.
-         */
-        AMD64Kind fromKind = (AMD64Kind) from.getPlatformKind();
-        switch ((AMD64Kind) to.getPlatformKind()) {
-            case DWORD:
-                switch (fromKind) {
-                    case SINGLE:
-                        return emitConvertOp(to, AMD64MROp.MOVD, DWORD, input);
-                }
-                break;
-            case QWORD:
-                switch (fromKind) {
-                    case DOUBLE:
-                        return emitConvertOp(to, AMD64MROp.MOVQ, QWORD, input);
-                }
-                break;
-            case SINGLE:
-                switch (fromKind) {
-                    case DWORD:
-                        return emitConvertOp(to, AMD64RMOp.MOVD, DWORD, input);
-                }
-                break;
-            case DOUBLE:
-                switch (fromKind) {
-                    case QWORD:
-                        return emitConvertOp(to, AMD64RMOp.MOVQ, QWORD, input);
-                }
-                break;
-        }
-        throw JVMCIError.shouldNotReachHere();
-    }
-
-    public Value emitFloatConvert(FloatConvert op, Value input) {
-        switch (op) {
-            case D2F:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSD2SS, SD, input);
-            case D2I:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSD2SI, DWORD, input);
-            case D2L:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSD2SI, QWORD, input);
-            case F2D:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSS2SD, SS, input);
-            case F2I:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DWORD), SSEOp.CVTTSS2SI, DWORD, input);
-            case F2L:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.QWORD), SSEOp.CVTTSS2SI, QWORD, input);
-            case I2D:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, DWORD, input);
-            case I2F:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, DWORD, input);
-            case L2D:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.DOUBLE), SSEOp.CVTSI2SD, QWORD, input);
-            case L2F:
-                return emitConvertOp(LIRKind.combine(input).changeType(AMD64Kind.SINGLE), SSEOp.CVTSI2SS, QWORD, input);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Value emitNarrow(Value inputVal, int bits) {
-        if (inputVal.getPlatformKind() == AMD64Kind.QWORD && bits <= 32) {
-            // TODO make it possible to reinterpret Long as Int in LIR without move
-            return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), AMD64RMOp.MOV, DWORD, inputVal);
-        } else {
-            return inputVal;
-        }
-    }
-
-    @Override
-    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
-        assert fromBits <= toBits && toBits <= 64;
-        if (fromBits == toBits) {
-            return inputVal;
-        } else if (toBits > 32) {
-            // sign extend to 64 bits
-            switch (fromBits) {
-                case 8:
-                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXB, QWORD, inputVal);
-                case 16:
-                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSX, QWORD, inputVal);
-                case 32:
-                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.QWORD), MOVSXD, QWORD, inputVal);
-                default:
-                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
-            }
-        } else {
-            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
-            switch (fromBits) {
-                case 8:
-                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSXB, DWORD, inputVal);
-                case 16:
-                    return emitConvertOp(LIRKind.combine(inputVal).changeType(AMD64Kind.DWORD), MOVSX, DWORD, inputVal);
-                case 32:
-                    return inputVal;
-                default:
-                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
-            }
-        }
-    }
-
-    @Override
-    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
-        assert fromBits <= toBits && toBits <= 64;
-        if (fromBits == toBits) {
-            return inputVal;
-        } else if (fromBits > 32) {
-            assert inputVal.getPlatformKind() == AMD64Kind.QWORD;
-            Variable result = newVariable(LIRKind.combine(inputVal));
-            long mask = CodeUtil.mask(fromBits);
-            append(new AMD64Binary.DataOp(AND.getRMOpcode(QWORD), QWORD, result, asAllocatable(inputVal), JavaConstant.forLong(mask)));
-            return result;
-        } else {
-            LIRKind resultKind = LIRKind.combine(inputVal);
-            if (toBits > 32) {
-                resultKind = resultKind.changeType(AMD64Kind.QWORD);
-            } else {
-                resultKind = resultKind.changeType(AMD64Kind.DWORD);
-            }
-
-            /*
-             * Always emit DWORD operations, even if the resultKind is Long. On AMD64, all DWORD
-             * operations implicitly set the upper half of the register to 0, which is what we want
-             * anyway. Compared to the QWORD oparations, the encoding of the DWORD operations is
-             * sometimes one byte shorter.
-             */
-            switch (fromBits) {
-                case 8:
-                    return emitConvertOp(resultKind, MOVZXB, DWORD, inputVal);
-                case 16:
-                    return emitConvertOp(resultKind, MOVZX, DWORD, inputVal);
-                case 32:
-                    return emitConvertOp(resultKind, MOV, DWORD, inputVal);
-            }
-
-            // odd bit count, fall back on manual masking
-            Variable result = newVariable(resultKind);
-            JavaConstant mask;
-            if (toBits > 32) {
-                mask = JavaConstant.forLong(CodeUtil.mask(fromBits));
-            } else {
-                mask = JavaConstant.forInt((int) CodeUtil.mask(fromBits));
-            }
-            append(new AMD64Binary.DataOp(AND.getRMOpcode(DWORD), DWORD, result, asAllocatable(inputVal), mask));
-            return result;
-        }
-    }
-
-    @Override
     public void emitMembar(int barriers) {
         int necessaryBarriers = target().arch.requiredBarriers(barriers);
         if (target().isMP && necessaryBarriers != 0) {
@@ -1420,119 +703,6 @@
     }
 
     @Override
-    public Variable emitBitCount(Value value) {
-        Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
-        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
-        if (value.getPlatformKind() == AMD64Kind.QWORD) {
-            append(new AMD64Unary.RMOp(POPCNT, QWORD, result, asAllocatable(value)));
-        } else {
-            append(new AMD64Unary.RMOp(POPCNT, DWORD, result, asAllocatable(value)));
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitBitScanForward(Value value) {
-        Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
-        append(new AMD64Unary.RMOp(BSF, QWORD, result, asAllocatable(value)));
-        return result;
-    }
-
-    @Override
-    public Variable emitBitScanReverse(Value value) {
-        Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
-        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
-        if (value.getPlatformKind() == AMD64Kind.QWORD) {
-            append(new AMD64Unary.RMOp(BSR, QWORD, result, asAllocatable(value)));
-        } else {
-            append(new AMD64Unary.RMOp(BSR, DWORD, result, asAllocatable(value)));
-        }
-        return result;
-    }
-
-    public Value emitCountLeadingZeros(Value value) {
-        Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
-        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
-        if (value.getPlatformKind() == AMD64Kind.QWORD) {
-            append(new AMD64Unary.RMOp(LZCNT, QWORD, result, asAllocatable(value)));
-        } else {
-            append(new AMD64Unary.RMOp(LZCNT, DWORD, result, asAllocatable(value)));
-        }
-        return result;
-    }
-
-    public Value emitCountTrailingZeros(Value value) {
-        Variable result = newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
-        assert ((AMD64Kind) value.getPlatformKind()).isInteger();
-        if (value.getPlatformKind() == AMD64Kind.QWORD) {
-            append(new AMD64Unary.RMOp(TZCNT, QWORD, result, asAllocatable(value)));
-        } else {
-            append(new AMD64Unary.RMOp(TZCNT, DWORD, result, asAllocatable(value)));
-        }
-        return result;
-    }
-
-    @Override
-    public Value emitMathAbs(Value input) {
-        Variable result = newVariable(LIRKind.combine(input));
-        switch ((AMD64Kind) input.getPlatformKind()) {
-            case SINGLE:
-                append(new AMD64Binary.DataOp(SSEOp.AND, PS, result, asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)), 16));
-                break;
-            case DOUBLE:
-                append(new AMD64Binary.DataOp(SSEOp.AND, PD, result, asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)), 16));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Value emitMathSqrt(Value input) {
-        Variable result = newVariable(LIRKind.combine(input));
-        switch ((AMD64Kind) input.getPlatformKind()) {
-            case SINGLE:
-                append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, asAllocatable(input)));
-                break;
-            case DOUBLE:
-                append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, asAllocatable(input)));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Value emitMathLog(Value input, boolean base10) {
-        Variable result = newVariable(LIRKind.combine(input));
-        append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, asAllocatable(input)));
-        return result;
-    }
-
-    @Override
-    public Value emitMathCos(Value input) {
-        Variable result = newVariable(LIRKind.combine(input));
-        append(new AMD64MathIntrinsicOp(COS, result, asAllocatable(input)));
-        return result;
-    }
-
-    @Override
-    public Value emitMathSin(Value input) {
-        Variable result = newVariable(LIRKind.combine(input));
-        append(new AMD64MathIntrinsicOp(SIN, result, asAllocatable(input)));
-        return result;
-    }
-
-    @Override
-    public Value emitMathTan(Value input) {
-        Variable result = newVariable(LIRKind.combine(input));
-        append(new AMD64MathIntrinsicOp(TAN, result, asAllocatable(input)));
-        return result;
-    }
-
-    @Override
     public Variable emitByteSwap(Value input) {
         Variable result = newVariable(LIRKind.combine(input));
         append(new AMD64ByteSwapOp(result, input));
@@ -1571,5 +741,4 @@
     protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
         append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(LIRKind.value(target().arch.getWordKind())), newVariable(key.getLIRKind())));
     }
-
 }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRKindTool.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRKindTool.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.compiler.amd64;
 
-import jdk.internal.jvmci.amd64.AMD64Kind;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.LIRKind;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.LIRKind;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,50 +23,18 @@
 
 package com.oracle.graal.compiler.amd64;
 
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS;
-import jdk.internal.jvmci.amd64.AMD64;
-import jdk.internal.jvmci.amd64.AMD64Kind;
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.JavaType;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.PlatformKind;
-import jdk.internal.jvmci.meta.Value;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.Value;
 
-import com.oracle.graal.asm.NumUtil;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp;
-import com.oracle.graal.compiler.common.calc.Condition;
 import com.oracle.graal.compiler.gen.NodeLIRBuilder;
-import com.oracle.graal.compiler.match.ComplexMatchResult;
-import com.oracle.graal.compiler.match.MatchRule;
-import com.oracle.graal.debug.Debug;
 import com.oracle.graal.lir.LIRFrameState;
-import com.oracle.graal.lir.LabelRef;
-import com.oracle.graal.lir.amd64.AMD64AddressValue;
-import com.oracle.graal.lir.amd64.AMD64BinaryConsumer;
 import com.oracle.graal.lir.amd64.AMD64BreakpointOp;
 import com.oracle.graal.lir.amd64.AMD64Call;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
 import com.oracle.graal.lir.gen.LIRGeneratorTool;
 import com.oracle.graal.nodes.BreakpointNode;
-import com.oracle.graal.nodes.ConstantNode;
 import com.oracle.graal.nodes.DeoptimizingNode;
 import com.oracle.graal.nodes.FixedNode;
 import com.oracle.graal.nodes.FixedWithNextNode;
@@ -74,25 +42,14 @@
 import com.oracle.graal.nodes.IndirectCallTargetNode;
 import com.oracle.graal.nodes.StructuredGraph;
 import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.calc.CompareNode;
 import com.oracle.graal.nodes.calc.FixedBinaryNode;
-import com.oracle.graal.nodes.calc.FloatConvertNode;
 import com.oracle.graal.nodes.calc.IntegerDivNode;
 import com.oracle.graal.nodes.calc.IntegerRemNode;
-import com.oracle.graal.nodes.calc.LeftShiftNode;
-import com.oracle.graal.nodes.calc.NarrowNode;
-import com.oracle.graal.nodes.calc.ReinterpretNode;
-import com.oracle.graal.nodes.calc.SignExtendNode;
-import com.oracle.graal.nodes.calc.UnsignedRightShiftNode;
-import com.oracle.graal.nodes.calc.ZeroExtendNode;
-import com.oracle.graal.nodes.extended.UnsafeCastNode;
-import com.oracle.graal.nodes.memory.Access;
-import com.oracle.graal.nodes.memory.WriteNode;
 
 public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
 
-    public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen) {
-        super(graph, gen);
+    public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
+        super(graph, gen, nodeMatchRules);
     }
 
     @Override
@@ -127,7 +84,7 @@
                 if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) {
                     FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode;
                     if (otherDivRem.getX() == divRem.getX() && otherDivRem.getY() == divRem.getY() && !hasOperand(otherDivRem)) {
-                        Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
+                        Value[] results = ((AMD64ArithmeticLIRGenerator) gen.getArithmetic()).emitIntegerDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
                         if (divRem instanceof IntegerDivNode) {
                             setResult(divRem, results[0]);
                             setResult(otherDivRem, results[1]);
@@ -144,352 +101,6 @@
         return false;
     }
 
-    protected LIRFrameState getState(Access access) {
-        if (access instanceof DeoptimizingNode) {
-            return state((DeoptimizingNode) access);
-        }
-        return null;
-    }
-
-    protected AMD64Kind getMemoryKind(Access access) {
-        return (AMD64Kind) gen.getLIRKind(access.asNode().stamp()).getPlatformKind();
-    }
-
-    protected OperandSize getMemorySize(Access access) {
-        switch (getMemoryKind(access)) {
-            case BYTE:
-                return OperandSize.BYTE;
-            case WORD:
-                return OperandSize.WORD;
-            case DWORD:
-                return OperandSize.DWORD;
-            case QWORD:
-                return OperandSize.QWORD;
-            case SINGLE:
-                return OperandSize.SS;
-            case DOUBLE:
-                return OperandSize.SD;
-            default:
-                throw JVMCIError.shouldNotReachHere("unsupported memory access type " + getMemoryKind(access));
-        }
-    }
-
-    protected ValueNode uncast(ValueNode value) {
-        if (value instanceof UnsafeCastNode) {
-            UnsafeCastNode cast = (UnsafeCastNode) value;
-            return cast.getOriginalNode();
-        }
-        return value;
-    }
-
-    protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, Access access) {
-        Condition cond = compare.condition();
-        AMD64Kind kind = getMemoryKind(access);
-
-        if (value.isConstant()) {
-            JavaConstant constant = value.asJavaConstant();
-            if (kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) {
-                // Only imm32 as long
-                return null;
-            }
-            if (kind.isXMM()) {
-                Debug.log("Skipping constant compares for float kinds");
-                return null;
-            }
-            if (constant.getJavaKind() == JavaKind.Object && !constant.isNull()) {
-                Debug.log("Skipping constant compares for Object kinds");
-                return null;
-            }
-        }
-
-        // emitCompareBranchMemory expects the memory on the right, so mirror the condition if
-        // that's not true. It might be mirrored again the actual compare is emitted but that's
-        // ok.
-        Condition finalCondition = uncast(compare.getX()) == access ? cond.mirror() : cond;
-        return new ComplexMatchResult() {
-            public Value evaluate(NodeLIRBuilder builder) {
-                LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
-                LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
-                boolean unorderedIsTrue = compare.unorderedIsTrue();
-                double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
-                Value other;
-                if (value.isConstant()) {
-                    other = gen.emitJavaConstant(value.asJavaConstant());
-                } else {
-                    other = operand(value);
-                }
-
-                AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-                getLIRGeneratorTool().emitCompareBranchMemory(kind, other, address, getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability);
-                return null;
-            }
-        };
-    }
-
-    private ComplexMatchResult emitIntegerTestBranchMemory(IfNode x, ValueNode value, Access access) {
-        LabelRef trueLabel = getLIRBlock(x.trueSuccessor());
-        LabelRef falseLabel = getLIRBlock(x.falseSuccessor());
-        double trueLabelProbability = x.probability(x.trueSuccessor());
-        AMD64Kind kind = getMemoryKind(access);
-        OperandSize size = kind == AMD64Kind.QWORD ? QWORD : DWORD;
-        if (value.isConstant()) {
-            JavaConstant constant = value.asJavaConstant();
-            if (kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) {
-                // Only imm32 as long
-                return null;
-            }
-            return builder -> {
-                AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-                gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, address, (int) constant.asLong(), getState(access)));
-                gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
-                return null;
-            };
-        } else {
-            return builder -> {
-                AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-                gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), address, getState(access)));
-                gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
-                return null;
-            };
-        }
-    }
-
-    protected ComplexMatchResult emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, Access access) {
-        return builder -> {
-            AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-            LIRFrameState state = getState(access);
-            return getLIRGeneratorTool().emitConvertMemoryOp(kind, op, size, address, state);
-        };
-    }
-
-    private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) {
-        assert fromBits <= toBits && toBits <= 64;
-        AMD64Kind kind = null;
-        AMD64RMOp op;
-        OperandSize size;
-        if (fromBits == toBits) {
-            return null;
-        } else if (toBits > 32) {
-            kind = AMD64Kind.QWORD;
-            size = OperandSize.QWORD;
-            // sign extend to 64 bits
-            switch (fromBits) {
-                case 8:
-                    op = MOVSXB;
-                    break;
-                case 16:
-                    op = MOVSX;
-                    break;
-                case 32:
-                    op = MOVSXD;
-                    break;
-                default:
-                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
-            }
-        } else {
-            kind = AMD64Kind.DWORD;
-            size = OperandSize.DWORD;
-            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
-            switch (fromBits) {
-                case 8:
-                    op = MOVSXB;
-                    break;
-                case 16:
-                    op = MOVSX;
-                    break;
-                case 32:
-                    return null;
-                default:
-                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
-            }
-        }
-        if (kind != null && op != null) {
-            return emitConvertMemoryOp(kind, op, size, access);
-        }
-        return null;
-    }
-
-    private Value emitReinterpretMemory(LIRKind to, Access access) {
-        AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-        LIRFrameState state = getState(access);
-        return getLIRGeneratorTool().emitLoad(to, address, state);
-    }
-
-    @MatchRule("(If (IntegerTest Read=access value))")
-    @MatchRule("(If (IntegerTest FloatingRead=access value))")
-    public ComplexMatchResult integerTestBranchMemory(IfNode root, Access access, ValueNode value) {
-        return emitIntegerTestBranchMemory(root, value, access);
-    }
-
-    @MatchRule("(If (IntegerEquals=compare value Read=access))")
-    @MatchRule("(If (IntegerLessThan=compare value Read=access))")
-    @MatchRule("(If (IntegerBelow=compare value Read=access))")
-    @MatchRule("(If (IntegerEquals=compare value FloatingRead=access))")
-    @MatchRule("(If (IntegerLessThan=compare value FloatingRead=access))")
-    @MatchRule("(If (IntegerBelow=compare value FloatingRead=access))")
-    @MatchRule("(If (FloatEquals=compare value Read=access))")
-    @MatchRule("(If (FloatEquals=compare value FloatingRead=access))")
-    @MatchRule("(If (FloatLessThan=compare value Read=access))")
-    @MatchRule("(If (FloatLessThan=compare value FloatingRead=access))")
-    public ComplexMatchResult ifCompareMemory(IfNode root, CompareNode compare, ValueNode value, Access access) {
-        return emitCompareBranchMemory(root, compare, value, access);
-    }
-
-    @MatchRule("(Or (LeftShift=lshift value Constant) (UnsignedRightShift=rshift value Constant))")
-    public ComplexMatchResult rotateLeftConstant(LeftShiftNode lshift, UnsignedRightShiftNode rshift) {
-        if ((lshift.getShiftAmountMask() & (lshift.getY().asJavaConstant().asInt() + rshift.getY().asJavaConstant().asInt())) == 0) {
-            return builder -> getLIRGeneratorTool().emitRol(operand(lshift.getX()), operand(lshift.getY()));
-        }
-        return null;
-    }
-
-    @MatchRule("(Or (LeftShift value (Sub Constant=delta shiftAmount)) (UnsignedRightShift value shiftAmount))")
-    public ComplexMatchResult rotateRightVariable(ValueNode value, ConstantNode delta, ValueNode shiftAmount) {
-        if (delta.asJavaConstant().asLong() == 0 || delta.asJavaConstant().asLong() == 32) {
-            return builder -> getLIRGeneratorTool().emitRor(operand(value), operand(shiftAmount));
-        }
-        return null;
-    }
-
-    @MatchRule("(Or (LeftShift value shiftAmount) (UnsignedRightShift value (Sub Constant=delta shiftAmount)))")
-    public ComplexMatchResult rotateLeftVariable(ValueNode value, ValueNode shiftAmount, ConstantNode delta) {
-        if (delta.asJavaConstant().asLong() == 0 || delta.asJavaConstant().asLong() == 32) {
-            return builder -> getLIRGeneratorTool().emitRol(operand(value), operand(shiftAmount));
-        }
-        return null;
-    }
-
-    private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode value, Access access) {
-        return builder -> getLIRGeneratorTool().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), getState(access));
-    }
-
-    @MatchRule("(Add value Read=access)")
-    @MatchRule("(Add value FloatingRead=access)")
-    public ComplexMatchResult addMemory(ValueNode value, Access access) {
-        OperandSize size = getMemorySize(access);
-        if (size.isXmmType()) {
-            return binaryRead(SSEOp.ADD, size, value, access);
-        } else {
-            return binaryRead(ADD.getRMOpcode(size), size, value, access);
-        }
-    }
-
-    @MatchRule("(Sub value Read=access)")
-    @MatchRule("(Sub value FloatingRead=access)")
-    public ComplexMatchResult subMemory(ValueNode value, Access access) {
-        OperandSize size = getMemorySize(access);
-        if (size.isXmmType()) {
-            return binaryRead(SSEOp.SUB, size, value, access);
-        } else {
-            return binaryRead(SUB.getRMOpcode(size), size, value, access);
-        }
-    }
-
-    @MatchRule("(Mul value Read=access)")
-    @MatchRule("(Mul value FloatingRead=access)")
-    public ComplexMatchResult mulMemory(ValueNode value, Access access) {
-        OperandSize size = getMemorySize(access);
-        if (size.isXmmType()) {
-            return binaryRead(SSEOp.MUL, size, value, access);
-        } else {
-            return binaryRead(AMD64RMOp.IMUL, size, value, access);
-        }
-    }
-
-    @MatchRule("(And value Read=access)")
-    @MatchRule("(And value FloatingRead=access)")
-    public ComplexMatchResult andMemory(ValueNode value, Access access) {
-        OperandSize size = getMemorySize(access);
-        if (size.isXmmType()) {
-            return null;
-        } else {
-            return binaryRead(AND.getRMOpcode(size), size, value, access);
-        }
-    }
-
-    @MatchRule("(Or value Read=access)")
-    @MatchRule("(Or value FloatingRead=access)")
-    public ComplexMatchResult orMemory(ValueNode value, Access access) {
-        OperandSize size = getMemorySize(access);
-        if (size.isXmmType()) {
-            return null;
-        } else {
-            return binaryRead(OR.getRMOpcode(size), size, value, access);
-        }
-    }
-
-    @MatchRule("(Xor value Read=access)")
-    @MatchRule("(Xor value FloatingRead=access)")
-    public ComplexMatchResult xorMemory(ValueNode value, Access access) {
-        OperandSize size = getMemorySize(access);
-        if (size.isXmmType()) {
-            return null;
-        } else {
-            return binaryRead(XOR.getRMOpcode(size), size, value, access);
-        }
-    }
-
-    @MatchRule("(Write object Narrow=narrow)")
-    public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
-        return builder -> {
-            LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
-            getLIRGeneratorTool().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
-            return null;
-        };
-    }
-
-    @MatchRule("(SignExtend Read=access)")
-    @MatchRule("(SignExtend FloatingRead=access)")
-    public ComplexMatchResult signExtend(SignExtendNode root, Access access) {
-        return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits());
-    }
-
-    @MatchRule("(ZeroExtend Read=access)")
-    @MatchRule("(ZeroExtend FloatingRead=access)")
-    public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) {
-        AMD64Kind memoryKind = getMemoryKind(access);
-        return builder -> getLIRGeneratorTool().emitZeroExtendMemory(memoryKind, root.getResultBits(), (AMD64AddressValue) operand(access.getAddress()), getState(access));
-    }
-
-    @MatchRule("(FloatConvert Read=access)")
-    @MatchRule("(FloatConvert FloatingRead=access)")
-    public ComplexMatchResult floatConvert(FloatConvertNode root, Access access) {
-        switch (root.getFloatConvert()) {
-            case D2F:
-                return emitConvertMemoryOp(AMD64Kind.SINGLE, SSEOp.CVTSD2SS, SD, access);
-            case D2I:
-                return emitConvertMemoryOp(AMD64Kind.DWORD, SSEOp.CVTTSD2SI, DWORD, access);
-            case D2L:
-                return emitConvertMemoryOp(AMD64Kind.QWORD, SSEOp.CVTTSD2SI, QWORD, access);
-            case F2D:
-                return emitConvertMemoryOp(AMD64Kind.DOUBLE, SSEOp.CVTSS2SD, SS, access);
-            case F2I:
-                return emitConvertMemoryOp(AMD64Kind.DWORD, SSEOp.CVTTSS2SI, DWORD, access);
-            case F2L:
-                return emitConvertMemoryOp(AMD64Kind.QWORD, SSEOp.CVTTSS2SI, QWORD, access);
-            case I2D:
-                return emitConvertMemoryOp(AMD64Kind.DOUBLE, SSEOp.CVTSI2SD, DWORD, access);
-            case I2F:
-                return emitConvertMemoryOp(AMD64Kind.SINGLE, SSEOp.CVTSI2SS, DWORD, access);
-            case L2D:
-                return emitConvertMemoryOp(AMD64Kind.DOUBLE, SSEOp.CVTSI2SD, QWORD, access);
-            case L2F:
-                return emitConvertMemoryOp(AMD64Kind.SINGLE, SSEOp.CVTSI2SS, QWORD, access);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @MatchRule("(Reinterpret Read=access)")
-    @MatchRule("(Reinterpret FloatingRead=access)")
-    public ComplexMatchResult reinterpret(ReinterpretNode root, Access access) {
-        return builder -> {
-            LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp());
-            return emitReinterpretMemory(kind, access);
-        };
-
-    }
-
     @Override
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java	Fri Oct 30 20:56:28 2015 +0100
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.compiler.amd64;
+
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS;
+
+import com.oracle.graal.asm.NumUtil;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
+import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp;
+import com.oracle.graal.compiler.common.calc.Condition;
+import com.oracle.graal.compiler.gen.NodeLIRBuilder;
+import com.oracle.graal.compiler.gen.NodeMatchRules;
+import com.oracle.graal.compiler.match.ComplexMatchResult;
+import com.oracle.graal.compiler.match.MatchRule;
+import com.oracle.graal.debug.Debug;
+import com.oracle.graal.lir.LIRFrameState;
+import com.oracle.graal.lir.LabelRef;
+import com.oracle.graal.lir.amd64.AMD64AddressValue;
+import com.oracle.graal.lir.amd64.AMD64BinaryConsumer;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
+import com.oracle.graal.lir.gen.LIRGeneratorTool;
+import com.oracle.graal.nodes.ConstantNode;
+import com.oracle.graal.nodes.DeoptimizingNode;
+import com.oracle.graal.nodes.IfNode;
+import com.oracle.graal.nodes.ValueNode;
+import com.oracle.graal.nodes.calc.CompareNode;
+import com.oracle.graal.nodes.calc.FloatConvertNode;
+import com.oracle.graal.nodes.calc.LeftShiftNode;
+import com.oracle.graal.nodes.calc.NarrowNode;
+import com.oracle.graal.nodes.calc.ReinterpretNode;
+import com.oracle.graal.nodes.calc.SignExtendNode;
+import com.oracle.graal.nodes.calc.UnsignedRightShiftNode;
+import com.oracle.graal.nodes.calc.ZeroExtendNode;
+import com.oracle.graal.nodes.extended.UnsafeCastNode;
+import com.oracle.graal.nodes.memory.Access;
+import com.oracle.graal.nodes.memory.WriteNode;
+
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
+
+public class AMD64NodeMatchRules extends NodeMatchRules {
+
+    public AMD64NodeMatchRules(LIRGeneratorTool gen) {
+        super(gen);
+    }
+
+    protected LIRFrameState getState(Access access) {
+        if (access instanceof DeoptimizingNode) {
+            return state((DeoptimizingNode) access);
+        }
+        return null;
+    }
+
+    protected AMD64Kind getMemoryKind(Access access) {
+        return (AMD64Kind) gen.getLIRKind(access.asNode().stamp()).getPlatformKind();
+    }
+
+    protected OperandSize getMemorySize(Access access) {
+        switch (getMemoryKind(access)) {
+            case BYTE:
+                return OperandSize.BYTE;
+            case WORD:
+                return OperandSize.WORD;
+            case DWORD:
+                return OperandSize.DWORD;
+            case QWORD:
+                return OperandSize.QWORD;
+            case SINGLE:
+                return OperandSize.SS;
+            case DOUBLE:
+                return OperandSize.SD;
+            default:
+                throw JVMCIError.shouldNotReachHere("unsupported memory access type " + getMemoryKind(access));
+        }
+    }
+
+    protected ValueNode uncast(ValueNode value) {
+        if (value instanceof UnsafeCastNode) {
+            UnsafeCastNode cast = (UnsafeCastNode) value;
+            return cast.getOriginalNode();
+        }
+        return value;
+    }
+
+    protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, Access access) {
+        Condition cond = compare.condition();
+        AMD64Kind kind = getMemoryKind(access);
+
+        if (value.isConstant()) {
+            JavaConstant constant = value.asJavaConstant();
+            if (constant != null && kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) {
+                // Only imm32 as long
+                return null;
+            }
+            if (kind.isXMM()) {
+                Debug.log("Skipping constant compares for float kinds");
+                return null;
+            }
+            if (constant != null && constant.getJavaKind() == JavaKind.Object && !constant.isNull()) {
+                Debug.log("Skipping constant compares for Object kinds");
+                return null;
+            }
+        }
+
+        // emitCompareBranchMemory expects the memory on the right, so mirror the condition if
+        // that's not true. It might be mirrored again the actual compare is emitted but that's
+        // ok.
+        Condition finalCondition = uncast(compare.getX()) == access ? cond.mirror() : cond;
+        return new ComplexMatchResult() {
+            public Value evaluate(NodeLIRBuilder builder) {
+                LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
+                LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
+                boolean unorderedIsTrue = compare.unorderedIsTrue();
+                double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
+                Value other;
+                JavaConstant constant = value.asJavaConstant();
+                if (constant != null) {
+                    other = gen.emitJavaConstant(constant);
+                } else {
+                    other = operand(value);
+                }
+
+                AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
+                getLIRGeneratorTool().emitCompareBranchMemory(kind, other, address, getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability);
+                return null;
+            }
+        };
+    }
+
+    private ComplexMatchResult emitIntegerTestBranchMemory(IfNode x, ValueNode value, Access access) {
+        LabelRef trueLabel = getLIRBlock(x.trueSuccessor());
+        LabelRef falseLabel = getLIRBlock(x.falseSuccessor());
+        double trueLabelProbability = x.probability(x.trueSuccessor());
+        AMD64Kind kind = getMemoryKind(access);
+        OperandSize size = kind == AMD64Kind.QWORD ? QWORD : DWORD;
+        if (value.isConstant()) {
+            JavaConstant constant = value.asJavaConstant();
+            if (constant != null && kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) {
+                // Only imm32 as long
+                return null;
+            }
+            return builder -> {
+                AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
+                gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, address, (int) constant.asLong(), getState(access)));
+                gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
+                return null;
+            };
+        } else {
+            return builder -> {
+                AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
+                gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), address, getState(access)));
+                gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
+                return null;
+            };
+        }
+    }
+
+    protected ComplexMatchResult emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, Access access) {
+        return builder -> {
+            AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
+            LIRFrameState state = getState(access);
+            return getArithmeticLIRGenerator().emitConvertMemoryOp(kind, op, size, address, state);
+        };
+    }
+
+    private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        AMD64Kind kind = null;
+        AMD64RMOp op;
+        OperandSize size;
+        if (fromBits == toBits) {
+            return null;
+        } else if (toBits > 32) {
+            kind = AMD64Kind.QWORD;
+            size = OperandSize.QWORD;
+            // sign extend to 64 bits
+            switch (fromBits) {
+                case 8:
+                    op = MOVSXB;
+                    break;
+                case 16:
+                    op = MOVSX;
+                    break;
+                case 32:
+                    op = MOVSXD;
+                    break;
+                default:
+                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        } else {
+            kind = AMD64Kind.DWORD;
+            size = OperandSize.DWORD;
+            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
+            switch (fromBits) {
+                case 8:
+                    op = MOVSXB;
+                    break;
+                case 16:
+                    op = MOVSX;
+                    break;
+                case 32:
+                    return null;
+                default:
+                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        }
+        if (kind != null && op != null) {
+            return emitConvertMemoryOp(kind, op, size, access);
+        }
+        return null;
+    }
+
+    private Value emitReinterpretMemory(LIRKind to, Access access) {
+        AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
+        LIRFrameState state = getState(access);
+        return getLIRGeneratorTool().emitLoad(to, address, state);
+    }
+
+    @MatchRule("(If (IntegerTest Read=access value))")
+    @MatchRule("(If (IntegerTest FloatingRead=access value))")
+    public ComplexMatchResult integerTestBranchMemory(IfNode root, Access access, ValueNode value) {
+        return emitIntegerTestBranchMemory(root, value, access);
+    }
+
+    @MatchRule("(If (IntegerEquals=compare value Read=access))")
+    @MatchRule("(If (IntegerLessThan=compare value Read=access))")
+    @MatchRule("(If (IntegerBelow=compare value Read=access))")
+    @MatchRule("(If (IntegerEquals=compare value FloatingRead=access))")
+    @MatchRule("(If (IntegerLessThan=compare value FloatingRead=access))")
+    @MatchRule("(If (IntegerBelow=compare value FloatingRead=access))")
+    @MatchRule("(If (FloatEquals=compare value Read=access))")
+    @MatchRule("(If (FloatEquals=compare value FloatingRead=access))")
+    @MatchRule("(If (FloatLessThan=compare value Read=access))")
+    @MatchRule("(If (FloatLessThan=compare value FloatingRead=access))")
+    public ComplexMatchResult ifCompareMemory(IfNode root, CompareNode compare, ValueNode value, Access access) {
+        return emitCompareBranchMemory(root, compare, value, access);
+    }
+
+    @MatchRule("(Or (LeftShift=lshift value Constant) (UnsignedRightShift=rshift value Constant))")
+    public ComplexMatchResult rotateLeftConstant(LeftShiftNode lshift, UnsignedRightShiftNode rshift) {
+        if ((lshift.getShiftAmountMask() & (lshift.getY().asJavaConstant().asInt() + rshift.getY().asJavaConstant().asInt())) == 0) {
+            return builder -> getArithmeticLIRGenerator().emitRol(operand(lshift.getX()), operand(lshift.getY()));
+        }
+        return null;
+    }
+
+    @MatchRule("(Or (LeftShift value (Sub Constant=delta shiftAmount)) (UnsignedRightShift value shiftAmount))")
+    public ComplexMatchResult rotateRightVariable(ValueNode value, ConstantNode delta, ValueNode shiftAmount) {
+        if (delta.asJavaConstant().asLong() == 0 || delta.asJavaConstant().asLong() == 32) {
+            return builder -> getArithmeticLIRGenerator().emitRor(operand(value), operand(shiftAmount));
+        }
+        return null;
+    }
+
+    @MatchRule("(Or (LeftShift value shiftAmount) (UnsignedRightShift value (Sub Constant=delta shiftAmount)))")
+    public ComplexMatchResult rotateLeftVariable(ValueNode value, ValueNode shiftAmount, ConstantNode delta) {
+        if (delta.asJavaConstant().asLong() == 0 || delta.asJavaConstant().asLong() == 32) {
+            return builder -> getArithmeticLIRGenerator().emitRol(operand(value), operand(shiftAmount));
+        }
+        return null;
+    }
+
+    private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode value, Access access) {
+        return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()),
+                        getState(access));
+    }
+
+    @MatchRule("(Add value Read=access)")
+    @MatchRule("(Add value FloatingRead=access)")
+    public ComplexMatchResult addMemory(ValueNode value, Access access) {
+        OperandSize size = getMemorySize(access);
+        if (size.isXmmType()) {
+            return binaryRead(SSEOp.ADD, size, value, access);
+        } else {
+            return binaryRead(ADD.getRMOpcode(size), size, value, access);
+        }
+    }
+
+    @MatchRule("(Sub value Read=access)")
+    @MatchRule("(Sub value FloatingRead=access)")
+    public ComplexMatchResult subMemory(ValueNode value, Access access) {
+        OperandSize size = getMemorySize(access);
+        if (size.isXmmType()) {
+            return binaryRead(SSEOp.SUB, size, value, access);
+        } else {
+            return binaryRead(SUB.getRMOpcode(size), size, value, access);
+        }
+    }
+
+    @MatchRule("(Mul value Read=access)")
+    @MatchRule("(Mul value FloatingRead=access)")
+    public ComplexMatchResult mulMemory(ValueNode value, Access access) {
+        OperandSize size = getMemorySize(access);
+        if (size.isXmmType()) {
+            return binaryRead(SSEOp.MUL, size, value, access);
+        } else {
+            return binaryRead(AMD64RMOp.IMUL, size, value, access);
+        }
+    }
+
+    @MatchRule("(And value Read=access)")
+    @MatchRule("(And value FloatingRead=access)")
+    public ComplexMatchResult andMemory(ValueNode value, Access access) {
+        OperandSize size = getMemorySize(access);
+        if (size.isXmmType()) {
+            return null;
+        } else {
+            return binaryRead(AND.getRMOpcode(size), size, value, access);
+        }
+    }
+
+    @MatchRule("(Or value Read=access)")
+    @MatchRule("(Or value FloatingRead=access)")
+    public ComplexMatchResult orMemory(ValueNode value, Access access) {
+        OperandSize size = getMemorySize(access);
+        if (size.isXmmType()) {
+            return null;
+        } else {
+            return binaryRead(OR.getRMOpcode(size), size, value, access);
+        }
+    }
+
+    @MatchRule("(Xor value Read=access)")
+    @MatchRule("(Xor value FloatingRead=access)")
+    public ComplexMatchResult xorMemory(ValueNode value, Access access) {
+        OperandSize size = getMemorySize(access);
+        if (size.isXmmType()) {
+            return null;
+        } else {
+            return binaryRead(XOR.getRMOpcode(size), size, value, access);
+        }
+    }
+
+    @MatchRule("(Write object Narrow=narrow)")
+    public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
+        return builder -> {
+            LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
+            getLIRGeneratorTool().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
+            return null;
+        };
+    }
+
+    @MatchRule("(SignExtend Read=access)")
+    @MatchRule("(SignExtend FloatingRead=access)")
+    public ComplexMatchResult signExtend(SignExtendNode root, Access access) {
+        return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits());
+    }
+
+    @MatchRule("(ZeroExtend Read=access)")
+    @MatchRule("(ZeroExtend FloatingRead=access)")
+    public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) {
+        AMD64Kind memoryKind = getMemoryKind(access);
+        return builder -> getArithmeticLIRGenerator().emitZeroExtendMemory(memoryKind, root.getResultBits(), (AMD64AddressValue) operand(access.getAddress()), getState(access));
+    }
+
+    @MatchRule("(FloatConvert Read=access)")
+    @MatchRule("(FloatConvert FloatingRead=access)")
+    public ComplexMatchResult floatConvert(FloatConvertNode root, Access access) {
+        switch (root.getFloatConvert()) {
+            case D2F:
+                return emitConvertMemoryOp(AMD64Kind.SINGLE, SSEOp.CVTSD2SS, SD, access);
+            case D2I:
+                return emitConvertMemoryOp(AMD64Kind.DWORD, SSEOp.CVTTSD2SI, DWORD, access);
+            case D2L:
+                return emitConvertMemoryOp(AMD64Kind.QWORD, SSEOp.CVTTSD2SI, QWORD, access);
+            case F2D:
+                return emitConvertMemoryOp(AMD64Kind.DOUBLE, SSEOp.CVTSS2SD, SS, access);
+            case F2I:
+                return emitConvertMemoryOp(AMD64Kind.DWORD, SSEOp.CVTTSS2SI, DWORD, access);
+            case F2L:
+                return emitConvertMemoryOp(AMD64Kind.QWORD, SSEOp.CVTTSS2SI, QWORD, access);
+            case I2D:
+                return emitConvertMemoryOp(AMD64Kind.DOUBLE, SSEOp.CVTSI2SD, DWORD, access);
+            case I2F:
+                return emitConvertMemoryOp(AMD64Kind.SINGLE, SSEOp.CVTSI2SS, DWORD, access);
+            case L2D:
+                return emitConvertMemoryOp(AMD64Kind.DOUBLE, SSEOp.CVTSI2SD, QWORD, access);
+            case L2F:
+                return emitConvertMemoryOp(AMD64Kind.SINGLE, SSEOp.CVTSI2SS, QWORD, access);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @MatchRule("(Reinterpret Read=access)")
+    @MatchRule("(Reinterpret FloatingRead=access)")
+    public ComplexMatchResult reinterpret(ReinterpretNode root, Access access) {
+        return builder -> {
+            LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp());
+            return emitReinterpretMemory(kind, access);
+        };
+
+    }
+
+    @Override
+    public AMD64LIRGenerator getLIRGeneratorTool() {
+        return (AMD64LIRGenerator) gen;
+    }
+
+    protected AMD64ArithmeticLIRGenerator getArithmeticLIRGenerator() {
+        return (AMD64ArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic();
+    }
+}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,12 +22,11 @@
  */
 package com.oracle.graal.compiler.common;
 
-import jdk.internal.jvmci.options.DerivedOptionValue;
-import jdk.internal.jvmci.options.DerivedOptionValue.OptionSupplier;
-import jdk.internal.jvmci.options.Option;
-import jdk.internal.jvmci.options.OptionType;
-import jdk.internal.jvmci.options.OptionValue;
-import jdk.internal.jvmci.options.StableOptionValue;
+import jdk.vm.ci.options.DerivedOptionValue;
+import jdk.vm.ci.options.DerivedOptionValue.OptionSupplier;
+import jdk.vm.ci.options.Option;
+import jdk.vm.ci.options.OptionType;
+import jdk.vm.ci.options.OptionValue;
 
 /**
  * Options to control the backend configuration.
@@ -42,8 +41,8 @@
         public static final OptionValue<Boolean> LIROptSSILinearScan = new OptionValue<>(false);
         @Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
         public static final OptionValue<Boolean> TraceRA = new OptionValue<>(false);
-        @Option(help = "Never spill constant intervals.", type = OptionType.Debug)
-        public static final OptionValue<Boolean> NeverSpillConstants = new StableOptionValue<>(false);
+        @Option(help = "Support object constant to stack move.", type = OptionType.Debug)
+        public static final OptionValue<Boolean> AllowObjectConstantToStackMove = new OptionValue<>(true);
         // @formatter:on
     }
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java	Fri Oct 30 20:56:28 2015 +0100
@@ -27,7 +27,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 
-import jdk.internal.jvmci.common.JVMCIError;
+import jdk.vm.ci.common.JVMCIError;
 import sun.misc.Unsafe;
 
 /**
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.compiler.common;
 
-import jdk.internal.jvmci.options.Option;
-import jdk.internal.jvmci.options.OptionType;
-import jdk.internal.jvmci.options.OptionValue;
-import jdk.internal.jvmci.options.StableOptionValue;
+import jdk.vm.ci.options.Option;
+import jdk.vm.ci.options.OptionType;
+import jdk.vm.ci.options.OptionValue;
+import jdk.vm.ci.options.StableOptionValue;
 
 /**
  * This class encapsulates options that control the behavior of the Graal compiler.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/RegisterAllocationConfig.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/RegisterAllocationConfig.java	Fri Oct 30 20:56:28 2015 +0100
@@ -27,9 +27,9 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.code.RegisterConfig;
-import jdk.internal.jvmci.meta.PlatformKind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.meta.PlatformKind;
 
 import com.oracle.graal.compiler.common.GraalOptions;
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/Condition.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/Condition.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.compiler.common.calc;
 
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.ConstantReflectionProvider;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.PrimitiveConstant;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.PrimitiveConstant;
 
 /**
  * Condition codes used in conditionals.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/FloatConvert.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/FloatConvert.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.common.calc;
 
-import jdk.internal.jvmci.common.JVMCIError;
+import jdk.vm.ci.common.JVMCIError;
 
 public enum FloatConvert {
     F2I,
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/CodeGenProviders.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/CodeGenProviders.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.compiler.common.spi;
 
-import jdk.internal.jvmci.code.CodeCacheProvider;
-import jdk.internal.jvmci.meta.ConstantReflectionProvider;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
 
 /**
  * A set of providers which are required for LIR and/or code generation. Some may not be present
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallLinkage.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallLinkage.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.compiler.common.spi;
 
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.meta.InvokeTarget;
-import jdk.internal.jvmci.meta.Value;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.meta.InvokeTarget;
+import jdk.vm.ci.meta.Value;
 
 /**
  * The runtime specific details of a {@linkplain ForeignCallDescriptor foreign} call.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallsProvider.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallsProvider.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.common.spi;
 
-import jdk.internal.jvmci.meta.LocationIdentity;
+import jdk.vm.ci.meta.LocationIdentity;
 
 /**
  * Details about a set of supported {@link ForeignCallDescriptor foreign calls}.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/LIRKindTool.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/LIRKindTool.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.common.spi;
 
-import jdk.internal.jvmci.meta.LIRKind;
+import jdk.vm.ci.meta.LIRKind;
 
 /**
  * This interface can be used to access platform and VM specific kinds.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -26,11 +26,11 @@
 import java.util.Objects;
 import java.util.RandomAccess;
 
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 /**
  * Type describing all pointers to Java objects.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractPointerStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractPointerStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 
 /**
  * Abstract base class of all pointer types.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import static jdk.internal.jvmci.meta.MetaUtil.getSimpleName;
+import static jdk.vm.ci.meta.MetaUtil.getSimpleName;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -30,8 +30,8 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaKind;
 
 import com.oracle.graal.compiler.common.calc.FloatConvert;
 import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Add;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -25,7 +25,7 @@
 import java.nio.ByteBuffer;
 import java.util.Objects;
 
-import jdk.internal.jvmci.meta.SerializableConstant;
+import jdk.vm.ci.meta.SerializableConstant;
 
 /**
  * Type describing values that support arithmetic operations.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -32,15 +32,15 @@
 import java.nio.ByteBuffer;
 import java.util.function.DoubleBinaryOperator;
 
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.PrimitiveConstant;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
-import jdk.internal.jvmci.meta.SerializableConstant;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.PrimitiveConstant;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.SerializableConstant;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MemoryAccessProvider;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.PrimitiveConstant;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.PrimitiveConstant;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -30,16 +30,16 @@
 import java.nio.ByteBuffer;
 import java.util.Formatter;
 
-import jdk.internal.jvmci.code.CodeUtil;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.PrimitiveConstant;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
-import jdk.internal.jvmci.meta.SerializableConstant;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.PrimitiveConstant;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.SerializableConstant;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MemoryAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.MemoryAccessProvider;
 
 /**
  * Type describing primitive values.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/RawPointerStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/RawPointerStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MemoryAccessProvider;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MemoryAccessProvider;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,15 +22,15 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.code.CodeUtil;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.JavaType;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaMethod;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
-import jdk.internal.jvmci.meta.Signature;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
 
 public class StampFactory {
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java	Fri Oct 30 20:56:28 2015 +0100
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.MemoryAccessProvider;
-import jdk.internal.jvmci.meta.MetaAccessProvider;
-import jdk.internal.jvmci.meta.ResolvedJavaType;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/Util.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/Util.java	Fri Oct 30 20:56:28 2015 +0100
@@ -26,8 +26,8 @@
 import java.util.Comparator;
 import java.util.List;
 
-import jdk.internal.jvmci.code.BailoutException;
-import jdk.internal.jvmci.code.CodeUtil;
+import jdk.vm.ci.code.BailoutException;
+import jdk.vm.ci.code.CodeUtil;
 
 import com.oracle.graal.debug.TTY;
 
--- a/graal/com.oracle.graal.compiler.match.processor/src/com/oracle/graal/compiler/match/processor/MatchProcessor.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.match.processor/src/com/oracle/graal/compiler/match/processor/MatchProcessor.java	Fri Oct 30 20:56:28 2015 +0100
@@ -63,10 +63,10 @@
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
 
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.service.ServiceProvider;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.service.ServiceProvider;
 
-import com.oracle.graal.compiler.gen.NodeLIRBuilder;
+import com.oracle.graal.compiler.gen.NodeMatchRules;
 import com.oracle.graal.compiler.match.ComplexMatchResult;
 import com.oracle.graal.compiler.match.MatchRule;
 import com.oracle.graal.compiler.match.MatchRules;
@@ -520,7 +520,7 @@
             out.println("");
             out.println("import java.util.*;");
             out.println("import " + MatchStatementSet.class.getPackage().getName() + ".*;");
-            out.println("import " + NodeLIRBuilder.class.getName() + ";");
+            out.println("import " + NodeMatchRules.class.getName() + ";");
             out.println("import " + Position.class.getName() + ";");
             out.println("import " + ServiceProvider.class.getName() + ";");
             for (String p : info.requiredPackages) {
@@ -552,8 +552,8 @@
                 out.printf("    private static final String[] %s = new String[] {%s};\n", invoker.argumentsListName(), args);
                 out.printf("    private static final class %s implements MatchGenerator {\n", invoker.wrapperClass());
                 out.printf("        static MatchGenerator instance = new %s();\n", invoker.wrapperClass());
-                out.printf("        public ComplexMatchResult match(NodeLIRBuilder builder, Object...args) {\n");
-                out.printf("            return ((%s) builder).%s(%s);\n", invoker.nodeLIRBuilderClass, invoker.methodName, types);
+                out.printf("        public ComplexMatchResult match(NodeMatchRules nodeMatchRules, Object...args) {\n");
+                out.printf("            return ((%s) nodeMatchRules).%s(%s);\n", invoker.nodeLIRBuilderClass, invoker.methodName, types);
                 out.printf("        }\n");
                 out.printf("        public String getName() {\n");
                 out.printf("             return \"%s\";\n", invoker.methodName);
@@ -565,7 +565,7 @@
 
             String desc = MatchStatement.class.getSimpleName();
 
-            out.println("    public Class<? extends NodeLIRBuilder> forClass() {");
+            out.println("    public Class<? extends NodeMatchRules> forClass() {");
             out.println("        return " + topDeclaringClass + ".class;");
             out.println("    }");
             out.println();
@@ -604,7 +604,7 @@
     }
 
     private void createProviderFile(String pkg, String providerClassName, Element... originatingElements) throws IOException {
-        String filename = "META-INF/providers/" + pkg + "." + providerClassName;
+        String filename = "META-INF/jvmci.providers/" + pkg + "." + providerClassName;
         FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements);
         PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
         writer.println(MatchStatementSet.class.getName());
--- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java	Fri Oct 30 20:56:28 2015 +0100
@@ -25,7 +25,7 @@
 import static com.oracle.graal.compiler.common.BackendOptions.UserOptions.TraceRA;
 import static com.oracle.graal.compiler.common.GraalOptions.RegisterPressure;
 import static org.junit.Assume.assumeTrue;
-import jdk.internal.jvmci.sparc.SPARC;
+import jdk.vm.ci.sparc.SPARC;
 
 import org.junit.Before;
 import org.junit.Test;
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCAddressLowering.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCAddressLowering.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,8 +23,8 @@
 
 package com.oracle.graal.compiler.sparc;
 
-import jdk.internal.jvmci.code.CodeCacheProvider;
-import jdk.internal.jvmci.meta.JavaConstant;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.meta.JavaConstant;
 
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.nodes.ValueNode;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java	Fri Oct 30 20:56:28 2015 +0100
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.compiler.sparc;
+
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Add;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Addcc;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.And;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Mulx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sdivx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sllx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sra;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srax;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srl;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sub;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Subcc;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Udivx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Xnor;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtos;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fstod;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fxtod;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.UMulxhi;
+import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
+import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
+import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.BSF;
+import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IBSR;
+import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LBSR;
+import static jdk.vm.ci.code.CodeUtil.mask;
+import static jdk.vm.ci.meta.JavaConstant.forLong;
+import static jdk.vm.ci.sparc.SPARC.g0;
+import static jdk.vm.ci.sparc.SPARCKind.DOUBLE;
+import static jdk.vm.ci.sparc.SPARCKind.XWORD;
+import static jdk.vm.ci.sparc.SPARCKind.SINGLE;
+import static jdk.vm.ci.sparc.SPARCKind.WORD;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
+import jdk.vm.ci.sparc.SPARC;
+import jdk.vm.ci.sparc.SPARC.CPUFeature;
+import jdk.vm.ci.sparc.SPARCKind;
+
+import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs;
+import com.oracle.graal.compiler.common.calc.FloatConvert;
+import com.oracle.graal.lir.ConstantValue;
+import com.oracle.graal.lir.LIRFrameState;
+import com.oracle.graal.lir.Variable;
+import com.oracle.graal.lir.gen.ArithmeticLIRGenerator;
+import com.oracle.graal.lir.sparc.SPARCArithmetic;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp.MulHigh;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp.Rem;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp;
+import com.oracle.graal.lir.sparc.SPARCBitManipulationOp;
+import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp;
+import com.oracle.graal.lir.sparc.SPARCOP3Op;
+import com.oracle.graal.lir.sparc.SPARCOPFOp;
+
+/**
+ * This class implements the SPARC specific portion of the LIR generator.
+ */
+public class SPARCArithmeticLIRGenerator extends ArithmeticLIRGenerator {
+
+    @Override
+    public SPARCLIRGenerator getLIRGen() {
+        return (SPARCLIRGenerator) super.getLIRGen();
+    }
+
+    @Override
+    public Variable emitBitCount(Value operand) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD));
+        Value usedOperand = operand;
+        if (operand.getPlatformKind() == SPARCKind.WORD) { // Zero extend
+            usedOperand = getLIRGen().newVariable(operand.getLIRKind());
+            getLIRGen().append(new SPARCOP3Op(Op3s.Srl, operand, SPARC.g0.asValue(), usedOperand));
+        }
+        getLIRGen().append(new SPARCOP3Op(Op3s.Popc, SPARC.g0.asValue(), usedOperand, result));
+        return result;
+    }
+
+    @Override
+    public Variable emitBitScanForward(Value operand) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD));
+        getLIRGen().append(new SPARCBitManipulationOp(BSF, result, getLIRGen().asAllocatable(operand), getLIRGen()));
+        return result;
+    }
+
+    @Override
+    public Variable emitBitScanReverse(Value operand) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD));
+        if (operand.getPlatformKind() == SPARCKind.XWORD) {
+            getLIRGen().append(new SPARCBitManipulationOp(LBSR, result, getLIRGen().asAllocatable(operand), getLIRGen()));
+        } else {
+            getLIRGen().append(new SPARCBitManipulationOp(IBSR, result, getLIRGen().asAllocatable(operand), getLIRGen()));
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitMathAbs(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        SPARCKind kind = (SPARCKind) input.getPlatformKind();
+        Opfs opf;
+        switch (kind) {
+            case SINGLE:
+                opf = Opfs.Fabss;
+                break;
+            case DOUBLE:
+                opf = Opfs.Fabsd;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere("Input kind: " + kind);
+        }
+        getLIRGen().append(new SPARCOPFOp(opf, g0.asValue(), input, result));
+        return result;
+    }
+
+    @Override
+    public Value emitMathSqrt(Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        SPARCKind kind = (SPARCKind) input.getPlatformKind();
+        Opfs opf;
+        switch (kind) {
+            case SINGLE:
+                opf = Opfs.Fsqrts;
+                break;
+            case DOUBLE:
+                opf = Opfs.Fsqrtd;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere("Input kind: " + kind);
+        }
+        getLIRGen().append(new SPARCOPFOp(opf, g0.asValue(), input, result));
+        return result;
+    }
+
+    @Override
+    public Value emitNegate(Value input) {
+        PlatformKind inputKind = input.getPlatformKind();
+        if (isNumericInteger(inputKind)) {
+            return emitUnary(Sub, input);
+        } else {
+            return emitUnary(inputKind.equals(DOUBLE) ? Fnegd : Fnegs, input);
+        }
+    }
+
+    @Override
+    public Value emitNot(Value input) {
+        return emitUnary(Xnor, input);
+    }
+
+    private Variable emitUnary(Opfs opf, Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        getLIRGen().append(new SPARCOPFOp(opf, g0.asValue(), input, result));
+        return result;
+    }
+
+    private Variable emitUnary(Op3s op3, Value input) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(input));
+        getLIRGen().append(SPARCOP3Op.newUnary(op3, input, result));
+        return result;
+    }
+
+    private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b) {
+        return emitBinary(resultKind, opf, a, b, null);
+    }
+
+    private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b, LIRFrameState state) {
+        Variable result = getLIRGen().newVariable(resultKind);
+        if (opf.isCommutative() && isJavaConstant(a) && getLIRGen().canInlineConstant(asJavaConstant(a))) {
+            getLIRGen().append(new SPARCOPFOp(opf, b, a, result, state));
+        } else {
+            getLIRGen().append(new SPARCOPFOp(opf, a, b, result, state));
+        }
+        return result;
+    }
+
+    private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, int b) {
+        return emitBinary(resultKind, op3, a, new ConstantValue(LIRKind.value(WORD), JavaConstant.forInt(b)));
+    }
+
+    private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b) {
+        return emitBinary(resultKind, op3, a, b, null);
+    }
+
+    private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b, LIRFrameState state) {
+        Variable result = getLIRGen().newVariable(resultKind);
+        if (op3.isCommutative() && isJavaConstant(a) && getLIRGen().canInlineConstant(asJavaConstant(a))) {
+            getLIRGen().append(new SPARCOP3Op(op3, getLIRGen().load(b), a, result, state));
+        } else {
+            getLIRGen().append(new SPARCOP3Op(op3, getLIRGen().load(a), b, result, state));
+        }
+        return result;
+    }
+
+    @Override
+    protected boolean isNumericInteger(PlatformKind kind) {
+        return ((SPARCKind) kind).isInteger();
+    }
+
+    @Override
+    public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
+        if (isNumericInteger(a.getPlatformKind())) {
+            return emitBinary(resultKind, setFlags ? Addcc : Add, a, b);
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Faddd : Fadds, a, b);
+        }
+    }
+
+    @Override
+    public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) {
+        if (isNumericInteger(a.getPlatformKind())) {
+            return emitBinary(resultKind, setFlags ? Subcc : Sub, a, b);
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Opfs.Fsubd : Opfs.Fsubs, a, b);
+        }
+    }
+
+    @Override
+    public Variable emitMul(Value a, Value b, boolean setFlags) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        PlatformKind aKind = a.getPlatformKind();
+        if (isNumericInteger(aKind)) {
+            if (setFlags) {
+                Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
+                if (aKind == XWORD) {
+                    getLIRGen().append(new SPARCLMulccOp(result, getLIRGen().load(a), getLIRGen().load(b), getLIRGen()));
+                } else if (aKind == WORD) {
+                    getLIRGen().append(new SPARCIMulccOp(result, getLIRGen().load(a), getLIRGen().load(b)));
+                } else {
+                    throw JVMCIError.shouldNotReachHere();
+                }
+                return result;
+            } else {
+                return emitBinary(resultKind, setFlags ? Op3s.Mulscc : Op3s.Mulx, a, b);
+            }
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Fmuld : Fmuls, a, b);
+        }
+    }
+
+    @Override
+    public Value emitMulHigh(Value a, Value b) {
+        MulHigh opcode;
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                opcode = MulHigh.IMUL;
+                break;
+            case XWORD:
+                opcode = MulHigh.LMUL;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return emitMulHigh(opcode, a, b);
+    }
+
+    @Override
+    public Value emitUMulHigh(Value a, Value b) {
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                Value aExtended = emitBinary(LIRKind.combine(a), Srl, a, 0);
+                Value bExtended = emitBinary(LIRKind.combine(b), Srl, b, 0);
+                Value result = emitBinary(LIRKind.combine(a, b), Mulx, aExtended, bExtended);
+                return emitBinary(LIRKind.combine(a, b), Srax, result, WORD.getSizeInBits());
+            case XWORD:
+                return emitBinary(LIRKind.combine(a, b), UMulxhi, a, b);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    private Value emitMulHigh(MulHigh opcode, Value a, Value b) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
+        MulHighOp mulHigh = new MulHighOp(opcode, getLIRGen().load(a), getLIRGen().load(b), result, getLIRGen().newVariable(LIRKind.combine(a, b)));
+        getLIRGen().append(mulHigh);
+        return result;
+    }
+
+    @Override
+    public Value emitDiv(Value a, Value b, LIRFrameState state) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        PlatformKind aKind = a.getPlatformKind();
+        PlatformKind bKind = b.getPlatformKind();
+        if (isJavaConstant(b) && asJavaConstant(b).isDefaultForKind()) { // Div by zero
+            Value zero = SPARC.g0.asValue(LIRKind.value(SPARCKind.WORD));
+            return emitBinary(resultKind, Op3s.Sdivx, zero, zero, state);
+        } else if (isNumericInteger(aKind)) {
+            Value fixedA = emitSignExtend(a, aKind.getSizeInBytes() * 8, 64);
+            Value fixedB = emitSignExtend(b, bKind.getSizeInBytes() * 8, 64);
+            return emitBinary(resultKind, Op3s.Sdivx, fixedA, fixedB, state);
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Opfs.Fdivd : Opfs.Fdivs, a, b, state);
+        }
+    }
+
+    @Override
+    public Value emitRem(Value a, Value b, LIRFrameState state) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
+        Value aLoaded;
+        Value bLoaded;
+        Variable q1; // Intermediate values
+        Variable q2;
+        Variable q3;
+        Variable q4;
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        switch (aKind) {
+            case WORD:
+                q1 = emitBinary(result.getLIRKind(), Sra, a, g0.asValue(LIRKind.value(WORD)));
+                q2 = emitBinary(q1.getLIRKind(), Sdivx, q1, b, state);
+                q3 = emitBinary(q2.getLIRKind(), Op3s.Mulx, q2, b);
+                result = emitSub(q1, q3, false);
+                break;
+            case XWORD:
+                aLoaded = getLIRGen().load(a); // Reuse the loaded value
+                q1 = emitBinary(result.getLIRKind(), Sdivx, aLoaded, b, state);
+                q2 = emitBinary(result.getLIRKind(), Mulx, q1, b);
+                result = emitSub(aLoaded, q2, false);
+                break;
+            case SINGLE:
+                aLoaded = getLIRGen().load(a);
+                bLoaded = getLIRGen().load(b);
+                q1 = emitBinary(result.getLIRKind(), Fdivs, aLoaded, bLoaded, state);
+                q2 = getLIRGen().newVariable(LIRKind.value(aKind));
+                getLIRGen().append(new FloatConvertOp(FloatConvertOp.FloatConvert.F2I, q1, q2));
+                q3 = emitUnary(Fitos, q2);
+                q4 = emitBinary(LIRKind.value(aKind), Fmuls, q3, bLoaded);
+                result = emitSub(aLoaded, q4, false);
+                break;
+            case DOUBLE:
+                aLoaded = getLIRGen().load(a);
+                bLoaded = getLIRGen().load(b);
+                q1 = emitBinary(result.getLIRKind(), Fdivd, aLoaded, bLoaded, state);
+                q2 = getLIRGen().newVariable(LIRKind.value(aKind));
+                getLIRGen().append(new FloatConvertOp(FloatConvertOp.FloatConvert.D2L, q1, q2));
+                q3 = emitUnary(Fxtod, q2);
+                q4 = emitBinary(result.getLIRKind(), Fmuld, q3, bLoaded);
+                result = emitSub(aLoaded, q4, false);
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitURem(Value a, Value b, LIRFrameState state) {
+        Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
+        Variable scratch1 = getLIRGen().newVariable(LIRKind.combine(a, b));
+        Variable scratch2 = getLIRGen().newVariable(LIRKind.combine(a, b));
+        Rem opcode;
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                opcode = Rem.IUREM;
+                break;
+            case XWORD:
+                opcode = Rem.LUREM;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        getLIRGen().append(new RemOp(opcode, result, getLIRGen().load(a), getLIRGen().load(b), scratch1, scratch2, state));
+        return result;
+
+    }
+
+    @Override
+    public Value emitUDiv(Value a, Value b, LIRFrameState state) {
+        Value actualA = a;
+        Value actualB = b;
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                actualA = emitZeroExtend(actualA, 32, 64);
+                actualB = emitZeroExtend(actualB, 32, 64);
+                break;
+            case XWORD:
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return emitBinary(LIRKind.combine(actualA, actualB), Udivx, actualA, actualB, state);
+    }
+
+    @Override
+    public Variable emitAnd(Value a, Value b) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        return emitBinary(resultKind, Op3s.And, a, b);
+    }
+
+    @Override
+    public Variable emitOr(Value a, Value b) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        return emitBinary(resultKind, Op3s.Or, a, b);
+    }
+
+    @Override
+    public Variable emitXor(Value a, Value b) {
+        LIRKind resultKind = LIRKind.combine(a, b);
+        return emitBinary(resultKind, Op3s.Xor, a, b);
+    }
+
+    @Override
+    public Variable emitShl(Value a, Value b) {
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind);
+        Op3s op;
+        switch (aKind) {
+            case WORD:
+                op = Op3s.Sll;
+                break;
+            case XWORD:
+                op = Op3s.Sllx;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return emitBinary(resultKind, op, a, b);
+    }
+
+    @Override
+    public Variable emitShr(Value a, Value b) {
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind);
+        Op3s op;
+        switch (aKind) {
+            case WORD:
+                op = Op3s.Sra;
+                break;
+            case XWORD:
+                op = Op3s.Srax;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return emitBinary(resultKind, op, a, b);
+    }
+
+    @Override
+    public Variable emitUShr(Value a, Value b) {
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind);
+        Op3s op;
+        switch (aKind) {
+            case WORD:
+                op = Op3s.Srl;
+                break;
+            case XWORD:
+                op = Op3s.Srlx;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return emitBinary(resultKind, op, a, b);
+    }
+
+    private AllocatableValue emitConvertMove(LIRKind kind, AllocatableValue input) {
+        Variable result = getLIRGen().newVariable(kind);
+        getLIRGen().emitMove(result, input);
+        return result;
+    }
+
+    @Override
+    public Value emitFloatConvert(FloatConvert op, Value inputVal) {
+        AllocatableValue input = getLIRGen().asAllocatable(inputVal);
+        Value result;
+        switch (op) {
+            case D2F:
+                result = getLIRGen().newVariable(LIRKind.combine(inputVal).changeType(SINGLE));
+                getLIRGen().append(new SPARCOPFOp(Fdtos, inputVal, result));
+                break;
+            case F2D:
+                result = getLIRGen().newVariable(LIRKind.combine(inputVal).changeType(DOUBLE));
+                getLIRGen().append(new SPARCOPFOp(Fstod, inputVal, result));
+                break;
+            case I2F: {
+                AllocatableValue intEncodedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE));
+                result = getLIRGen().newVariable(intEncodedFloatReg.getLIRKind());
+                moveBetweenFpGp(intEncodedFloatReg, input);
+                getLIRGen().append(new SPARCOPFOp(Fitos, intEncodedFloatReg, result));
+                break;
+            }
+            case I2D: {
+                // Unfortunately we must do int -> float -> double because fitod has float
+                // and double encoding in one instruction
+                AllocatableValue convertedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE));
+                result = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                moveBetweenFpGp(convertedFloatReg, input);
+                getLIRGen().append(new SPARCOPFOp(Fitod, convertedFloatReg, result));
+                break;
+            }
+            case L2D: {
+                AllocatableValue longEncodedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                moveBetweenFpGp(longEncodedDoubleReg, input);
+                AllocatableValue convertedDoubleReg = getLIRGen().newVariable(longEncodedDoubleReg.getLIRKind());
+                getLIRGen().append(new SPARCOPFOp(Fxtod, longEncodedDoubleReg, convertedDoubleReg));
+                result = convertedDoubleReg;
+                break;
+            }
+            case D2I: {
+                AllocatableValue convertedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE));
+                getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2I, input, convertedFloatReg));
+                AllocatableValue convertedIntReg = getLIRGen().newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD));
+                moveBetweenFpGp(convertedIntReg, convertedFloatReg);
+                result = convertedIntReg;
+                break;
+            }
+            case F2L: {
+                AllocatableValue convertedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2L, input, convertedDoubleReg));
+                AllocatableValue convertedLongReg = getLIRGen().newVariable(LIRKind.combine(convertedDoubleReg).changeType(XWORD));
+                moveBetweenFpGp(convertedLongReg, convertedDoubleReg);
+                result = convertedLongReg;
+                break;
+            }
+            case F2I: {
+                AllocatableValue convertedFloatReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE));
+                getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2I, input, convertedFloatReg));
+                AllocatableValue convertedIntReg = getLIRGen().newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD));
+                moveBetweenFpGp(convertedIntReg, convertedFloatReg);
+                result = convertedIntReg;
+                break;
+            }
+            case D2L: {
+                AllocatableValue convertedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                getLIRGen().append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2L, input, convertedDoubleReg));
+                AllocatableValue convertedLongReg = getLIRGen().newVariable(LIRKind.combine(convertedDoubleReg).changeType(XWORD));
+                moveBetweenFpGp(convertedLongReg, convertedDoubleReg);
+                result = convertedLongReg;
+                break;
+            }
+            case L2F: {
+                AllocatableValue convertedDoubleReg = getLIRGen().newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                result = getLIRGen().newVariable(LIRKind.combine(input).changeType(SINGLE));
+                moveBetweenFpGp(convertedDoubleReg, input);
+                getLIRGen().append(new SPARCOPFOp(Opfs.Fxtos, convertedDoubleReg, result));
+                break;
+            }
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) {
+        AllocatableValue tempSlot;
+        if (getLIRGen().getArchitecture().getFeatures().contains(CPUFeature.VIS3)) {
+            tempSlot = AllocatableValue.ILLEGAL;
+        } else {
+            tempSlot = getLIRGen().getTempSlot(LIRKind.value(XWORD));
+        }
+        getLIRGen().append(new MoveFpGp(dst, src, tempSlot));
+    }
+
+    @Override
+    public Value emitNarrow(Value inputVal, int bits) {
+        if (inputVal.getPlatformKind() == XWORD && bits <= 32) {
+            LIRKind resultKind = LIRKind.combine(inputVal).changeType(WORD);
+            Variable result = getLIRGen().newVariable(resultKind);
+            getLIRGen().emitMove(result, inputVal);
+            return result;
+        } else {
+            return inputVal;
+        }
+    }
+
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= XWORD.getSizeInBits();
+        LIRKind shiftKind = LIRKind.value(WORD);
+        LIRKind resultKind = LIRKind.combine(inputVal).changeType(toBits > 32 ? XWORD : WORD);
+        Value result;
+        int shiftCount = XWORD.getSizeInBits() - fromBits;
+        if (fromBits == toBits) {
+            result = inputVal;
+        } else if (isJavaConstant(inputVal)) {
+            JavaConstant javaConstant = asJavaConstant(inputVal);
+            long constant;
+            if (javaConstant.isNull()) {
+                constant = 0;
+            } else {
+                constant = javaConstant.asLong();
+            }
+            return new ConstantValue(resultKind, JavaConstant.forLong((constant << shiftCount) >> shiftCount));
+        } else if (fromBits == WORD.getSizeInBits() && toBits == XWORD.getSizeInBits()) {
+            result = getLIRGen().newVariable(resultKind);
+            getLIRGen().append(new SPARCOP3Op(Sra, inputVal, SPARC.g0.asValue(LIRKind.value(WORD)), result));
+        } else {
+            Variable tmp = getLIRGen().newVariable(resultKind.changeType(XWORD));
+            result = getLIRGen().newVariable(resultKind);
+            getLIRGen().append(new SPARCOP3Op(Sllx, inputVal, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), tmp));
+            getLIRGen().append(new SPARCOP3Op(Srax, tmp, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), result));
+        }
+        return result;
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        }
+        Variable result = getLIRGen().newVariable(LIRKind.combine(inputVal).changeType(toBits > WORD.getSizeInBits() ? XWORD : WORD));
+        if (fromBits == 32) {
+            getLIRGen().append(new SPARCOP3Op(Srl, inputVal, g0.asValue(), result));
+        } else {
+            Value mask = getLIRGen().emitConstant(LIRKind.value(XWORD), forLong(mask(fromBits)));
+            getLIRGen().append(new SPARCOP3Op(And, inputVal, mask, result));
+        }
+        return result;
+    }
+
+    @Override
+    public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) {
+        SPARCKind fromKind = (SPARCKind) inputVal.getPlatformKind();
+        SPARCKind toKind = (SPARCKind) to.getPlatformKind();
+        AllocatableValue input = getLIRGen().asAllocatable(inputVal);
+        Variable result = getLIRGen().newVariable(to);
+        // These cases require a move between CPU and FPU registers:
+        if (fromKind.isFloat() != toKind.isFloat()) {
+            moveBetweenFpGp(result, input);
+            return result;
+        } else {
+            // Otherwise, just emit an ordinary move instruction.
+            // Instructions that move or generate 32-bit register values also set the upper 32
+            // bits of the register to zero.
+            // Consequently, there is no need for a special zero-extension move.
+            return emitConvertMove(to, input);
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCImmediateAddressNode.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCImmediateAddressNode.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,8 +23,8 @@
 
 package com.oracle.graal.compiler.sparc;
 
-import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.LIRKind;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.LIRKind;
 
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.graph.NodeClass;
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCIndexedAddressNode.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCIndexedAddressNode.java	Fri Oct 30 20:56:28 2015 +0100
@@ -23,8 +23,8 @@
 
 package com.oracle.graal.compiler.sparc;
 
-import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.LIRKind;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.LIRKind;
 
 import com.oracle.graal.graph.NodeClass;
 import com.oracle.graal.lir.sparc.SPARCIndexedAddressValue;
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Oct 30 20:55:32 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Oct 30 20:56:28 2015 +0100
@@ -27,61 +27,25 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.FMOVSCC;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.MOVicc;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.Fcc0;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Add;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Addcc;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.And;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Mulx;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sdivx;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sllx;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sra;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srax;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srl;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sub;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Subcc;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Udivx;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Xnor;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmpd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmps;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtos;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegs;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fstod;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fxtod;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.UMulxhi;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.BSF;
-import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IBSR;
-import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LBSR;
-import static jdk.internal.jvmci.code.CodeUtil.mask;
-import static jdk.internal.jvmci.code.ValueUtil.isStackSlotValue;
-import static jdk.internal.jvmci.meta.JavaConstant.forLong;
-import static jdk.internal.jvmci.sparc.SPARC.g0;
-import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE;
-import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
-import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE;
-import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
-import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.StackSlotValue;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.PlatformKind;
-import jdk.internal.jvmci.meta.Value;
-import jdk.internal.jvmci.sparc.SPARC;
-import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
-import jdk.internal.jvmci.sparc.SPARCKind;
+import static com.oracle.graal.lir.LIRValueUtil.isStackSlotValue;
+import static jdk.vm.ci.sparc.SPARCKind.SINGLE;
+import static jdk.vm.ci.sparc.SPARCKind.XWORD;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
+import jdk.vm.ci.sparc.SPARC;
+import jdk.vm.ci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
@@ -90,7 +54,6 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs;
 import com.oracle.graal.compiler.common.calc.Condition;
-import com.oracle.graal.compiler.common.calc.FloatConvert;
 import com.oracle.graal.compiler.common.spi.ForeignCallLinkage;
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
 import com.oracle.graal.lir.ConstantValue;
@@ -102,20 +65,12 @@
 import com.oracle.graal.lir.StandardOp.NoOp;
 import com.oracle.graal.lir.SwitchStrategy;
 import com.oracle.graal.lir.Variable;
+import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
 import com.oracle.graal.lir.gen.LIRGenerator;
 import com.oracle.graal.lir.gen.SpillMoveFactoryBase;
 import com.oracle.graal.lir.sparc.SPARCAddressValue;
-import com.oracle.graal.lir.sparc.SPARCArithmetic;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp.MulHigh;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp.Rem;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp;
 import com.oracle.graal.lir.sparc.SPARCArrayEqualsOp;
-import com.oracle.graal.lir.sparc.SPARCBitManipulationOp;
 import com.oracle.graal.lir.sparc.SPARCByteSwapOp;
 import com.oracle.graal.lir.sparc.SPARCCall;
 import com.oracle.graal.lir.sparc.SPARCControlFlow;
@@ -134,11 +89,9 @@
 import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MembarOp;
 import com.oracle.graal.lir.sparc.SPARCMove.Move;
-import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp;
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCOP3Op;
-import com.oracle.graal.lir.sparc.SPARCOPFOp;
 import com.oracle.graal.phases.util.Providers;
 
 /**
@@ -168,8 +121,8 @@
         }
     }
 
-    public SPARCLIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        super(lirKindTool, providers, cc, lirGenRes);
+    public SPARCLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
+        super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes);
     }
 
     public SpillMoveFactory getSpillMoveFactory() {
@@ -207,7 +160,7 @@
                 return JavaConstant.forShort((short) dead);
             case WORD:
                 return JavaConstant.forInt((int) dead);
-            case DWORD:
+            case XWORD:
                 return JavaConstant.forLong(dead);
             case SINGLE:
             case V32_BYTE:
@@ -304,9 +257,9 @@
     }
 
     @Override
-    public Variable emitAddress(StackSlotValue address) {
+    public Variable emitAddress(AllocatableValue stackslot) {
         Variable result = newVariable(LIRKind.value(target().arch.getWordKind()));
-        append(new StackLoadAddressOp(result, address));
+        append(new StackLoadAddressOp(result, stackslot));
         return result;
     }
 
@@ -373,7 +326,7 @@
             if (from == to) {
                 return v;
             } else {
-                return emitSignExtend(v, fromBytes, toBytes);
+                return arithmeticLIRGen.emitSignExtend(v, fromBytes, toBytes);
             }
         }
     }
@@ -477,10 +430,10 @@
         int compareBytes = cmpKind.getSizeInBytes();
         // SPARC compares 32 or 64 bits
         if (compareBytes < left.getPlatformKind().getSizeInBytes()) {
-            left = emitSignExtend(left, compareBytes * 8, DWORD.getSizeInBytes() * 8);
+            left = arithmeticLIRGen.emitSignExtend(left, compareBytes * 8, XWORD.getSizeInBytes() * 8);
         }
         if (compareBytes < right.getPlatformKind().getSizeInBytes()) {
-            right = emitSignExtend(right, compareBytes * 8, DWORD.getSizeInBytes() * 8);
+