changeset 7893:d81109e2d7be

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 26 Feb 2013 20:10:02 +0100
parents 7f3fc1210e8c (current diff) 14b52a260099 (diff)
children fed868d1aefd
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java
diffstat 13 files changed, 314 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Feb 26 20:10:02 2013 +0100
@@ -67,6 +67,8 @@
 import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.NullCheckOp;
 import com.oracle.graal.lir.amd64.AMD64Move.SpillMoveOp;
+import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
+import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -139,12 +141,12 @@
     @Override
     public Variable emitMove(Value input) {
         Variable result = newVariable(input.getKind());
-        emitMove(input, result);
+        emitMove(result, input);
         return result;
     }
 
     @Override
-    public void emitMove(Value src, Value dst) {
+    public void emitMove(Value dst, Value src) {
         if (isRegister(src) || isStackSlot(dst)) {
             append(new MoveFromRegOp(dst, src));
         } else {
@@ -166,7 +168,7 @@
                     baseRegister = Value.ILLEGAL;
                 } else {
                     Value newBase = newVariable(Kind.Long);
-                    emitMove(base, newBase);
+                    emitMove(newBase, base);
                     baseRegister = newBase;
                 }
             }
@@ -187,7 +189,7 @@
                     // create a temporary variable for the index, the pointer load cannot handle a
                     // constant index
                     Value newIndex = newVariable(Kind.Long);
-                    emitMove(index, newIndex);
+                    emitMove(newIndex, index);
                     indexRegister = newIndex;
                 }
             }
@@ -210,8 +212,18 @@
     @Override
     public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, boolean canTrap) {
         AMD64Address storeAddress = prepareAddress(kind, base, displacement, index, scale);
-        Value input = loadForStore(inputVal, storeAddress.getKind());
-        append(new StoreOp(storeAddress, input, canTrap ? state() : null));
+        LIRFrameState state = canTrap ? state() : null;
+
+        if (isConstant(inputVal)) {
+            Constant c = asConstant(inputVal);
+            if (canStoreConstant(c)) {
+                append(new StoreConstantOp(storeAddress, c, state));
+                return;
+            }
+        }
+
+        Variable input = load(inputVal);
+        append(new StoreOp(storeAddress, input, state));
     }
 
     @Override
@@ -225,7 +237,7 @@
     @Override
     public Variable emitLea(StackSlot address) {
         Variable result = newVariable(target().wordKind);
-        append(new LeaOp(result, address));
+        append(new StackLeaOp(result, address));
         return result;
     }
 
