changeset 19987:414c068bd862

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 21 Mar 2015 15:41:55 +0100
parents 3c78119de0cd (current diff) a8d664e10e4f (diff)
children 5f15e5f844d6 9af92bb0dd71
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompareConstOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompareMemoryConstOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotComparePatchOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryCommutativeOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryConstOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryMemoryOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryPatchOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareConstOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareMemoryConstOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareMemoryOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MulConstOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RegStackConstOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryMOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryMROp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryMemoryOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryRMOp.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/OnAdoptTest.java
diffstat 55 files changed, 1279 insertions(+), 1803 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Sat Mar 21 15:41:38 2015 +0100
+++ b/CHANGELOG.md	Sat Mar 21 15:41:55 2015 +0100
@@ -17,6 +17,8 @@
 * Instrumentation:  AST "probing" is now safe and implemented by Node.probe(); language implementors need only implement Node.isInstrumentable() and Node.createWrapperNode().
 * Instrumentation:  A new framework defines a category of  simple "instrumentation tools" that can be created, configured, and installed, after which they autonomously collect execution data of some kind.
 * Instrumentation:  A new example "instrumentation tool" is a language-agnostic collector of code coverage information (CoverageTracker); there are two other examples.
+* Removed unsafe compiler directives; use `sun.misc.Unsafe` instead.
+* Removed `Node#onAdopt()`.
 
 ### Truffle-DSL
 * Implemented a new generated code layout that reduces the code size.
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Sat Mar 21 15:41:55 2015 +0100
@@ -601,11 +601,14 @@
         public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB",       P_0F, 0xBE, false, true, OpAssertion.IntegerAssertion);
         public static final AMD64RMOp MOVSX  = new AMD64RMOp("MOVSX",        P_0F, 0xBF, OpAssertion.No16BitAssertion);
         public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD",             0x63, OpAssertion.QwordOnlyAssertion);
+        public static final AMD64RMOp MOVB   = new AMD64RMOp("MOVB",               0x8A, OpAssertion.ByteAssertion);
         public static final AMD64RMOp MOV    = new AMD64RMOp("MOV",                0x8B);
 
-        // MOVD and MOVQ are the same opcode, just with different operand size prefix
+        // MOVD/MOVQ and MOVSS/MOVSD are the same opcode, just with different operand size prefix
         public static final AMD64RMOp MOVD   = new AMD64RMOp("MOVD",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
         public static final AMD64RMOp MOVQ   = new AMD64RMOp("MOVQ",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
+        public static final AMD64RMOp MOVSS  = new AMD64RMOp("MOVSS",        P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
+        public static final AMD64RMOp MOVSD  = new AMD64RMOp("MOVSD",        P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
 
         // TEST is documented as MR operation, but it's symmetric, and using it as RM operation is more convenient.
         public static final AMD64RMOp TESTB  = new AMD64RMOp("TEST",               0x84, OpAssertion.ByteAssertion);
@@ -628,6 +631,10 @@
             this(opcode, 0, prefix, op, assertion, null);
         }
 
+        protected AMD64RMOp(String opcode, int prefix, int op, OpAssertion assertion, CPUFeature feature) {
+            this(opcode, 0, prefix, op, assertion, feature);
+        }
+
         protected AMD64RMOp(String opcode, int prefix, int op, boolean dstIsByte, boolean srcIsByte, OpAssertion assertion) {
             super(opcode, 0, prefix, op, dstIsByte, srcIsByte, assertion, null);
         }
@@ -659,12 +666,17 @@
      */
     public static class AMD64MROp extends AMD64RROp {
         // @formatter:off
+        public static final AMD64MROp MOVB   = new AMD64MROp("MOVB",               0x88, OpAssertion.ByteAssertion);
         public static final AMD64MROp MOV    = new AMD64MROp("MOV",                0x89);
 
         // MOVD and MOVQ are the same opcode, just with different operand size prefix
         // Note that as MR opcodes, they have reverse operand order, so the IntToFloatingAssertion must be used.
         public static final AMD64MROp MOVD   = new AMD64MROp("MOVD",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
         public static final AMD64MROp MOVQ   = new AMD64MROp("MOVQ",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
+
+        // MOVSS and MOVSD are the same opcode, just with different operand size prefix
+        public static final AMD64MROp MOVSS  = new AMD64MROp("MOVSS",        P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
+        public static final AMD64MROp MOVSD  = new AMD64MROp("MOVSD",        P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
         // @formatter:on
 
         protected AMD64MROp(String opcode, int op) {
@@ -680,7 +692,11 @@
         }
 
         protected AMD64MROp(String opcode, int prefix, int op, OpAssertion assertion) {
-            this(opcode, 0, prefix, op, assertion, null);
+            this(opcode, prefix, op, assertion, null);
+        }
+
+        protected AMD64MROp(String opcode, int prefix, int op, OpAssertion assertion, CPUFeature feature) {
+            this(opcode, 0, prefix, op, assertion, feature);
         }
 
         protected AMD64MROp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@@ -747,6 +763,7 @@
      */
     public static class AMD64MIOp extends AMD64ImmOp {
         // @formatter:off
+        public static final AMD64MIOp MOVB = new AMD64MIOp("MOVB", true,  0xC6, 0, OpAssertion.ByteAssertion);
         public static final AMD64MIOp MOV  = new AMD64MIOp("MOV",  false, 0xC7, 0);
         public static final AMD64MIOp TEST = new AMD64MIOp("TEST", false, 0xF7, 0);
         // @formatter:on
@@ -754,7 +771,11 @@
         private final int ext;
 
         protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext) {
-            this(opcode, immIsByte, 0, op, ext, OpAssertion.IntegerAssertion);
+            this(opcode, immIsByte, op, ext, OpAssertion.IntegerAssertion);
+        }
+
+        protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext, OpAssertion assertion) {
+            this(opcode, immIsByte, 0, op, ext, assertion);
         }
 
         protected AMD64MIOp(String opcode, boolean immIsByte, int prefix, int op, int ext, OpAssertion assertion) {
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Sat Mar 21 15:41:55 2015 +0100
@@ -50,7 +50,6 @@
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.spi.*;
-import com.oracle.graal.compiler.common.util.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.amd64.*;
@@ -68,7 +67,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.AMD64Move.ZeroExtendLoadOp;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.phases.util.*;
 
@@ -107,28 +105,6 @@
         }
     }
 
-    /**
-     * Checks whether the supplied constant can be used without loading it into a register for store
-     * operations, i.e., on the right hand side of a memory access.
-     *
-     * @param c The constant to check.
-     * @return True if the constant can be used directly, false if the constant needs to be in a
-     *         register.
-     */
-    protected boolean canStoreConstant(JavaConstant c) {
-        // there is no immediate move of 64-bit constants on Intel
-        switch (c.getKind()) {
-            case Long:
-                return Util.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
-            case Double:
-                return false;
-            case Object:
-                return c.isNull();
-            default:
-                return true;
-        }
-    }
-
     protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
         if (src instanceof AMD64AddressValue) {
             return new LeaOp(dst, (AMD64AddressValue) src);
@@ -290,14 +266,14 @@
     private void emitIntegerTest(Value a, Value b) {
         assert a.getKind().isNumericInteger();
         OperandSize size = a.getKind() == Kind.Long ? QWORD : DWORD;
-        if (isConstant(b)) {
-            append(new AMD64CompareConstOp(AMD64MIOp.TEST, size, asAllocatable(a), asConstant(b)));
-        } else if (isConstant(a)) {
-            append(new AMD64CompareConstOp(AMD64MIOp.TEST, size, asAllocatable(b), asConstant(a)));
+        if (isConstant(b) && NumUtil.is32bit(asConstant(b).asLong())) {
+            append(new AMD64BinaryConsumer.ConstOp(AMD64MIOp.TEST, size, asAllocatable(a), (int) asConstant(b).asLong()));
+        } else if (isConstant(a) && NumUtil.is32bit(asConstant(a).asLong())) {
+            append(new AMD64BinaryConsumer.ConstOp(AMD64MIOp.TEST, size, asAllocatable(b), (int) asConstant(a).asLong()));
         } else if (isAllocatableValue(b)) {
-            append(new AMD64CompareOp(AMD64RMOp.TEST, size, asAllocatable(b), asAllocatable(a)));
+            append(new AMD64BinaryConsumer.Op(AMD64RMOp.TEST, size, asAllocatable(b), asAllocatable(a)));
         } else {
-            append(new AMD64CompareOp(AMD64RMOp.TEST, size, asAllocatable(a), asAllocatable(b)));
+            append(new AMD64BinaryConsumer.Op(AMD64RMOp.TEST, size, asAllocatable(a), asAllocatable(b)));
         }
     }
 
@@ -320,10 +296,10 @@
                 size = QWORD;
                 break;
             case Float:
-                append(new AMD64CompareOp(SSEOp.UCOMIS, PS, left, asAllocatable(right)));
+                append(new AMD64BinaryConsumer.Op(SSEOp.UCOMIS, PS, left, asAllocatable(right)));
                 return;
             case Double:
-                append(new AMD64CompareOp(SSEOp.UCOMIS, PD, left, asAllocatable(right)));
+                append(new AMD64BinaryConsumer.Op(SSEOp.UCOMIS, PD, left, asAllocatable(right)));
                 return;
             default:
                 throw GraalInternalError.shouldNotReachHere("unexpected kind: " + cmpKind);
@@ -333,17 +309,16 @@
             JavaConstant c = asConstant(right);
             if (c.isDefaultForKind()) {
                 AMD64RMOp op = size == BYTE ? TESTB : TEST;
-                append(new AMD64CompareOp(op, size, left, left));
+                append(new AMD64BinaryConsumer.Op(op, size, left, left));
                 return;
             } else if (NumUtil.is32bit(c.asLong())) {
-                AMD64MIOp op = CMP.getMIOpcode(size, NumUtil.isByte(c.asLong()));
-                append(new AMD64CompareConstOp(op, size, left, c));
+                append(new AMD64BinaryConsumer.ConstOp(CMP, size, left, (int) c.asLong()));
                 return;
             }
         }
 
         AMD64RMOp op = CMP.getRMOpcode(size);
-        append(new AMD64CompareOp(op, size, left, asAllocatable(right)));
+        append(new AMD64BinaryConsumer.Op(op, size, left, asAllocatable(right)));
     }
 
     /**
@@ -372,10 +347,10 @@
                 size = QWORD;
                 break;
             case Float:
-                append(new AMD64CompareMemoryOp(SSEOp.UCOMIS, PS, asAllocatable(a), b, state));
+                append(new AMD64BinaryConsumer.MemoryRMOp(SSEOp.UCOMIS, PS, asAllocatable(a), b, state));
                 return false;
             case Double:
-                append(new AMD64CompareMemoryOp(SSEOp.UCOMIS, PD, asAllocatable(a), b, state));
+                append(new AMD64BinaryConsumer.MemoryRMOp(SSEOp.UCOMIS, PD, asAllocatable(a), b, state));
                 return false;
             default:
                 throw GraalInternalError.shouldNotReachHere("unexpected kind: " + cmpKind);
@@ -390,8 +365,7 @@
 
     protected boolean emitCompareMemoryConOp(OperandSize size, JavaConstant a, AMD64AddressValue b, LIRFrameState state) {
         if (NumUtil.is32bit(a.asLong())) {
-            AMD64MIOp op = CMP.getMIOpcode(size, NumUtil.isByte(a.asLong()));
-            append(new AMD64CompareMemoryConstOp(op, size, b, a, state));
+            append(new AMD64BinaryConsumer.MemoryConstOp(CMP, size, b, (int) a.asLong(), state));
             return true;
         } else {
             return emitCompareRegMemoryOp(size, a, b, state);
@@ -400,7 +374,7 @@
 
     private boolean emitCompareRegMemoryOp(OperandSize size, Value a, AMD64AddressValue b, LIRFrameState state) {
         AMD64RMOp op = CMP.getRMOpcode(size);
-        append(new AMD64CompareMemoryOp(op, size, asAllocatable(a), b, state));
+        append(new AMD64BinaryConsumer.MemoryRMOp(op, size, asAllocatable(a), b, state));
         return false;
     }
 
@@ -435,16 +409,16 @@
         Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
-                append(new AMD64UnaryMOp(NEG, DWORD, result, input));
+                append(new AMD64Unary.MOp(NEG, DWORD, result, input));
                 break;
             case Long:
-                append(new AMD64UnaryMOp(NEG, QWORD, result, input));
+                append(new AMD64Unary.MOp(NEG, QWORD, result, input));
                 break;
             case Float:
-                append(new AMD64BinaryPatchOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16));
+                append(new AMD64Binary.DataOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16));
                 break;
             case Double:
-                append(new AMD64BinaryPatchOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16));
+                append(new AMD64Binary.DataOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -458,10 +432,10 @@
         Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
-                append(new AMD64UnaryMOp(NOT, DWORD, result, input));
+                append(new AMD64Unary.MOp(NOT, DWORD, result, input));
                 break;
             case Long:
-                append(new AMD64UnaryMOp(NOT, QWORD, result, input));
+                append(new AMD64Unary.MOp(NOT, QWORD, result, input));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -492,7 +466,7 @@
     private Variable emitBinaryConst(AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, JavaConstant b) {
         if (NumUtil.isInt(b.asLong())) {
             Variable result = newVariable(LIRKind.derive(a, b));
-            append(new AMD64BinaryConstOp(op, size, result, a, b));
+            append(new AMD64Binary.ConstOp(op, size, result, a, (int) b.asLong()));
             return result;
         } else {
             return emitBinaryVar(op.getRMOpcode(size), size, commutative, a, asAllocatable(b));
@@ -501,16 +475,16 @@
 
     private Variable emitBinaryConst(AMD64RMOp op, OperandSize size, AllocatableValue a, JavaConstant b) {
         Variable result = newVariable(LIRKind.derive(a, b));
-        append(new AMD64BinaryPatchOp(op, size, result, a, b));
+        append(new AMD64Binary.DataOp(op, size, result, a, b));
         return result;
     }
 
     private Variable emitBinaryVar(AMD64RMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) {
         Variable result = newVariable(LIRKind.derive(a, b));
         if (commutative) {
-            append(new AMD64BinaryCommutativeOp(op, size, result, a, b));
+            append(new AMD64Binary.CommutativeOp(op, size, result, a, b));
         } else {
-            append(new AMD64BinaryOp(op, size, result, a, b));
+            append(new AMD64Binary.Op(op, size, result, a, b));
         }
         return result;
     }
@@ -558,7 +532,7 @@
             }
 
             Variable ret = newVariable(LIRKind.derive(a, b));
-            append(new AMD64MulConstOp(op, size, ret, a, b));
+            append(new AMD64Binary.RMIOp(op, size, ret, a, imm));
             return ret;
         } else {
             return emitBinaryVar(AMD64RMOp.IMUL, size, true, a, asAllocatable(b));
@@ -628,13 +602,13 @@
 
     public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
         Variable result = newVariable(LIRKind.derive(a));
-        append(new AMD64BinaryMemoryOp(op, size, result, a, location, state));
+        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 AMD64UnaryMemoryOp(op, size, result, address, state));
+        append(new AMD64Unary.MemoryOp(op, size, result, address, state));
         return result;
     }
 
@@ -642,7 +616,24 @@
         // 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 ? Kind.Int : Kind.Long));
-        append(new ZeroExtendLoadOp(memoryKind, result, address, state));
+        switch (memoryKind) {
+            case Boolean:
+            case Byte:
+                append(new AMD64Unary.MemoryOp(MOVZXB, DWORD, result, address, state));
+                break;
+            case Char:
+            case Short:
+                append(new AMD64Unary.MemoryOp(MOVZX, DWORD, result, address, state));
+                break;
+            case Int:
+                append(new AMD64Unary.MemoryOp(MOV, DWORD, result, address, state));
+                break;
+            case Long:
+                append(new AMD64Unary.MemoryOp(MOV, QWORD, result, address, state));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
         return result;
     }
 
@@ -805,9 +796,13 @@
         if (isConstant(b)) {
             JavaConstant c = asConstant(b);
             if (c.asLong() == 1) {
-                append(new AMD64UnaryMOp(op.m1Op, size, result, input));
+                append(new AMD64Unary.MOp(op.m1Op, size, result, input));
             } else {
-                append(new AMD64BinaryConstOp(op.miOp, size, result, input, c));
+                /*
+                 * 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);
@@ -876,13 +871,13 @@
 
     private AllocatableValue emitConvertOp(LIRKind kind, AMD64RMOp op, OperandSize size, Value input) {
         Variable result = newVariable(kind);
-        append(new AMD64UnaryRMOp(op, size, result, asAllocatable(input)));
+        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 AMD64UnaryMROp(op, size, result, asAllocatable(input)));
+        append(new AMD64Unary.MROp(op, size, result, asAllocatable(input)));
         return result;
     }
 
@@ -1006,13 +1001,13 @@
             assert inputVal.getKind() == Kind.Long;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
             long mask = CodeUtil.mask(fromBits);
-            append(new AMD64BinaryPatchOp(AND.getRMOpcode(QWORD), QWORD, result, asAllocatable(inputVal), JavaConstant.forLong(mask)));
+            append(new AMD64Binary.DataOp(AND.getRMOpcode(QWORD), QWORD, result, asAllocatable(inputVal), JavaConstant.forLong(mask)));
             return result;
         } else {
             assert inputVal.getKind().getStackKind() == Kind.Int;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
             int mask = (int) CodeUtil.mask(fromBits);
-            append(new AMD64BinaryPatchOp(AND.getRMOpcode(DWORD), DWORD, result, asAllocatable(inputVal), JavaConstant.forInt(mask)));
+            append(new AMD64Binary.DataOp(AND.getRMOpcode(DWORD), DWORD, result, asAllocatable(inputVal), JavaConstant.forInt(mask)));
             if (toBits > 32) {
                 Variable longResult = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
                 emitMove(longResult, result);
@@ -1047,9 +1042,9 @@
     public Variable emitBitCount(Value value) {
         Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
-            append(new AMD64UnaryRMOp(POPCNT, DWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(POPCNT, DWORD, result, asAllocatable(value)));
         } else {
-            append(new AMD64UnaryRMOp(POPCNT, QWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(POPCNT, QWORD, result, asAllocatable(value)));
         }
         return result;
     }
@@ -1057,7 +1052,7 @@
     @Override
     public Variable emitBitScanForward(Value value) {
         Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
-        append(new AMD64UnaryRMOp(BSF, QWORD, result, asAllocatable(value)));
+        append(new AMD64Unary.RMOp(BSF, QWORD, result, asAllocatable(value)));
         return result;
     }
 
@@ -1065,9 +1060,9 @@
     public Variable emitBitScanReverse(Value value) {
         Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
-            append(new AMD64UnaryRMOp(BSR, DWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(BSR, DWORD, result, asAllocatable(value)));
         } else {
-            append(new AMD64UnaryRMOp(BSR, QWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(BSR, QWORD, result, asAllocatable(value)));
         }
         return result;
     }
@@ -1075,9 +1070,9 @@
     public Value emitCountLeadingZeros(Value value) {
         Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
-            append(new AMD64UnaryRMOp(LZCNT, DWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(LZCNT, DWORD, result, asAllocatable(value)));
         } else {
-            append(new AMD64UnaryRMOp(LZCNT, QWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(LZCNT, QWORD, result, asAllocatable(value)));
         }
         return result;
     }
@@ -1085,9 +1080,9 @@
     public Value emitCountTrailingZeros(Value value) {
         Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
-            append(new AMD64UnaryRMOp(TZCNT, DWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(TZCNT, DWORD, result, asAllocatable(value)));
         } else {
-            append(new AMD64UnaryRMOp(TZCNT, QWORD, result, asAllocatable(value)));
+            append(new AMD64Unary.RMOp(TZCNT, QWORD, result, asAllocatable(value)));
         }
         return result;
     }
@@ -1097,10 +1092,10 @@
         Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Float:
-                append(new AMD64BinaryPatchOp(SSEOp.AND, PS, result, asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)), 16));
+                append(new AMD64Binary.DataOp(SSEOp.AND, PS, result, asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)), 16));
                 break;
             case Double:
-                append(new AMD64BinaryPatchOp(SSEOp.AND, PD, result, asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)), 16));
+                append(new AMD64Binary.DataOp(SSEOp.AND, PD, result, asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)), 16));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -1113,10 +1108,10 @@
         Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Float:
-                append(new AMD64UnaryRMOp(SSEOp.SQRT, SS, result, asAllocatable(input)));
+                append(new AMD64Unary.RMOp(SSEOp.SQRT, SS, result, asAllocatable(input)));
                 break;
             case Double:
-                append(new AMD64UnaryRMOp(SSEOp.SQRT, SD, result, asAllocatable(input)));
+                append(new AMD64Unary.RMOp(SSEOp.SQRT, SD, result, asAllocatable(input)));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Sat Mar 21 15:41:55 2015 +0100
@@ -214,13 +214,13 @@
                 return null;
             }
             return builder -> {
-                gen.append(new AMD64CompareMemoryConstOp(AMD64MIOp.TEST, size, makeAddress(access), constant, getState(access)));
+                gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, makeAddress(access), (int) constant.asLong(), getState(access)));
                 gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
                 return null;
             };
         } else {
             return builder -> {
-                gen.append(new AMD64CompareMemoryOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), makeAddress(access), getState(access)));
+                gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), makeAddress(access), getState(access)));
                 gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
                 return null;
             };
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Sat Mar 21 15:41:55 2015 +0100
@@ -168,7 +168,7 @@
      * {@link InvocationPlugins} in the copy.
      */
     public GraphBuilderConfiguration copy() {
-        Plugins newPlugins = new Plugins(new InvocationPlugins(plugins.getInvocationPlugins()));
+        Plugins newPlugins = new Plugins(plugins);
         GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, newPlugins);
         result.useProfiling = useProfiling;
         return result;
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Sat Mar 21 15:41:55 2015 +0100
@@ -59,11 +59,6 @@
          * Determines if the receiver is constant.
          */
         boolean isConstant();
-
-        /**
-         * Determines if the receiver is the null constant.
-         */
-        boolean isNullConstant();
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBinaryConsumer.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 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.hotspot.amd64;
+
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+
+public class AMD64HotSpotBinaryConsumer {
+
+    /**
+     * Instruction that has one {@link AllocatableValue} operand and one {@link HotSpotConstant}
+     * operand.
+     */
+    public static class ConstOp extends AMD64BinaryConsumer.ConstOp {
+        public static final LIRInstructionClass<ConstOp> TYPE = LIRInstructionClass.create(ConstOp.class);
+
+        protected final HotSpotConstant c;
+
+        public ConstOp(AMD64MIOp opcode, AllocatableValue x, HotSpotConstant c) {
+            super(TYPE, opcode, DWORD, x, asImm32(c));
+            this.c = c;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            assert crb.target.inlineObjects || !(c instanceof HotSpotObjectConstant);
+            crb.recordInlineDataInCode(c);
+            super.emitCode(crb, masm);
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AMD64AddressValue memory} operand and one
+     * {@link HotSpotConstant} operand.
+     */
+    public static class MemoryConstOp extends AMD64BinaryConsumer.MemoryConstOp {
+        public static final LIRInstructionClass<MemoryConstOp> TYPE = LIRInstructionClass.create(MemoryConstOp.class);
+
+        protected final HotSpotConstant c;
+
+        public MemoryConstOp(AMD64MIOp opcode, AMD64AddressValue x, HotSpotConstant c, LIRFrameState state) {
+            super(TYPE, opcode, DWORD, x, asImm32(c), state);
+            this.c = c;
+
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            assert crb.target.inlineObjects || !(c instanceof HotSpotObjectConstant);
+            crb.recordInlineDataInCode(c);
+            super.emitCode(crb, masm);
+        }
+    }
+
+    private static int asImm32(HotSpotConstant c) {
+        assert c.isCompressed();
+        if (c instanceof HotSpotMetaspaceConstant) {
+            return (int) ((HotSpotMetaspaceConstant) c).rawValue();
+        } else {
+            assert c instanceof HotSpotObjectConstant;
+            return 0xDEADDEAD;
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompareConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2015, 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.hotspot.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64HotSpotCompareConstOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64HotSpotCompareConstOp> TYPE = LIRInstructionClass.create(AMD64HotSpotCompareConstOp.class);
-
-    @Opcode private final AMD64MIOp opcode;
-
-    @Use({REG, STACK}) protected AllocatableValue x;
-    protected HotSpotConstant y;
-
-    public AMD64HotSpotCompareConstOp(AMD64MIOp opcode, AllocatableValue x, HotSpotConstant y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.x = x;
-        this.y = y;
-
-        assert y.isCompressed();
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        int imm32;
-        if (y instanceof HotSpotMetaspaceConstant) {
-            imm32 = (int) ((HotSpotMetaspaceConstant) y).rawValue();
-        } else {
-            assert y instanceof HotSpotObjectConstant;
-            imm32 = 0xDEADDEAD;
-        }
-
-        crb.recordInlineDataInCode(y);
-        if (isRegister(x)) {
-            opcode.emit(masm, DWORD, asRegister(x), imm32);
-        } else {
-            assert isStackSlot(x);
-            opcode.emit(masm, DWORD, (AMD64Address) crb.asAddress(x), imm32);
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompareMemoryConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2015, 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.hotspot.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64HotSpotCompareMemoryConstOp extends AMD64LIRInstruction implements ImplicitNullCheck {
-    public static final LIRInstructionClass<AMD64HotSpotCompareMemoryConstOp> TYPE = LIRInstructionClass.create(AMD64HotSpotCompareMemoryConstOp.class);
-
-    @Opcode private final AMD64MIOp opcode;
-
-    @Use({COMPOSITE}) protected AMD64AddressValue x;
-    protected HotSpotConstant y;
-
-    @State protected LIRFrameState state;
-
-    public AMD64HotSpotCompareMemoryConstOp(AMD64MIOp opcode, AMD64AddressValue x, HotSpotConstant y, LIRFrameState state) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.x = x;
-        this.y = y;
-        this.state = state;
-
-        assert y.isCompressed();
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        int imm32;
-        if (y instanceof HotSpotMetaspaceConstant) {
-            imm32 = (int) ((HotSpotMetaspaceConstant) y).rawValue();
-        } else {
-            assert y instanceof HotSpotObjectConstant;
-            imm32 = 0xDEADDEAD;
-        }
-
-        crb.recordInlineDataInCode(y);
-        if (isRegister(x)) {
-            opcode.emit(masm, DWORD, asRegister(x), imm32);
-        } else {
-            assert isStackSlot(x);
-            opcode.emit(masm, DWORD, (AMD64Address) crb.asAddress(x), imm32);
-        }
-    }
-
-    public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-        if (state == null && x.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
-            state = nullCheckState;
-            return true;
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotComparePatchOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2015, 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.hotspot.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64HotSpotComparePatchOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64HotSpotComparePatchOp> TYPE = LIRInstructionClass.create(AMD64HotSpotComparePatchOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Use({REG}) protected AllocatableValue x;
-    protected HotSpotConstant y;
-
-    public AMD64HotSpotComparePatchOp(AMD64RMOp opcode, OperandSize size, AllocatableValue x, HotSpotConstant y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AMD64Address addr = (AMD64Address) crb.recordDataReferenceInCode(y, size.getBytes());
-        opcode.emit(masm, size, asRegister(x), addr);
-    }
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sat Mar 21 15:41:55 2015 +0100
@@ -34,6 +34,9 @@
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
 import com.oracle.graal.compiler.amd64.*;
 import com.oracle.graal.compiler.common.*;
@@ -42,7 +45,6 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
-import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.HotSpotStoreConstantOp;
 import com.oracle.graal.hotspot.debug.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
@@ -53,9 +55,7 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
 import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
@@ -506,22 +506,137 @@
     public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
         AMD64AddressValue loadAddress = asAddressValue(address);
         Variable result = newVariable(toStackKind(kind));
-        append(new LoadOp((Kind) kind.getPlatformKind(), result, loadAddress, state));
+        switch ((Kind) kind.getPlatformKind()) {
+            case Boolean:
+                append(new AMD64Unary.MemoryOp(MOVZXB, DWORD, result, loadAddress, state));
+                break;
+            case Byte:
+                append(new AMD64Unary.MemoryOp(MOVSXB, DWORD, result, loadAddress, state));
+                break;
+            case Char:
+                append(new AMD64Unary.MemoryOp(MOVZX, DWORD, result, loadAddress, state));
+                break;
+            case Short:
+                append(new AMD64Unary.MemoryOp(MOVSX, DWORD, result, loadAddress, state));
+                break;
+            case Int:
+                append(new AMD64Unary.MemoryOp(MOV, DWORD, result, loadAddress, state));
+                break;
+            case Long:
+            case Object:
+                append(new AMD64Unary.MemoryOp(MOV, QWORD, result, loadAddress, state));
+                break;
+            case Float:
+                append(new AMD64Unary.MemoryOp(MOVSS, SS, result, loadAddress, state));
+                break;
+            case Double:
+                append(new AMD64Unary.MemoryOp(MOVSD, SD, result, loadAddress, state));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
         return result;
     }
 
+    private void emitStoreConst(Kind kind, AMD64AddressValue address, JavaConstant value, LIRFrameState state) {
+        if (value.isNull()) {
+            assert kind == Kind.Int || kind == Kind.Long || kind == Kind.Object;
+            OperandSize size = kind == Kind.Int ? DWORD : QWORD;
+            append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.MOV, size, address, 0, state));
+        } else if (value instanceof HotSpotConstant) {
+            HotSpotConstant c = (HotSpotConstant) value;
+            if (c.isCompressed()) {
+                assert kind == Kind.Int;
+                if (!target().inlineObjects && c instanceof HotSpotObjectConstant) {
+                    emitStore(kind, address, asAllocatable(value), state);
+                } else {
+                    append(new AMD64HotSpotBinaryConsumer.MemoryConstOp(AMD64MIOp.MOV, address, c, state));
+                }
+            } else {
+                emitStore(kind, address, asAllocatable(value), state);
+            }
+        } else {
+            AMD64MIOp op = AMD64MIOp.MOV;
+            OperandSize size;
+            long imm;
+
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                    op = AMD64MIOp.MOVB;
+                    size = BYTE;
+                    imm = value.asInt();
+                    break;
+                case Char:
+                case Short:
+                    size = WORD;
+                    imm = value.asInt();
+                    break;
+                case Int:
+                    size = DWORD;
+                    imm = value.asInt();
+                    break;
+                case Long:
+                    size = QWORD;
+                    imm = value.asLong();
+                    break;
+                case Float:
+                    size = DWORD;
+                    imm = Float.floatToRawIntBits(value.asFloat());
+                    break;
+                case Double:
+                    size = QWORD;
+                    imm = Double.doubleToRawLongBits(value.asDouble());
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("unexpected kind " + kind);
+            }
+
+            if (NumUtil.isInt(imm)) {
+                append(new AMD64BinaryConsumer.MemoryConstOp(op, size, address, (int) imm, state));
+            } else {
+                emitStore(kind, address, asAllocatable(value), state);
+            }
+        }
+    }
+
+    private void emitStore(Kind kind, AMD64AddressValue address, AllocatableValue value, LIRFrameState state) {
+        switch (kind) {
+            case Boolean:
+            case Byte:
+                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVB, BYTE, address, value, state));
+                break;
+            case Char:
+            case Short:
+                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, WORD, address, value, state));
+                break;
+            case Int:
+                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, DWORD, address, value, state));
+                break;
+            case Long:
+            case Object:
+                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, QWORD, address, value, state));
+                break;
+            case Float:
+                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVSS, SS, address, value, state));
+                break;
+            case Double:
+                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVSD, SD, address, value, state));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     @Override
-    public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
+    public void emitStore(LIRKind lirKind, Value address, Value input, LIRFrameState state) {
         AMD64AddressValue storeAddress = asAddressValue(address);
-        if (isConstant(inputVal)) {
-            JavaConstant c = asConstant(inputVal);
-            if (canStoreConstant(c)) {
-                append(new HotSpotStoreConstantOp((Kind) kind.getPlatformKind(), storeAddress, c, state));
-                return;
-            }
+        Kind kind = (Kind) lirKind.getPlatformKind();
+        if (isConstant(input)) {
+            emitStoreConst(kind, storeAddress, asConstant(input), state);
+        } else {
+            emitStore(kind, storeAddress, asAllocatable(input), state);
         }
-        Variable input = load(inputVal);
-        append(new StoreOp((Kind) kind.getPlatformKind(), storeAddress, input, state));
     }
 
     @Override
@@ -628,17 +743,17 @@
     @Override
     protected void emitCompareOp(PlatformKind cmpKind, Variable left, Value right) {
         if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(right)) {
-            append(new AMD64CompareOp(TEST, DWORD, left, left));
+            append(new AMD64BinaryConsumer.Op(TEST, DWORD, left, left));
         } else if (right instanceof HotSpotConstant) {
             HotSpotConstant c = (HotSpotConstant) right;
 
             boolean isImmutable = GraalOptions.ImmutableCode.getValue();
             boolean generatePIC = GraalOptions.GeneratePIC.getValue();
             if (c.isCompressed() && !(isImmutable && generatePIC)) {
-                append(new AMD64HotSpotCompareConstOp(CMP.getMIOpcode(DWORD, false), left, c));
+                append(new AMD64HotSpotBinaryConsumer.ConstOp(CMP.getMIOpcode(DWORD, false), left, c));
             } else {
                 OperandSize size = c.isCompressed() ? DWORD : QWORD;
-                append(new AMD64HotSpotComparePatchOp(CMP.getRMOpcode(size), size, left, c));
+                append(new AMD64BinaryConsumer.DataOp(CMP.getRMOpcode(size), size, left, c));
             }
         } else {
             super.emitCompareOp(cmpKind, left, right);
@@ -648,11 +763,11 @@
     @Override
     protected boolean emitCompareMemoryConOp(OperandSize size, JavaConstant a, AMD64AddressValue b, LIRFrameState state) {
         if (a.isNull()) {
-            append(new AMD64CompareMemoryConstOp(CMP.getMIOpcode(size, true), size, b, PrimitiveConstant.INT_0, state));
+            append(new AMD64BinaryConsumer.MemoryConstOp(CMP, size, b, 0, state));
             return true;
         } else if (a instanceof HotSpotConstant && size == DWORD) {
             assert ((HotSpotConstant) a).isCompressed();
-            append(new AMD64HotSpotCompareMemoryConstOp(CMP.getMIOpcode(size, false), b, (HotSpotConstant) a, state));
+            append(new AMD64HotSpotBinaryConsumer.MemoryConstOp(CMP.getMIOpcode(size, false), b, (HotSpotConstant) a, state));
             return true;
         } else {
             return super.emitCompareMemoryConOp(size, a, b, state);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Sat Mar 21 15:41:55 2015 +0100
@@ -38,7 +38,6 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
 import com.oracle.graal.lir.asm.*;
 
 public class AMD64HotSpotMove {
@@ -146,44 +145,6 @@
         }
     }
 
-    public static class HotSpotStoreConstantOp extends StoreConstantOp {
-        public static final LIRInstructionClass<HotSpotStoreConstantOp> TYPE = LIRInstructionClass.create(HotSpotStoreConstantOp.class);
-
-        public HotSpotStoreConstantOp(Kind kind, AMD64AddressValue address, JavaConstant input, LIRFrameState state) {
-            super(TYPE, kind, address, input, state);
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            if (input.isNull() && kind == Kind.Int) {
-                // compressed null
-                masm.movl(address.toAddress(), 0);
-            } else if (input instanceof HotSpotObjectConstant) {
-                HotSpotObjectConstant c = (HotSpotObjectConstant) input;
-                if (c.isCompressed() && crb.target.inlineObjects) {
-                    // compressed oop
-                    crb.recordInlineDataInCode(input);
-                    masm.movl(address.toAddress(), 0xDEADDEAD);
-                } else {
-                    // uncompressed oop
-                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                }
-            } else if (input instanceof HotSpotMetaspaceConstant) {
-                if (input.getKind() == Kind.Int) {
-                    // compressed metaspace pointer
-                    crb.recordInlineDataInCode(input);
-                    masm.movl(address.toAddress(), input.asInt());
-                } else {
-                    // uncompressed metaspace pointer
-                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                }
-            } else {
-                // primitive value
-                super.emitMemAccess(crb, masm);
-            }
-        }
-    }
-
     public static final class CompressPointer extends AMD64LIRInstruction {
         public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Sat Mar 21 15:41:55 2015 +0100
@@ -141,7 +141,7 @@
         Registration r = new Registration(plugins, StableOptionValue.class);
         r.register1("getValue", Receiver.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                if (receiver.isConstant() && !receiver.isNullConstant()) {
+                if (receiver.isConstant()) {
                     Object object = ((HotSpotObjectConstantImpl) receiver.get().asConstant()).object();
                     StableOptionValue<?> option = (StableOptionValue<?>) object;
                     ConstantNode value = b.append(ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(option.getValue()), b.getMetaAccess()));
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Mar 21 15:41:55 2015 +0100
@@ -261,11 +261,6 @@
                 return args[0].isConstant();
             }
 
-            @Override
-            public boolean isNullConstant() {
-                return args[0].isNullConstant();
-            }
-
             InvocationPluginReceiver init(ResolvedJavaMethod targetMethod, ValueNode[] newArgs) {
                 if (!targetMethod.isStatic()) {
                     this.args = newArgs;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Binary.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2015, 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.lir.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.code.CompilationResult.DataSectionReference;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * AMD64 LIR instructions that have two inputs and one output.
+ */
+public class AMD64Binary {
+
+    /**
+     * Instruction that has two {@link AllocatableValue} operands.
+     */
+    public static class Op extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<Op> TYPE = LIRInstructionClass.create(Op.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        @Alive({REG, STACK}) protected AllocatableValue y;
+
+        public Op(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            if (isRegister(y)) {
+                opcode.emit(masm, size, asRegister(result), asRegister(y));
+            } else {
+                assert isStackSlot(y);
+                opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(y));
+            }
+        }
+    }
+
+    /**
+     * Commutative instruction that has two {@link AllocatableValue} operands.
+     */
+    public static class CommutativeOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<CommutativeOp> TYPE = LIRInstructionClass.create(CommutativeOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        @Use({REG, STACK}) protected AllocatableValue y;
+
+        public CommutativeOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AllocatableValue input;
+            if (sameRegister(result, y)) {
+                input = x;
+            } else {
+                AMD64Move.move(crb, masm, result, x);
+                input = y;
+            }
+
+            if (isRegister(input)) {
+                opcode.emit(masm, size, asRegister(result), asRegister(input));
+            } else {
+                assert isStackSlot(input);
+                opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
+            }
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AllocatableValue} operand and one 32-bit immediate operand.
+     */
+    public static class ConstOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<ConstOp> TYPE = LIRInstructionClass.create(ConstOp.class);
+
+        @Opcode private final AMD64MIOp opcode;
+        private final OperandSize size;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        private final int y;
+
+        public ConstOp(AMD64BinaryArithmetic opcode, OperandSize size, AllocatableValue result, AllocatableValue x, int y) {
+            this(opcode.getMIOpcode(size, NumUtil.isByte(y)), size, result, x, y);
+        }
+
+        public ConstOp(AMD64MIOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, int y) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            opcode.emit(masm, size, asRegister(result), y);
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AllocatableValue} operand and one
+     * {@link DataSectionReference} operand.
+     */
+    public static class DataOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<DataOp> TYPE = LIRInstructionClass.create(DataOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        private final JavaConstant y;
+
+        private final int alignment;
+
+        public DataOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) {
+            this(opcode, size, result, x, y, y.getKind().getByteCount());
+        }
+
+        public DataOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y, int alignment) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.x = x;
+            this.y = y;
+
+            this.alignment = alignment;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(y, alignment));
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AllocatableValue} operand and one {@link AMD64AddressValue
+     * memory} operand.
+     */
+    public static class MemoryOp extends AMD64LIRInstruction implements ImplicitNullCheck {
+        public static final LIRInstructionClass<MemoryOp> TYPE = LIRInstructionClass.create(MemoryOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        @Alive({COMPOSITE}) protected AMD64AddressValue y;
+
+        @State protected LIRFrameState state;
+
+        public MemoryOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.x = x;
+            this.y = y;
+
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            if (state != null) {
+                crb.recordImplicitException(masm.position(), state);
+            }
+            opcode.emit(masm, size, asRegister(result), y.toAddress());
+        }
+
+        @Override
+        public void verify() {
+            super.verify();
+            assert differentRegisters(result, y) || sameRegister(x, y);
+        }
+
+        @Override
+        public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
+            if (state == null && y.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
+                state = nullCheckState;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Instruction with a separate result operand, one {@link AllocatableValue} input and one 32-bit
+     * immediate input.
+     */
+    public static class RMIOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<RMIOp> TYPE = LIRInstructionClass.create(RMIOp.class);
+
+        @Opcode private final AMD64RMIOp opcode;
+        private final OperandSize size;
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        private final int y;
+
+        public RMIOp(AMD64RMIOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, int y) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (isRegister(x)) {
+                opcode.emit(masm, size, asRegister(result), asRegister(x), y);
+            } else {
+                assert isStackSlot(x);
+                opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(x), y);
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryCommutativeOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64BinaryCommutativeOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64BinaryCommutativeOp> TYPE = LIRInstructionClass.create(AMD64BinaryCommutativeOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Def({REG, HINT}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    @Use({REG, STACK}) protected AllocatableValue y;
-
-    public AMD64BinaryCommutativeOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AllocatableValue input;
-        if (sameRegister(result, y)) {
-            input = x;
-        } else {
-            AMD64Move.move(crb, masm, result, x);
-            input = y;
-        }
-
-        if (isRegister(input)) {
-            opcode.emit(masm, size, asRegister(result), asRegister(input));
-        } else {
-            assert isStackSlot(input);
-            opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64BinaryConstOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64BinaryConstOp> TYPE = LIRInstructionClass.create(AMD64BinaryConstOp.class);
-
-    @Opcode private final AMD64MIOp opcode;
-    private final OperandSize size;
-
-    @Def({REG, HINT}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    protected JavaConstant y;
-
-    public AMD64BinaryConstOp(AMD64BinaryArithmetic opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) {
-        this(opcode.getMIOpcode(size, NumUtil.isByte(y.asLong())), size, result, x, y);
-    }
-
-    public AMD64BinaryConstOp(AMD64MIOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AMD64Move.move(crb, masm, result, x);
-        assert NumUtil.is32bit(y.asLong());
-        opcode.emit(masm, size, asRegister(result), (int) y.asLong());
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryConsumer.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2015, 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.lir.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.code.CompilationResult.DataSectionReference;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * AMD64 LIR instructions that have two input operands, but no output operand.
+ */
+public class AMD64BinaryConsumer {
+
+    /**
+     * Instruction that has two {@link AllocatableValue} operands.
+     */
+    public static class Op extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<Op> TYPE = LIRInstructionClass.create(Op.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Use({REG}) protected AllocatableValue x;
+        @Use({REG, STACK}) protected AllocatableValue y;
+
+        public Op(AMD64RMOp opcode, OperandSize size, AllocatableValue x, AllocatableValue y) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (isRegister(y)) {
+                opcode.emit(masm, size, asRegister(x), asRegister(y));
+            } else {
+                assert isStackSlot(y);
+                opcode.emit(masm, size, asRegister(x), (AMD64Address) crb.asAddress(y));
+            }
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AllocatableValue} operand and one 32-bit immediate operand.
+     */
+    public static class ConstOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<ConstOp> TYPE = LIRInstructionClass.create(ConstOp.class);
+
+        @Opcode private final AMD64MIOp opcode;
+        private final OperandSize size;
+
+        @Use({REG, STACK}) protected AllocatableValue x;
+        private final int y;
+
+        public ConstOp(AMD64BinaryArithmetic opcode, OperandSize size, AllocatableValue x, int y) {
+            this(opcode.getMIOpcode(size, NumUtil.isByte(y)), size, x, y);
+        }
+
+        public ConstOp(AMD64MIOp opcode, OperandSize size, AllocatableValue x, int y) {
+            this(TYPE, opcode, size, x, y);
+        }
+
+        protected ConstOp(LIRInstructionClass<? extends ConstOp> c, AMD64MIOp opcode, OperandSize size, AllocatableValue x, int y) {
+            super(c);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (isRegister(x)) {
+                opcode.emit(masm, size, asRegister(x), y);
+            } else {
+                assert isStackSlot(x);
+                opcode.emit(masm, size, (AMD64Address) crb.asAddress(x), y);
+            }
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AllocatableValue} operand and one
+     * {@link DataSectionReference} operand.
+     */
+    public static class DataOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<DataOp> TYPE = LIRInstructionClass.create(DataOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Use({REG}) protected AllocatableValue x;
+        private final Constant y;
+
+        private final int alignment;
+
+        public DataOp(AMD64RMOp opcode, OperandSize size, AllocatableValue x, Constant y) {
+            this(opcode, size, x, y, size.getBytes());
+        }
+
+        public DataOp(AMD64RMOp opcode, OperandSize size, AllocatableValue x, Constant y, int alignment) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.x = x;
+            this.y = y;
+
+            this.alignment = alignment;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            opcode.emit(masm, size, asRegister(x), (AMD64Address) crb.recordDataReferenceInCode(y, alignment));
+        }
+    }
+
+    /**
+     * Instruction that has an {@link AllocatableValue} as first input and a
+     * {@link AMD64AddressValue memory} operand as second input.
+     */
+    public static class MemoryRMOp extends AMD64LIRInstruction implements ImplicitNullCheck {
+        public static final LIRInstructionClass<MemoryRMOp> TYPE = LIRInstructionClass.create(MemoryRMOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Use({REG}) protected AllocatableValue x;
+        @Use({COMPOSITE}) protected AMD64AddressValue y;
+
+        @State protected LIRFrameState state;
+
+        public MemoryRMOp(AMD64RMOp opcode, OperandSize size, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.x = x;
+            this.y = y;
+
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (state != null) {
+                crb.recordImplicitException(masm.position(), state);
+            }
+            opcode.emit(masm, size, asRegister(x), y.toAddress());
+        }
+
+        @Override
+        public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
+            if (state == null && y.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
+                state = nullCheckState;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Instruction that has a {@link AMD64AddressValue memory} operand as first input and an
+     * {@link AllocatableValue} as second input.
+     */
+    public static class MemoryMROp extends AMD64LIRInstruction implements ImplicitNullCheck {
+        public static final LIRInstructionClass<MemoryMROp> TYPE = LIRInstructionClass.create(MemoryMROp.class);
+
+        @Opcode private final AMD64MROp opcode;
+        private final OperandSize size;
+
+        @Use({COMPOSITE}) protected AMD64AddressValue x;
+        @Use({REG}) protected AllocatableValue y;
+
+        @State protected LIRFrameState state;
+
+        public MemoryMROp(AMD64MROp opcode, OperandSize size, AMD64AddressValue x, AllocatableValue y, LIRFrameState state) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.x = x;
+            this.y = y;
+
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (state != null) {
+                crb.recordImplicitException(masm.position(), state);
+            }
+            opcode.emit(masm, size, x.toAddress(), asRegister(y));
+        }
+
+        @Override
+        public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
+            if (state == null && x.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
+                state = nullCheckState;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Instruction that has one {@link AMD64AddressValue memory} operand and one 32-bit immediate
+     * operand.
+     */
+    public static class MemoryConstOp extends AMD64LIRInstruction implements ImplicitNullCheck {
+        public static final LIRInstructionClass<MemoryConstOp> TYPE = LIRInstructionClass.create(MemoryConstOp.class);
+
+        @Opcode private final AMD64MIOp opcode;
+        private final OperandSize size;
+
+        @Use({COMPOSITE}) protected AMD64AddressValue x;
+        private final int y;
+
+        @State protected LIRFrameState state;
+
+        public MemoryConstOp(AMD64BinaryArithmetic opcode, OperandSize size, AMD64AddressValue x, int y, LIRFrameState state) {
+            this(opcode.getMIOpcode(size, NumUtil.isByte(y)), size, x, y, state);
+        }
+
+        public MemoryConstOp(AMD64MIOp opcode, OperandSize size, AMD64AddressValue x, int y, LIRFrameState state) {
+            this(TYPE, opcode, size, x, y, state);
+        }
+
+        protected MemoryConstOp(LIRInstructionClass<? extends MemoryConstOp> c, AMD64MIOp opcode, OperandSize size, AMD64AddressValue x, int y, LIRFrameState state) {
+            super(c);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.x = x;
+            this.y = y;
+
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (state != null) {
+                crb.recordImplicitException(masm.position(), state);
+            }
+            opcode.emit(masm, size, x.toAddress(), y);
+        }
+
+        @Override
+        public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
+            if (state == null && x.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
+                state = nullCheckState;
+                return true;
+            }
+            return false;
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryMemoryOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64BinaryMemoryOp extends AMD64LIRInstruction implements ImplicitNullCheck {
-    public static final LIRInstructionClass<AMD64BinaryMemoryOp> TYPE = LIRInstructionClass.create(AMD64BinaryMemoryOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Def({REG, HINT}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    @Alive({COMPOSITE}) protected AMD64AddressValue y;
-
-    @State protected LIRFrameState state;
-
-    public AMD64BinaryMemoryOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-
-        this.state = state;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AMD64Move.move(crb, masm, result, x);
-        if (state != null) {
-            crb.recordImplicitException(masm.position(), state);
-        }
-        opcode.emit(masm, size, asRegister(result), y.toAddress());
-    }
-
-    @Override
-    public void verify() {
-        super.verify();
-        assert differentRegisters(result, y) || sameRegister(x, y);
-    }
-
-    @Override
-    public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-        if (state == null && y.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
-            state = nullCheckState;
-            return true;
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64BinaryOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64BinaryOp> TYPE = LIRInstructionClass.create(AMD64BinaryOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Def({REG, HINT}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    @Alive({REG, STACK}) protected AllocatableValue y;
-
-    public AMD64BinaryOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AMD64Move.move(crb, masm, result, x);
-        if (isRegister(y)) {
-            opcode.emit(masm, size, asRegister(result), asRegister(y));
-        } else {
-            assert isStackSlot(y);
-            opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(y));
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BinaryPatchOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64BinaryPatchOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64BinaryPatchOp> TYPE = LIRInstructionClass.create(AMD64BinaryPatchOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Def({REG, HINT}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    protected JavaConstant y;
-
-    private final int alignment;
-
-    public AMD64BinaryPatchOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) {
-        this(opcode, size, result, x, y, y.getKind().getByteCount());
-    }
-
-    public AMD64BinaryPatchOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y, int alignment) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-
-        this.alignment = alignment;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AMD64Move.move(crb, masm, result, x);
-        opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(y, alignment));
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64CompareConstOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64CompareConstOp> TYPE = LIRInstructionClass.create(AMD64CompareConstOp.class);
-
-    @Opcode private final AMD64MIOp opcode;
-    private final OperandSize size;
-
-    @Use({REG, STACK}) protected AllocatableValue x;
-    protected JavaConstant y;
-
-    public AMD64CompareConstOp(AMD64MIOp opcode, OperandSize size, AllocatableValue x, JavaConstant y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        assert NumUtil.is32bit(y.asLong());
-        if (isRegister(x)) {
-            opcode.emit(masm, size, asRegister(x), (int) y.asLong());
-        } else {
-            assert isStackSlot(x);
-            opcode.emit(masm, size, (AMD64Address) crb.asAddress(x), (int) y.asLong());
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareMemoryConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64CompareMemoryConstOp extends AMD64LIRInstruction implements ImplicitNullCheck {
-    public static final LIRInstructionClass<AMD64CompareMemoryConstOp> TYPE = LIRInstructionClass.create(AMD64CompareMemoryConstOp.class);
-
-    @Opcode private final AMD64MIOp opcode;
-    private final OperandSize size;
-
-    @Use({COMPOSITE}) protected AMD64AddressValue x;
-    protected JavaConstant y;
-
-    @State protected LIRFrameState state;
-
-    public AMD64CompareMemoryConstOp(AMD64MIOp opcode, OperandSize size, AMD64AddressValue x, JavaConstant y, LIRFrameState state) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.x = x;
-        this.y = y;
-
-        this.state = state;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (state != null) {
-            crb.recordImplicitException(masm.position(), state);
-        }
-        assert NumUtil.is32bit(y.asLong());
-        opcode.emit(masm, size, x.toAddress(), (int) y.asLong());
-    }
-
-    @Override
-    public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-        if (state == null && x.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
-            state = nullCheckState;
-            return true;
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareMemoryOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64CompareMemoryOp extends AMD64LIRInstruction implements ImplicitNullCheck {
-    public static final LIRInstructionClass<AMD64CompareMemoryOp> TYPE = LIRInstructionClass.create(AMD64CompareMemoryOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Use({REG}) protected AllocatableValue x;
-    @Use({COMPOSITE}) protected AMD64AddressValue y;
-
-    @State protected LIRFrameState state;
-
-    public AMD64CompareMemoryOp(AMD64RMOp opcode, OperandSize size, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.x = x;
-        this.y = y;
-
-        this.state = state;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (state != null) {
-            crb.recordImplicitException(masm.position(), state);
-        }
-        opcode.emit(masm, size, asRegister(x), y.toAddress());
-    }
-
-    @Override
-    public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-        if (state == null && y.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
-            state = nullCheckState;
-            return true;
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CompareOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64CompareOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64CompareOp> TYPE = LIRInstructionClass.create(AMD64CompareOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Use({REG}) protected AllocatableValue x;
-    @Use({REG, STACK}) protected AllocatableValue y;
-
-    public AMD64CompareOp(AMD64RMOp opcode, OperandSize size, AllocatableValue x, AllocatableValue y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (isRegister(y)) {
-            opcode.emit(masm, size, asRegister(x), asRegister(y));
-        } else {
-            assert isStackSlot(y);
-            opcode.emit(masm, size, asRegister(x), (AMD64Address) crb.asAddress(y));
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Sat Mar 21 15:41:55 2015 +0100
@@ -30,11 +30,9 @@
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.StandardOp.NullCheck;
 import com.oracle.graal.lir.asm.*;
@@ -110,210 +108,6 @@
         }
     }
 
-    public abstract static class MemOp extends AMD64LIRInstruction implements ImplicitNullCheck {
-        public static final LIRInstructionClass<MemOp> TYPE = LIRInstructionClass.create(MemOp.class);
-
-        protected final Kind kind;
-        @Use({COMPOSITE}) protected AMD64AddressValue address;
-        @State protected LIRFrameState state;
-
-        public MemOp(LIRInstructionClass<? extends MemOp> c, Kind kind, AMD64AddressValue address, LIRFrameState state) {
-            super(c);
-            this.kind = kind;
-            this.address = address;
-            this.state = state;
-        }
-
-        protected abstract void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm);
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            if (state != null) {
-                crb.recordImplicitException(masm.position(), state);
-            }
-            emitMemAccess(crb, masm);
-        }
-
-        public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-            if (state == null && value.equals(address.base) && address.index.equals(Value.ILLEGAL) && address.displacement >= 0 && address.displacement < implicitNullCheckLimit) {
-                state = nullCheckState;
-                return true;
-            }
-            return false;
-        }
-    }
-
-    public static final class LoadOp extends MemOp {
-        public static final LIRInstructionClass<LoadOp> TYPE = LIRInstructionClass.create(LoadOp.class);
-
-        @Def({REG}) protected AllocatableValue result;
-
-        public LoadOp(Kind kind, AllocatableValue result, AMD64AddressValue address, LIRFrameState state) {
-            super(TYPE, kind, address, state);
-            this.result = result;
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            switch (kind) {
-                case Boolean:
-                    masm.movzbl(asRegister(result), address.toAddress());
-                    break;
-                case Byte:
-                    masm.movsbl(asRegister(result), address.toAddress());
-                    break;
-                case Char:
-                    masm.movzwl(asRegister(result), address.toAddress());
-                    break;
-                case Short:
-                    masm.movswl(asRegister(result), address.toAddress());
-                    break;
-                case Int:
-                    masm.movl(asRegister(result), address.toAddress());
-                    break;
-                case Long:
-                    masm.movq(asRegister(result), address.toAddress());
-                    break;
-                case Float:
-                    masm.movflt(asFloatReg(result), address.toAddress());
-                    break;
-                case Double:
-                    masm.movdbl(asDoubleReg(result), address.toAddress());
-                    break;
-                case Object:
-                    masm.movq(asRegister(result), address.toAddress());
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-    }
-
-    public static final class ZeroExtendLoadOp extends MemOp {
-        public static final LIRInstructionClass<ZeroExtendLoadOp> TYPE = LIRInstructionClass.create(ZeroExtendLoadOp.class);
-
-        @Def({REG}) protected AllocatableValue result;
-
-        public ZeroExtendLoadOp(Kind kind, AllocatableValue result, AMD64AddressValue address, LIRFrameState state) {
-            super(TYPE, kind, address, state);
-            this.result = result;
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    masm.movzbl(asRegister(result), address.toAddress());
-                    break;
-                case Char:
-                case Short:
-                    masm.movzwl(asRegister(result), address.toAddress());
-                    break;
-                case Int:
-                    masm.movl(asRegister(result), address.toAddress());
-                    break;
-                case Long:
-                    masm.movq(asRegister(result), address.toAddress());
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-    }
-
-    public static final class StoreOp extends MemOp {
-        public static final LIRInstructionClass<StoreOp> TYPE = LIRInstructionClass.create(StoreOp.class);
-
-        @Use({REG}) protected AllocatableValue input;
-
-        public StoreOp(Kind kind, AMD64AddressValue address, AllocatableValue input, LIRFrameState state) {
-            super(TYPE, kind, address, state);
-            this.input = input;
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            assert isRegister(input);
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    masm.movb(address.toAddress(), asRegister(input));
-                    break;
-                case Char:
-                case Short:
-                    masm.movw(address.toAddress(), asRegister(input));
-                    break;
-                case Int:
-                    masm.movl(address.toAddress(), asRegister(input));
-                    break;
-                case Long:
-                    masm.movq(address.toAddress(), asRegister(input));
-                    break;
-                case Float:
-                    masm.movflt(address.toAddress(), asFloatReg(input));
-                    break;
-                case Double:
-                    masm.movsd(address.toAddress(), asDoubleReg(input));
-                    break;
-                case Object:
-                    masm.movq(address.toAddress(), asRegister(input));
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-    }
-
-    public abstract static class StoreConstantOp extends MemOp {
-        public static final LIRInstructionClass<StoreConstantOp> TYPE = LIRInstructionClass.create(StoreConstantOp.class);
-
-        protected final JavaConstant input;
-
-        protected StoreConstantOp(LIRInstructionClass<? extends StoreConstantOp> c, Kind kind, AMD64AddressValue address, JavaConstant input, LIRFrameState state) {
-            super(c, kind, address, state);
-            this.input = input;
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    masm.movb(address.toAddress(), input.asInt() & 0xFF);
-                    break;
-                case Char:
-                case Short:
-                    masm.movw(address.toAddress(), input.asInt() & 0xFFFF);
-                    break;
-                case Int:
-                    masm.movl(address.toAddress(), input.asInt());
-                    break;
-                case Long:
-                    if (NumUtil.isInt(input.asLong())) {
-                        masm.movslq(address.toAddress(), (int) input.asLong());
-                    } else {
-                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                case Float:
-                    masm.movl(address.toAddress(), floatToRawIntBits(input.asFloat()));
-                    break;
-                case Double:
-                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                case Object:
-                    if (input.isNull()) {
-                        masm.movptr(address.toAddress(), 0);
-                    } else {
-                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-    }
-
     public static final class LeaOp extends AMD64LIRInstruction {
         public static final LIRInstructionClass<LeaOp> TYPE = LIRInstructionClass.create(LeaOp.class);
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MulConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64MulConstOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64MulConstOp> TYPE = LIRInstructionClass.create(AMD64MulConstOp.class);
-
-    @Opcode private final AMD64RMIOp opcode;
-    private final OperandSize size;
-
-    @Def({REG}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    protected JavaConstant y;
-
-    public AMD64MulConstOp(AMD64RMIOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        assert NumUtil.isInt(y.asLong());
-        int imm = (int) y.asLong();
-        if (isRegister(x)) {
-            opcode.emit(masm, size, asRegister(result), asRegister(x), imm);
-        } else {
-            assert isStackSlot(x);
-            opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(x), imm);
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MulDivOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MulDivOp.java	Sat Mar 21 15:41:55 2015 +0100
@@ -34,6 +34,10 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
+/**
+ * AMD64 mul/div operation. This operation has a single operand for the second input. The first
+ * input must be in RAX for mul and in RDX:RAX for div. The result is in RDX:RAX.
+ */
 public class AMD64MulDivOp extends AMD64LIRInstruction {
     public static final LIRInstructionClass<AMD64MulDivOp> TYPE = LIRInstructionClass.create(AMD64MulDivOp.class);
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RegStackConstOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64RegStackConstOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64RegStackConstOp> TYPE = LIRInstructionClass.create(AMD64RegStackConstOp.class);
-
-    @Opcode private final AMD64RMIOp opcode;
-    private final OperandSize size;
-
-    @Def({REG}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue x;
-    protected JavaConstant y;
-
-    public AMD64RegStackConstOp(AMD64RMIOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        assert NumUtil.is32bit(y.asLong());
-        if (isRegister(x)) {
-            opcode.emit(masm, size, asRegister(result), asRegister(x), (int) y.asLong());
-        } else {
-            assert isStackSlot(x);
-            opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(x), (int) y.asLong());
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ShiftOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ShiftOp.java	Sat Mar 21 15:41:55 2015 +0100
@@ -33,6 +33,10 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
+/**
+ * AMD64 shift/rotate operation. This operation has a single operand for the first input and output.
+ * The second input must be in the RCX register.
+ */
 public class AMD64ShiftOp extends AMD64LIRInstruction {
     public static final LIRInstructionClass<AMD64ShiftOp> TYPE = LIRInstructionClass.create(AMD64ShiftOp.class);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Unary.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015, 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.lir.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
+import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * AMD64 LIR instructions that have one input and one output.
+ */
+public class AMD64Unary {
+
+    /**
+     * Instruction with a single operand that is both input and output.
+     */
+    public static class MOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<MOp> TYPE = LIRInstructionClass.create(MOp.class);
+
+        @Opcode private final AMD64MOp opcode;
+        private final OperandSize size;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue value;
+
+        public MOp(AMD64MOp opcode, OperandSize size, AllocatableValue result, AllocatableValue value) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.value = value;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, value);
+            opcode.emit(masm, size, asRegister(result));
+        }
+    }
+
+    /**
+     * Instruction with separate input and output operands, and an operand encoding of RM.
+     */
+    public static class RMOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<RMOp> TYPE = LIRInstructionClass.create(RMOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue value;
+
+        public RMOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue value) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.value = value;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (isRegister(value)) {
+                opcode.emit(masm, size, asRegister(result), asRegister(value));
+            } else {
+                assert isStackSlot(value);
+                opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(value));
+            }
+        }
+    }
+
+    /**
+     * Instruction with separate input and output operands, and an operand encoding of MR.
+     */
+    public static class MROp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<MROp> TYPE = LIRInstructionClass.create(MROp.class);
+
+        @Opcode private final AMD64MROp opcode;
+        private final OperandSize size;
+
+        @Def({REG, STACK}) protected AllocatableValue result;
+        @Use({REG}) protected AllocatableValue value;
+
+        public MROp(AMD64MROp opcode, OperandSize size, AllocatableValue result, AllocatableValue value) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.value = value;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (isRegister(result)) {
+                opcode.emit(masm, size, asRegister(result), asRegister(value));
+            } else {
+                assert isStackSlot(result);
+                opcode.emit(masm, size, (AMD64Address) crb.asAddress(result), asRegister(value));
+            }
+        }
+    }
+
+    /**
+     * Instruction with a {@link AMD64AddressValue memory} operand.
+     */
+    public static class MemoryOp extends AMD64LIRInstruction implements ImplicitNullCheck {
+        public static final LIRInstructionClass<MemoryOp> TYPE = LIRInstructionClass.create(MemoryOp.class);
+
+        @Opcode private final AMD64RMOp opcode;
+        private final OperandSize size;
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({COMPOSITE}) protected AMD64AddressValue input;
+
+        @State protected LIRFrameState state;
+
+        public MemoryOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
+            super(TYPE);
+            this.opcode = opcode;
+            this.size = size;
+
+            this.result = result;
+            this.input = input;
+
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (state != null) {
+                crb.recordImplicitException(masm.position(), state);
+            }
+            opcode.emit(masm, size, asRegister(result), input.toAddress());
+        }
+
+        public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
+            if (state == null && input.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
+                state = nullCheckState;
+                return true;
+            }
+            return false;
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryMOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64UnaryMOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64UnaryMOp> TYPE = LIRInstructionClass.create(AMD64UnaryMOp.class);
-
-    @Opcode private final AMD64MOp opcode;
-    private final OperandSize size;
-
-    @Def({REG, HINT}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue value;
-
-    public AMD64UnaryMOp(AMD64MOp opcode, OperandSize size, AllocatableValue result, AllocatableValue value) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.value = value;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        AMD64Move.move(crb, masm, result, value);
-        opcode.emit(masm, size, asRegister(result));
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryMROp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64UnaryMROp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64UnaryMROp> TYPE = LIRInstructionClass.create(AMD64UnaryMROp.class);
-
-    @Opcode private final AMD64MROp opcode;
-    private final OperandSize size;
-
-    @Def({REG, STACK}) protected AllocatableValue result;
-    @Use({REG}) protected AllocatableValue value;
-
-    public AMD64UnaryMROp(AMD64MROp opcode, OperandSize size, AllocatableValue result, AllocatableValue value) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.value = value;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (isRegister(result)) {
-            opcode.emit(masm, size, asRegister(result), asRegister(value));
-        } else {
-            assert isStackSlot(result);
-            opcode.emit(masm, size, (AMD64Address) crb.asAddress(result), asRegister(value));
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryMemoryOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64UnaryMemoryOp extends AMD64LIRInstruction implements ImplicitNullCheck {
-    public static final LIRInstructionClass<AMD64UnaryMemoryOp> TYPE = LIRInstructionClass.create(AMD64UnaryMemoryOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Def({REG}) protected AllocatableValue result;
-    @Use({COMPOSITE}) protected AMD64AddressValue input;
-
-    @State protected LIRFrameState state;
-
-    public AMD64UnaryMemoryOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.input = input;
-
-        this.state = state;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (state != null) {
-            crb.recordImplicitException(masm.position(), state);
-        }
-        opcode.emit(masm, size, asRegister(result), input.toAddress());
-    }
-
-    public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-        if (state == null && input.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
-            state = nullCheckState;
-            return true;
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64UnaryRMOp.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, 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.lir.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64UnaryRMOp extends AMD64LIRInstruction {
-    public static final LIRInstructionClass<AMD64UnaryRMOp> TYPE = LIRInstructionClass.create(AMD64UnaryRMOp.class);
-
-    @Opcode private final AMD64RMOp opcode;
-    private final OperandSize size;
-
-    @Def({REG}) protected AllocatableValue result;
-    @Use({REG, STACK}) protected AllocatableValue value;
-
-    public AMD64UnaryRMOp(AMD64RMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue value) {
-        super(TYPE);
-        this.opcode = opcode;
-        this.size = size;
-
-        this.result = result;
-        this.value = value;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (isRegister(value)) {
-            opcode.emit(masm, size, asRegister(result), asRegister(value));
-        } else {
-            assert isStackSlot(value);
-            opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(value));
-        }
-    }
-}
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/UnsafeSubstitutionsTest.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/UnsafeSubstitutionsTest.java	Sat Mar 21 15:41:55 2015 +0100
@@ -79,11 +79,6 @@
     }
 
     @Test
-    public void testFoo() throws Exception {
-        testGraph("unsafeDirectMemoryRead");
-    }
-
-    @Test
     public void testUnsafeSubstitutions() throws Exception {
         test("unsafeCompareAndSwapInt", unsafe, supply(() -> new Foo()), fooOffset("i"));
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Sat Mar 21 15:41:55 2015 +0100
@@ -385,7 +385,7 @@
         });
         r.register2("cast", Receiver.class, Object.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
-                if (receiver.isConstant() && !receiver.isNullConstant()) {
+                if (receiver.isConstant()) {
                     ResolvedJavaType type = b.getConstantReflection().asJavaType(receiver.get().asConstant());
                     if (type != null && !type.isPrimitive()) {
                         b.push(Kind.Object, b.append(CheckCastNode.create(type, object, null, false, b.getAssumptions())));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.truffle;
+
+import com.oracle.graal.api.runtime.*;
+import com.oracle.truffle.api.nodes.*;
+
+@ServiceProvider(LoopNodeFactory.class)
+public class DefaultLoopNodeFactory implements LoopNodeFactory {
+
+    public LoopNode create(RepeatingNode repeatingNode) {
+        return new OptimizedLoopNode(repeatingNode);
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategy.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategy.java	Sat Mar 21 15:41:55 2015 +0100
@@ -62,7 +62,7 @@
             return false;
         }
         OptimizedCallTarget splitTarget = call.getCallTarget();
-        int nodeCount = splitTarget.countNonTrivialNodes();
+        int nodeCount = splitTarget.getNonTrivialNodeCount();
         if (nodeCount > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) {
             return false;
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java	Sat Mar 21 15:41:55 2015 +0100
@@ -55,7 +55,7 @@
         if (TruffleCompilerOptions.TruffleSplittingAggressive.getValue()) {
             return true;
         }
-        int size = call.getCallTarget().countNonTrivialNodes();
+        int size = call.getCallTarget().getNonTrivialNodeCount();
         if (size > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) {
             return false;
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Sat Mar 21 15:41:55 2015 +0100
@@ -56,10 +56,28 @@
     private final List<GraalTruffleCompilationListener> compilationListeners = new ArrayList<>();
     private final GraalTruffleCompilationListener compilationNotify = new DispatchTruffleCompilationListener();
 
+    private LoopNodeFactory loopNodeFactory;
+
     public GraalTruffleRuntime() {
         Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
     }
 
+    private static <T extends PrioritizedServiceProvider> T loadPrioritizedServiceProvider(Class<T> clazz) {
+        ServiceLoader<T> serviceLoader = ServiceLoader.load(clazz, GraalTruffleRuntime.class.getClassLoader());
+        T bestFactory = null;
+        for (T factory : serviceLoader) {
+            if (bestFactory == null) {
+                bestFactory = factory;
+            } else if (factory.getPriority() > bestFactory.getPriority()) {
+                bestFactory = factory;
+            }
+        }
+        if (bestFactory == null) {
+            throw new IllegalStateException("Unable to load a factory for " + clazz.getName());
+        }
+        return bestFactory;
+    }
+
     protected void installDefaultListeners() {
         TraceCompilationFailureListener.install(this);
         TraceCompilationListener.install(this);
@@ -80,11 +98,15 @@
     }
 
     @Override
-    public LoopNode createLoopNode(RepeatingNode repeating) {
-        if (!(repeating instanceof Node)) {
+    public LoopNode createLoopNode(RepeatingNode repeatingNode) {
+        if (!(repeatingNode instanceof Node)) {
             throw new IllegalArgumentException("Repeating node must be of type Node.");
         }
-        return new OptimizedLoopNode(repeating);
+        if (loopNodeFactory == null) {
+            loopNodeFactory = loadPrioritizedServiceProvider(LoopNodeFactory.class);
+        }
+
+        return loopNodeFactory.create(repeatingNode);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.truffle;
+
+import com.oracle.truffle.api.nodes.*;
+
+public interface LoopNodeFactory extends PrioritizedServiceProvider {
+
+    LoopNode create(RepeatingNode repeatingNode);
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sat Mar 21 15:41:55 2015 +0100
@@ -486,16 +486,16 @@
         return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
     }
 
-    public final int countNonTrivialNodes() {
+    public final int getNonTrivialNodeCount() {
         if (cachedNonTrivialNodeCount == -1) {
-            cachedNonTrivialNodeCount = calculateNonTrivialNodesImpl();
+            cachedNonTrivialNodeCount = calculateNonTrivialNodes(getRootNode());
         }
         return cachedNonTrivialNodeCount;
     }
 
-    private int calculateNonTrivialNodesImpl() {
+    public static int calculateNonTrivialNodes(Node node) {
         NonTrivialNodeCountVisitor visitor = new NonTrivialNodeCountVisitor();
-        getRootNode().accept(visitor);
+        node.accept(visitor);
         return visitor.nodeCount;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedLoopNode.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedLoopNode.java	Sat Mar 21 15:41:55 2015 +0100
@@ -32,15 +32,22 @@
  */
 public final class OptimizedLoopNode extends LoopNode {
 
-    public OptimizedLoopNode(RepeatingNode body) {
-        super(body);
+    @Child private RepeatingNode repeatingNode;
+
+    public OptimizedLoopNode(RepeatingNode repeatingNode) {
+        this.repeatingNode = repeatingNode;
+    }
+
+    @Override
+    public RepeatingNode getRepeatingNode() {
+        return repeatingNode;
     }
 
     @Override
     public void executeLoop(VirtualFrame frame) {
         int loopCount = 0;
         try {
-            while (executeRepeatingNode(frame)) {
+            while (repeatingNode.executeRepeating(frame)) {
                 if (CompilerDirectives.inInterpreter()) {
                     loopCount++;
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PrioritizedServiceProvider.java	Sat Mar 21 15:41:55 2015 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.truffle;
+
+public interface PrioritizedServiceProvider {
+
+    default int getPriority() {
+        return 0;
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Sat Mar 21 15:41:55 2015 +0100
@@ -43,7 +43,7 @@
     }
 
     private static List<TruffleInliningDecision> createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy, CompilerOptions options) {
-        int nodeCount = sourceTarget.countNonTrivialNodes();
+        int nodeCount = sourceTarget.getNonTrivialNodeCount();
         List<TruffleInliningDecision> exploredCallSites = exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), nodeCount, policy);
         return decideInlining(exploredCallSites, policy, nodeCount, options);
     }
@@ -66,7 +66,7 @@
 
         List<TruffleInliningDecision> childCallSites = Collections.emptyList();
         double frequency = calculateFrequency(parentTarget, callNode);
-        int nodeCount = callNode.getCurrentCallTarget().countNonTrivialNodes();
+        int nodeCount = callNode.getCurrentCallTarget().getNonTrivialNodeCount();
 
         int recursions = countRecursions(callStack);
         int deepNodeCount = nodeCount;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java	Sat Mar 21 15:41:55 2015 +0100
@@ -101,7 +101,7 @@
     }
 
     public static void addASTSizeProperty(OptimizedCallTarget target, Map<String, Object> properties) {
-        int nodeCount = target.countNonTrivialNodes();
+        int nodeCount = target.getNonTrivialNodeCount();
         int deepNodeCount = nodeCount;
         TruffleInlining inlining = target.getInlining();
         if (inlining != null) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/HistogramInlineInvokePlugin.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/HistogramInlineInvokePlugin.java	Sat Mar 21 15:41:55 2015 +0100
@@ -26,9 +26,11 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.truffle.*;
 
 public class HistogramInlineInvokePlugin implements InlineInvokePlugin {
@@ -47,7 +49,7 @@
     public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) {
         InlineInfo inlineInfo = delegate.getInlineInfo(b, method, args, returnType);
         if (inlineInfo != null) {
-            currentStatistic = new MethodStatistic(currentStatistic, inlineInfo.methodToInline, graph.getNodeCount(), graph.getNodes(MethodCallTargetNode.TYPE).count());
+            currentStatistic = new MethodStatistic(currentStatistic, inlineInfo.methodToInline, countNodes(), countCalls());
         }
         return inlineInfo;
     }
@@ -56,13 +58,25 @@
         delegate.postInline(inlinedTargetMethod);
 
         if (currentStatistic != null) {
-            currentStatistic.applyNodeCountAfter(graph.getNodeCount());
-            currentStatistic.applyCallsAfter(graph.getNodes(MethodCallTargetNode.TYPE).count());
+            currentStatistic.applyNodeCountAfter(countNodes());
+            currentStatistic.applyCallsAfter(countCalls());
             accept(currentStatistic);
             currentStatistic = currentStatistic.getParent();
         }
     }
 
+    private int countNodes() {
+        return graph.getNodes().filter(node -> isNonTrivial(node)).count();
+    }
+
+    private int countCalls() {
+        return graph.getNodes(MethodCallTargetNode.TYPE).count();
+    }
+
+    private static boolean isNonTrivial(Node node) {
+        return !(node instanceof VirtualState || node instanceof VirtualObjectNode || node instanceof BeginNode || node instanceof DeoptimizeNode);
+    }
+
     private void accept(MethodStatistic current) {
         ResolvedJavaMethod method = current.getMethod();
         HistogramInlineInvokePlugin.MethodStatistics statistics = histogram.get(method);
@@ -74,12 +88,12 @@
     }
 
     public void print(OptimizedCallTarget target, PrintStream out) {
-        out.printf("Truffle expansion histogram for %s", target);
+        out.printf("Truffle expansion histogram for %s%n", target);
         out.println("  Invocations = Number of expanded invocations");
-        out.println("  Nodes = Number of Graal nodes created for this method during partial evaluation.");
+        out.println("  Nodes = Number of non-trival Graal nodes created for this method during partial evaluation.");
         out.println("  Calls = Number of not expanded calls created for this method during partial evaluation.");
         out.printf(" %-11s |Nodes %5s %5s %5s %8s |Calls %5s %5s %5s %8s | Method Name%n", "Invocations", "Sum", "Min", "Max", "Avg", "Sum", "Min", "Max", "Avg");
-        histogram.values().stream().sorted().forEach(statistics -> statistics.print(out));
+        histogram.values().stream().filter(statistics -> statistics.shallowCount.getSum() > 0).sorted().forEach(statistics -> statistics.print(out));
     }
 
     private static class MethodStatistics implements Comparable<MethodStatistics> {
@@ -95,16 +109,16 @@
         }
 
         public void print(PrintStream out) {
-            out.printf(" %11d |        %5d %5d %5d %8.2f |      %5d %5d %5d %8.2f | %s%n", //
+            out.printf(" %11d |      %5d %5d %5d %8.2f |      %5d %5d %5d %8.2f | %s%n", //
                             count, shallowCount.getSum(), shallowCount.getMin(), shallowCount.getMax(), //
                             shallowCount.getAverage(), callCount.getSum(), callCount.getMin(), callCount.getMax(), //
                             callCount.getAverage(), method.format("%h.%n(%p)"));
         }
 
         public int compareTo(MethodStatistics o) {
-            int result = (int) (o.shallowCount.getSum() - shallowCount.getSum());
+            int result = Long.compare(o.shallowCount.getSum(), shallowCount.getSum());
             if (result == 0) {
-                return o.count - count;
+                return Integer.compare(o.count, count);
             }
             return result;
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Sat Mar 21 15:41:55 2015 +0100
@@ -94,10 +94,4 @@
     public void lower(LoweringTool tool) {
         IntegerExactArithmeticSplitNode.lower(tool, this);
     }
-
-    @NodeIntrinsic
-    public static native int subtractExact(int a, int b);
-
-    @NodeIntrinsic
-    public static native long subtractExact(long a, long b);
 }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/OnAdoptTest.java	Sat Mar 21 15:41:38 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2014, 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.truffle.api.test;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * <h3>Inserting Extra Nodes into the AST Transparently</h3>
- *
- * <p>
- * The {@link Node} class provides a callback that is invoked whenever a node is adopted in an AST
- * by insertion or replacement. Node classes can override the {@code onAdopt()} method to run extra
- * functionality upon adoption.
- * </p>
- *
- * <p>
- * This test demonstrates how node instances of a specific class can be automatically wrapped in
- * extra nodes when they are inserted into the AST.
- * </p>
- */
-public class OnAdoptTest {
-
-    static class Root extends RootNode {
-
-        @Child private Base child1;
-        @Child private Base child2;
-
-        public Root(Base child1, Base child2) {
-            super(null);
-            this.child1 = child1;
-            this.child2 = child2;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            return child1.executeInt(frame) + child2.executeInt(frame);
-        }
-
-    }
-
-    abstract static class Base extends Node {
-        public abstract int executeInt(VirtualFrame frame);
-    }
-
-    static class Wrapper extends Base {
-
-        @Child private Base wrappee;
-
-        public Wrapper(Base wrappee) {
-            this.wrappee = wrappee;
-        }
-
-        @Override
-        public int executeInt(VirtualFrame frame) {
-            return 1 + wrappee.executeInt(frame);
-        }
-
-    }
-
-    abstract static class GenBase extends Base {
-
-        private final int k;
-
-        public GenBase(int k) {
-            this.k = k;
-        }
-
-        @Override
-        public int executeInt(VirtualFrame frame) {
-            return k;
-        }
-
-    }
-
-    static class Gen extends GenBase {
-        public Gen(int k) {
-            super(k);
-        }
-    }
-
-    static class GenWrapped extends GenBase {
-
-        public GenWrapped(int k) {
-            super(k);
-        }
-
-        @Override
-        protected void onAdopt() {
-            Wrapper w = new Wrapper(this);
-            this.replace(w);
-        }
-
-    }
-
-    @Test
-    public void testOnInsert() {
-        TruffleRuntime runtime = Truffle.getRuntime();
-        Base b1 = new Gen(11);
-        Base b2 = new GenWrapped(11);
-        Root r = new Root(b1, b2);
-        CallTarget ct = runtime.createCallTarget(r);
-        Object result = ct.call();
-        Assert.assertEquals(23, result);
-    }
-
-}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultLoopNode.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultLoopNode.java	Sat Mar 21 15:41:55 2015 +0100
@@ -29,13 +29,20 @@
 
 public final class DefaultLoopNode extends LoopNode {
 
+    @Child private RepeatingNode repeatNode;
+
     public DefaultLoopNode(RepeatingNode repeatNode) {
-        super(repeatNode);
+        this.repeatNode = repeatNode;
+    }
+
+    @Override
+    public RepeatingNode getRepeatingNode() {
+        return repeatNode;
     }
 
     @Override
     public void executeLoop(VirtualFrame frame) {
-        while (executeRepeatingNode(frame)) {
+        while (repeatNode.executeRepeating(frame)) {
             // Empty
         }
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/LoopNode.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/LoopNode.java	Sat Mar 21 15:41:55 2015 +0100
@@ -31,20 +31,8 @@
  */
 public abstract class LoopNode extends Node {
 
-    @Child protected RepeatingNode repeatingNode;
-
-    public LoopNode(RepeatingNode repeatingNode) {
-        this.repeatingNode = repeatingNode;
-    }
-
     public abstract void executeLoop(VirtualFrame frame);
 
-    protected final boolean executeRepeatingNode(VirtualFrame frame) {
-        return getRepeatingNode().executeRepeating(frame);
-    }
-
-    public final RepeatingNode getRepeatingNode() {
-        return repeatingNode;
-    }
+    public abstract RepeatingNode getRepeatingNode();
 
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Sat Mar 21 15:41:55 2015 +0100
@@ -176,15 +176,11 @@
         if (newChild == this) {
             throw new IllegalStateException("The parent of a node can never be the node itself.");
         }
-        boolean isInserted = newChild.parent == null;
         newChild.parent = this;
         if (TruffleOptions.TraceASTJSON) {
             JSONHelper.dumpNewChild(this, newChild);
         }
         newChild.adoptHelper();
-        if (isInserted) {
-            newChild.onAdopt();
-        }
     }
 
     private void adoptHelper() {
@@ -201,12 +197,8 @@
         if (newChild == this) {
             throw new IllegalStateException("The parent of a node can never be the node itself.");
         }
-        boolean isInserted = newChild.parent == null;
         newChild.parent = this;
         newChild.adoptUnadoptedHelper();
-        if (isInserted) {
-            newChild.onAdopt();
-        }
     }
 
     private void adoptUnadoptedHelper() {
@@ -329,16 +321,6 @@
     }
 
     /**
-     * Subclasses of {@link Node} can implement this method to execute extra functionality when a
-     * node is effectively inserted into the AST. The {@code onAdopt} callback is called after the
-     * node has been effectively inserted, and it is guaranteed to be called only once for any given
-     * node.
-     */
-    protected void onAdopt() {
-        // empty default
-    }
-
-    /**
      * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all
      * child nodes.
      *
@@ -575,22 +557,19 @@
 
     private static final Object GIL = new Object();
 
-    private static final ThreadLocal<Integer> IN_ATOMIC_BLOCK = new ThreadLocal<>();
+    private static final ThreadLocal<Integer> IN_ATOMIC_BLOCK = new ThreadLocal<Integer>() {
+        @Override
+        protected Integer initialValue() {
+            return 0;
+        }
+    };
 
     private static boolean inAtomicBlock() {
-        Integer value = IN_ATOMIC_BLOCK.get();
-        if (value == null) {
-            return false;
-        }
-        return value > 0;
+        return IN_ATOMIC_BLOCK.get() > 0;
     }
 
     private static boolean enterAtomic() {
-        Integer currentValue = IN_ATOMIC_BLOCK.get();
-        if (currentValue == null) {
-            currentValue = 0;
-        }
-        IN_ATOMIC_BLOCK.set(currentValue + 1);
+        IN_ATOMIC_BLOCK.set(IN_ATOMIC_BLOCK.get() + 1);
         return true;
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Sat Mar 21 15:41:55 2015 +0100
@@ -155,14 +155,20 @@
 
         @Override
         public void putObject(Node receiver, Object value) {
-            assert !type.isPrimitive() && value == null || type.isInstance(value);
-            unsafe.putObject(receiver, offset, value);
+            if (!type.isPrimitive() && value == null || type.isInstance(value)) {
+                unsafe.putObject(receiver, offset, value);
+            } else {
+                throw new IllegalArgumentException();
+            }
         }
 
         @Override
         public Object getObject(Node receiver) {
-            assert !type.isPrimitive();
-            return unsafe.getObject(receiver, offset);
+            if (!type.isPrimitive()) {
+                return unsafe.getObject(receiver, offset);
+            } else {
+                throw new IllegalArgumentException();
+            }
         }
 
         @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java	Sat Mar 21 15:41:38 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java	Sat Mar 21 15:41:55 2015 +0100
@@ -24,6 +24,8 @@
  */
 package com.oracle.truffle.api.utilities;
 
+import com.oracle.truffle.api.nodes.*;
+
 /**
  * Utility class to speculate on certain properties of values.
  *
@@ -42,7 +44,7 @@
  * @see #createIdentityProfile()
  * @see #createClassProfile()
  */
-public abstract class ValueProfile {
+public abstract class ValueProfile extends NodeCloneable {
 
     public abstract <T> T profile(T value);