@@ -459,11 +471,11 @@
     public Value[] emitIntegerDivRem(Value a, Value b) {
         switch (a.getKind()) {
             case Int:
-                emitMove(a, RAX_I);
+                emitMove(RAX_I, a);
                 append(new DivRemOp(IDIVREM, RAX_I, load(b), state()));
                 return new Value[]{emitMove(RAX_I), emitMove(RDX_I)};
             case Long:
-                emitMove(a, RAX_L);
+                emitMove(RAX_L, a);
                 append(new DivRemOp(LDIVREM, RAX_L, load(b), state()));
                 return new Value[]{emitMove(RAX_L), emitMove(RDX_L)};
             default:
@@ -475,11 +487,11 @@
     public Value emitDiv(Value a, Value b) {
         switch (a.getKind()) {
             case Int:
-                emitMove(a, RAX_I);
+                emitMove(RAX_I, a);
                 append(new DivOp(IDIV, RAX_I, RAX_I, load(b), state()));
                 return emitMove(RAX_I);
             case Long:
-                emitMove(a, RAX_L);
+                emitMove(RAX_L, a);
                 append(new DivOp(LDIV, RAX_L, RAX_L, load(b), state()));
                 return emitMove(RAX_L);
             case Float: {
@@ -501,11 +513,11 @@
     public Value emitRem(Value a, Value b) {
         switch (a.getKind()) {
             case Int:
-                emitMove(a, RAX_I);
+                emitMove(RAX_I, a);
                 append(new DivOp(IREM, RDX_I, RAX_I, load(b), state()));
                 return emitMove(RDX_I);
             case Long:
-                emitMove(a, RAX_L);
+                emitMove(RAX_L, a);
                 append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
                 return emitMove(RDX_L);
             case Float: {
@@ -525,11 +537,11 @@
     public Variable emitUDiv(Value a, Value b) {
         switch (a.getKind()) {
             case Int:
-                emitMove(a, RAX_I);
+                emitMove(RAX_I, a);
                 append(new DivOp(IUDIV, RAX_I, RAX_I, load(b), state()));
                 return emitMove(RAX_I);
             case Long:
-                emitMove(a, RAX_L);
+                emitMove(RAX_L, a);
                 append(new DivOp(LUDIV, RAX_L, RAX_L, load(b), state()));
                 return emitMove(RAX_L);
             default:
@@ -541,11 +553,11 @@
     public Variable emitURem(Value a, Value b) {
         switch (a.getKind()) {
             case Int:
-                emitMove(a, RAX_I);
+                emitMove(RAX_I, a);
                 append(new DivOp(IUREM, RDX_I, RAX_I, load(b), state()));
                 return emitMove(RDX_I);
             case Long:
-                emitMove(a, RAX_L);
+                emitMove(RAX_L, a);
                 append(new DivOp(LUREM, RDX_L, RAX_L, load(b), state()));
                 return emitMove(RDX_L);
             default:
@@ -654,7 +666,7 @@
             return value;
         }
         // Non-constant shift count must be in RCX
-        emitMove(value, RCX_I);
+        emitMove(RCX_I, value);
         return RCX_I;
     }
 
@@ -724,7 +736,7 @@
                 // Instructions that move or generate 32-bit register values also set the upper 32
                 // bits of the register to zero.
                 // Consequently, there is no need for a special zero-extension move.
-                emitMove(input, result);
+                emitMove(result, input);
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -764,7 +776,7 @@
         // The current register allocator cannot handle variables at call sites, need a fixed
         // register.
         Value targetAddress = AMD64.rax.asValue();
-        emitMove(operand(callTarget.computedAddress()), targetAddress);
+        emitMove(targetAddress, operand(callTarget.computedAddress()));
         append(new IndirectCallOp(callTarget.target(), result, parameters, temps, targetAddress, callState));
     }
 
@@ -888,7 +900,7 @@
         Value expected = loadNonConst(operand(node.expected()));
         Variable newValue = load(operand(node.newValue()));
 
-        Address address;
+        AMD64Address address;
         int displacement = node.displacement();
         Value index = operand(node.offset());
         if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) {
@@ -900,7 +912,7 @@
         }
 
         RegisterValue rax = AMD64.rax.asValue(kind);
-        emitMove(expected, rax);
+        emitMove(rax, expected);
         append(new CompareAndSwapOp(rax, address, rax, newValue));
 
         Variable result = newVariable(node.kind());
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Tue Feb 26 20:10:02 2013 +0100
@@ -101,12 +101,12 @@
     @Override
     public Variable emitMove(Value input) {
         Variable result = newVariable(input.getKind());
-        emitMove(input, result);
+        emitMove(result, input);
         return result;
     }
 
     @Override
-    public void emitMove(Value src, Value dst) {
+    public void emitMove(Value dst, Value src) {
         if (isRegister(src) || isStackSlot(dst)) {
             append(new MoveFromRegOp(dst, src));
         } else {
@@ -156,7 +156,7 @@
     @Override
     public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, boolean canTrap) {
         PTXAddress storeAddress = prepareAddress(kind, base, displacement, index, scale);
-        Value input = loadForStore(inputVal, storeAddress.getKind());
+        Value input = load(inputVal);
         append(new StoreOp(storeAddress, input, canTrap ? state() : null));
     }
 
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Feb 26 20:10:02 2013 +0100
@@ -214,7 +214,7 @@
     }
 
     @Override
-    public void emitMove(Value src, Value dst) {
+    public void emitMove(Value dst, Value src) {
         // SPARC: Auto-generated method stub
 
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Feb 26 20:10:02 2013 +0100
@@ -207,18 +207,6 @@
         return value;
     }
 
-    public Value loadForStore(Value value, Kind storeKind) {
-        if (isConstant(value) && canStoreConstant((Constant) value)) {
-            return value;
-        }
-        if (storeKind == Kind.Byte || storeKind == Kind.Boolean) {
-            Variable tempVar = new Variable(value.getKind(), lir.nextVariable(), Register.RegisterFlag.Byte);
-            emitMove(value, tempVar);
-            return tempVar;
-        }
-        return load(value);
-    }
-
     protected LabelRef getLIRBlock(FixedNode b) {
         Block result = lir.cfg.blockFor(b);
         int suxIndex = currentBlock.getSuccessors().indexOf(result);
@@ -535,7 +523,7 @@
         Value operand = Value.ILLEGAL;
         if (x.result() != null) {
             operand = resultOperandFor(x.result().kind());
-            emitMove(operand(x.result()), operand);
+            emitMove(operand, operand(x.result()));
         }
         emitReturn(operand);
     }
@@ -757,7 +745,7 @@
         for (ValueNode arg : arguments) {
             if (arg != null) {
                 Value operand = toStackKind(cc.getArgument(j));
-                emitMove(operand(arg), operand);
+                emitMove(operand, operand(arg));
                 result[j] = operand;
                 j++;
             } else {
@@ -780,7 +768,7 @@
         for (int i = 0; i < args.length; i++) {
             Value arg = args[i];
             Value loc = cc.getArgument(i);
-            emitMove(arg, loc);
+            emitMove(loc, arg);
             argLocations[i] = loc;
         }
         emitCall(callTarget, cc.getReturn(), argLocations, cc.getTemporaries(), Constant.forLong(0), info);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java	Tue Feb 26 20:10:02 2013 +0100
@@ -187,7 +187,7 @@
     private void emitMove(Value src, Value dest) {
         assert isLegal(src);
         assert isLegal(dest);
-        gen.emitMove(src, dest);
+        gen.emitMove(dest, src);
     }
 
     // Traverse assignment graph in depth first order and generate moves in post order
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Feb 26 20:10:02 2013 +0100
@@ -128,7 +128,7 @@
             Variable newVal = load(operand(x.newValue()));
 
             int disp = 0;
-            Address address;
+            AMD64Address address;
             Value index = operand(x.offset());
             if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) {
                 assert !runtime.needsDataPatch(asConstant(index));
@@ -139,11 +139,11 @@
             }
 
             RegisterValue rax = AMD64.rax.asValue(kind);
-            emitMove(expected, rax);
+            emitMove(rax, expected);
             append(new CompareAndSwapOp(rax, address, rax, newVal));
 
             Variable result = newVariable(x.kind());
-            emitMove(rax, result);
+            emitMove(result, rax);
             setResult(x, result);
         }
 
@@ -161,9 +161,9 @@
         @Override
         protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
             Value metaspaceMethod = AMD64.rbx.asValue();
-            emitMove(operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()), metaspaceMethod);
+            emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()));
             Value targetAddress = AMD64.rax.asValue();
-            emitMove(operand(callTarget.computedAddress()), targetAddress);
+            emitMove(targetAddress, operand(callTarget.computedAddress()));
             append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java	Tue Feb 26 20:10:02 2013 +0100
@@ -41,7 +41,7 @@
     @Override
     public void generate(LIRGeneratorTool generator) {
         Value obj = generator.newVariable(generator.target().wordKind);
-        generator.emitMove(generator.operand(object()), obj);
+        generator.emitMove(obj, generator.operand(object()));
         generateBarrier(obj, generator);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java	Tue Feb 26 20:10:02 2013 +0100
@@ -47,7 +47,7 @@
     @Override
     public void generate(LIRGeneratorTool gen) {
         Value obj = gen.newVariable(gen.target().wordKind);
-        gen.emitMove(gen.operand(object), obj);
+        gen.emitMove(obj, gen.operand(object));
         gen.setResult(this, obj);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java	Tue Feb 26 20:10:02 2013 +0100
@@ -54,7 +54,7 @@
             // The register allocator would prefer us not to tie up an allocatable
             // register for the complete lifetime of this node.
             result = generator.newVariable(kind());
-            generator.emitMove(register.asValue(kind()), result);
+            generator.emitMove(result, register.asValue(kind()));
         } else {
             result = register.asValue(kind());
         }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Feb 26 20:10:02 2013 +0100
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
 import static java.lang.Double.*;
 import static java.lang.Float.*;
 
@@ -42,6 +43,7 @@
 
     @Opcode("MOVE")
     public static class SpillMoveOp extends AMD64LIRInstruction implements MoveOp {
+
         @Def({REG, STACK}) protected Value result;
         @Use({REG, STACK, CONST}) protected Value input;
 
@@ -59,15 +61,16 @@
         public Value getInput() {
             return input;
         }
+
         @Override
         public Value getResult() {
             return result;
         }
     }
 
-
     @Opcode("MOVE")
     public static class MoveToRegOp extends AMD64LIRInstruction implements MoveOp {
+
         @Def({REG, HINT}) protected Value result;
         @Use({REG, STACK, CONST}) protected Value input;
 
@@ -85,15 +88,16 @@
         public Value getInput() {
             return input;
         }
+
         @Override
         public Value getResult() {
             return result;
         }
     }
 
-
     @Opcode("MOVE")
     public static class MoveFromRegOp extends AMD64LIRInstruction implements MoveOp {
+
         @Def({REG, STACK}) protected Value result;
         @Use({REG, CONST, HINT}) protected Value input;
 
@@ -111,19 +115,20 @@
         public Value getInput() {
             return input;
         }
+
         @Override
         public Value getResult() {
             return result;
         }
     }
 
+    public static class LoadOp extends AMD64LIRInstruction {
 
-    public static class LoadOp extends AMD64LIRInstruction {
         @Def({REG}) protected Value result;
-        @Use({ADDR}) protected Value address;
+        @Use({ADDR}) protected AMD64Address address;
         @State protected LIRFrameState state;
 
-        public LoadOp(Value result, Value address, LIRFrameState state) {
+        public LoadOp(Value result, AMD64Address address, LIRFrameState state) {
             this.result = result;
             this.address = address;
             this.state = state;
@@ -131,17 +136,48 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            load(tasm, masm, result, (AMD64Address) address, state);
+            if (state != null) {
+                tasm.recordImplicitException(masm.codeBuffer.position(), state);
+            }
+            switch (address.getKind()) {
+                case Boolean:
+                case Byte:
+                    masm.movsxb(asRegister(result), address);
+                    break;
+                case Char:
+                    masm.movzxl(asRegister(result), address);
+                    break;
+                case Short:
+                    masm.movswl(asRegister(result), address);
+                    break;
+                case Int:
+                    masm.movslq(asRegister(result), address);
+                    break;
+                case Long:
+                    masm.movq(asRegister(result), address);
+                    break;
+                case Float:
+                    masm.movflt(asFloatReg(result), address);
+                    break;
+                case Double:
+                    masm.movdbl(asDoubleReg(result), address);
+                    break;
+                case Object:
+                    masm.movq(asRegister(result), address);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
         }
     }
 
+    public static class StoreOp extends AMD64LIRInstruction {
 
-    public static class StoreOp extends AMD64LIRInstruction {
-        @Use({ADDR}) protected Value address;
-        @Use({REG, CONST}) protected Value input;
+        @Use({ADDR}) protected AMD64Address address;
+        @Use({REG}) protected Value input;
         @State protected LIRFrameState state;
 
-        public StoreOp(Value address, Value input, LIRFrameState state) {
+        public StoreOp(AMD64Address address, Value input, LIRFrameState state) {
             this.address = address;
             this.input = input;
             this.state = state;
@@ -149,28 +185,130 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            store(tasm, masm, (AMD64Address) address, input, state);
+            if (state != null) {
+                tasm.recordImplicitException(masm.codeBuffer.position(), state);
+            }
+
+            assert isRegister(input);
+            switch (address.getKind()) {
+                case Boolean:
+                case Byte:
+                    masm.movb(address, asRegister(input));
+                    break;
+                case Char:
+                case Short:
+                    masm.movw(address, asRegister(input));
+                    break;
+                case Int:
+                    masm.movl(address, asRegister(input));
+                    break;
+                case Long:
+                    masm.movq(address, asRegister(input));
+                    break;
+                case Float:
+                    masm.movflt(address, asFloatReg(input));
+                    break;
+                case Double:
+                    masm.movsd(address, asDoubleReg(input));
+                    break;
+                case Object:
+                    masm.movq(address, asRegister(input));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
         }
     }
 
+    public static class StoreConstantOp extends AMD64LIRInstruction {
+
+        @Use({ADDR}) protected AMD64Address address;
+        @Use({CONST}) protected Constant input;
+        @State protected LIRFrameState state;
+
+        public StoreConstantOp(AMD64Address address, Constant input, LIRFrameState state) {
+            this.address = address;
+            this.input = input;
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            if (state != null) {
+                tasm.recordImplicitException(masm.codeBuffer.position(), state);
+            }
+
+            switch (address.getKind()) {
+                case Boolean:
+                case Byte:
+                    masm.movb(address, input.asInt() & 0xFF);
+                    break;
+                case Char:
+                case Short:
+                    masm.movw(address, input.asInt() & 0xFFFF);
+                    break;
+                case Int:
+                    masm.movl(address, input.asInt());
+                    break;
+                case Long:
+                    if (NumUtil.isInt(input.asLong())) {
+                        masm.movslq(address, (int) input.asLong());
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                case Float:
+                    masm.movl(address, floatToRawIntBits(input.asFloat()));
+                    break;
+                case Double:
+                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                case Object:
+                    if (input.isNull()) {
+                        masm.movptr(address, 0);
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
 
     public static class LeaOp extends AMD64LIRInstruction {
+
         @Def({REG}) protected Value result;
-        @Use({ADDR, STACK, UNINITIALIZED}) protected Value address;
+        @Use({ADDR, UNINITIALIZED}) protected AMD64Address address;
 
-        public LeaOp(Value result, Value address) {
+        public LeaOp(Value result, AMD64Address address) {
             this.result = result;
             this.address = address;
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            masm.leaq(asLongReg(result), (AMD64Address) tasm.asAddress(address));
+            masm.leaq(asLongReg(result), address);
         }
     }
 
+    public static class StackLeaOp extends AMD64LIRInstruction {
+
+        @Def({REG}) protected Value result;
+        @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
+
+        public StackLeaOp(Value result, StackSlot slot) {
+            this.result = result;
+            this.slot = slot;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.leaq(asLongReg(result), (AMD64Address) tasm.asAddress(slot));
+        }
+    }
 
     public static class MembarOp extends AMD64LIRInstruction {
+
         private final int barriers;
 
         public MembarOp(final int barriers) {
@@ -183,8 +321,8 @@
         }
     }
 
+    public static class NullCheckOp extends AMD64LIRInstruction {
 
-    public static class NullCheckOp extends AMD64LIRInstruction {
         @Use protected Value input;
         @State protected LIRFrameState state;
 
@@ -200,15 +338,15 @@
         }
     }
 
-
     @Opcode("CAS")
     public static class CompareAndSwapOp extends AMD64LIRInstruction {
+
         @Def protected Value result;
-        @Use({ADDR}) protected Value address;
+        @Use({ADDR}) protected AMD64Address address;
         @Use protected Value cmpValue;
         @Use protected Value newValue;
 
-        public CompareAndSwapOp(Value result, Address address, Value cmpValue, Value newValue) {
+        public CompareAndSwapOp(Value result, AMD64Address address, Value cmpValue, Value newValue) {
             this.result = result;
             this.address = address;
             this.cmpValue = cmpValue;
@@ -217,11 +355,10 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            compareAndSwap(tasm, masm, result, (AMD64Address) address, cmpValue, newValue);
+            compareAndSwap(tasm, masm, result, address, cmpValue, newValue);
         }
     }
 
-
     public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
@@ -255,43 +392,79 @@
             return;
         }
         switch (input.getKind()) {
-            case Int:    masm.movl(asRegister(result),    asRegister(input)); break;
-            case Long:   masm.movq(asRegister(result),    asRegister(input)); break;
-            case Float:  masm.movflt(asFloatReg(result),  asFloatReg(input)); break;
-            case Double: masm.movdbl(asDoubleReg(result), asDoubleReg(input)); break;
-            case Object: masm.movq(asRegister(result),    asRegister(input)); break;
-            default:     throw GraalInternalError.shouldNotReachHere("kind=" + result.getKind());
+            case Int:
+                masm.movl(asRegister(result), asRegister(input));
+                break;
+            case Long:
+                masm.movq(asRegister(result), asRegister(input));
+                break;
+            case Float:
+                masm.movflt(asFloatReg(result), asFloatReg(input));
+                break;
+            case Double:
+                masm.movdbl(asDoubleReg(result), asDoubleReg(input));
+                break;
+            case Object:
+                masm.movq(asRegister(result), asRegister(input));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("kind=" + result.getKind());
         }
     }
 
     private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         AMD64Address dest = (AMD64Address) tasm.asAddress(result);
         switch (input.getKind()) {
-            case Int:    masm.movl(dest,   asRegister(input)); break;
-            case Long:   masm.movq(dest,   asRegister(input)); break;
-            case Float:  masm.movflt(dest, asFloatReg(input)); break;
-            case Double: masm.movsd(dest,  asDoubleReg(input)); break;
-            case Object: masm.movq(dest,   asRegister(input)); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
+            case Int:
+                masm.movl(dest, asRegister(input));
+                break;
+            case Long:
+                masm.movq(dest, asRegister(input));
+                break;
+            case Float:
+                masm.movflt(dest, asFloatReg(input));
+                break;
+            case Double:
+                masm.movsd(dest, asDoubleReg(input));
+                break;
+            case Object:
+                masm.movq(dest, asRegister(input));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         AMD64Address src = (AMD64Address) tasm.asAddress(input);
         switch (input.getKind()) {
-            case Int:    masm.movl(asRegister(result),    src); break;
-            case Long:   masm.movq(asRegister(result),    src); break;
-            case Float:  masm.movflt(asFloatReg(result),  src); break;
-            case Double: masm.movdbl(asDoubleReg(result), src); break;
-            case Object: masm.movq(asRegister(result),    src); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
+            case Int:
+                masm.movl(asRegister(result), src);
+                break;
+            case Long:
+                masm.movq(asRegister(result), src);
+                break;
+            case Float:
+                masm.movflt(asFloatReg(result), src);
+                break;
+            case Double:
+                masm.movdbl(asDoubleReg(result), src);
+                break;
+            case Object:
+                masm.movq(asRegister(result), src);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
-        // Note: we use the kind of the input operand (and not the kind of the result operand) because they don't match
-        // in all cases. For example, an object constant can be loaded to a long register when unsafe casts occurred (e.g.,
-        // for a write barrier where arithmetic operations are then performed on the pointer).
+        /*
+         * Note: we use the kind of the input operand (and not the kind of the result operand)
+         * because they don't match in all cases. For example, an object constant can be loaded to a
+         * long register when unsafe casts occurred (e.g., for a write barrier where arithmetic
+         * operations are then performed on the pointer).
+         */
         switch (input.getKind().getStackKind()) {
             case Int:
                 if (tasm.runtime.needsDataPatch(input)) {
@@ -352,10 +525,18 @@
         assert !tasm.runtime.needsDataPatch(input);
         AMD64Address dest = (AMD64Address) tasm.asAddress(result);
         switch (input.getKind().getStackKind()) {
-            case Int:    masm.movl(dest, input.asInt()); break;
-            case Long:   masm.movlong(dest, input.asLong()); break;
-            case Float:  masm.movl(dest, floatToRawIntBits(input.asFloat())); break;
-            case Double: masm.movlong(dest, doubleToRawLongBits(input.asDouble())); break;
+            case Int:
+                masm.movl(dest, input.asInt());
+                break;
+            case Long:
+                masm.movlong(dest, input.asLong());
+                break;
+            case Float:
+                masm.movl(dest, floatToRawIntBits(input.asFloat()));
+                break;
+            case Double:
+                masm.movlong(dest, doubleToRawLongBits(input.asDouble()));
+                break;
             case Object:
                 if (input.isNull()) {
                     masm.movlong(dest, 0L);
@@ -368,76 +549,6 @@
         }
     }
 
-
-    public static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, AMD64Address loadAddr, LIRFrameState info) {
-        if (info != null) {
-            tasm.recordImplicitException(masm.codeBuffer.position(), info);
-        }
-        switch (loadAddr.getKind()) {
-            case Boolean:
-            case Byte:   masm.movsxb(asRegister(result),  loadAddr); break;
-            case Char:   masm.movzxl(asRegister(result),  loadAddr); break;
-            case Short:  masm.movswl(asRegister(result),  loadAddr); break;
-            case Int:    masm.movslq(asRegister(result),  loadAddr); break;
-            case Long:   masm.movq(asRegister(result),    loadAddr); break;
-            case Float:  masm.movflt(asFloatReg(result),  loadAddr); break;
-            case Double: masm.movdbl(asDoubleReg(result), loadAddr); break;
-            case Object: masm.movq(asRegister(result),    loadAddr); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Address storeAddr, Value input, LIRFrameState info) {
-        if (info != null) {
-            tasm.recordImplicitException(masm.codeBuffer.position(), info);
-        }
-
-        if (isRegister(input)) {
-            switch (storeAddr.getKind()) {
-                case Boolean:
-                case Byte:   masm.movb(storeAddr,   asRegister(input)); break;
-                case Char:
-                case Short:  masm.movw(storeAddr,   asRegister(input)); break;
-                case Int:    masm.movl(storeAddr,   asRegister(input)); break;
-                case Long:   masm.movq(storeAddr,   asRegister(input)); break;
-                case Float:  masm.movflt(storeAddr, asFloatReg(input)); break;
-                case Double: masm.movsd(storeAddr,  asDoubleReg(input)); break;
-                case Object: masm.movq(storeAddr,   asRegister(input)); break;
-                default:     throw GraalInternalError.shouldNotReachHere();
-            }
-        } else if (isConstant(input)) {
-            Constant c = (Constant) input;
-            switch (storeAddr.getKind()) {
-                case Boolean:
-                case Byte:   masm.movb(storeAddr, c.asInt() & 0xFF); break;
-                case Char:
-                case Short:  masm.movw(storeAddr, c.asInt() & 0xFFFF); break;
-                case Int:    masm.movl(storeAddr, c.asInt()); break;
-                case Long:
-                    if (NumUtil.isInt(c.asLong())) {
-                        masm.movslq(storeAddr, (int) c.asLong());
-                    } else {
-                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                case Float:  masm.movl(storeAddr, floatToRawIntBits(c.asFloat())); break;
-                case Double: throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                case Object:
-                    if (c.isNull()) {
-                        masm.movptr(storeAddr, 0);
-                    } else {
-                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
     protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, AMD64Address address, Value cmpValue, Value newValue) {
         assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax;
 
@@ -445,10 +556,15 @@
             masm.lock();
         }
         switch (cmpValue.getKind()) {
-            case Int:    masm.cmpxchgl(asRegister(newValue), address); break;
+            case Int:
+                masm.cmpxchgl(asRegister(newValue), address);
+                break;
             case Long:
-            case Object: masm.cmpxchgq(asRegister(newValue), address); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
+            case Object:
+                masm.cmpxchgq(asRegister(newValue), address);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
         }
     }
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Tue Feb 26 20:10:02 2013 +0100
@@ -121,10 +121,10 @@
     public static class LoadOp extends PTXLIRInstruction {
 
         @Def({REG}) protected Value result;
-        @Use({ADDR}) protected Value address;
+        @Use({ADDR}) protected PTXAddress address;
         @State protected LIRFrameState state;
 
-        public LoadOp(Value result, Value address, LIRFrameState state) {
+        public LoadOp(Value result, PTXAddress address, LIRFrameState state) {
             this.result = result;
             this.address = address;
             this.state = state;
@@ -132,17 +132,17 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
-            load(tasm, masm, result, (PTXAddress) address, state);
+            load(tasm, masm, result, address, state);
         }
     }
 
     public static class StoreOp extends PTXLIRInstruction {
 
-        @Use({ADDR}) protected Value address;
+        @Use({ADDR}) protected PTXAddress address;
         @Use({REG, CONST}) protected Value input;
         @State protected LIRFrameState state;
 
-        public StoreOp(Value address, Value input, LIRFrameState state) {
+        public StoreOp(PTXAddress address, Value input, LIRFrameState state) {
             this.address = address;
             this.input = input;
             this.state = state;
@@ -150,16 +150,16 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
-            store(tasm, masm, (PTXAddress) address, input, state);
+            store(tasm, masm, address, input, state);
         }
     }
 
     public static class LeaOp extends PTXLIRInstruction {
 
         @Def({REG}) protected Value result;
-        @Use({ADDR, STACK, UNINITIALIZED}) protected Value address;
+        @Use({ADDR, UNINITIALIZED}) protected PTXAddress address;
 
-        public LeaOp(Value result, Value address) {
+        public LeaOp(Value result, PTXAddress address) {
             this.result = result;
             this.address = address;
         }
@@ -170,15 +170,31 @@
         }
     }
 
+    public static class StackLeaOp extends PTXLIRInstruction {
+
+        @Def({REG}) protected Value result;
+        @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
+
+        public StackLeaOp(Value result, StackSlot slot) {
+            this.result = result;
+            this.slot = slot;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
+            throw new InternalError("NYI");
+        }
+    }
+
     @Opcode("CAS")
     public static class CompareAndSwapOp extends PTXLIRInstruction {
 
         @Def protected Value result;
-        @Use({ADDR}) protected Value address;
+        @Use({ADDR}) protected PTXAddress address;
         @Use protected Value cmpValue;
         @Use protected Value newValue;
 
-        public CompareAndSwapOp(Value result, Address address, Value cmpValue, Value newValue) {
+        public CompareAndSwapOp(Value result, PTXAddress address, Value cmpValue, Value newValue) {
             this.result = result;
             this.address = address;
             this.cmpValue = cmpValue;
@@ -187,7 +203,7 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
-            compareAndSwap(tasm, masm, result, (Address) address, cmpValue, newValue);
+            compareAndSwap(tasm, masm, result, address, cmpValue, newValue);
         }
     }
 
@@ -279,7 +295,7 @@
     }
 
     @SuppressWarnings("unused")
-    protected static void compareAndSwap(TargetMethodAssembler tasm, PTXAssembler masm, Value result, Address address, Value cmpValue, Value newValue) {
+    protected static void compareAndSwap(TargetMethodAssembler tasm, PTXAssembler masm, Value result, PTXAddress address, Value cmpValue, Value newValue) {
         throw new InternalError("NYI");
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Tue Feb 26 20:10:02 2013 +0100
@@ -93,7 +93,7 @@
         if (kind() != object.kind()) {
             assert generator.target().sizeInBytes(kind()) == generator.target().sizeInBytes(object.kind()) : "unsafe cast cannot be used to change the size of a value";
             Value result = generator.newVariable(kind());
-            generator.emitMove(generator.operand(object), result);
+            generator.emitMove(result, generator.operand(object));
             generator.setResult(this, result);
         } else {
             // The LIR only cares about the kind of an operand, not the actual type of an object. So
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Feb 26 20:07:29 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Feb 26 20:10:02 2013 +0100
@@ -55,7 +55,7 @@
 
     public abstract Value emitMove(Value input);
 
-    public abstract void emitMove(Value src, Value dst);
+    public abstract void emitMove(Value dst, Value src);
 
     public abstract Value emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap);