changeset 4330:d13bfce7b3dd

Merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 26 Jan 2012 12:23:00 +0100
parents 4aacce9c9cb9 (current diff) b0aa4a52b89c (diff)
children daaee28c65c6
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRCall.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/MoveInstruction.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/StandardOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/package-info.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ArithmeticOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompareOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ControlFlowOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DivOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LogicFloatOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MoveOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MulOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Op1Opcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ShiftOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64StandardOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOpcode.java mx/commands.py
diffstat 68 files changed, 3333 insertions(+), 3476 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java	Thu Jan 26 12:23:00 2012 +0100
@@ -110,25 +110,19 @@
     }
 
 
-    public static boolean sameRegister(CiValue...values) {
-        for (int i = 0; i < values.length; i++) {
-            for (int j = i + 1; j < values.length; j++) {
-                if (isRegister(values[i]) && isRegister(values[j]) && asRegister(values[i]) != asRegister(values[j])) {
-                    return false;
-                }
-            }
-        }
-        return true;
+    public static boolean sameRegister(CiValue v1, CiValue v2) {
+        return isRegister(v1) && isRegister(v2) && asRegister(v1) == asRegister(v2);
+    }
+
+    public static boolean sameRegister(CiValue v1, CiValue v2, CiValue v3) {
+        return sameRegister(v1, v2) && sameRegister(v1, v3);
     }
 
-    public static boolean differentRegisters(CiValue...values) {
-        for (int i = 0; i < values.length; i++) {
-            for (int j = i + 1; j < values.length; j++) {
-                if (isRegister(values[i]) && isRegister(values[j]) && asRegister(values[i]) == asRegister(values[j])) {
-                    return false;
-                }
-            }
-        }
-        return true;
+    public static boolean differentRegisters(CiValue v1, CiValue v2) {
+        return !isRegister(v1) || !isRegister(v2) || asRegister(v1) != asRegister(v2);
+    }
+
+    public static boolean differentRegisters(CiValue v1, CiValue v2, CiValue v3) {
+        return differentRegisters(v1, v2) && differentRegisters(v1, v3) && differentRegisters(v2, v3);
     }
 }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Thu Jan 26 12:23:00 2012 +0100
@@ -186,7 +186,7 @@
      * @param method a method whose executable code is being modified
      * @param code the code to be executed when {@code method} is called
      */
-    void installMethod(RiMethod method, CiTargetMethod code);
+    void installMethod(RiResolvedMethod method, CiTargetMethod code);
 
     /**
      * Adds the given machine code as an implementation of the given method without making it the default implementation.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java	Thu Jan 26 12:23:00 2012 +0100
@@ -76,7 +76,7 @@
                     if (op instanceof LIRXirInstruction) {
                         LIRXirInstruction xir = (LIRXirInstruction) op;
                         if (xir.infoAfter != null) {
-                            xir.infoAfter.finish(op.hasCall() ? null : new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+                            xir.infoAfter.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
                         }
                     }
                 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Thu Jan 26 12:23:00 2012 +0100
@@ -55,14 +55,14 @@
         this.dataFlow = new DataFlowAnalysis(lir, frameMap.registerConfig);
         this.blockBeginLocations = new LocationMap[lir.linearScanOrder().size()];
         this.blockEndLocations = new LocationMap[lir.linearScanOrder().size()];
-        this.moveResolver = new MoveResolverImpl(frameMap);
+        this.moveResolver = new MoveResolverImpl(lir, frameMap);
 
         this.variableLastUse = new int[lir.numVariables()];
     }
 
     private class MoveResolverImpl extends MoveResolver {
-        public MoveResolverImpl(FrameMap frameMap) {
-            super(frameMap);
+        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
         }
 
         @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java	Thu Jan 26 12:23:00 2012 +0100
@@ -104,7 +104,7 @@
         if (fromBlock.numberOfSux() == 1) {
             List<LIRInstruction> instructions = fromBlock.lir();
             LIRInstruction instr = instructions.get(instructions.size() - 1);
-            assert instr instanceof LIRBranch && instr.code == StandardOpcode.JUMP : "block does not end with an unconditional jump";
+            assert instr instanceof StandardOp.JumpOp : "block does not end with an unconditional jump";
             moveResolver.init(instructions, instructions.size() - 1);
             assert trace("  insert at end of %s before %d", fromBlock, instructions.size() - 1);
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Thu Jan 26 12:23:00 2012 +0100
@@ -54,12 +54,12 @@
 
         this.dataFlow = new DataFlowAnalysis(lir, frameMap.registerConfig);
         this.blockLocations = new LocationMap[lir.linearScanOrder().size()];
-        this.moveResolver = new MoveResolverImpl(frameMap);
+        this.moveResolver = new MoveResolverImpl(lir, frameMap);
     }
 
     private class MoveResolverImpl extends MoveResolver {
-        public MoveResolverImpl(FrameMap frameMap) {
-            super(frameMap);
+        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
         }
 
         @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, 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.max.graal.alloc.util;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.max.graal.alloc.util.ValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
-import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure;
-import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public final class LIRVerifier {
-    private final LIR lir;
-    private final FrameMap frameMap;
-
-    private final boolean beforeRegisterAllocation;
-
-    private final BitSet[] blockLiveOut;
-    private final Object[] variableDefinitions;
-
-    private BitSet liveOutFor(Block block) {
-        return blockLiveOut[block.blockID()];
-    }
-    private void setLiveOutFor(Block block, BitSet liveOut) {
-        blockLiveOut[block.blockID()] = liveOut;
-    }
-
-    private int maxRegisterNum() {
-        return frameMap.target.arch.registers.length;
-    }
-
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
-    }
-
-    public static boolean verify(final LIRInstruction op) {
-        ValueProcedure allowedProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return allowed(op, value, mode, flags); } };
-
-        op.forEachInput(allowedProc);
-        op.forEachAlive(allowedProc);
-        op.forEachState(allowedProc);
-        op.forEachTemp(allowedProc);
-        op.forEachOutput(allowedProc);
-        return true;
-    }
-
-    public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
-        LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap);
-        verifier.verify();
-        return true;
-    }
-
-
-    private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
-        this.beforeRegisterAllocation = beforeRegisterAllocation;
-        this.lir = lir;
-        this.frameMap = frameMap;
-        this.blockLiveOut = new BitSet[lir.linearScanOrder().size()];
-        this.variableDefinitions = new Object[lir.numVariables()];
-    }
-
-    private BitSet curVariablesLive;
-    private CiValue[] curRegistersLive;
-
-    private LIRBlock curBlock;
-    private Object curInstruction;
-    private BitSet curRegistersDefined;
-
-    private void verify() {
-        PhiValueProcedure useProc = new PhiValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
-        ValueProcedure defProc =    new ValueProcedure() {    @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
-
-        curRegistersDefined = new BitSet();
-        for (LIRBlock block : lir.linearScanOrder()) {
-            curBlock = block;
-            curVariablesLive = new BitSet();
-            curRegistersLive = new CiValue[maxRegisterNum()];
-
-            if (block.dominator() != null) {
-                curVariablesLive.or(liveOutFor(block.dominator()));
-            }
-
-            if (block.phis != null) {
-                assert beforeRegisterAllocation;
-                curInstruction = block.phis;
-                block.phis.forEachOutput(defProc);
-            }
-
-            for (LIRInstruction op : block.lir()) {
-                curInstruction = op;
-
-                op.forEachInput(useProc);
-                if (op.hasCall()) {
-                    for (CiRegister register : frameMap.registerConfig.getCallerSaveRegisters()) {
-                        curRegistersLive[register.number] = null;
-                    }
-                }
-                curRegistersDefined.clear();
-                op.forEachAlive(useProc);
-                op.forEachState(useProc);
-                op.forEachTemp(defProc);
-                op.forEachOutput(defProc);
-
-                curInstruction = null;
-            }
-
-            for (LIRBlock sux : block.getLIRSuccessors()) {
-                if (sux.phis != null) {
-                    assert beforeRegisterAllocation;
-                    curInstruction = sux.phis;
-                    sux.phis.forEachInput(block, useProc);
-                }
-            }
-
-            setLiveOutFor(block, curVariablesLive);
-        }
-    }
-
-    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        allowed(curInstruction, value, mode, flags);
-
-        if (isVariable(value)) {
-            assert beforeRegisterAllocation;
-
-            int variableIdx = asVariable(value).index;
-            if (!curVariablesLive.get(variableIdx)) {
-                TTY.println("block %s  instruction %s", curBlock, curInstruction);
-                TTY.println("live variables: %s", curVariablesLive);
-                if (variableDefinitions[variableIdx] != null) {
-                    TTY.println("definition of %s: %s", value, variableDefinitions[variableIdx]);
-                }
-                TTY.println("ERROR: Use of variable %s that is not defined in dominator", value);
-                throw Util.shouldNotReachHere();
-            }
-
-        } else if (isAllocatableRegister(value)) {
-            int regNum = asRegister(value).number;
-            if (mode == OperandMode.Alive) {
-                curRegistersDefined.set(regNum);
-            }
-
-            if (beforeRegisterAllocation && curRegistersLive[regNum] != value) {
-                TTY.println("block %s  instruction %s", curBlock, curInstruction);
-                TTY.println("live registers: %s", Arrays.toString(curRegistersLive));
-                TTY.println("ERROR: Use of fixed register %s that is not defined in this block", value);
-                throw Util.shouldNotReachHere();
-            }
-        }
-        return value;
-    }
-
-    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        allowed(curInstruction, value, mode, flags);
-
-        if (isVariable(value)) {
-            assert beforeRegisterAllocation;
-
-            int variableIdx = asVariable(value).index;
-            if (variableDefinitions[variableIdx] != null) {
-                TTY.println("block %s  instruction %s", curBlock, curInstruction);
-                TTY.println("live variables: %s", curVariablesLive);
-                TTY.println("definition of %s: %s", value, variableDefinitions[variableIdx]);
-                TTY.println("ERROR: Variable %s defined multiple times", value);
-                throw Util.shouldNotReachHere();
-            }
-            assert curInstruction != null;
-            variableDefinitions[variableIdx] = curInstruction;
-            assert !curVariablesLive.get(variableIdx);
-            if (mode == OperandMode.Output) {
-                curVariablesLive.set(variableIdx);
-            }
-
-        } else if (isAllocatableRegister(value)) {
-            int regNum = asRegister(value).number;
-            if (curRegistersDefined.get(regNum)) {
-                TTY.println("block %s  instruction %s", curBlock, curInstruction);
-                TTY.println("ERROR: Same register defined twice in the same instruction: %s", value);
-                throw Util.shouldNotReachHere();
-            }
-            curRegistersDefined.set(regNum);
-
-            if (beforeRegisterAllocation) {
-                if (mode == OperandMode.Output) {
-                    curRegistersLive[regNum] = value;
-                } else {
-                    curRegistersLive[regNum] = null;
-                }
-            }
-        }
-        return value;
-    }
-
-    private static CiValue allowed(Object op, CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        if ((isVariable(value)  && flags.contains(OperandFlag.Register)) ||
-            (isRegister(value)  && flags.contains(OperandFlag.Register)) ||
-            (isStackSlot(value) && flags.contains(OperandFlag.Stack)) ||
-            (isConstant(value)  && flags.contains(OperandFlag.Constant) && mode != OperandMode.Output) ||
-            (isIllegal(value)   && flags.contains(OperandFlag.Illegal))) {
-            return value;
-        }
-        TTY.println("instruction %s", op);
-        TTY.println("mode: %s  flags: %s", mode, flags);
-        TTY.println("Unexpected value: %s %s", value.getClass().getSimpleName(), value);
-        throw Util.shouldNotReachHere();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/MoveResolver.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/MoveResolver.java	Thu Jan 26 12:23:00 2012 +0100
@@ -34,6 +34,7 @@
 import com.oracle.max.graal.compiler.util.*;
 
 public abstract class MoveResolver {
+    private final LIR lir;
     private final FrameMap frameMap;
     private final int[] registersBlocked;
     private final Map<CiValue, Integer> valuesBlocked;
@@ -42,7 +43,8 @@
     private final LIRInsertionBuffer insertionBuffer;
     private int insertPos;
 
-    public MoveResolver(FrameMap frameMap) {
+    public MoveResolver(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
         this.frameMap = frameMap;
 
         registersBlocked = new int[frameMap.target.arch.registers.length];
@@ -292,7 +294,7 @@
 
         } else {
             assert trace("mr      MOV %s -> %s", src, dst);
-            insertionBuffer.append(insertPos, StandardOpcode.SPILL_MOVE.create(dst,  src));
+            insertionBuffer.append(insertPos, lir.spillMoveFactory.createMove(dst,  src));
         }
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Thu Jan 26 12:23:00 2012 +0100
@@ -203,14 +203,18 @@
     }
 
     private CiValue temp(CiValue value) {
-        assert trace("    temp %s -> remove key %s", value, key(value));
-        curInputState.remove(key(value));
+        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            assert trace("    temp %s -> remove key %s", value, key(value));
+            curInputState.remove(key(value));
+        }
         return value;
     }
 
     private CiValue output(CiValue value) {
-        assert trace("    output %s -> set key %s", value, key(value));
-        curInputState.put(key(value), value);
+        if (value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            assert trace("    output %s -> set key %s", value, key(value));
+            curInputState.put(key(value), value);
+        }
         return value;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Thu Jan 26 12:23:00 2012 +0100
@@ -102,9 +102,9 @@
         List<LIRInstruction> instructions = block.lir();
 
         assert instructions.size() >= 2 : "block must have label and branch";
-        assert instructions.get(0).code == StandardOpcode.LABEL : "first instruction must always be a label";
-        assert instructions.get(instructions.size() - 1).code == StandardOpcode.JUMP : "last instruction must always be a branch";
-        assert ((LIRBranch) instructions.get(instructions.size() - 1)).destination().label() == block.suxAt(0).label() : "branch target must be the successor " + ((LIRBranch) instructions.get(instructions.size() - 1)).destination();
+        assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label";
+        assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "last instruction must always be a branch";
+        assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == block.suxAt(0).label() : "branch target must be the successor";
 
         // block must have exactly one successor
 
@@ -147,22 +147,22 @@
             List<LIRInstruction> instructions = block.lir();
 
             LIRInstruction lastOp = instructions.get(instructions.size() - 1);
-            if (lastOp instanceof LIRBranch) {
-                LIRBranch lastBranch = (LIRBranch) lastOp;
+            if (lastOp instanceof StandardOp.JumpOp) {
+                StandardOp.JumpOp lastJump = (StandardOp.JumpOp) lastOp;
 
-                if (lastBranch.info == null) {
-                    if (lastBranch.destination().label() == code.get(i + 1).label()) {
+                if (lastOp.info == null) {
+                    if (lastJump.destination().label() == code.get(i + 1).label()) {
                         // delete last branch instruction
                         Util.truncate(instructions, instructions.size() - 1);
 
                     } else {
                         LIRInstruction prevOp = instructions.get(instructions.size() - 2);
-                        if (prevOp instanceof LIRBranch) {
-                            LIRBranch prevBranch = (LIRBranch) prevOp;
+                        if (prevOp instanceof StandardOp.BranchOp) {
+                            StandardOp.BranchOp prevBranch = (StandardOp.BranchOp) prevOp;
 
-                            if (prevBranch.destination().label() == code.get(i + 1).label && prevBranch.info == null) {
+                            if (prevBranch.destination().label() == code.get(i + 1).label && prevOp.info == null) {
                                 // eliminate a conditional branch to the immediate successor
-                                prevBranch.negate(lastBranch.destination());
+                                prevBranch.negate(lastJump.destination());
                                 Util.truncate(instructions, instructions.size() - 1);
                             }
                         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Thu Jan 26 12:23:00 2012 +0100
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.lir.StandardOp.*;
 
 /**
  * This class optimizes moves, particularly those that result from eliminating SSA form.
@@ -88,10 +89,10 @@
         assert op1 != null;
         assert op2 != null;
 
-        if (op1 instanceof MoveInstruction && op2 instanceof MoveInstruction) {
-            MoveInstruction move1 = (MoveInstruction) op1;
-            MoveInstruction move2 = (MoveInstruction) op2;
-            if (move1.getSource() == move2.getSource() && move1.getDest() == move2.getDest()) {
+        if (op1 instanceof MoveOp && op2 instanceof MoveOp) {
+            MoveOp move1 = (MoveOp) op1;
+            MoveOp move2 = (MoveOp) op2;
+            if (move1.getInput() == move2.getInput() && move1.getResult() == move2.getResult()) {
                 // these moves are exactly equal and can be optimized
                 return true;
             }
@@ -128,12 +129,12 @@
                 return;
             }
 
-            if (predInstructions.get(predInstructions.size() - 1).code == StandardOpcode.XIR) {
+            if (predInstructions.get(predInstructions.size() - 1) instanceof LIRXirInstruction) {
                 return;
             }
 
             assert pred.suxAt(0) == block : "invalid control flow";
-            assert predInstructions.get(predInstructions.size() - 1).code == StandardOpcode.JUMP : "block must end with unconditional jump";
+            assert predInstructions.get(predInstructions.size() - 1) instanceof StandardOp.JumpOp : "block must end with unconditional jump";
 
             if (predInstructions.get(predInstructions.size() - 1).info != null) {
                 // can not optimize instructions that have debug info
@@ -185,12 +186,12 @@
 
         assert numSux == 2 : "method should not be called otherwise";
 
-        if (instructions.get(instructions.size() - 1).code == StandardOpcode.XIR) {
+        if (instructions.get(instructions.size() - 1) instanceof LIRXirInstruction) {
             // cannot optimize when last instruction is Xir.
             return;
         }
 
-        assert instructions.get(instructions.size() - 1).code == StandardOpcode.JUMP : "block must end with unconditional jump";
+        assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block must end with unconditional jump";
 
         if (instructions.get(instructions.size() - 1).info != null) {
             // cannot optimize instructions when debug info is needed
@@ -198,7 +199,7 @@
         }
 
         LIRInstruction branch = instructions.get(instructions.size() - 2);
-        if (!(branch instanceof LIRBranch) || branch.info != null) {
+        if (!(branch instanceof StandardOp.BranchOp) || branch.info != null) {
             // not a valid case for optimization
             // currently, only blocks that end with two branches (conditional branch followed
             // by unconditional branch) are optimized
@@ -214,7 +215,7 @@
             LIRBlock sux = block.suxAt(i);
             List<LIRInstruction> suxInstructions = sux.lir();
 
-            assert suxInstructions.get(0).code == StandardOpcode.LABEL : "block must start with label";
+            assert suxInstructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
 
             if (sux.numberOfPreds() != 1) {
                 // this can happen with switch-statements where multiple edges are between
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Thu Jan 26 12:23:00 2012 +0100
@@ -43,6 +43,7 @@
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.compiler.lir.StandardOp.*;
 
 /**
  * An implementation of the linear scan register allocator algorithm described
@@ -376,7 +377,7 @@
 
             case NoSpillStore:
                 assert defPos <= interval.spillDefinitionPos() : "positions are processed in reverse order when intervals are created";
-                if (defPos < interval.spillDefinitionPos() - 2 || instructionForId(interval.spillDefinitionPos()).code == StandardOpcode.XIR) {
+                if (defPos < interval.spillDefinitionPos() - 2 || instructionForId(interval.spillDefinitionPos()) instanceof LIRXirInstruction) {
                     // second definition found, so no spill optimization possible for this interval
                     interval.setSpillState(SpillState.NoOptimization);
                 } else {
@@ -471,17 +472,17 @@
                 int opId = op.id();
 
                 if (opId == -1) {
-                    MoveInstruction move = (MoveInstruction) op;
+                    MoveOp move = (MoveOp) op;
                     // remove move from register to stack if the stack slot is guaranteed to be correct.
                     // only moves that have been inserted by LinearScan can be removed.
-                    assert isVariable(move.getDest()) : "LinearScan inserts only moves to variables";
+                    assert isVariable(move.getResult()) : "LinearScan inserts only moves to variables";
 
-                    Interval curInterval = intervalFor(move.getDest());
+                    Interval curInterval = intervalFor(move.getResult());
 
                     if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
                         // move target is a stack slot that is always correct, so eliminate instruction
                         if (GraalOptions.TraceLinearScanLevel >= 4) {
-                            TTY.println("eliminating move from interval %d to %d", operandNumber(move.getSource()), operandNumber(move.getDest()));
+                            TTY.println("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult()));
                         }
                         instructions.set(j, null); // null-instructions are deleted by assignRegNum
                     }
@@ -503,7 +504,7 @@
                         assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
                         assert isStackSlot(toLocation) : "to operand must be a stack slot";
 
-                        insertionBuffer.append(j + 1, StandardOpcode.SPILL_MOVE.create(toLocation, fromLocation));
+                        insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation));
 
                         if (GraalOptions.TraceLinearScanLevel >= 4) {
                             CiStackSlot slot = interval.spillSlot();
@@ -988,9 +989,9 @@
      * Determines the register priority for an instruction's output/result operand.
      */
     static RegisterPriority registerPriorityOfOutputOperand(LIRInstruction op) {
-        if (op instanceof MoveInstruction) {
-            MoveInstruction move = (MoveInstruction) op;
-            if (isStackSlot(move.getSource()) && move.getSource().kind != CiKind.Object) {
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            if (isStackSlot(move.getInput()) && move.getInput().kind != CiKind.Object) {
                 // method argument (condition must be equal to handleMethodArguments)
                 return RegisterPriority.None;
             }
@@ -1018,21 +1019,21 @@
      * spill slot.
      */
     void handleMethodArguments(LIRInstruction op) {
-        if (op instanceof MoveInstruction) {
-            MoveInstruction move = (MoveInstruction) op;
-            if (isStackSlot(move.getSource()) && move.getSource().kind != CiKind.Object) {
-                CiStackSlot slot = (CiStackSlot) move.getSource();
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            if (isStackSlot(move.getInput()) && move.getInput().kind != CiKind.Object) {
+                CiStackSlot slot = (CiStackSlot) move.getInput();
                 if (GraalOptions.DetailedAsserts) {
-                    assert move.id() > 0 : "invalid id";
-                    assert blockForId(move.id()).numberOfPreds() == 0 : "move from stack must be in first block";
-                    assert isVariable(move.getDest()) : "result of move must be a variable";
+                    assert op.id() > 0 : "invalid id";
+                    assert blockForId(op.id()).numberOfPreds() == 0 : "move from stack must be in first block";
+                    assert isVariable(move.getResult()) : "result of move must be a variable";
 
                     if (GraalOptions.TraceLinearScanLevel >= 4) {
-                        TTY.println("found move from stack slot %s to %s", slot, move.getDest());
+                        TTY.println("found move from stack slot %s to %s", slot, move.getResult());
                     }
                 }
 
-                Interval interval = intervalFor(move.getDest());
+                Interval interval = intervalFor(move.getResult());
                 interval.setSpillSlot(slot);
                 interval.assignLocation(slot);
             }
@@ -1420,9 +1421,8 @@
 
             List<LIRInstruction> instructions = fromBlock.lir();
             LIRInstruction instr = instructions.get(instructions.size() - 1);
-            if (instr instanceof LIRBranch) {
+            if (instr instanceof StandardOp.JumpOp) {
                 // insert moves before branch
-                assert instr.code == StandardOpcode.JUMP : "block does not end with an unconditional jump";
                 moveResolver.setInsertPosition(fromBlock.lir(), instructions.size() - 1);
             } else {
                 moveResolver.setInsertPosition(fromBlock.lir(), instructions.size());
@@ -1434,7 +1434,7 @@
             }
 
             if (GraalOptions.DetailedAsserts) {
-                assert fromBlock.lir().get(0).code == StandardOpcode.LABEL : "block does not start with a label";
+                assert fromBlock.lir().get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
 
                 // because the number of predecessor edges matches the number of
                 // successor edges, blocks which are reached by switch statements
@@ -1466,8 +1466,8 @@
             // check if block has only one predecessor and only one successor
             if (block.numberOfPreds() == 1 && block.numberOfSux() == 1) {
                 List<LIRInstruction> instructions = block.lir();
-                assert instructions.get(0).code == StandardOpcode.LABEL : "block must start with label";
-                assert instructions.get(instructions.size() - 1).code == StandardOpcode.JUMP : "block with successor must end with unconditional jump";
+                assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+                assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
 
                 // check if block is empty (only label and branch)
                 if (instructions.size() == 2) {
@@ -1591,10 +1591,8 @@
                     // before the branch instruction. So the split child information for this branch would
                     // be incorrect.
                     LIRInstruction instr = block.lir().get(block.lir().size() - 1);
-                    if (instr instanceof LIRBranch) {
-                        LIRBranch branch = (LIRBranch) instr;
+                    if (instr instanceof StandardOp.JumpOp) {
                         if (block.liveOut.get(operandNumber(operand))) {
-                            assert branch.code == StandardOpcode.JUMP : "block does not end with an unconditional jump";
                             assert false : "can't get split child for the last branch of a block because the information would be incorrect (moves are inserted before the branch in resolveDataFlow)";
                         }
                     }
@@ -1702,7 +1700,7 @@
                     // considered in the live ranges of intervals)
                     // Solution: use the first opId of the branch target block instead.
                     final LIRInstruction instr = block.lir().get(block.lir().size() - 1);
-                    if (instr instanceof LIRBranch) {
+                    if (instr instanceof StandardOp.JumpOp) {
                         if (block.liveOut.get(operandNumber(operand))) {
                             tempOpId = block.suxAt(0).firstLirInstructionId();
                             mode = OperandMode.Output;
@@ -1754,9 +1752,9 @@
             }
 
             // remove useless moves
-            if (op instanceof MoveInstruction) {
-                MoveInstruction move = (MoveInstruction) op;
-                if (move.getSource() == move.getDest()) {
+            if (op instanceof MoveOp) {
+                MoveOp move = (MoveOp) op;
+                if (move.getInput() == move.getResult()) {
                     instructions.set(j, null);
                     hasDead = true;
                 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Thu Jan 26 12:23:00 2012 +0100
@@ -37,6 +37,7 @@
 import com.oracle.max.graal.compiler.alloc.Interval.State;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.compiler.lir.StandardOp.*;
 
 /**
  */
@@ -824,9 +825,9 @@
     }
 
     static boolean isMove(LIRInstruction op, Interval from, Interval to) {
-        if (op instanceof MoveInstruction) {
-            MoveInstruction move = (MoveInstruction) op;
-            return isVariable(move.getSource()) && isVariable(move.getDest()) && move.getSource() == from.operand && move.getDest() == to.operand;
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            return isVariable(move.getInput()) && isVariable(move.getResult()) && move.getInput() == from.operand && move.getResult() == to.operand;
         }
         return false;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Thu Jan 26 12:23:00 2012 +0100
@@ -198,7 +198,7 @@
         CiValue fromOpr = fromInterval.operand;
         CiValue toOpr = toInterval.operand;
 
-        insertionBuffer.append(insertIdx, StandardOpcode.SPILL_MOVE.create(toOpr, fromOpr));
+        insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
         if (GraalOptions.TraceLinearScanLevel >= 4) {
             TTY.println("MoveResolver: inserted move from %d (%s) to %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
@@ -210,7 +210,7 @@
         assert insertIdx != -1 : "must setup insert position first";
 
         CiValue toOpr = toInterval.operand;
-        insertionBuffer.append(insertIdx, StandardOpcode.SPILL_MOVE.create(toOpr, fromOpr));
+        insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
         if (GraalOptions.TraceLinearScanLevel >= 4) {
             TTY.print("MoveResolver: inserted move from constant %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Thu Jan 26 12:23:00 2012 +0100
@@ -242,6 +242,31 @@
         return recordDataReferenceInCode((CiConstant) value, 8);
     }
 
+    public CiAddress asIntAddr(CiValue value) {
+        assert value.kind == CiKind.Int;
+        return asAddress(value);
+    }
+
+    public CiAddress asLongAddr(CiValue value) {
+        assert value.kind == CiKind.Long;
+        return asAddress(value);
+    }
+
+    public CiAddress asObjectAddr(CiValue value) {
+        assert value.kind == CiKind.Object;
+        return asAddress(value);
+    }
+
+    public CiAddress asFloatAddr(CiValue value) {
+        assert value.kind == CiKind.Float;
+        return asAddress(value);
+    }
+
+    public CiAddress asDoubleAddr(CiValue value) {
+        assert value.kind == CiKind.Double;
+        return asAddress(value);
+    }
+
     public CiAddress asAddress(CiValue value) {
         if (isStackSlot(value)) {
             CiStackSlot slot = (CiStackSlot) value;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Thu Jan 26 12:23:00 2012 +0100
@@ -27,26 +27,27 @@
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.cri.util.MemoryBarriers.*;
 import static com.oracle.max.graal.alloc.util.ValueUtil.*;
-import static com.oracle.max.graal.compiler.lir.StandardOpcode.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.max.asm.*;
 import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.ri.RiType.Representation;
 import com.oracle.max.cri.xir.CiXirAssembler.XirConstant;
 import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
 import com.oracle.max.cri.xir.CiXirAssembler.XirOperand;
 import com.oracle.max.cri.xir.CiXirAssembler.XirParameter;
 import com.oracle.max.cri.xir.CiXirAssembler.XirRegister;
 import com.oracle.max.cri.xir.CiXirAssembler.XirTemp;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.criutils.*;
-import com.oracle.max.graal.alloc.util.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.lir.StandardOp.ParametersOp;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
@@ -444,11 +445,11 @@
         for (int i = 0; i < params.length; i++) {
             params[i] = toStackKind(incomingArguments.locations[i]);
         }
-        append(PARAMS.create(params));
+        append(new ParametersOp(params));
 
         XirSnippet prologue = xir.genPrologue(null, method);
         if (prologue != null) {
-            emitXir(prologue, null, null, null, false);
+            emitXir(prologue, null, null, false);
         }
 
         for (LocalNode local : graph.getNodes(LocalNode.class)) {
@@ -481,14 +482,14 @@
     public void visitArrayLength(ArrayLengthNode x) {
         XirArgument array = toXirArgument(x.array());
         XirSnippet snippet = xir.genArrayLength(site(x), array);
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
         operand(x);
     }
 
     @Override
     public void visitCheckCast(CheckCastNode x) {
         XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass());
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
         // The result of a checkcast is the unmodified object, so no need to allocate a new variable for it.
         setResult(x, operand(x.object()));
     }
@@ -513,7 +514,7 @@
         LIRDebugInfo stateAfter = stateFor(x.stateAfter());
 
         XirSnippet snippet = xir.genMonitorEnter(site(x), obj, lockAddress);
-        emitXir(snippet, x, stateBefore, stateAfter, null, true);
+        emitXir(snippet, x, stateBefore, stateAfter, true, null, null);
     }
 
     @Override
@@ -534,7 +535,7 @@
         curLocks = curLocks.outer;
 
         XirSnippet snippet = xir.genMonitorExit(site(x), obj, lockAddress);
-        emitXir(snippet, x, stateBefore, null, true);
+        emitXir(snippet, x, stateBefore, true);
     }
 
     @Override
@@ -546,7 +547,7 @@
         }
         XirArgument receiver = toXirArgument(x.object());
         XirSnippet snippet = x.isStatic() ? xir.genGetStatic(site(x), receiver, field) : xir.genGetField(site(x), receiver, field);
-        emitXir(snippet, x, info, null, true);
+        emitXir(snippet, x, info, true);
         if (x.isVolatile()) {
             emitMembar(JMM_POST_VOLATILE_READ);
         }
@@ -562,7 +563,7 @@
         XirArgument receiver = toXirArgument(x.object());
         XirArgument value = toXirArgument(x.value());
         XirSnippet snippet = x.isStatic() ? xir.genPutStatic(site(x), receiver, field, value) : xir.genPutField(site(x), receiver, field, value);
-        emitXir(snippet, x, info, null, true);
+        emitXir(snippet, x, info, true);
         if (x.isVolatile()) {
             emitMembar(JMM_POST_VOLATILE_WRITE);
         }
@@ -573,7 +574,7 @@
         XirArgument array = toXirArgument(x.array());
         XirArgument index = toXirArgument(x.index());
         XirSnippet snippet = xir.genArrayLoad(site(x), array, index, x.elementKind(), null);
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
     }
 
     @Override
@@ -582,27 +583,27 @@
         XirArgument index = toXirArgument(x.index());
         XirArgument value = toXirArgument(x.value());
         XirSnippet snippet = xir.genArrayStore(site(x), array, index, value, x.elementKind(), null);
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
     }
 
     @Override
     public void visitNewInstance(NewInstanceNode x) {
         XirSnippet snippet = xir.genNewInstance(site(x), x.instanceClass());
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
     }
 
     @Override
     public void visitNewTypeArray(NewTypeArrayNode x) {
         XirArgument length = toXirArgument(x.length());
         XirSnippet snippet = xir.genNewArray(site(x), length, x.elementType().kind(true), null, null);
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
     }
 
     @Override
     public void visitNewObjectArray(NewObjectArrayNode x) {
         XirArgument length = toXirArgument(x.length());
         XirSnippet snippet = xir.genNewArray(site(x), length, CiKind.Object, x.elementType(), x.exactType());
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
     }
 
     @Override
@@ -612,14 +613,14 @@
             dims[i] = toXirArgument(x.dimension(i));
         }
         XirSnippet snippet = xir.genNewMultiArray(site(x), dims, x.type());
-        emitXir(snippet, x, state(), null, true);
+        emitXir(snippet, x, state(), true);
     }
 
     @Override
     public void visitExceptionObject(ExceptionObjectNode x) {
         XirSnippet snippet = xir.genExceptionObject(site(x));
         LIRDebugInfo info = state();
-        emitXir(snippet, x, info, null, true);
+        emitXir(snippet, x, info, true);
     }
 
     @Override
@@ -631,16 +632,18 @@
         }
         XirSnippet epilogue = xir.genEpilogue(site(x), method);
         if (epilogue != null) {
-            emitXir(epilogue, x, null, method, false);
-            append(StandardOpcode.RETURN.create(operand));
+            emitXir(epilogue, x, null, false);
+            emitReturn(operand);
         }
     }
 
+    protected abstract void emitReturn(CiValue input);
+
     @SuppressWarnings("unused")
     protected void postGCWriteBarrier(CiValue addr, CiValue newVal) {
         XirSnippet writeBarrier = xir.genWriteBarrier(toXirArgument(addr));
         if (writeBarrier != null) {
-            emitXir(writeBarrier, null, null, null, false);
+            emitXir(writeBarrier, null, null, false);
         }
     }
 
@@ -677,7 +680,7 @@
     public void emitSafepointPoll(FixedNode x) {
         if (!lastState.method().noSafepointPolls()) {
             XirSnippet snippet = xir.genSafepointPoll(site(x));
-            emitXir(snippet, x, state(), null, false);
+            emitXir(snippet, x, state(), false);
         }
     }
 
@@ -703,20 +706,14 @@
         }
     }
 
-    private void emitNullCheckGuard(NullCheckNode node) {
-        assert !node.expectedNull;
-        NullCheckNode x = node;
-        Variable value = load(operand(x.object()));
-        LIRDebugInfo info = state();
-        append(StandardOpcode.NULL_CHECK.create(value, info));
-    }
+    protected abstract void emitNullCheckGuard(NullCheckNode node);
 
     private void emitTypeGuard(IsTypeNode node) {
         load(operand(node.object()));
         LIRDebugInfo info = state();
         XirArgument clazz = toXirArgument(node.type().getEncoding(Representation.ObjectHub));
         XirSnippet typeCheck = xir.genTypeCheck(site(node), toXirArgument(node.object()), clazz, node.type());
-        emitXir(typeCheck, node, info, method, false);
+        emitXir(typeCheck, node, info, false);
     }
 
 
@@ -752,10 +749,7 @@
     private void emitInstanceOfBranch(InstanceOfNode x, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
         XirArgument obj = toXirArgument(x.object());
         XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass());
-        emitXir(snippet, x, info, null, false);
-        LIRXirInstruction instr = (LIRXirInstruction) currentBlock.lir().get(currentBlock.lir().size() - 1);
-        instr.setTrueSuccessor(x.negated ? falseSuccessor : trueSuccessor);
-        instr.setFalseSuccessor(x.negated ? trueSuccessor : falseSuccessor);
+        emitXir(snippet, x, info, null, false, x.negated ? falseSuccessor : trueSuccessor, x.negated ? trueSuccessor : falseSuccessor);
     }
 
 
@@ -800,7 +794,7 @@
         XirArgument trueArg = toXirArgument(x.negated ? falseValue : trueValue);
         XirArgument falseArg = toXirArgument(x.negated ? trueValue : falseValue);
         XirSnippet snippet = xir.genMaterializeInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass());
-        return (Variable) emitXir(snippet, null, null, null, false);
+        return (Variable) emitXir(snippet, null, null, false);
     }
 
     private Variable emitConstantConditional(boolean value, CiValue trueValue, CiValue falseValue) {
@@ -882,7 +876,7 @@
             // TODO This is the version currently necessary for Maxine: since the invokeinterface-snippet uses a division, it
             // destroys rdx, which is also used to pass a parameter.  Therefore, the snippet must be before the parameters are assigned to their locations.
             LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()));
-            destinationAddress = emitXir(snippet, x.node(), addrInfo, null, callTarget.targetMethod(), false);
+            destinationAddress = emitXir(snippet, x.node(), addrInfo, false);
         }
 
         CiValue resultOperand = resultOperandFor(x.node().kind());
@@ -896,26 +890,20 @@
         if (target().invokeSnippetAfterArguments) {
             // TODO This is the version currently active for HotSpot.
             LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()), pointerSlots, null);
-            destinationAddress = emitXir(snippet, x.node(), addrInfo, null, callTarget.targetMethod(), false);
+            destinationAddress = emitXir(snippet, x.node(), addrInfo, false);
         }
 
         LIRDebugInfo callInfo = stateFor(x.stateDuring(), pointerSlots, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null);
-
-        // emit direct or indirect call to the destination address
-        if (destinationAddress instanceof CiConstant) {
-            // Direct call
-            assert ((CiConstant) destinationAddress).isDefaultValue() : "destination address should be zero";
-            append(StandardOpcode.DIRECT_CALL.create(targetMethod, resultOperand, argList, null, callInfo, snippet.marks));
-        } else {
-            // Indirect call
-            append(StandardOpcode.INDIRECT_CALL.create(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks));
-        }
+        emitCall(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks);
 
         if (isLegal(resultOperand)) {
             setResult(x.node(), emitMove(resultOperand));
         }
     }
 
+    protected abstract void emitCall(Object targetMethod, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks);
+
+
     private static CiValue toStackKind(CiValue value) {
         if (value.kind.stackKind() != value.kind) {
             // We only have stack-kinds in the LIR, so convert the operand kind for values from the calling convention.
@@ -983,7 +971,7 @@
             argumentList = Collections.emptyList();
         }
 
-        append(StandardOpcode.DIRECT_CALL.create(runtimeCall, physReg, argumentList, null, info, null));
+        emitCall(runtimeCall, physReg, argumentList, CiConstant.forLong(0), info, null);
 
         if (isLegal(physReg)) {
             return emitMove(physReg);
@@ -1012,7 +1000,7 @@
             info = stateFor(stateBeforeReturn);
         }
 
-        append(StandardOpcode.DIRECT_CALL.create(x.call(), resultOperand, argList, null, info, null));
+        emitCall(x.call(), resultOperand, argList, CiConstant.forLong(0), info, null);
 
         if (isLegal(resultOperand)) {
             setResult(x, emitMove(resultOperand));
@@ -1211,11 +1199,11 @@
         return variable;
     }
 
-    protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, RiMethod currentMethod, boolean setInstructionResult) {
-        return emitXir(snippet, x, info, null, currentMethod, setInstructionResult);
+    protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, boolean setInstructionResult) {
+        return emitXir(snippet, x, info, null, setInstructionResult, null, null);
     }
 
-    protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod currentMethod, boolean setInstructionResult) {
+    protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, boolean setInstructionResult, LabelRef trueSuccessor, LabelRef falseSuccessor) {
         if (GraalOptions.PrintXirTemplates) {
             TTY.println("Emit XIR template " + snippet.template.name);
         }
@@ -1312,10 +1300,10 @@
         XirInstruction[] slowPath = snippet.template.slowPath;
         if (!isConstant(operandsArray[resultOperand.index]) || snippet.template.fastPath.length != 0 || (slowPath != null && slowPath.length > 0)) {
             // XIR instruction is only needed when the operand is not a constant!
-            append(StandardOpcode.XIR.create(snippet, operandsArray, allocatedResultOperand,
+            emitXir(snippet, operandsArray, allocatedResultOperand,
                     inputOperandArray, tempOperandArray, inputOperandIndicesArray, tempOperandIndicesArray,
                     (allocatedResultOperand == IllegalValue) ? -1 : resultOperand.index,
-                    info, infoAfter, currentMethod));
+                    info, infoAfter, trueSuccessor, falseSuccessor);
             if (GraalOptions.Meter) {
                 context.metrics.LIRXIRInstructions++;
             }
@@ -1324,6 +1312,9 @@
         return operandsArray[resultOperand.index];
     }
 
+    protected abstract void emitXir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+                    LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor);
+
     protected final CiValue callRuntime(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) {
         // get a result register
         CiKind result = runtimeCall.resultKind;
@@ -1349,7 +1340,7 @@
             argumentList = Util.uncheckedCast(Collections.emptyList());
         }
 
-        append(StandardOpcode.DIRECT_CALL.create(runtimeCall, physReg, argumentList, null, info, null));
+        emitCall(runtimeCall, physReg, argumentList, CiConstant.forLong(0), info, null);
 
         return physReg;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Thu Jan 26 12:23:00 2012 +0100
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.asm.*;
@@ -67,6 +68,12 @@
 
     private final int loopCount;
 
+    public SpillMoveFactory spillMoveFactory;
+
+    public interface SpillMoveFactory {
+        LIRInstruction createMove(CiValue result, CiValue input);
+        LIRInstruction createExchange(CiValue input1, CiValue input2);
+    }
 
     public interface SlowPath {
         void emitCode(TargetMethodAssembler tasm);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java	Thu Jan 26 12:23:00 2012 +0100
@@ -205,9 +205,9 @@
         LIRInstruction lirInstruction = lir.get(lir.size() - 1);
         if (lirInstruction instanceof LIRXirInstruction) {
             LIRXirInstruction lirXirInstruction = (LIRXirInstruction) lirInstruction;
-            return (lirXirInstruction.falseSuccessor() != null) && (lirXirInstruction.trueSuccessor() != null);
+            return (lirXirInstruction.falseSuccessor != null) && (lirXirInstruction.trueSuccessor != null);
         }
-        return lirInstruction instanceof LIRBranch;
+        return lirInstruction instanceof StandardOp.JumpOp;
     }
 
     public boolean isExceptionEntry() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, 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.max.graal.compiler.lir;
-
-import com.oracle.max.graal.nodes.calc.*;
-
-public abstract class LIRBranch extends LIRInstruction {
-
-    /**
-     * The condition when this branch is taken, or {@code null} if it is an unconditional branch.
-     */
-    protected Condition cond;
-
-    /**
-     * For floating point branches only. True when the branch should be taken when the comparison is unordered.
-     */
-    protected boolean unorderedIsTrue;
-
-    /**
-     * The target of this branch.
-     */
-    protected LabelRef destination;
-
-
-    public LIRBranch(LIROpcode code, Condition cond, boolean unorderedIsTrue, LabelRef destination, LIRDebugInfo info) {
-        super(code, LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
-        this.cond = cond;
-        this.unorderedIsTrue = unorderedIsTrue;
-        this.destination = destination;
-    }
-
-    public LabelRef destination() {
-        return destination;
-    }
-
-    public void negate(LabelRef newDestination) {
-        destination = newDestination;
-        cond = cond.negate();
-        unorderedIsTrue = !unorderedIsTrue;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRCall.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, 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.max.graal.compiler.lir;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.CiXirAssembler.*;
-import com.oracle.max.graal.compiler.util.*;
-
-/**
- * This class represents a call instruction; either to a {@linkplain CiRuntimeCall runtime method},
- * a {@linkplain RiMethod Java method}, a native function or a global stub.
- */
-public abstract class LIRCall extends LIRInstruction {
-
-    /**
-     * The target of the call. This will be a {@link CiRuntimeCall}, {@link RiMethod} or {@link CiValue}
-     * object denoting a call to the runtime, a Java method or a native function respectively.
-     */
-    public final Object target;
-    /**
-     * The call site needs to be marked if this is non-null.
-     */
-    public final Map<XirMark, Mark> marks;
-
-    private final int targetAddressIndex;
-
-    private static CiValue[] toArray(List<CiValue> arguments, CiValue targetAddress) {
-        CiValue[] result = new CiValue[arguments.size() + (targetAddress != null ? 1 : 0)];
-        arguments.toArray(result);
-        if (targetAddress != null) {
-            result[arguments.size()] = targetAddress;
-        }
-        return result;
-    }
-
-    public LIRCall(LIROpcode opcode,
-                   Object target,
-                   CiValue result,
-                   List<CiValue> arguments,
-                   CiValue targetAddress,
-                   LIRDebugInfo info,
-                   Map<XirMark, Mark> marks) {
-        super(opcode, isLegal(result) ? new CiValue[] {result} : LIRInstruction.NO_OPERANDS, info, toArray(arguments, targetAddress), LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
-        this.marks = marks;
-        if (targetAddress == null) {
-            this.targetAddressIndex = -1;
-        } else {
-            // The last argument is the operand holding the address for the indirect call
-            assert inputs.length - 1 == arguments.size();
-            this.targetAddressIndex = arguments.size();
-        }
-        this.target = target;
-    }
-
-    public CiValue targetAddress() {
-        if (targetAddressIndex >= 0) {
-            return input(targetAddressIndex);
-        }
-        return null;
-    }
-
-    @Override
-    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-        if (mode == OperandMode.Input) {
-            return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-        } else if (mode == OperandMode.Output) {
-            return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
-        }
-        throw Util.shouldNotReachHere();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java	Thu Jan 26 12:23:00 2012 +0100
@@ -157,7 +157,7 @@
     /**
      * The opcode of this instruction.
      */
-    public final LIROpcode code;
+    protected final Object code;
 
     /**
      * The output operands for this instruction (modified by the register allocator).
@@ -198,7 +198,7 @@
      * @param inputs the input operands for the instruction.
      * @param temps the temp operands for the instruction.
      */
-    public LIRInstruction(LIROpcode opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+    public LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
         this.code = opcode;
         this.outputs = outputs;
         this.inputs = inputs;
@@ -319,8 +319,8 @@
     /**
      * Returns true when this instruction is a call instruction that destroys all caller-saved registers.
      */
-    public boolean hasCall() {
-        return false;
+    public final boolean hasCall() {
+        return this instanceof StandardOp.CallOp;
     }
 
     /**
@@ -362,8 +362,9 @@
      * @return The flags for the operand.
      */
     // TODO this method will go away when we have named operands, the flags will be specified as annotations instead.
-    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-        return EnumSet.of(OperandFlag.Register);
+    protected abstract EnumSet<OperandFlag> flagsFor(OperandMode mode, int index);
+
+    protected void verify() {
     }
 
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, 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.max.graal.compiler.lir;
-
-public interface LIROpcode {
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRVerifier.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2009, 2012, 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.max.graal.compiler.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
+import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.compiler.util.*;
+
+public final class LIRVerifier {
+    private final LIR lir;
+    private final FrameMap frameMap;
+
+    private final boolean beforeRegisterAllocation;
+
+    private final BitSet[] blockLiveOut;
+    private final Object[] variableDefinitions;
+
+    private BitSet liveOutFor(Block block) {
+        return blockLiveOut[block.blockID()];
+    }
+    private void setLiveOutFor(Block block, BitSet liveOut) {
+        blockLiveOut[block.blockID()] = liveOut;
+    }
+
+    private int maxRegisterNum() {
+        return frameMap.target.arch.registers.length;
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+    public static boolean verify(final LIRInstruction op) {
+        ValueProcedure allowedProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return allowed(op, value, mode, flags); } };
+
+        op.forEachInput(allowedProc);
+        op.forEachAlive(allowedProc);
+        op.forEachState(allowedProc);
+        op.forEachTemp(allowedProc);
+        op.forEachOutput(allowedProc);
+
+        op.verify();
+        return true;
+    }
+
+    public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
+        LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap);
+        verifier.verify();
+        return true;
+    }
+
+
+    private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
+        this.beforeRegisterAllocation = beforeRegisterAllocation;
+        this.lir = lir;
+        this.frameMap = frameMap;
+        this.blockLiveOut = new BitSet[lir.linearScanOrder().size()];
+        this.variableDefinitions = new Object[lir.numVariables()];
+    }
+
+    private BitSet curVariablesLive;
+    private CiValue[] curRegistersLive;
+
+    private LIRBlock curBlock;
+    private Object curInstruction;
+    private BitSet curRegistersDefined;
+
+    private void verify() {
+        PhiValueProcedure useProc = new PhiValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc =    new ValueProcedure() {    @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
+
+        curRegistersDefined = new BitSet();
+        for (LIRBlock block : lir.linearScanOrder()) {
+            curBlock = block;
+            curVariablesLive = new BitSet();
+            curRegistersLive = new CiValue[maxRegisterNum()];
+
+            if (block.dominator() != null) {
+                curVariablesLive.or(liveOutFor(block.dominator()));
+            }
+
+            if (block.phis != null) {
+                assert beforeRegisterAllocation;
+                curInstruction = block.phis;
+                block.phis.forEachOutput(defProc);
+            }
+
+            assert block.lir().get(0) instanceof StandardOp.LabelOp : "block must start with label";
+            if (block.numberOfSux() > 0) {
+                LIRInstruction last = block.lir().get(block.lir().size() - 1);
+                assert last instanceof StandardOp.JumpOp || last instanceof LIRXirInstruction : "block with successor must end with unconditional jump";
+            }
+
+            for (LIRInstruction op : block.lir()) {
+                curInstruction = op;
+
+                op.forEachInput(useProc);
+                if (op.hasCall()) {
+                    for (CiRegister register : frameMap.registerConfig.getCallerSaveRegisters()) {
+                        curRegistersLive[register.number] = null;
+                    }
+                }
+                curRegistersDefined.clear();
+                op.forEachAlive(useProc);
+                op.forEachState(useProc);
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+
+                curInstruction = null;
+            }
+
+            for (LIRBlock sux : block.getLIRSuccessors()) {
+                if (sux.phis != null) {
+                    assert beforeRegisterAllocation;
+                    curInstruction = sux.phis;
+                    sux.phis.forEachInput(block, useProc);
+                }
+            }
+
+            setLiveOutFor(block, curVariablesLive);
+        }
+    }
+
+    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        allowed(curInstruction, value, mode, flags);
+
+        if (isVariable(value)) {
+            assert beforeRegisterAllocation;
+
+            int variableIdx = asVariable(value).index;
+            if (!curVariablesLive.get(variableIdx)) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("live variables: %s", curVariablesLive);
+                if (variableDefinitions[variableIdx] != null) {
+                    TTY.println("definition of %s: %s", value, variableDefinitions[variableIdx]);
+                }
+                TTY.println("ERROR: Use of variable %s that is not defined in dominator", value);
+                throw Util.shouldNotReachHere();
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (mode == OperandMode.Alive) {
+                curRegistersDefined.set(regNum);
+            }
+
+            if (beforeRegisterAllocation && curRegistersLive[regNum] != value) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("live registers: %s", Arrays.toString(curRegistersLive));
+                TTY.println("ERROR: Use of fixed register %s that is not defined in this block", value);
+                throw Util.shouldNotReachHere();
+            }
+        }
+        return value;
+    }
+
+    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        allowed(curInstruction, value, mode, flags);
+
+        if (isVariable(value)) {
+            assert beforeRegisterAllocation;
+
+            int variableIdx = asVariable(value).index;
+            if (variableDefinitions[variableIdx] != null) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("live variables: %s", curVariablesLive);
+                TTY.println("definition of %s: %s", value, variableDefinitions[variableIdx]);
+                TTY.println("ERROR: Variable %s defined multiple times", value);
+                throw Util.shouldNotReachHere();
+            }
+            assert curInstruction != null;
+            variableDefinitions[variableIdx] = curInstruction;
+            assert !curVariablesLive.get(variableIdx);
+            if (mode == OperandMode.Output) {
+                curVariablesLive.set(variableIdx);
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (curRegistersDefined.get(regNum)) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("ERROR: Same register defined twice in the same instruction: %s", value);
+                throw Util.shouldNotReachHere();
+            }
+            curRegistersDefined.set(regNum);
+
+            if (beforeRegisterAllocation) {
+                if (mode == OperandMode.Output) {
+                    curRegistersLive[regNum] = value;
+                } else {
+                    curRegistersLive[regNum] = null;
+                }
+            }
+        }
+        return value;
+    }
+
+    private static CiValue allowed(Object op, CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        if ((isVariable(value)  && flags.contains(OperandFlag.Register)) ||
+            (isRegister(value)  && flags.contains(OperandFlag.Register)) ||
+            (isStackSlot(value) && flags.contains(OperandFlag.Stack)) ||
+            (isConstant(value)  && flags.contains(OperandFlag.Constant) && mode != OperandMode.Output) ||
+            (isIllegal(value)   && flags.contains(OperandFlag.Illegal))) {
+            return value;
+        }
+        TTY.println("instruction %s", op);
+        TTY.println("mode: %s  flags: %s", mode, flags);
+        TTY.println("Unexpected value: %s %s", value.getClass().getSimpleName(), value);
+        throw Util.shouldNotReachHere();
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java	Thu Jan 26 12:23:00 2012 +0100
@@ -27,8 +27,8 @@
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.compiler.util.*;
 
 public abstract class LIRXirInstruction extends LIRInstruction {
 
@@ -37,12 +37,11 @@
     public final int[] inputOperandIndices;
     public final int[] tempOperandIndices;
     public final XirSnippet snippet;
-    public final RiMethod method;
     public final LIRDebugInfo infoAfter;
-    private LabelRef trueSuccessor;
-    private LabelRef falseSuccessor;
+    public final LabelRef trueSuccessor;
+    public final LabelRef falseSuccessor;
 
-    public LIRXirInstruction(LIROpcode opcode,
+    public LIRXirInstruction(Object opcode,
                              XirSnippet snippet,
                              CiValue[] originalOperands,
                              CiValue outputOperand,
@@ -51,17 +50,19 @@
                              int outputOperandIndex,
                              LIRDebugInfo info,
                              LIRDebugInfo infoAfter,
-                             RiMethod method) {
+                             LabelRef trueSuccessor,
+                             LabelRef falseSuccessor) {
         // Note that we register the XIR input operands as Alive, because the XIR specification allows that input operands
         // are used at any time, even when the temp operands and the actual output operands have already be assigned.
         super(opcode, isLegal(outputOperand) ? new CiValue[] {outputOperand} : LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, inputs, temps);
         this.infoAfter = infoAfter;
-        this.method = method;
         this.snippet = snippet;
         this.inputOperandIndices = inputOperandIndices;
         this.tempOperandIndices = tempOperandIndices;
         this.outputOperandIndex = outputOperandIndex;
         this.originalOperands = originalOperands;
+        this.falseSuccessor = falseSuccessor;
+        this.trueSuccessor = trueSuccessor;
         assert isLegal(outputOperand) || outputOperandIndex == -1;
     }
 
@@ -69,25 +70,10 @@
     protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
         if (mode == OperandMode.Alive || mode == OperandMode.Temp) {
             return EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Illegal);
+        } else if (mode == OperandMode.Output && index == 0) {
+            return EnumSet.of(OperandFlag.Register);
         }
-        return super.flagsFor(mode, index);
-    }
-
-    public void setFalseSuccessor(LabelRef falseSuccessor) {
-        this.falseSuccessor = falseSuccessor;
-    }
-
-
-    public void setTrueSuccessor(LabelRef trueSuccessor) {
-        this.trueSuccessor = trueSuccessor;
-    }
-
-    public LabelRef falseSuccessor() {
-        return falseSuccessor;
-    }
-
-    public LabelRef trueSuccessor() {
-        return trueSuccessor;
+        throw Util.shouldNotReachHere();
     }
 
     public CiValue[] getOperands() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/MoveInstruction.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, 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.max.graal.compiler.lir;
-
-import com.oracle.max.cri.ci.*;
-
-public abstract class MoveInstruction extends LIRInstruction {
-    public MoveInstruction(LIROpcode opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
-        super(opcode, outputs, info, inputs, alives, temps);
-    }
-
-    public abstract CiValue getSource();
-    public abstract CiValue getDest();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/StandardOp.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.lir;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.util.*;
+
+/**
+ * A collection of machine-independent LIR operations, as well as interfaces to be implemented for specific kinds or LIR
+ * operations.
+ */
+public class StandardOp {
+
+    /**
+     * Marker interface for a LIR operation that defines the position of a label.
+     * The first operation of every block must implement this interface.
+     */
+    public interface LabelOp {
+    }
+
+    /**
+     * Marker interface for a LIR operation that is an unconditional jump to {@link #destination()}.
+     * When the LIR is constructed, the last operation of every block must implement this interface. After
+     * register allocation, unnecessary jumps can be deleted.
+     *
+     * TODO Currently, a block can also end with an XIR operation.
+     */
+    public interface JumpOp {
+        LabelRef destination();
+    }
+
+    /**
+     * Marker interface for a LIR operation that is a conditional jump to {@link #destination()}.
+     * Conditional jumps may be negated or optimized away after register allocation.
+     */
+    public interface BranchOp {
+        LabelRef destination();
+        void negate(LabelRef newDestination);
+    }
+
+    /**
+     * Marker interface for a LIR operation that moves a value from {@link #getInput()} to {@link #getResult()}.
+     */
+    public interface MoveOp {
+        CiValue getInput();
+        CiValue getResult();
+    }
+
+    /**
+     * Marker interface for a LIR operation that calls a method, i.e., destroys all caller-saved registers.
+     */
+    public interface CallOp {
+    }
+
+
+    /**
+     * Meta-operation that defines the incoming method parameters. In the LIR, every register and variable must be
+     * defined before it is used. This operation is the definition point of method parameters, but is otherwise a no-op.
+     * In particular, it is not the actual method prologue.
+     */
+    public static final class ParametersOp extends LIRInstruction {
+        public ParametersOp(CiValue[] params) {
+            super("PARAMS", params, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm) {
+            // No code to emit.
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/StandardOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.lir;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
-import com.oracle.max.cri.xir.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public class StandardOpcode {
-    // Checkstyle: stop
-    public static MoveOpcode SPILL_MOVE;
-    public static NullCheckOpcode NULL_CHECK;
-    public static CallOpcode DIRECT_CALL;
-    public static CallOpcode INDIRECT_CALL;
-    public static LIROpcode LABEL;
-    public static LIROpcode JUMP;
-    public static ReturnOpcode RETURN;
-    public static XirOpcode XIR;
-    public static ParametersOpcode PARAMS = ParametersOpcode.PARAMS;
-    // Checkstyle: resume
-
-    public interface MoveOpcode extends LIROpcode {
-        MoveInstruction create(CiValue result, CiValue input);
-    }
-
-    public interface NullCheckOpcode extends LIROpcode {
-        LIRInstruction create(Variable input, LIRDebugInfo info);
-    }
-
-    public interface CallOpcode extends LIROpcode {
-        LIRInstruction create(Object target, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks);
-    }
-
-    public interface ReturnOpcode extends LIROpcode {
-        LIRInstruction create(CiValue input);
-    }
-
-    public interface XirOpcode extends LIROpcode {
-        LIRInstruction create(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
-                        LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method);
-    }
-
-
-    public enum ParametersOpcode implements LIROpcode {
-        @SuppressWarnings("hiding")
-        PARAMS;
-
-        public LIRInstruction create(CiValue[] params) {
-            return new LIRInstruction(this, params, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm) {
-                    // No code to emit. This is not the actual method prologue, but only a meta-instruction that defines the incoming method parameters.
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Output) {
-                        return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-                    }
-                    throw Util.shouldNotReachHere();
-                }
-            };
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/package-info.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.
- */
-
-/**
- *
- * Port of the backend (LIR) of the client compiler to Java.
- */
-package com.oracle.max.graal.compiler.lir;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Arithmetic.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.util.*;
+
+public enum AMD64Arithmetic {
+    IADD, ISUB, IMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
+    LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
+    FADD, FSUB, FMUL, FDIV, FAND, FOR, FXOR,
+    DADD, DSUB, DMUL, DDIV, DAND, DOR, DXOR,
+    INEG, LNEG,
+    I2L, L2I, I2B, I2C, I2S,
+    F2D, D2F,
+    I2F, I2D, F2I, D2I,
+    L2F, L2D, F2L, D2L,
+    MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
+
+
+    public static class Op1Reg extends AMD64LIRInstruction {
+        public Op1Reg(AMD64Arithmetic opcode, CiValue result, CiValue x) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+
+            emit(tasm, masm, (AMD64Arithmetic) code, result, x, null);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+    public static class Op1Stack extends AMD64LIRInstruction {
+        public Op1Stack(AMD64Arithmetic opcode, CiValue result, CiValue x) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+    public static class Op2Stack extends AMD64LIRInstruction {
+        public Op2Stack(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw Util.shouldNotReachHere();
+        }
+
+        @Override
+        public void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            assert differentRegisters(result, y) || sameRegister(x, y);
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+    public static class Op2RegCommutative extends AMD64LIRInstruction {
+        public Op2RegCommutative(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            if (sameRegister(result, y)) {
+                emit(tasm, masm, (AMD64Arithmetic) code, result, x, null);
+            } else {
+                AMD64Move.move(tasm, masm, result, x);
+                emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+            }
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw Util.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            super.verify();
+            assert differentRegisters(result, y) || sameRegister(x, y);
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+    public static class ShiftOp extends AMD64LIRInstruction {
+        public ShiftOp(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw Util.shouldNotReachHere();
+        }
+
+        @Override
+        public void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            assert isConstant(y) || asRegister(y) == AMD64.rcx;
+            assert differentRegisters(result, y) || sameRegister(x, y);
+            verifyKind((AMD64Arithmetic) code, result, x, x);
+            assert y.kind.stackKind() == CiKind.Int;
+        }
+    }
+
+    public static class DivOp extends AMD64LIRInstruction {
+        public DivOp(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y, LIRDebugInfo info) {
+            super(opcode, new CiValue[] {result}, info, new CiValue[] {x}, new CiValue[] {y}, new CiValue[] {asRegister(result) == AMD64.rax ? AMD64.rdx.asValue(result.kind) : AMD64.rax.asValue(result.kind)});
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue y = alive(0);
+
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, info);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx
+            assert asRegister(x) == AMD64.rax;
+            assert differentRegisters(y, AMD64.rax.asValue(), AMD64.rdx.asValue());
+            assert (name().endsWith("DIV") && asRegister(result) == AMD64.rax) || (name().endsWith("REM") && asRegister(result) == AMD64.rdx);
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+
+    @SuppressWarnings("unused")
+    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, CiValue result) {
+        switch (opcode) {
+            case INEG: masm.negl(asIntReg(result)); break;
+            case LNEG: masm.negq(asLongReg(result)); break;
+            case L2I:  masm.andl(asIntReg(result), 0xFFFFFFFF); break;
+            case I2B:  masm.signExtendByte(asIntReg(result)); break;
+            case I2C:  masm.andl(asIntReg(result), 0xFFFF); break;
+            case I2S:  masm.signExtendShort(asIntReg(result)); break;
+            default:   throw Util.shouldNotReachHere();
+        }
+    }
+
+    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, CiValue dst, CiValue src, LIRDebugInfo info) {
+        int exceptionOffset = -1;
+        if (isRegister(src)) {
+            switch (opcode) {
+                case IADD: masm.addl(asIntReg(dst),  asIntReg(src)); break;
+                case ISUB: masm.subl(asIntReg(dst),  asIntReg(src)); break;
+                case IAND: masm.andl(asIntReg(dst),  asIntReg(src)); break;
+                case IMUL: masm.imull(asIntReg(dst), asIntReg(src)); break;
+                case IOR:  masm.orl(asIntReg(dst),   asIntReg(src)); break;
+                case IXOR: masm.xorl(asIntReg(dst),  asIntReg(src)); break;
+                case ISHL: masm.shll(asIntReg(dst)); break;
+                case ISHR: masm.sarl(asIntReg(dst)); break;
+                case IUSHR:masm.shrl(asIntReg(dst)); break;
+
+                case LADD: masm.addq(asLongReg(dst),  asLongReg(src)); break;
+                case LSUB: masm.subq(asLongReg(dst),  asLongReg(src)); break;
+                case LMUL: masm.imulq(asLongReg(dst), asLongReg(src)); break;
+                case LAND: masm.andq(asLongReg(dst),  asLongReg(src)); break;
+                case LOR:  masm.orq(asLongReg(dst),   asLongReg(src)); break;
+                case LXOR: masm.xorq(asLongReg(dst),  asLongReg(src)); break;
+                case LSHL: masm.shlq(asLongReg(dst)); break;
+                case LSHR: masm.sarq(asLongReg(dst)); break;
+                case LUSHR:masm.shrq(asLongReg(dst)); break;
+
+                case FADD: masm.addss(asFloatReg(dst), asFloatReg(src)); break;
+                case FSUB: masm.subss(asFloatReg(dst), asFloatReg(src)); break;
+                case FMUL: masm.mulss(asFloatReg(dst), asFloatReg(src)); break;
+                case FDIV: masm.divss(asFloatReg(dst), asFloatReg(src)); break;
+                case FAND: masm.andps(asFloatReg(dst), asFloatReg(src)); break;
+                case FOR:  masm.orps(asFloatReg(dst),  asFloatReg(src)); break;
+                case FXOR: masm.xorps(asFloatReg(dst), asFloatReg(src)); break;
+
+                case DADD: masm.addsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DSUB: masm.subsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DMUL: masm.mulsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DDIV: masm.divsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DAND: masm.andpd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DOR:  masm.orpd(asDoubleReg(dst),  asDoubleReg(src)); break;
+                case DXOR: masm.xorpd(asDoubleReg(dst), asDoubleReg(src)); break;
+
+                case I2L: masm.movslq(asLongReg(dst), asIntReg(src)); break;
+                case F2D: masm.cvtss2sd(asDoubleReg(dst), asFloatReg(src)); break;
+                case D2F: masm.cvtsd2ss(asFloatReg(dst), asDoubleReg(src)); break;
+                case I2F: masm.cvtsi2ssl(asFloatReg(dst), asIntReg(src)); break;
+                case I2D: masm.cvtsi2sdl(asDoubleReg(dst), asIntReg(src)); break;
+                case L2F: masm.cvtsi2ssq(asFloatReg(dst), asLongReg(src)); break;
+                case L2D: masm.cvtsi2sdq(asDoubleReg(dst), asLongReg(src)); break;
+                case F2I:
+                    masm.cvttss2sil(asIntReg(dst), asFloatReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case D2I:
+                    masm.cvttsd2sil(asIntReg(dst), asDoubleReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case F2L:
+                    masm.cvttss2siq(asLongReg(dst), asFloatReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case D2L:
+                    masm.cvttsd2siq(asLongReg(dst), asDoubleReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case MOV_I2F: masm.movdl(asFloatReg(dst), asIntReg(src)); break;
+                case MOV_L2D: masm.movdq(asDoubleReg(dst), asLongReg(src)); break;
+                case MOV_F2I: masm.movdl(asIntReg(dst), asFloatReg(src)); break;
+                case MOV_D2L: masm.movdq(asLongReg(dst), asDoubleReg(src)); break;
+
+                case IDIV:
+                case IREM:
+                    masm.cdql();
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.idivl(asRegister(src));
+                    break;
+
+                case LDIV:
+                case LREM:
+                    Label continuation = new Label();
+                    if (opcode == LDIV) {
+                        // check for special case of Long.MIN_VALUE / -1
+                        Label normalCase = new Label();
+                        masm.movq(AMD64.rdx, java.lang.Long.MIN_VALUE);
+                        masm.cmpq(AMD64.rax, AMD64.rdx);
+                        masm.jcc(ConditionFlag.notEqual, normalCase);
+                        masm.cmpl(asRegister(src), -1);
+                        masm.jcc(ConditionFlag.equal, continuation);
+                        masm.bind(normalCase);
+                    }
+
+                    masm.cdqq();
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.idivq(asRegister(src));
+                    masm.bind(continuation);
+                    break;
+
+                case IUDIV:
+                case IUREM:
+                    // Must zero the high 64-bit word (in RDX) of the dividend
+                    masm.xorq(AMD64.rdx, AMD64.rdx);
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.divl(asRegister(src));
+                    break;
+
+                case LUDIV:
+                case LUREM:
+                    // Must zero the high 64-bit word (in RDX) of the dividend
+                    masm.xorq(AMD64.rdx, AMD64.rdx);
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.divq(asRegister(src));
+                    break;
+                default:
+                    throw Util.shouldNotReachHere();
+            }
+        } else if (isConstant(src)) {
+            switch (opcode) {
+                case IADD: masm.incrementl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case ISUB: masm.decrementl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case IMUL: masm.imull(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
+                case IAND: masm.andl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case IOR:  masm.orl(asIntReg(dst),  tasm.asIntConst(src)); break;
+                case IXOR: masm.xorl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case ISHL: masm.shll(asIntReg(dst), tasm.asIntConst(src) & 31); break;
+                case ISHR: masm.sarl(asIntReg(dst), tasm.asIntConst(src) & 31); break;
+                case IUSHR:masm.shrl(asIntReg(dst), tasm.asIntConst(src) & 31); break;
+
+                case LADD: masm.addq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LSUB: masm.subq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LMUL: masm.imulq(asLongReg(dst), asLongReg(dst), tasm.asIntConst(src)); break;
+                case LAND: masm.andq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LOR:  masm.orq(asLongReg(dst),  tasm.asIntConst(src)); break;
+                case LXOR: masm.xorq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LSHL: masm.shlq(asLongReg(dst), tasm.asIntConst(src) & 63); break;
+                case LSHR: masm.sarq(asLongReg(dst), tasm.asIntConst(src) & 63); break;
+                case LUSHR:masm.shrq(asLongReg(dst), tasm.asIntConst(src) & 63); break;
+
+                case FADD: masm.addss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+                case FSUB: masm.subss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+                case FMUL: masm.mulss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+                case FAND: masm.andps(asFloatReg(dst), tasm.asFloatConstRef(src, 16)); break;
+                case FOR:  masm.orps(asFloatReg(dst),  tasm.asFloatConstRef(src, 16)); break;
+                case FXOR: masm.xorps(asFloatReg(dst), tasm.asFloatConstRef(src, 16)); break;
+                case FDIV: masm.divss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+
+                case DADD: masm.addsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DSUB: masm.subsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DMUL: masm.mulsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DDIV: masm.divsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DAND: masm.andpd(asDoubleReg(dst), tasm.asDoubleConstRef(src, 16)); break;
+                case DOR:  masm.orpd(asDoubleReg(dst),  tasm.asDoubleConstRef(src, 16)); break;
+                case DXOR: masm.xorpd(asDoubleReg(dst), tasm.asDoubleConstRef(src, 16)); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+        } else {
+            switch (opcode) {
+                case IADD: masm.addl(asIntReg(dst), tasm.asIntAddr(src)); break;
+                case ISUB: masm.subl(asIntReg(dst), tasm.asIntAddr(src)); break;
+                case IAND: masm.andl(asIntReg(dst), tasm.asIntAddr(src)); break;
+                case IOR:  masm.orl(asIntReg(dst),  tasm.asIntAddr(src)); break;
+                case IXOR: masm.xorl(asIntReg(dst), tasm.asIntAddr(src)); break;
+
+                case LADD: masm.addq(asLongReg(dst), tasm.asLongAddr(src)); break;
+                case LSUB: masm.subq(asLongReg(dst), tasm.asLongAddr(src)); break;
+                case LAND: masm.andq(asLongReg(dst), tasm.asLongAddr(src)); break;
+                case LOR:  masm.orq(asLongReg(dst),  tasm.asLongAddr(src)); break;
+                case LXOR: masm.xorq(asLongReg(dst), tasm.asLongAddr(src)); break;
+
+                case FADD: masm.addss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+                case FSUB: masm.subss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+                case FMUL: masm.mulss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+                case FDIV: masm.divss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+
+                case DADD: masm.addsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                case DSUB: masm.subsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                case DMUL: masm.mulsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                case DDIV: masm.divsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+        }
+
+        if (info != null) {
+            assert exceptionOffset != -1;
+            tasm.recordImplicitException(exceptionOffset, info);
+        }
+    }
+
+    private static void emitConvertFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
+        ConvertSlowPath slowPath = new ConvertSlowPath(result, x);
+        tasm.slowPaths.add(slowPath);
+        switch (result.kind) {
+            case Int:  masm.cmpl(asIntReg(result),  Integer.MIN_VALUE); break;
+            case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(CiConstant.forLong(java.lang.Long.MIN_VALUE))); break;
+            default:   throw Util.shouldNotReachHere();
+        }
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
+    }
+
+    private static class ConvertSlowPath extends AMD64SlowPath {
+        public final Label start = new Label();
+        public final Label continuation = new Label();
+        private final CiValue result;
+        private final CiValue x;
+
+        public ConvertSlowPath(CiValue result, CiValue x) {
+            this.result = result;
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.bind(start);
+            switch (x.kind) {
+                case Float:  masm.ucomiss(asFloatReg(x),  tasm.asFloatConstRef(CiConstant.FLOAT_0)); break;
+                case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); break;
+                default:     throw Util.shouldNotReachHere();
+            }
+            Label nan = new Label();
+            masm.jcc(ConditionFlag.parity, nan);
+            masm.jcc(ConditionFlag.below, continuation);
+
+            // input is > 0 -> return maxInt
+            // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff
+            switch (result.kind) {
+                case Int:  masm.decrementl(asIntReg(result),  1); break;
+                case Long: masm.decrementq(asLongReg(result), 1); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+            masm.jmp(continuation);
+
+            // input is NaN -> return 0
+            masm.bind(nan);
+            masm.xorptr(asRegister(result), asRegister(result));
+            masm.jmp(continuation);
+        }
+    }
+
+
+    private static void verifyKind(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+        assert (opcode.name().startsWith("I") && result.kind == CiKind.Int && x.kind.stackKind() == CiKind.Int && y.kind.stackKind() == CiKind.Int)
+            || (opcode.name().startsWith("L") && result.kind == CiKind.Long && x.kind == CiKind.Long && y.kind == CiKind.Long)
+            || (opcode.name().startsWith("F") && result.kind == CiKind.Float && x.kind == CiKind.Float && y.kind == CiKind.Float)
+            || (opcode.name().startsWith("D") && result.kind == CiKind.Double && x.kind == CiKind.Double && y.kind == CiKind.Double);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ArithmeticOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64ArithmeticOpcode implements LIROpcode {
-    IADD, ISUB, IAND, IOR, IXOR,
-    LADD, LSUB, LAND, LOR, LXOR,
-    FADD, FSUB, FMUL, FDIV,
-    DADD, DSUB, DMUL, DDIV;
-
-    public LIRInstruction create(CiValue result, CiValue x, CiValue y) {
-        assert (name().startsWith("I") && result.kind == CiKind.Int && x.kind.stackKind() == CiKind.Int && y.kind.stackKind() == CiKind.Int)
-            || (name().startsWith("L") && result.kind == CiKind.Long && x.kind == CiKind.Long && y.kind == CiKind.Long)
-            || (name().startsWith("F") && result.kind == CiKind.Float && x.kind == CiKind.Float && y.kind == CiKind.Float)
-            || (name().startsWith("D") && result.kind == CiKind.Double && x.kind == CiKind.Double && y.kind == CiKind.Double);
-
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] alives = new CiValue[] {y};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, alives, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0), alive(0));
-            }
-
-            @Override
-            public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Input && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                } else if (mode == OperandMode.Alive && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                } else if (mode == OperandMode.Output && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    protected void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue y) {
-        assert sameRegister(x, y) || differentRegisters(result, y);
-        AMD64MoveOpcode.move(tasm, masm, result, x);
-
-        CiRegister dst = asRegister(result);
-        if (isRegister(y)) {
-            CiRegister rreg = asRegister(y);
-            switch (this) {
-                case IADD: masm.addl(dst,  rreg); break;
-                case ISUB: masm.subl(dst,  rreg); break;
-                case IAND: masm.andl(dst,  rreg); break;
-                case IOR:  masm.orl(dst,   rreg); break;
-                case IXOR: masm.xorl(dst,  rreg); break;
-                case LADD: masm.addq(dst,  rreg); break;
-                case LSUB: masm.subq(dst,  rreg); break;
-                case LAND: masm.andq(dst,  rreg); break;
-                case LOR:  masm.orq(dst,   rreg); break;
-                case LXOR: masm.xorq(dst,  rreg); break;
-                case FADD: masm.addss(dst, rreg); break;
-                case FSUB: masm.subss(dst, rreg); break;
-                case FMUL: masm.mulss(dst, rreg); break;
-                case FDIV: masm.divss(dst, rreg); break;
-                case DADD: masm.addsd(dst, rreg); break;
-                case DSUB: masm.subsd(dst, rreg); break;
-                case DMUL: masm.mulsd(dst, rreg); break;
-                case DDIV: masm.divsd(dst, rreg); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else if (isConstant(y)) {
-            switch (this) {
-                case IADD: masm.incrementl(dst, tasm.asIntConst(y)); break;
-                case ISUB: masm.decrementl(dst, tasm.asIntConst(y)); break;
-                case IAND: masm.andl(dst,  tasm.asIntConst(y)); break;
-                case IOR:  masm.orl(dst,   tasm.asIntConst(y)); break;
-                case IXOR: masm.xorl(dst,  tasm.asIntConst(y)); break;
-                case LADD: masm.addq(dst,  tasm.asIntConst(y)); break;
-                case LSUB: masm.subq(dst,  tasm.asIntConst(y)); break;
-                case LAND: masm.andq(dst,  tasm.asIntConst(y)); break;
-                case LOR:  masm.orq(dst,   tasm.asIntConst(y)); break;
-                case LXOR: masm.xorq(dst,  tasm.asIntConst(y)); break;
-                case FADD: masm.addss(dst, tasm.asFloatConstRef(y)); break;
-                case FSUB: masm.subss(dst, tasm.asFloatConstRef(y)); break;
-                case FMUL: masm.mulss(dst, tasm.asFloatConstRef(y)); break;
-                case FDIV: masm.divss(dst, tasm.asFloatConstRef(y)); break;
-                case DADD: masm.addsd(dst, tasm.asDoubleConstRef(y)); break;
-                case DSUB: masm.subsd(dst, tasm.asDoubleConstRef(y)); break;
-                case DMUL: masm.mulsd(dst, tasm.asDoubleConstRef(y)); break;
-                case DDIV: masm.divsd(dst, tasm.asDoubleConstRef(y)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else {
-            CiAddress raddr = tasm.asAddress(y);
-            switch (this) {
-                case IADD: masm.addl(dst,  raddr); break;
-                case ISUB: masm.subl(dst,  raddr); break;
-                case IAND: masm.andl(dst,  raddr); break;
-                case IOR:  masm.orl(dst,   raddr); break;
-                case IXOR: masm.xorl(dst,  raddr); break;
-                case LADD: masm.addq(dst,  raddr); break;
-                case LSUB: masm.subq(dst,  raddr); break;
-                case LAND: masm.andq(dst,  raddr); break;
-                case LOR:  masm.orq(dst,   raddr); break;
-                case LXOR: masm.xorq(dst,  raddr); break;
-                case FADD: masm.addss(dst, raddr); break;
-                case FSUB: masm.subss(dst, raddr); break;
-                case FMUL: masm.mulss(dst, raddr); break;
-                case FDIV: masm.divss(dst, raddr); break;
-                case DADD: masm.addsd(dst, raddr); break;
-                case DSUB: masm.subsd(dst, raddr); break;
-                case DMUL: masm.mulsd(dst, raddr); break;
-                case DDIV: masm.divsd(dst, raddr); break;
-                default:  throw Util.shouldNotReachHere();
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Call.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.util.*;
+
+public class AMD64Call {
+
+    public static class DirectCallOp extends AMD64LIRInstruction implements StandardOp.CallOp {
+        private final Object targetMethod;
+        private final Map<XirMark, Mark> marks;
+
+        public DirectCallOp(Object targetMethod, CiValue result, CiValue[] parameters, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+            super("CALL_DIRECT", new CiValue[] {result}, info, parameters, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.targetMethod = targetMethod;
+            this.marks = marks;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            callAlignment(tasm, masm);
+            if (marks != null) {
+                marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
+            }
+            directCall(tasm, masm, targetMethod, info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            } else if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+    public static class IndirectCallOp extends AMD64LIRInstruction implements StandardOp.CallOp {
+        private final Object targetMethod;
+        private final Map<XirMark, Mark> marks;
+
+        private static CiValue[] concat(CiValue[] parameters, CiValue targetAddress) {
+            CiValue[] result = Arrays.copyOf(parameters, parameters.length + 1);
+            result[result.length - 1] = targetAddress;
+            return result;
+        }
+
+        public IndirectCallOp(Object targetMethod, CiValue result, CiValue[] parameters, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+            super("CALL_INDIRECT", new CiValue[] {result}, info, concat(parameters, targetAddress), LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.targetMethod = targetMethod;
+            this.marks = marks;
+        }
+
+        private CiValue targetAddress() {
+            return input(inputs.length - 1);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            callAlignment(tasm, masm);
+            if (marks != null) {
+                marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
+            }
+            indirectCall(tasm, masm, asRegister(targetAddress()), targetMethod, info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            } else if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static void callAlignment(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        if (GraalOptions.AlignCallsForPatching) {
+            // make sure that the displacement word of the call ends up word aligned
+            int offset = masm.codeBuffer.position();
+            offset += tasm.target.arch.machineCodeCallDisplacementOffset;
+            while (offset++ % tasm.target.wordSize != 0) {
+                masm.nop();
+            }
+        }
+    }
+
+    public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRDebugInfo info) {
+        int before = masm.codeBuffer.position();
+        if (target instanceof CiRuntimeCall) {
+            long maxOffset = tasm.runtime.getMaxCallTargetOffset((CiRuntimeCall) target);
+            if (maxOffset != (int) maxOffset) {
+                // offset might not fit a 32-bit immediate, generate an
+                // indirect call with a 64-bit immediate
+                CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
+                // TODO(cwi): we want to get rid of a generally reserved scratch register.
+                masm.movq(scratch, 0L);
+                masm.call(scratch);
+            } else {
+                masm.call();
+            }
+        } else {
+            masm.call();
+        }
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, tasm.runtime.asCallTarget(target), info);
+        tasm.recordExceptionHandlers(after, info);
+        masm.ensureUniquePC();
+    }
+
+    public static void directJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target) {
+        int before = masm.codeBuffer.position();
+        masm.jmp(0, true);
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, tasm.runtime.asCallTarget(target), null);
+        masm.ensureUniquePC();
+    }
+
+    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiRegister dst, Object target, LIRDebugInfo info) {
+        int before = masm.codeBuffer.position();
+        masm.call(dst);
+        int after = masm.codeBuffer.position();
+        tasm.recordIndirectCall(before, after, tasm.runtime.asCallTarget(target), info);
+        tasm.recordExceptionHandlers(after, info);
+        masm.ensureUniquePC();
+    }
+
+    public static void shouldNotReachHere(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        if (GraalOptions.GenAssertionCode) {
+            directCall(tasm, masm, CiRuntimeCall.Debug, null);
+            masm.hlt();
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
-import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64CallOpcode implements StandardOpcode.CallOpcode {
-    DIRECT_CALL, INDIRECT_CALL, NATIVE_CALL;
-
-    public LIRInstruction create(Object target, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
-        return new LIRCall(this, target, result, arguments, targetAddress, info, marks) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm) {
-                emit(tasm, (AMD64MacroAssembler) tasm.asm, this);
-            }
-
-            @Override
-            public boolean hasCall() {
-                return true;
-            }
-        };
-    }
-
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, LIRCall op) {
-        switch (this) {
-            case DIRECT_CALL: {
-                callAlignment(tasm, masm);
-                if (op.marks != null) {
-                    op.marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
-                }
-                directCall(tasm, masm, op.target, op.info);
-                break;
-            }
-            case INDIRECT_CALL: {
-                callAlignment(tasm, masm);
-                if (op.marks != null) {
-                    op.marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
-                }
-                CiRegister reg = asRegister(op.targetAddress());
-                indirectCall(tasm, masm, reg, op.target, op.info);
-                break;
-            }
-            case NATIVE_CALL: {
-                CiRegister reg = asRegister(op.targetAddress());
-                indirectCall(tasm, masm, reg, op.target, op.info);
-                break;
-            }
-            default:
-                throw Util.shouldNotReachHere();
-        }
-    }
-
-
-    public static void callAlignment(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        if (GraalOptions.AlignCallsForPatching) {
-            // make sure that the displacement word of the call ends up word aligned
-            int offset = masm.codeBuffer.position();
-            offset += tasm.target.arch.machineCodeCallDisplacementOffset;
-            while (offset++ % tasm.target.wordSize != 0) {
-                masm.nop();
-            }
-        }
-    }
-
-    public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRDebugInfo info) {
-        int before = masm.codeBuffer.position();
-        if (target instanceof CiRuntimeCall) {
-            long maxOffset = tasm.runtime.getMaxCallTargetOffset((CiRuntimeCall) target);
-            if (maxOffset != (int) maxOffset) {
-                // offset might not fit a 32-bit immediate, generate an
-                // indirect call with a 64-bit immediate
-                CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
-                // TODO(cwi): we want to get rid of a generally reserved scratch register.
-                masm.movq(scratch, 0L);
-                masm.call(scratch);
-            } else {
-                masm.call();
-            }
-        } else {
-            masm.call();
-        }
-        int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, asCallTarget(tasm, target), info);
-        tasm.recordExceptionHandlers(after, info);
-        masm.ensureUniquePC();
-    }
-
-    public static void directJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target) {
-        int before = masm.codeBuffer.position();
-        masm.jmp(0, true);
-        int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, asCallTarget(tasm, target), null);
-        masm.ensureUniquePC();
-    }
-
-    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiRegister dst, Object target, LIRDebugInfo info) {
-        int before = masm.codeBuffer.position();
-        masm.call(dst);
-        int after = masm.codeBuffer.position();
-        tasm.recordIndirectCall(before, after, asCallTarget(tasm, target), info);
-        tasm.recordExceptionHandlers(after, info);
-        masm.ensureUniquePC();
-    }
-
-    private static Object asCallTarget(TargetMethodAssembler tasm, Object o) {
-        return tasm.runtime.asCallTarget(o);
-    }
-
-    public static void shouldNotReachHere(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        if (GraalOptions.GenAssertionCode) {
-            directCall(tasm, masm, CiRuntimeCall.Debug, null);
-            masm.hlt();
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Compare.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.util.*;
+
+public enum AMD64Compare {
+    ICMP, LCMP, ACMP, FCMP, DCMP;
+
+    public static class CompareOp extends AMD64LIRInstruction {
+        public CompareOp(AMD64Compare opcode, CiValue x, CiValue y) {
+            super(opcode, LIRInstruction.NO_OPERANDS, null, new CiValue[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue x = input(0);
+            CiValue y = input(1);
+            emit(tasm, masm, (AMD64Compare) code, x, y);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            }
+            throw Util.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            super.verify();
+            assert (name().startsWith("I") && x.kind == CiKind.Int && y.kind.stackKind() == CiKind.Int)
+                || (name().startsWith("I") && x.kind == CiKind.Jsr && y.kind == CiKind.Jsr)
+                || (name().startsWith("L") && x.kind == CiKind.Long && y.kind == CiKind.Long)
+                || (name().startsWith("A") && x.kind == CiKind.Object && y.kind == CiKind.Object)
+                || (name().startsWith("F") && x.kind == CiKind.Float && y.kind == CiKind.Float)
+                || (name().startsWith("D") && x.kind == CiKind.Double && y.kind == CiKind.Double);
+        }
+    }
+
+    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Compare opcode, CiValue x, CiValue y) {
+        if (isRegister(y)) {
+            switch (opcode) {
+                case ICMP: masm.cmpl(asIntReg(x), asIntReg(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), asLongReg(y)); break;
+                case ACMP: masm.cmpptr(asObjectReg(x), asObjectReg(y)); break;
+                case FCMP: masm.ucomiss(asFloatReg(x), asFloatReg(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), asDoubleReg(y)); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+        } else if (isConstant(y)) {
+            switch (opcode) {
+                case ICMP: masm.cmpl(asIntReg(x), tasm.asIntConst(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), tasm.asIntConst(y)); break;
+                case ACMP:
+                    if (((CiConstant) y).isNull()) {
+                        masm.cmpq(asObjectReg(x), 0); break;
+                    } else {
+                        throw Util.shouldNotReachHere("Only null object constants are allowed in comparisons");
+                    }
+                case FCMP: masm.ucomiss(asFloatReg(x), tasm.asFloatConstRef(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(y)); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+        } else {
+            switch (opcode) {
+                case ICMP: masm.cmpl(asIntReg(x), tasm.asIntAddr(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), tasm.asLongAddr(y)); break;
+                case ACMP: masm.cmpptr(asObjectReg(x), tasm.asObjectAddr(y)); break;
+                case FCMP: masm.ucomiss(asFloatReg(x), tasm.asFloatAddr(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), tasm.asDoubleAddr(y)); break;
+                default:  throw Util.shouldNotReachHere();
+            }
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompareOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64CompareOpcode implements LIROpcode {
-    ICMP, LCMP, ACMP, FCMP, DCMP;
-
-    public LIRInstruction create(CiValue x, CiValue y) {
-        assert (name().startsWith("I") && x.kind == CiKind.Int && y.kind.stackKind() == CiKind.Int)
-            || (name().startsWith("I") && x.kind == CiKind.Jsr && y.kind == CiKind.Jsr)
-            || (name().startsWith("L") && x.kind == CiKind.Long && y.kind == CiKind.Long)
-            || (name().startsWith("A") && x.kind == CiKind.Object && y.kind == CiKind.Object)
-            || (name().startsWith("F") && x.kind == CiKind.Float && y.kind == CiKind.Float)
-            || (name().startsWith("D") && x.kind == CiKind.Double && y.kind == CiKind.Double);
-        CiValue[] inputs = new CiValue[] {x, y};
-
-        return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, input(0), input(1));
-            }
-
-            @Override
-            public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Input && index == 1) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    protected void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue x, CiValue y) {
-        CiRegister lreg = asRegister(x);
-        if (isRegister(y)) {
-            CiRegister rreg = asRegister(y);
-            switch (this) {
-                case ICMP: masm.cmpl(lreg, rreg); break;
-                case LCMP: masm.cmpq(lreg, rreg); break;
-                case ACMP: masm.cmpptr(lreg, rreg); break;
-                case FCMP: masm.ucomiss(lreg, rreg); break;
-                case DCMP: masm.ucomisd(lreg, rreg); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else if (isConstant(y)) {
-            switch (this) {
-                case ICMP: masm.cmpl(lreg, tasm.asIntConst(y)); break;
-                case LCMP: masm.cmpq(lreg, tasm.asIntConst(y)); break;
-                case ACMP:
-                    if (((CiConstant) y).isNull()) {
-                        masm.cmpq(lreg, 0); break;
-                    } else {
-                        throw Util.shouldNotReachHere("Only null object constants are allowed in comparisons");
-                    }
-                case FCMP: masm.ucomiss(lreg, tasm.asFloatConstRef(y)); break;
-                case DCMP: masm.ucomisd(lreg, tasm.asDoubleConstRef(y)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else {
-            CiAddress raddr = tasm.asAddress(y);
-            switch (this) {
-                case ICMP: masm.cmpl(lreg, raddr); break;
-                case LCMP: masm.cmpq(lreg, raddr); break;
-                case ACMP: masm.cmpptr(lreg, raddr); break;
-                case FCMP: masm.ucomiss(lreg, raddr); break;
-                case DCMP: masm.ucomisd(lreg, raddr); break;
-                default:  throw Util.shouldNotReachHere();
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompareToIntOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompareToIntOpcode.java	Thu Jan 26 12:23:00 2012 +0100
@@ -24,6 +24,8 @@
 
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 
+import java.util.*;
+
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
@@ -37,7 +39,7 @@
  * integer constants -1, 0, 1 on less, equal, or greater, respectively.  For floating point compares,
  * unordered can be either greater {@link #CMP2INT_UG} or less {@link #CMP2INT_UL}.
  */
-public enum AMD64CompareToIntOpcode implements LIROpcode {
+public enum AMD64CompareToIntOpcode {
     CMP2INT, CMP2INT_UG, CMP2INT_UL;
 
     public LIRInstruction create(CiValue result) {
@@ -48,6 +50,14 @@
             public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
                 emit(masm, output(0));
             }
+
+            @Override
+            protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+                if (mode == OperandMode.Output && index == 0) {
+                    return EnumSet.of(OperandFlag.Register);
+                }
+                throw Util.shouldNotReachHere();
+            }
         };
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ControlFlow.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiAddress.Scale;
+import com.oracle.max.cri.ci.CiTargetMethod.JumpTable;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+public class AMD64ControlFlow {
+
+    public static class LabelOp extends AMD64LIRInstruction implements StandardOp.LabelOp {
+        private final Label label;
+        private final boolean align;
+
+        public LabelOp(Label label, boolean align) {
+            super("LABEL", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.label = label;
+            this.align = align;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            if (align) {
+                masm.align(tasm.target.wordSize);
+            }
+            masm.bind(label);
+        }
+
+        @Override
+        public String operationString() {
+            return label.toString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class ReturnOp extends AMD64LIRInstruction {
+        public ReturnOp(CiValue input) {
+            super("RETURN", LIRInstruction.NO_OPERANDS, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.ret(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class JumpOp extends AMD64LIRInstruction implements StandardOp.JumpOp {
+        private final LabelRef destination;
+
+        public JumpOp(LabelRef destination, LIRDebugInfo info) {
+            super("JUMP", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.destination = destination;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.jmp(destination.label());
+        }
+
+        @Override
+        public LabelRef destination() {
+            return destination;
+        }
+
+        @Override
+        public String operationString() {
+            return  "[" + destination + "]";
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
+        protected Condition condition;
+        protected LabelRef destination;
+
+        public BranchOp(Condition condition, LabelRef destination, LIRDebugInfo info) {
+            super("BRANCH", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.condition = condition;
+            this.destination = destination;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.jcc(intCond(condition), destination.label());
+        }
+
+        @Override
+        public LabelRef destination() {
+            return destination;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+        }
+
+        @Override
+        public String operationString() {
+            return condition.operator + " [" + destination + "]";
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class FloatBranchOp extends BranchOp {
+        protected boolean unorderedIsTrue;
+
+        public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef destination, LIRDebugInfo info) {
+            super(condition, destination, info);
+            this.unorderedIsTrue = unorderedIsTrue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            floatJcc(masm, condition, unorderedIsTrue, destination.label());
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            super.negate(newDestination);
+            unorderedIsTrue = !unorderedIsTrue;
+        }
+
+        @Override
+        public String operationString() {
+            return condition.operator + " [" + destination + "]" + (unorderedIsTrue ? " unorderedIsTrue" : " unorderedIsFalse");
+        }
+    }
+
+
+    public static class TableSwitchOp extends AMD64LIRInstruction {
+        private final int lowKey;
+        private final LabelRef defaultTarget;
+        private final LabelRef[] targets;
+
+        public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
+            super("TABLE_SWITCH", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, new CiValue[] {index}, new CiValue[] {scratch});
+            this.lowKey = lowKey;
+            this.defaultTarget = defaultTarget;
+            this.targets = targets;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(alive(0)), asLongReg(temp(0)));
+        }
+
+        @Override
+        public String operationString() {
+            StringBuilder buf = new StringBuilder(super.operationString());
+            buf.append("\ndefault: [").append(defaultTarget).append(']');
+            int key = lowKey;
+            for (LabelRef l : targets) {
+                buf.append("\ncase ").append(key).append(": [").append(l).append(']');
+                key++;
+            }
+            return buf.toString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class CondMoveOp extends AMD64LIRInstruction {
+        private final Condition condition;
+
+        public CondMoveOp(Variable result, Condition condition, Variable trueValue, CiValue falseValue) {
+            super("CMOVE", new CiValue[] {result}, null, new CiValue[] {falseValue}, new CiValue[] {trueValue}, LIRInstruction.NO_OPERANDS);
+            this.condition = condition;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            cmove(tasm, masm, output(0), false, condition, false, alive(0), input(0));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw Util.shouldNotReachHere();
+        }
+
+        @Override
+        public String operationString() {
+            return condition.toString() + " " + super.operationString();
+        }
+    }
+
+
+    public static class FloatCondMoveOp extends AMD64LIRInstruction {
+        private final Condition condition;
+        private final boolean unorderedIsTrue;
+
+        public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) {
+            super("FLOAT_CMOVE", new CiValue[] {result}, null, LIRInstruction.NO_OPERANDS, new CiValue[] {trueValue, falseValue}, LIRInstruction.NO_OPERANDS);
+            this.condition = condition;
+            this.unorderedIsTrue = unorderedIsTrue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            cmove(tasm, masm, output(0), true, condition, unorderedIsTrue, alive(0), alive(1));
+        }
+
+        @Override
+        public String operationString() {
+            return condition.toString() + " unordered=" + unorderedIsTrue + " " + super.operationString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Alive && index == 1) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    private static void tableswitch(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiRegister value, CiRegister scratch) {
+        Buffer buf = masm.codeBuffer;
+        // Compare index against jump table bounds
+        int highKey = lowKey + targets.length - 1;
+        if (lowKey != 0) {
+            // subtract the low value from the switch value
+            masm.subl(value, lowKey);
+            masm.cmpl(value, highKey - lowKey);
+        } else {
+            masm.cmpl(value, highKey);
+        }
+
+        // Jump to default target if index is not within the jump table
+        masm.jcc(ConditionFlag.above, defaultTarget.label());
+
+        // Set scratch to address of jump table
+        int leaPos = buf.position();
+        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), 0));
+        int afterLea = buf.position();
+
+        // Load jump table entry into scratch and jump to it
+        masm.movslq(value, new CiAddress(CiKind.Int, scratch.asValue(), value.asValue(), Scale.Times4, 0));
+        masm.addq(scratch, value);
+        masm.jmp(scratch);
+
+        // Inserting padding so that jump table address is 4-byte aligned
+        if ((buf.position() & 0x3) != 0) {
+            masm.nop(4 - (buf.position() & 0x3));
+        }
+
+        // Patch LEA instruction above now that we know the position of the jump table
+        int jumpTablePos = buf.position();
+        buf.setPosition(leaPos);
+        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), jumpTablePos - afterLea));
+        buf.setPosition(jumpTablePos);
+
+        // Emit jump table entries
+        for (LabelRef target : targets) {
+            Label label = target.label();
+            int offsetToJumpTableBase = buf.position() - jumpTablePos;
+            if (label.isBound()) {
+                int imm32 = label.position() - jumpTablePos;
+                buf.emitInt(imm32);
+            } else {
+                label.addPatchAt(buf.position());
+
+                buf.emitByte(0); // psuedo-opcode for jump table entry
+                buf.emitShort(offsetToJumpTableBase);
+                buf.emitByte(0); // padding to make jump table entry 4 bytes wide
+            }
+        }
+
+        JumpTable jt = new JumpTable(jumpTablePos, lowKey, highKey, 4);
+        tasm.targetMethod.addAnnotation(jt);
+    }
+
+    private static void floatJcc(AMD64MacroAssembler masm, Condition condition, boolean unorderedIsTrue, Label label) {
+        ConditionFlag cond = floatCond(condition);
+        Label endLabel = new Label();
+        if (unorderedIsTrue && !trueOnUnordered(cond)) {
+            masm.jcc(ConditionFlag.parity, label);
+        } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
+            masm.jcc(ConditionFlag.parity, endLabel);
+        }
+        masm.jcc(cond, label);
+        masm.bind(endLabel);
+    }
+
+    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, boolean isFloat, Condition condition, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) {
+        ConditionFlag cond = isFloat ? floatCond(condition) : intCond(condition);
+        // check that we don't overwrite an input operand before it is used.
+        assert !result.equals(trueValue);
+
+        AMD64Move.move(tasm, masm, result, falseValue);
+        cmove(tasm, masm, result, cond, trueValue);
+
+        if (isFloat) {
+            if (unorderedIsTrue && !trueOnUnordered(cond)) {
+                cmove(tasm, masm, result, ConditionFlag.parity, trueValue);
+            } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
+                cmove(tasm, masm, result, ConditionFlag.parity, falseValue);
+            }
+        }
+    }
+
+    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, ConditionFlag cond, CiValue other) {
+        if (isRegister(other)) {
+            assert asRegister(other) != asRegister(result) : "other already overwritten by previous move";
+            switch (other.kind) {
+                case Int:  masm.cmovl(cond, asRegister(result), asRegister(other)); break;
+                case Long: masm.cmovq(cond, asRegister(result), asRegister(other)); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+        } else {
+            switch (other.kind) {
+                case Int:  masm.cmovl(cond, asRegister(result), tasm.asAddress(other)); break;
+                case Long: masm.cmovq(cond, asRegister(result), tasm.asAddress(other)); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+        }
+    }
+
+    private static ConditionFlag intCond(Condition cond) {
+        switch (cond) {
+            case EQ: return ConditionFlag.equal;
+            case NE: return ConditionFlag.notEqual;
+            case LT: return ConditionFlag.less;
+            case LE: return ConditionFlag.lessEqual;
+            case GE: return ConditionFlag.greaterEqual;
+            case GT: return ConditionFlag.greater;
+            case BE: return ConditionFlag.belowEqual;
+            case AE: return ConditionFlag.aboveEqual;
+            case AT: return ConditionFlag.above;
+            case BT: return ConditionFlag.below;
+            case OF: return ConditionFlag.overflow;
+            case NOF: return ConditionFlag.noOverflow;
+            default: throw Util.shouldNotReachHere();
+        }
+    }
+
+    private static ConditionFlag floatCond(Condition cond) {
+        switch (cond) {
+            case EQ: return ConditionFlag.equal;
+            case NE: return ConditionFlag.notEqual;
+            case BT: return ConditionFlag.below;
+            case BE: return ConditionFlag.belowEqual;
+            case AE: return ConditionFlag.aboveEqual;
+            case AT: return ConditionFlag.above;
+            default: throw Util.shouldNotReachHere();
+        }
+    }
+
+    private static boolean trueOnUnordered(ConditionFlag condition) {
+        switch(condition) {
+            case aboveEqual:
+            case notEqual:
+            case above:
+            case less:
+            case overflow:
+                return false;
+            case equal:
+            case belowEqual:
+            case below:
+            case greaterEqual:
+            case noOverflow:
+                return true;
+            default:
+                throw Util.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ControlFlowOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiAddress.Scale;
-import com.oracle.max.cri.ci.CiTargetMethod.JumpTable;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-import com.oracle.max.graal.nodes.calc.*;
-
-public class AMD64ControlFlowOpcode {
-
-    public enum LabelOpcode implements LIROpcode {
-        LABEL;
-
-        public LIRInstruction create(final Label label, final boolean align) {
-            return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    if (align) {
-                        masm.align(tasm.target.wordSize);
-                    }
-                    masm.bind(label);
-                }
-
-                @Override
-                public String operationString() {
-                    return label.toString();
-                }
-            };
-        }
-    }
-
-
-    public enum ReturnOpcode implements StandardOpcode.ReturnOpcode {
-        RETURN;
-
-        public LIRInstruction create(CiValue input) {
-            CiValue[] inputs = new CiValue[] {input};
-
-            return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    masm.ret(0);
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Input && index == 0) {
-                        return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
-                    }
-                    throw Util.shouldNotReachHere();
-                }
-            };
-        }
-    }
-
-
-    public enum JumpOpcode implements LIROpcode {
-        JUMP;
-
-        public LIRInstruction create(LabelRef label, LIRDebugInfo info) {
-            return new LIRBranch(this, null, false, label, info) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm) {
-                    AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm;
-                    masm.jmp(this.destination.label());
-                }
-
-                @Override
-                public String operationString() {
-                    return  "[" + destination + "]";
-                }
-            };
-        }
-    }
-
-
-    public enum BranchOpcode implements LIROpcode {
-        BRANCH;
-
-        public LIRInstruction create(Condition cond, LabelRef label, LIRDebugInfo info) {
-            return new LIRBranch(this, cond, false, label, info) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm) {
-                    AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm;
-                    masm.jcc(intCond(cond), destination.label());
-                }
-
-                @Override
-                public String operationString() {
-                    return cond.operator + " [" + destination + "]";
-                }
-            };
-        }
-    }
-
-
-    public enum FloatBranchOpcode implements LIROpcode {
-        FLOAT_BRANCH;
-
-        public LIRInstruction create(Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info) {
-            return new LIRBranch(this, cond, unorderedIsTrue, label, info) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm) {
-                    floatJcc((AMD64MacroAssembler) tasm.asm, cond, unorderedIsTrue, destination.label());
-                }
-
-                @Override
-                public String operationString() {
-                    return cond.operator + " [" + destination + "]" + (unorderedIsTrue ? " unorderedIsTrue" : " unorderedIsFalse");
-                }
-            };
-        }
-    }
-
-
-    public enum TableSwitchOpcode implements LIROpcode {
-        TABLE_SWITCH;
-
-        public LIRInstruction create(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
-            CiValue[] alives = new CiValue[] {index};
-            CiValue[] temps = new CiValue[] {scratch};
-
-            return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, alives, temps) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(alive(0)), asLongReg(temp(0)));
-                }
-
-                @Override
-                public String operationString() {
-                    StringBuilder buf = new StringBuilder(super.operationString());
-                    buf.append("\ndefault: [").append(defaultTarget).append(']');
-                    int key = lowKey;
-                    for (LabelRef l : targets) {
-                        buf.append("\ncase ").append(key).append(": [").append(l).append(']');
-                        key++;
-                    }
-                    return buf.toString();
-                }
-            };
-        }
-    }
-
-
-    public enum CondMoveOpcode implements LIROpcode {
-        CMOVE;
-
-        public LIRInstruction create(Variable result, final Condition condition, Variable trueValue, CiValue falseValue) {
-            CiValue[] inputs = new CiValue[] {falseValue};
-            CiValue[] alives = new CiValue[] {trueValue};
-            CiValue[] outputs = new CiValue[] {result};
-
-            return new AMD64LIRInstruction(this, outputs, null, inputs, alives, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    cmove(tasm, masm, output(0), false, condition, false, alive(0), input(0));
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Input && index == 0) {
-                        return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                    } else if (mode == OperandMode.Output && index == 0) {
-                        return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                    }
-                    return super.flagsFor(mode, index);
-                }
-
-                @Override
-                public String operationString() {
-                    return condition.toString() + " " + super.operationString();
-                }
-            };
-        }
-    }
-
-
-    public enum FloatCondMoveOpcode implements LIROpcode {
-        FLOAT_CMOVE;
-
-        public LIRInstruction create(Variable result, final Condition condition, final boolean unorderedIsTrue, Variable trueValue, Variable falseValue) {
-            CiValue[] alives = new CiValue[] {trueValue, falseValue};
-            CiValue[] outputs = new CiValue[] {result};
-
-            return new AMD64LIRInstruction(this, outputs, null, LIRInstruction.NO_OPERANDS, alives, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    cmove(tasm, masm, output(0), true, condition, unorderedIsTrue, alive(0), alive(1));
-                }
-
-                @Override
-                public String operationString() {
-                    return condition.toString() + " unordered=" + unorderedIsTrue + " " + super.operationString();
-                }
-            };
-        }
-    }
-
-
-    private static void tableswitch(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiRegister value, CiRegister scratch) {
-        Buffer buf = masm.codeBuffer;
-        // Compare index against jump table bounds
-        int highKey = lowKey + targets.length - 1;
-        if (lowKey != 0) {
-            // subtract the low value from the switch value
-            masm.subl(value, lowKey);
-            masm.cmpl(value, highKey - lowKey);
-        } else {
-            masm.cmpl(value, highKey);
-        }
-
-        // Jump to default target if index is not within the jump table
-        masm.jcc(ConditionFlag.above, defaultTarget.label());
-
-        // Set scratch to address of jump table
-        int leaPos = buf.position();
-        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), 0));
-        int afterLea = buf.position();
-
-        // Load jump table entry into scratch and jump to it
-        masm.movslq(value, new CiAddress(CiKind.Int, scratch.asValue(), value.asValue(), Scale.Times4, 0));
-        masm.addq(scratch, value);
-        masm.jmp(scratch);
-
-        // Inserting padding so that jump table address is 4-byte aligned
-        if ((buf.position() & 0x3) != 0) {
-            masm.nop(4 - (buf.position() & 0x3));
-        }
-
-        // Patch LEA instruction above now that we know the position of the jump table
-        int jumpTablePos = buf.position();
-        buf.setPosition(leaPos);
-        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), jumpTablePos - afterLea));
-        buf.setPosition(jumpTablePos);
-
-        // Emit jump table entries
-        for (LabelRef target : targets) {
-            Label label = target.label();
-            int offsetToJumpTableBase = buf.position() - jumpTablePos;
-            if (label.isBound()) {
-                int imm32 = label.position() - jumpTablePos;
-                buf.emitInt(imm32);
-            } else {
-                label.addPatchAt(buf.position());
-
-                buf.emitByte(0); // psuedo-opcode for jump table entry
-                buf.emitShort(offsetToJumpTableBase);
-                buf.emitByte(0); // padding to make jump table entry 4 bytes wide
-            }
-        }
-
-        JumpTable jt = new JumpTable(jumpTablePos, lowKey, highKey, 4);
-        tasm.targetMethod.addAnnotation(jt);
-    }
-
-    private static void floatJcc(AMD64MacroAssembler masm, Condition condition, boolean unorderedIsTrue, Label label) {
-        ConditionFlag cond = floatCond(condition);
-        Label endLabel = new Label();
-        if (unorderedIsTrue && !trueOnUnordered(cond)) {
-            masm.jcc(ConditionFlag.parity, label);
-        } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
-            masm.jcc(ConditionFlag.parity, endLabel);
-        }
-        masm.jcc(cond, label);
-        masm.bind(endLabel);
-    }
-
-    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, boolean isFloat, Condition condition, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) {
-        ConditionFlag cond = isFloat ? floatCond(condition) : intCond(condition);
-        // check that we don't overwrite an input operand before it is used.
-        assert !result.equals(trueValue);
-
-        AMD64MoveOpcode.move(tasm, masm, result, falseValue);
-        cmove(tasm, masm, result, cond, trueValue);
-
-        if (isFloat) {
-            if (unorderedIsTrue && !trueOnUnordered(cond)) {
-                cmove(tasm, masm, result, ConditionFlag.parity, trueValue);
-            } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
-                cmove(tasm, masm, result, ConditionFlag.parity, falseValue);
-            }
-        }
-    }
-
-    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, ConditionFlag cond, CiValue other) {
-        if (isRegister(other)) {
-            assert asRegister(other) != asRegister(result) : "other already overwritten by previous move";
-            switch (other.kind) {
-                case Int:  masm.cmovl(cond, asRegister(result), asRegister(other)); break;
-                case Long: masm.cmovq(cond, asRegister(result), asRegister(other)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else {
-            switch (other.kind) {
-                case Int:  masm.cmovl(cond, asRegister(result), tasm.asAddress(other)); break;
-                case Long: masm.cmovq(cond, asRegister(result), tasm.asAddress(other)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        }
-    }
-
-    private static ConditionFlag intCond(Condition cond) {
-        switch (cond) {
-            case EQ: return ConditionFlag.equal;
-            case NE: return ConditionFlag.notEqual;
-            case LT: return ConditionFlag.less;
-            case LE: return ConditionFlag.lessEqual;
-            case GE: return ConditionFlag.greaterEqual;
-            case GT: return ConditionFlag.greater;
-            case BE: return ConditionFlag.belowEqual;
-            case AE: return ConditionFlag.aboveEqual;
-            case AT: return ConditionFlag.above;
-            case BT: return ConditionFlag.below;
-            case OF: return ConditionFlag.overflow;
-            case NOF: return ConditionFlag.noOverflow;
-            default: throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static ConditionFlag floatCond(Condition cond) {
-        switch (cond) {
-            case EQ: return ConditionFlag.equal;
-            case NE: return ConditionFlag.notEqual;
-            case BT: return ConditionFlag.below;
-            case BE: return ConditionFlag.belowEqual;
-            case AE: return ConditionFlag.aboveEqual;
-            case AT: return ConditionFlag.above;
-            default: throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static boolean trueOnUnordered(ConditionFlag condition) {
-        switch(condition) {
-            case aboveEqual:
-            case notEqual:
-            case above:
-            case less:
-            case overflow:
-                return false;
-            case equal:
-            case belowEqual:
-            case below:
-            case greaterEqual:
-            case noOverflow:
-                return true;
-            default:
-                throw Util.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64ConvertOpcode implements LIROpcode {
-    I2L, L2I, I2B, I2C, I2S,
-    F2D, D2F,
-    I2F, I2D, F2I, D2I,
-    L2F, L2D, F2L, D2L,
-    MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
-
-    public LIRInstruction create(CiValue result, CiValue x) {
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0));
-            }
-
-            @Override
-            protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Output && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
-        switch (this) {
-            case L2I:
-                AMD64MoveOpcode.move(tasm, masm, result, x);
-                masm.andl(asIntReg(result), 0xFFFFFFFF);
-                break;
-            case I2B:
-                AMD64MoveOpcode.move(tasm, masm, result, x);
-                masm.signExtendByte(asIntReg(result));
-                break;
-            case I2C:
-                AMD64MoveOpcode.move(tasm, masm, result, x);
-                masm.andl(asIntReg(result), 0xFFFF);
-                break;
-            case I2S:
-                AMD64MoveOpcode.move(tasm, masm, result, x);
-                masm.signExtendShort(asIntReg(result));
-                break;
-            case I2L: masm.movslq(asLongReg(result), asIntReg(x)); break;
-            case F2D: masm.cvtss2sd(asDoubleReg(result), asFloatReg(x)); break;
-            case D2F: masm.cvtsd2ss(asFloatReg(result), asDoubleReg(x)); break;
-            case I2F: masm.cvtsi2ssl(asFloatReg(result), asIntReg(x)); break;
-            case I2D: masm.cvtsi2sdl(asDoubleReg(result), asIntReg(x)); break;
-            case L2F: masm.cvtsi2ssq(asFloatReg(result), asLongReg(x)); break;
-            case L2D: masm.cvtsi2sdq(asDoubleReg(result), asLongReg(x)); break;
-            case F2I:
-                masm.cvttss2sil(asIntReg(result), asFloatReg(x));
-                emitFixup(tasm, masm, result, x);
-                break;
-            case D2I:
-                masm.cvttsd2sil(asIntReg(result), asDoubleReg(x));
-                emitFixup(tasm, masm, result, x);
-                break;
-            case F2L:
-                masm.cvttss2siq(asLongReg(result), asFloatReg(x));
-                emitFixup(tasm, masm, result, x);
-                break;
-            case D2L:
-                masm.cvttsd2siq(asLongReg(result), asDoubleReg(x));
-                emitFixup(tasm, masm, result, x);
-                break;
-            case MOV_I2F: masm.movdl(asFloatReg(result), asIntReg(x)); break;
-            case MOV_L2D: masm.movdq(asDoubleReg(result), asLongReg(x)); break;
-            case MOV_F2I: masm.movdl(asIntReg(result), asFloatReg(x)); break;
-            case MOV_D2L: masm.movdq(asLongReg(result), asDoubleReg(x)); break;
-            default: throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static void emitFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
-        FixupSlowPath slowPath = new FixupSlowPath(result, x);
-        tasm.slowPaths.add(slowPath);
-        switch (result.kind) {
-            case Int:  masm.cmpl(asIntReg(result),  Integer.MIN_VALUE); break;
-            case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(CiConstant.forLong(java.lang.Long.MIN_VALUE))); break;
-            default:   throw Util.shouldNotReachHere();
-        }
-        masm.jcc(ConditionFlag.equal, slowPath.start);
-        masm.bind(slowPath.continuation);
-    }
-
-    private static class FixupSlowPath extends AMD64SlowPath {
-        public final Label start = new Label();
-        public final Label continuation = new Label();
-        private final CiValue result;
-        private final CiValue x;
-
-        public FixupSlowPath(CiValue result, CiValue x) {
-            this.result = result;
-            this.x = x;
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            masm.bind(start);
-            switch (x.kind) {
-                case Float:  masm.ucomiss(asFloatReg(x),  tasm.asFloatConstRef(CiConstant.FLOAT_0)); break;
-                case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); break;
-                default:     throw Util.shouldNotReachHere();
-            }
-            Label nan = new Label();
-            masm.jcc(ConditionFlag.parity, nan);
-            masm.jcc(ConditionFlag.below, continuation);
-
-            // input is > 0 -> return maxInt
-            // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff
-            switch (result.kind) {
-                case Int:  masm.decrementl(asIntReg(result),  1); break;
-                case Long: masm.decrementq(asLongReg(result), 1); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-            masm.jmp(continuation);
-
-            // input is NaN -> return 0
-            masm.bind(nan);
-            masm.xorptr(asRegister(result), asRegister(result));
-            masm.jmp(continuation);
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Thu Jan 26 12:23:00 2012 +0100
@@ -57,9 +57,9 @@
         if (GraalOptions.CreateDeoptInfo && deoptInfo != null) {
             masm.nop();
             keepAlive.add(deoptInfo.toString());
-            AMD64MoveOpcode.move(tasm, masm, scratch.asValue(), CiConstant.forObject(deoptInfo));
+            AMD64Move.move(tasm, masm, scratch.asValue(), CiConstant.forObject(deoptInfo));
             // TODO Why use scratch register here? Is it an implicit calling convention that the runtime function reads this register?
-            AMD64CallOpcode.directCall(tasm, masm, CiRuntimeCall.SetDeoptInfo, info);
+            AMD64Call.directCall(tasm, masm, CiRuntimeCall.SetDeoptInfo, info);
         }
         int code;
         switch(action) {
@@ -83,7 +83,7 @@
         }
         masm.movq(scratch, code);
         // TODO Why use scratch register here? Is it an implicit calling convention that the runtime function reads this register?
-        AMD64CallOpcode.directCall(tasm, masm, CiRuntimeCall.Deoptimize, info);
-        AMD64CallOpcode.shouldNotReachHere(tasm, masm);
+        AMD64Call.directCall(tasm, masm, CiRuntimeCall.Deoptimize, info);
+        AMD64Call.shouldNotReachHere(tasm, masm);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DivOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64DivOpcode implements LIROpcode {
-    IDIV, IREM, IUDIV, IUREM,
-    LDIV, LREM, LUDIV, LUREM;
-
-    public LIRInstruction create(CiValue result, LIRDebugInfo info, CiValue x, CiValue y) {
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] alives = new CiValue[] {y};
-        CiValue[] temps = new CiValue[] {asRegister(result) == AMD64.rax ? AMD64.rdx.asValue(result.kind) : AMD64.rax.asValue(result.kind)};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, info, inputs, alives, temps) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), info, input(0), alive(0));
-            }
-        };
-    }
-
-    protected void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, LIRDebugInfo info, CiValue x, CiValue y) {
-        // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx
-        assert asRegister(x) == AMD64.rax;
-        assert differentRegisters(y, AMD64.rax.asValue(), AMD64.rdx.asValue());
-        assert (name().endsWith("DIV") && asRegister(result) == AMD64.rax) || (name().endsWith("REM") && asRegister(result) == AMD64.rdx);
-
-        int exceptionOffset;
-        switch (this) {
-            case IDIV:
-            case IREM:
-                masm.cdql();
-                exceptionOffset = masm.codeBuffer.position();
-                masm.idivl(asRegister(y));
-                break;
-
-            case LDIV:
-            case LREM:
-                Label continuation = new Label();
-                if (this == LDIV) {
-                    // check for special case of Long.MIN_VALUE / -1
-                    Label normalCase = new Label();
-                    masm.movq(AMD64.rdx, java.lang.Long.MIN_VALUE);
-                    masm.cmpq(AMD64.rax, AMD64.rdx);
-                    masm.jcc(ConditionFlag.notEqual, normalCase);
-                    masm.cmpl(asRegister(y), -1);
-                    masm.jcc(ConditionFlag.equal, continuation);
-                    masm.bind(normalCase);
-                }
-
-                masm.cdqq();
-                exceptionOffset = masm.codeBuffer.position();
-                masm.idivq(asRegister(y));
-                masm.bind(continuation);
-                break;
-
-            case IUDIV:
-            case IUREM:
-                // Must zero the high 64-bit word (in RDX) of the dividend
-                masm.xorq(AMD64.rdx, AMD64.rdx);
-                exceptionOffset = masm.codeBuffer.position();
-                masm.divl(asRegister(y));
-                break;
-
-            case LUDIV:
-            case LUREM:
-                // Must zero the high 64-bit word (in RDX) of the dividend
-                masm.xorq(AMD64.rdx, AMD64.rdx);
-                exceptionOffset = masm.codeBuffer.position();
-                masm.divq(asRegister(y));
-                break;
-
-            default:
-                throw Util.shouldNotReachHere();
-        }
-        tasm.recordImplicitException(exceptionOffset, info);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Jan 26 12:23:00 2012 +0100
@@ -23,26 +23,33 @@
 
 package com.oracle.max.graal.compiler.target.amd64;
 
+import com.oracle.max.graal.compiler.target.amd64.AMD64Call.*;
 import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64ArithmeticOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64CompareOpcode.*;
+import static com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.*;
+import static com.oracle.max.graal.compiler.target.amd64.AMD64Compare.*;
 import static com.oracle.max.graal.compiler.target.amd64.AMD64CompareToIntOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64DivOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64LogicFloatOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64MulOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64Op1Opcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64ShiftOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64StandardOpcode.*;
+import static com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.*;
+
+import java.util.*;
 
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
+import com.oracle.max.cri.xir.CiXirAssembler.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.DivOp;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.Op1Reg;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.Op1Stack;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.Op2RegCommutative;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.Op2Stack;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.ShiftOp;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Compare.CompareOp;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Move.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
@@ -62,20 +69,23 @@
     private static final CiRegisterValue RDX_L = AMD64.rdx.asValue(CiKind.Long);
     private static final CiRegisterValue RCX_I = AMD64.rcx.asValue(CiKind.Int);
 
-    static {
-        StandardOpcode.SPILL_MOVE = AMD64MoveOpcode.SpillMoveOpcode.SPILL_MOVE;
-        StandardOpcode.NULL_CHECK = AMD64StandardOpcode.NULL_CHECK;
-        StandardOpcode.DIRECT_CALL = AMD64CallOpcode.DIRECT_CALL;
-        StandardOpcode.INDIRECT_CALL = AMD64CallOpcode.INDIRECT_CALL;
-        StandardOpcode.LABEL = AMD64StandardOpcode.LABEL;
-        StandardOpcode.JUMP = AMD64StandardOpcode.JUMP;
-        StandardOpcode.RETURN = AMD64StandardOpcode.RETURN;
-        StandardOpcode.XIR = AMD64XirOpcode.XIR;
+    public static class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
+        @Override
+        public LIRInstruction createMove(CiValue result, CiValue input) {
+            return new SpillMoveOp(result, input);
+        }
+
+        @Override
+        public LIRInstruction createExchange(CiValue input1, CiValue input2) {
+            // TODO implement XCHG operation for LIR
+            return null;
+        }
     }
 
     public AMD64LIRGenerator(GraalContext context, Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
         super(context, graph, runtime, target, frameMap, method, lir, xir);
         lir.methodEndMarker = new AMD64MethodEndStub();
+        lir.spillMoveFactory = new AMD64SpillMoveFactory();
     }
 
     @Override
@@ -144,43 +154,47 @@
     @Override
     public Variable emitMove(CiValue input) {
         Variable result = newVariable(input.kind);
-        append(MOVE.create(result, input));
+        emitMove(input, result);
         return result;
     }
 
     @Override
     public void emitMove(CiValue src, CiValue dst) {
-        append(MOVE.create(dst, src));
+        if (isRegister(src) || isStackSlot(dst)) {
+            append(new MoveFromRegOp(dst, src));
+        } else {
+            append(new MoveToRegOp(dst, src));
+        }
     }
 
     @Override
     public Variable emitLoad(CiValue loadAddress, boolean canTrap) {
         Variable result = newVariable(loadAddress.kind);
-        append(LOAD.create(result, loadAddress, canTrap ? state() : null));
+        append(new LoadOp(result, loadAddress, canTrap ? state() : null));
         return result;
     }
 
     @Override
     public void emitStore(CiValue storeAddress, CiValue inputVal, boolean canTrap) {
         CiValue input = loadForStore(inputVal, storeAddress.kind);
-        append(STORE.create(storeAddress, input, canTrap ? state() : null));
+        append(new StoreOp(storeAddress, input, canTrap ? state() : null));
     }
 
     @Override
     public Variable emitLea(CiValue address) {
         Variable result = newVariable(target().wordKind);
-        append(LEA.create(result, address));
+        append(new LeaOp(result, address));
         return result;
     }
 
     @Override
     public void emitLabel(Label label, boolean align) {
-        append(LABEL.create(label, align));
+        append(new LabelOp(label, align));
     }
 
     @Override
     public void emitJump(LabelRef label, LIRDebugInfo info) {
-        append(JUMP.create(label, info));
+        append(new JumpOp(label, info));
     }
 
     @Override
@@ -190,9 +204,9 @@
             case Boolean:
             case Int:
             case Long:
-            case Object: append(BRANCH.create(cond, label, info)); break;
+            case Object: append(new BranchOp(cond, label, info)); break;
             case Float:
-            case Double: append(FLOAT_BRANCH.create(cond, unorderedIsTrue, label, info)); break;
+            case Double: append(new FloatBranchOp(cond, unorderedIsTrue, label, info)); break;
             default: throw Util.shouldNotReachHere("" + left.kind);
         }
     }
@@ -206,9 +220,9 @@
             case Boolean:
             case Int:
             case Long:
-            case Object: append(CMOVE.create(result, cond, load(trueValue), loadNonConst(falseValue))); break;
+            case Object: append(new CondMoveOp(result, cond, load(trueValue), loadNonConst(falseValue))); break;
             case Float:
-            case Double: append(FLOAT_CMOVE.create(result, cond, unorderedIsTrue, load(trueValue), load(falseValue))); break;
+            case Double: append(new FloatCondMoveOp(result, cond, unorderedIsTrue, load(trueValue), load(falseValue))); break;
 
         }
         return result;
@@ -219,11 +233,11 @@
         CiValue right = loadNonConst(b);
         switch (left.kind) {
             case Jsr:
-            case Int: append(ICMP.create(left, right)); break;
-            case Long: append(LCMP.create(left, right)); break;
-            case Object: append(ACMP.create(left, right)); break;
-            case Float: append(FCMP.create(left, right)); break;
-            case Double: append(DCMP.create(left, right)); break;
+            case Int: append(new CompareOp(ICMP, left, right)); break;
+            case Long: append(new CompareOp(LCMP, left, right)); break;
+            case Object: append(new CompareOp(ACMP, left, right)); break;
+            case Float: append(new CompareOp(FCMP, left, right)); break;
+            case Double: append(new CompareOp(DCMP, left, right)); break;
             default: throw Util.shouldNotReachHere();
         }
     }
@@ -232,10 +246,10 @@
     public Variable emitNegate(CiValue input) {
         Variable result = newVariable(input.kind);
         switch (input.kind) {
-            case Int:    append(INEG.create(result, input)); break;
-            case Long:   append(LNEG.create(result, input)); break;
-            case Float:  append(FXOR.create(result, input, CiConstant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
-            case Double: append(DXOR.create(result, input, CiConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
+            case Int:    append(new Op1Stack(INEG, result, input)); break;
+            case Long:   append(new Op1Stack(LNEG, result, input)); break;
+            case Float:  append(new Op2RegCommutative(FXOR, result, input, CiConstant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
+            case Double: append(new Op2RegCommutative(DXOR, result, input, CiConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
             default: throw Util.shouldNotReachHere();
         }
         return result;
@@ -245,10 +259,10 @@
     public Variable emitAdd(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
-            case Int:    append(IADD.create(result, a, loadNonConst(b))); break;
-            case Long:   append(LADD.create(result, a, loadNonConst(b))); break;
-            case Float:  append(FADD.create(result, a, loadNonConst(b))); break;
-            case Double: append(DADD.create(result, a, loadNonConst(b))); break;
+            case Int:    append(new Op2Stack(IADD, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LADD, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FADD, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DADD, result, a, loadNonConst(b))); break;
             default:     throw Util.shouldNotReachHere();
         }
         return result;
@@ -258,10 +272,10 @@
     public Variable emitSub(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
-            case Int:    append(ISUB.create(result, a, loadNonConst(b))); break;
-            case Long:   append(LSUB.create(result, a, loadNonConst(b))); break;
-            case Float:  append(FSUB.create(result, a, loadNonConst(b))); break;
-            case Double: append(DSUB.create(result, a, loadNonConst(b))); break;
+            case Int:    append(new Op2Stack(ISUB, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LSUB, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FSUB, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DSUB, result, a, loadNonConst(b))); break;
             default:     throw Util.shouldNotReachHere();
         }
         return result;
@@ -271,10 +285,10 @@
     public Variable emitMul(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
-            case Int:    append(IMUL.create(result, a, loadNonConst(b))); break;
-            case Long:   append(LMUL.create(result, a, loadNonConst(b))); break;
-            case Float:  append(FMUL.create(result, a, loadNonConst(b))); break;
-            case Double: append(DMUL.create(result, a, loadNonConst(b))); break;
+            case Int:    append(new Op2RegCommutative(IMUL, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2RegCommutative(LMUL, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FMUL, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DMUL, result, a, loadNonConst(b))); break;
             default:     throw Util.shouldNotReachHere();
         }
         return result;
@@ -284,21 +298,21 @@
     public Variable emitDiv(CiValue a, CiValue b) {
         switch(a.kind) {
             case Int:
-                append(MOVE.create(RAX_I, a));
-                append(IDIV.create(RAX_I, state(), RAX_I, load(b)));
+                emitMove(a, RAX_I);
+                append(new DivOp(IDIV, RAX_I, RAX_I, load(b), state()));
                 return emitMove(RAX_I);
             case Long:
-                append(MOVE.create(RAX_L, a));
-                append(LDIV.create(RAX_L, state(), RAX_L, load(b)));
+                emitMove(a, RAX_L);
+                append(new DivOp(LDIV, RAX_L, RAX_L, load(b), state()));
                 return emitMove(RAX_L);
             case Float: {
                 Variable result = newVariable(a.kind);
-                append(FDIV.create(result, a, loadNonConst(b)));
+                append(new Op2Stack(FDIV, result, a, loadNonConst(b)));
                 return result;
             }
             case Double: {
                 Variable result = newVariable(a.kind);
-                append(DDIV.create(result, a, loadNonConst(b)));
+                append(new Op2Stack(DDIV, result, a, loadNonConst(b)));
                 return result;
             }
             default:
@@ -310,12 +324,12 @@
     public Variable emitRem(CiValue a, CiValue b) {
         switch(a.kind) {
             case Int:
-                append(MOVE.create(RAX_I, a));
-                append(IREM.create(RDX_I, state(), RAX_I, load(b)));
+                emitMove(a, RAX_I);
+                append(new DivOp(IREM, RDX_I, RAX_I, load(b), state()));
                 return emitMove(RDX_I);
             case Long:
-                append(MOVE.create(RAX_L, a));
-                append(LREM.create(RDX_L, state(), RAX_L, load(b)));
+                emitMove(a, RAX_L);
+                append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
                 return emitMove(RDX_L);
             case Float:
                 return emitCallToRuntime(CiRuntimeCall.ArithmeticFrem, false, a, b);
@@ -330,12 +344,12 @@
     public Variable emitUDiv(CiValue a, CiValue b) {
         switch(a.kind) {
             case Int:
-                append(MOVE.create(RAX_I, load(a)));
-                append(IUDIV.create(RAX_I, state(), RAX_I, load(b)));
+                emitMove(a, RAX_I);
+                append(new DivOp(IUDIV, RAX_I, RAX_I, load(b), state()));
                 return emitMove(RAX_I);
             case Long:
-                append(MOVE.create(RAX_L, load(a)));
-                append(LUDIV.create(RAX_L, state(), RAX_L, load(b)));
+                emitMove(a, RAX_L);
+                append(new DivOp(LUDIV, RAX_L, RAX_L, load(b), state()));
                 return emitMove(RAX_L);
             default:
                 throw Util.shouldNotReachHere();
@@ -346,12 +360,12 @@
     public Variable emitURem(CiValue a, CiValue b) {
         switch(a.kind) {
             case Int:
-                append(MOVE.create(RAX_I, load(a)));
-                append(IUREM.create(RDX_I, state(), RAX_I, load(b)));
+                emitMove(a, RAX_I);
+                append(new DivOp(IUREM, RDX_I, RAX_I, load(b), state()));
                 return emitMove(RDX_I);
             case Long:
-                append(MOVE.create(RAX_L, load(a)));
-                append(LUREM.create(RDX_L, state(), RAX_L, load(b)));
+                emitMove(a, RAX_L);
+                append(new DivOp(LUREM, RDX_L, RAX_L, load(b), state()));
                 return emitMove(RDX_L);
             default:
                 throw Util.shouldNotReachHere();
@@ -363,8 +377,8 @@
     public Variable emitAnd(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
-            case Int:    append(IAND.create(result, a, loadNonConst(b))); break;
-            case Long:   append(LAND.create(result, a, loadNonConst(b))); break;
+            case Int:    append(new Op2Stack(IAND, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LAND, result, a, loadNonConst(b))); break;
             default:     throw Util.shouldNotReachHere();
         }
         return result;
@@ -374,8 +388,8 @@
     public Variable emitOr(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
-            case Int:    append(IOR.create(result, a, loadNonConst(b))); break;
-            case Long:   append(LOR.create(result, a, loadNonConst(b))); break;
+            case Int:    append(new Op2Stack(IOR, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LOR, result, a, loadNonConst(b))); break;
             default:     throw Util.shouldNotReachHere();
         }
         return result;
@@ -385,8 +399,8 @@
     public Variable emitXor(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
-            case Int:    append(IXOR.create(result, a, loadNonConst(b))); break;
-            case Long:   append(LXOR.create(result, a, loadNonConst(b))); break;
+            case Int:    append(new Op2Stack(IXOR, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LXOR, result, a, loadNonConst(b))); break;
             default:     throw Util.shouldNotReachHere();
         }
         return result;
@@ -397,8 +411,8 @@
     public Variable emitShl(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch (a.kind) {
-            case Int:    append(ISHL.create(result, a, loadShiftCount(b))); break;
-            case Long:   append(LSHL.create(result, a, loadShiftCount(b))); break;
+            case Int:    append(new ShiftOp(ISHL, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LSHL, result, a, loadShiftCount(b))); break;
             default: Util.shouldNotReachHere();
         }
         return result;
@@ -408,8 +422,8 @@
     public Variable emitShr(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch (a.kind) {
-            case Int:    append(ISHR.create(result, a, loadShiftCount(b))); break;
-            case Long:   append(LSHR.create(result, a, loadShiftCount(b))); break;
+            case Int:    append(new ShiftOp(ISHR, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LSHR, result, a, loadShiftCount(b))); break;
             default: Util.shouldNotReachHere();
         }
         return result;
@@ -419,8 +433,8 @@
     public Variable emitUShr(CiValue a, CiValue b) {
         Variable result = newVariable(a.kind);
         switch (a.kind) {
-            case Int:    append(IUSHR.create(result, a, loadShiftCount(b))); break;
-            case Long:   append(LUSHR.create(result, a, loadShiftCount(b))); break;
+            case Int:    append(new ShiftOp(IUSHR, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LUSHR, result, a, loadShiftCount(b))); break;
             default: Util.shouldNotReachHere();
         }
         return result;
@@ -431,7 +445,7 @@
             return value;
         }
         // Non-constant shift count must be in RCX
-        append(MOVE.create(RCX_I, value));
+        emitMove(value, RCX_I);
         return RCX_I;
     }
 
@@ -441,25 +455,25 @@
         Variable input = load(inputVal);
         Variable result = newVariable(opcode.to);
         switch (opcode) {
-            case I2L: append(I2L.create(result, input)); break;
-            case L2I: append(L2I.create(result, input)); break;
-            case I2B: append(I2B.create(result, input)); break;
-            case I2C: append(I2C.create(result, input)); break;
-            case I2S: append(I2S.create(result, input)); break;
-            case F2D: append(F2D.create(result, input)); break;
-            case D2F: append(D2F.create(result, input)); break;
-            case I2F: append(I2F.create(result, input)); break;
-            case I2D: append(I2D.create(result, input)); break;
-            case F2I: append(F2I.create(result, input)); break;
-            case D2I: append(D2I.create(result, input)); break;
-            case L2F: append(L2F.create(result, input)); break;
-            case L2D: append(L2D.create(result, input)); break;
-            case F2L: append(F2L.create(result, input)); break;
-            case D2L: append(D2L.create(result, input)); break;
-            case MOV_I2F: append(MOV_I2F.create(result, input)); break;
-            case MOV_L2D: append(MOV_L2D.create(result, input)); break;
-            case MOV_F2I: append(MOV_F2I.create(result, input)); break;
-            case MOV_D2L: append(MOV_D2L.create(result, input)); break;
+            case I2L: append(new Op1Reg(I2L, result, input)); break;
+            case L2I: append(new Op1Stack(L2I, result, input)); break;
+            case I2B: append(new Op1Stack(I2B, result, input)); break;
+            case I2C: append(new Op1Stack(I2C, result, input)); break;
+            case I2S: append(new Op1Stack(I2S, result, input)); break;
+            case F2D: append(new Op1Reg(F2D, result, input)); break;
+            case D2F: append(new Op1Reg(D2F, result, input)); break;
+            case I2F: append(new Op1Reg(I2F, result, input)); break;
+            case I2D: append(new Op1Reg(I2D, result, input)); break;
+            case F2I: append(new Op1Reg(F2I, result, input)); break;
+            case D2I: append(new Op1Reg(D2I, result, input)); break;
+            case L2F: append(new Op1Reg(L2F, result, input)); break;
+            case L2D: append(new Op1Reg(L2D, result, input)); break;
+            case F2L: append(new Op1Reg(F2L, result, input)); break;
+            case D2L: append(new Op1Reg(D2L, result, input)); break;
+            case MOV_I2F: append(new Op1Reg(MOV_I2F, result, input)); break;
+            case MOV_L2D: append(new Op1Reg(MOV_L2D, result, input)); break;
+            case MOV_F2I: append(new Op1Reg(MOV_F2I, result, input)); break;
+            case MOV_D2L: append(new Op1Reg(MOV_D2L, result, input)); break;
             default: throw Util.shouldNotReachHere();
         }
         return result;
@@ -471,9 +485,9 @@
         LIRDebugInfo info = state();
         LabelRef stubEntry = createDeoptStub(action, info, deoptInfo);
         if (cond != null) {
-            append(BRANCH.create(cond, stubEntry, info));
+            append(new BranchOp(cond, stubEntry, info));
         } else {
-            append(JUMP.create(stubEntry, info));
+            append(new JumpOp(stubEntry, info));
         }
     }
 
@@ -481,15 +495,36 @@
     public void emitMembar(int barriers) {
         int necessaryBarriers = target.arch.requiredBarriers(barriers);
         if (target.isMP && necessaryBarriers != 0) {
-            append(MEMBAR.create(necessaryBarriers));
+            append(new MembarOp(necessaryBarriers));
+        }
+    }
+
+    @Override
+    protected void emitCall(Object targetMethod, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+        if (isConstant(targetAddress)) {
+            assert asConstant(targetAddress).isDefaultValue() : "destination address should be zero";
+            append(new DirectCallOp(targetMethod, result, arguments.toArray(new CiValue[arguments.size()]), info, marks));
+        } else {
+            append(new IndirectCallOp(targetMethod, result, arguments.toArray(new CiValue[arguments.size()]), targetAddress, info, marks));
         }
     }
 
     @Override
+    protected void emitReturn(CiValue input) {
+        append(new ReturnOp(input));
+    }
+
+    @Override
+    protected void emitXir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+                    LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        append(new AMD64XirOp(snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, trueSuccessor, falseSuccessor));
+    }
+
+    @Override
     protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index) {
         // Making a copy of the switch value is necessary because jump table destroys the input value
         Variable tmp = emitMove(index);
-        append(TABLE_SWITCH.create(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
+        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
     }
 
     @Override
@@ -500,6 +535,14 @@
         return LabelRef.forLabel(stub.label);
     }
 
+    @Override
+    protected void emitNullCheckGuard(NullCheckNode node) {
+        assert !node.expectedNull;
+        Variable value = load(operand(node.object()));
+        LIRDebugInfo info = state();
+        append(new NullCheckOp(value, info));
+    }
+
     // TODO The CompareAndSwapNode in its current form needs to be lowered to several Nodes before code generation to separate three parts:
     // * The write barriers (and possibly read barriers) when accessing an object field
     // * The distinction of returning a boolean value (semantic similar to a BooleanNode to be used as a condition?) or the old value being read
@@ -526,14 +569,14 @@
         }
 
         CiRegisterValue rax = AMD64.rax.asValue(kind);
-        append(MOVE.create(rax, expected));
-        append(CAS.create(rax, address, rax, newValue));
+        emitMove(expected, rax);
+        append(new CompareAndSwapOp(rax, address, rax, newValue));
 
         Variable result = newVariable(node.kind());
         if (node.directResult()) {
-            append(MOVE.create(result, rax));
+            emitMove(rax, result);
         } else {
-            append(CMOVE.create(result, Condition.EQ, load(CiConstant.TRUE), CiConstant.FALSE));
+            append(new CondMoveOp(result, Condition.EQ, load(CiConstant.TRUE), CiConstant.FALSE));
         }
         setResult(node, result);
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRInstruction.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRInstruction.java	Thu Jan 26 12:23:00 2012 +0100
@@ -32,7 +32,7 @@
  */
 public abstract class AMD64LIRInstruction extends LIRInstruction {
 
-    public AMD64LIRInstruction(LIROpcode opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+    public AMD64LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
         super(opcode, outputs, info, inputs, alives, temps);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LogicFloatOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64LogicFloatOpcode implements LIROpcode {
-    FAND, FOR, FXOR,
-    DAND, DOR, DXOR;
-
-    public LIRInstruction create(CiValue result, CiValue x, CiValue y) {
-        assert (name().startsWith("F") && result.kind == CiKind.Float && x.kind == CiKind.Float && y.kind == CiKind.Float)
-            || (name().startsWith("D") && result.kind == CiKind.Double && x.kind == CiKind.Double && y.kind == CiKind.Double);
-
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] alives = new CiValue[] {y};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, alives, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0), alive(0));
-            }
-
-            @Override
-            public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Input && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                } else if (mode == OperandMode.Alive && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
-                } else if (mode == OperandMode.Output && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    protected void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue y) {
-        assert sameRegister(x, y) || differentRegisters(result, y);
-        AMD64MoveOpcode.move(tasm, masm, result, x);
-
-        CiRegister dst = asRegister(result);
-        if (isRegister(y)) {
-            CiRegister rreg = asRegister(y);
-            switch (this) {
-                case FAND: masm.andps(dst, rreg); break;
-                case FOR:  masm.orps(dst,  rreg); break;
-                case FXOR: masm.xorps(dst, rreg); break;
-                case DAND: masm.andpd(dst, rreg); break;
-                case DOR:  masm.orpd(dst,  rreg); break;
-                case DXOR: masm.xorpd(dst, rreg); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else {
-            switch (this) {
-                case FAND: masm.andps(dst, tasm.asFloatConstRef(y, 16)); break;
-                case FOR:  masm.orps(dst,  tasm.asFloatConstRef(y, 16)); break;
-                case FXOR: masm.xorps(dst, tasm.asFloatConstRef(y, 16)); break;
-                case DAND: masm.andpd(dst, tasm.asDoubleConstRef(y, 16)); break;
-                case DOR:  masm.orpd(dst,  tasm.asDoubleConstRef(y, 16)); break;
-                case DXOR: masm.xorpd(dst, tasm.asDoubleConstRef(y, 16)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Move.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static java.lang.Double.*;
+import static java.lang.Float.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.lir.StandardOp.MoveOp;
+import com.oracle.max.graal.compiler.util.*;
+
+public class AMD64Move {
+
+    public static class SpillMoveOp extends AMD64LIRInstruction implements MoveOp {
+        public SpillMoveOp(CiValue result, CiValue input) {
+            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public CiValue getInput() {
+            return input(0);
+        }
+        @Override
+        public CiValue getResult() {
+            return output(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class MoveToRegOp extends AMD64LIRInstruction implements MoveOp {
+        public MoveToRegOp(CiValue result, CiValue input) {
+            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public CiValue getInput() {
+            return input(0);
+        }
+        @Override
+        public CiValue getResult() {
+            return output(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class MoveFromRegOp extends AMD64LIRInstruction implements MoveOp {
+        public MoveFromRegOp(CiValue result, CiValue input) {
+            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public CiValue getInput() {
+            return input(0);
+        }
+        @Override
+        public CiValue getResult() {
+            return output(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.RegisterHint);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class LoadOp extends AMD64LIRInstruction {
+        public LoadOp(CiValue result, CiValue address, LIRDebugInfo info) {
+            super("LOAD", new CiValue[] {result}, info, new CiValue[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            load(tasm, masm, output(0), (CiAddress) input(0), info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class StoreOp extends AMD64LIRInstruction {
+        public StoreOp(CiValue address, CiValue input, LIRDebugInfo info) {
+            super("STORE", LIRInstruction.NO_OPERANDS, info, new CiValue[] {address, input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            store(tasm, masm, (CiAddress) input(0), input(1), info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class LeaOp extends AMD64LIRInstruction {
+        public LeaOp(CiValue result, CiValue address) {
+            super("LEA", new CiValue[] {result}, null, new CiValue[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.leaq(asLongReg(output(0)), tasm.asAddress(input(0)));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address, OperandFlag.Stack, OperandFlag.Uninitialized);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class MembarOp extends AMD64LIRInstruction {
+        private final int barriers;
+
+        public MembarOp(final int barriers) {
+            super("MEMBAR", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.barriers = barriers;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.membar(barriers);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class NullCheckOp extends AMD64LIRInstruction {
+        public NullCheckOp(Variable input, LIRDebugInfo info) {
+            super("NULL_CHECK", LIRInstruction.NO_OPERANDS, info, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), info);
+            masm.nullCheck(asRegister(input(0)));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    public static class CompareAndSwapOp extends AMD64LIRInstruction {
+        public CompareAndSwapOp(CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
+            super("CAS", new CiValue[] {result}, null, new CiValue[] {address, cmpValue, newValue}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            compareAndSwap(tasm, masm, output(0), asAddress(input(0)), input(1), input(2));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Input && index == 2) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    protected static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        if (isRegister(input)) {
+            if (isRegister(result)) {
+                reg2reg(masm, result, input);
+            } else if (isStackSlot(result)) {
+                reg2stack(tasm, masm, result, input);
+            } else {
+                throw Util.shouldNotReachHere();
+            }
+        } else if (isStackSlot(input)) {
+            if (isRegister(result)) {
+                stack2reg(tasm, masm, result, input);
+            } else {
+                throw Util.shouldNotReachHere();
+            }
+        } else if (isConstant(input)) {
+            if (isRegister(result)) {
+                const2reg(tasm, masm, result, (CiConstant) input);
+            } else if (isStackSlot(result)) {
+                const2stack(tasm, masm, result, (CiConstant) input);
+            } else {
+                throw Util.shouldNotReachHere();
+            }
+        } else {
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+    private static void reg2reg(AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        if (input.equals(result)) {
+            return;
+        }
+        switch (result.kind) {
+            case Jsr:
+            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 Util.shouldNotReachHere("kind=" + result.kind);
+        }
+    }
+
+    private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        switch (result.kind) {
+            case Jsr:
+            case Int:    masm.movl(tasm.asAddress(result),   asRegister(input)); break;
+            case Long:   masm.movq(tasm.asAddress(result),   asRegister(input)); break;
+            case Float:  masm.movflt(tasm.asAddress(result), asFloatReg(input)); break;
+            case Double: masm.movsd(tasm.asAddress(result),  asDoubleReg(input)); break;
+            case Object: masm.movq(tasm.asAddress(result),   asRegister(input)); break;
+            default:     throw Util.shouldNotReachHere();
+        }
+    }
+
+    private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        switch (result.kind) {
+            case Jsr:
+            case Int:    masm.movl(asRegister(result),    tasm.asAddress(input)); break;
+            case Long:   masm.movq(asRegister(result),    tasm.asAddress(input)); break;
+            case Float:  masm.movflt(asFloatReg(result),  tasm.asAddress(input)); break;
+            case Double: masm.movdbl(asDoubleReg(result), tasm.asAddress(input)); break;
+            case Object: masm.movq(asRegister(result),    tasm.asAddress(input)); break;
+            default:     throw Util.shouldNotReachHere();
+        }
+    }
+
+    private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant c) {
+        switch (result.kind) {
+            case Jsr:
+            case Int:
+                // Do not optimize with an XOR as this instruction may be between
+                // a CMP and a Jcc in which case the XOR will modify the condition
+                // flags and interfere with the Jcc.
+                masm.movl(asRegister(result), tasm.asIntConst(c));
+                break;
+            case Long:
+                // Do not optimize with an XOR as this instruction may be between
+                // a CMP and a Jcc in which case the XOR will modify the condition
+                // flags and interfere with the Jcc.
+                masm.movq(asRegister(result), c.asLong());
+                break;
+            case Float:
+                // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
+                if (Float.floatToRawIntBits(c.asFloat()) == Float.floatToRawIntBits(0.0f)) {
+                    masm.xorps(asFloatReg(result), asFloatReg(result));
+                } else {
+                    masm.movflt(asFloatReg(result), tasm.asFloatConstRef(c));
+                }
+                break;
+            case Double:
+                // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
+                if (Double.doubleToRawLongBits(c.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
+                    masm.xorpd(asDoubleReg(result), asDoubleReg(result));
+                } else {
+                    masm.movdbl(asDoubleReg(result), tasm.asDoubleConstRef(c));
+                }
+                break;
+            case Object:
+                // Do not optimize with an XOR as this instruction may be between
+                // a CMP and a Jcc in which case the XOR will modify the condition
+                // flags and interfere with the Jcc.
+                if (c.isNull()) {
+                    masm.movq(asRegister(result), 0x0L);
+                } else if (tasm.target.inlineObjects) {
+                    tasm.recordDataReferenceInCode(c, 0);
+                    masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
+                } else {
+                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(c, 0));
+                }
+                break;
+            default:
+                throw Util.shouldNotReachHere();
+        }
+    }
+
+    private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant c) {
+        switch (result.kind) {
+            case Jsr:
+            case Int:    masm.movl(tasm.asAddress(result), c.asInt()); break;
+            case Long:   masm.movlong(tasm.asAddress(result), c.asLong()); break;
+            case Float:  masm.movl(tasm.asAddress(result), floatToRawIntBits(c.asFloat())); break;
+            case Double: masm.movlong(tasm.asAddress(result), doubleToRawLongBits(c.asDouble())); break;
+            case Object:
+                if (c.isNull()) {
+                    masm.movlong(tasm.asAddress(result), 0L);
+                } else {
+                    throw Util.shouldNotReachHere("Non-null object constants must be in register");
+                }
+                break;
+            default:
+                throw Util.shouldNotReachHere();
+        }
+    }
+
+
+    protected static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress loadAddr, LIRDebugInfo info) {
+        if (info != null) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), info);
+        }
+        switch (loadAddr.kind) {
+            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 Util.shouldNotReachHere();
+        }
+    }
+
+    protected static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiAddress storeAddr, CiValue input, LIRDebugInfo info) {
+        if (info != null) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), info);
+        }
+
+        if (isRegister(input)) {
+            switch (storeAddr.kind) {
+                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 Util.shouldNotReachHere();
+            }
+        } else if (isConstant(input)) {
+            CiConstant c = (CiConstant) input;
+            switch (storeAddr.kind) {
+                case Boolean:
+                case Byte:   masm.movb(storeAddr, c.asInt() & 0xFF); break;
+                case Char:
+                case Short:  masm.movw(storeAddr, c.asInt() & 0xFFFF); break;
+                case Jsr:
+                case Int:    masm.movl(storeAddr, c.asInt()); break;
+                case Long:
+                    if (Util.isInt(c.asLong())) {
+                        masm.movslq(storeAddr, (int) c.asLong());
+                    } else {
+                        throw Util.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                case Float:  masm.movl(storeAddr, floatToRawIntBits(c.asFloat())); break;
+                case Double: throw Util.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                case Object:
+                    if (c.isNull()) {
+                        masm.movptr(storeAddr, 0);
+                    } else {
+                        throw Util.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                default:
+                    throw Util.shouldNotReachHere();
+            }
+
+        } else {
+            throw Util.shouldNotReachHere();
+        }
+    }
+
+    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
+        assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax;
+
+        if (tasm.target.isMP) {
+            masm.lock();
+        }
+        switch (cmpValue.kind) {
+            case Int:    masm.cmpxchgl(asRegister(newValue), address); break;
+            case Long:
+            case Object: masm.cmpxchgq(asRegister(newValue), address); break;
+            default:     throw Util.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MoveOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.graal.alloc.util.ValueUtil.*;
-import static java.lang.Double.*;
-import static java.lang.Float.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public class AMD64MoveOpcode {
-
-    public enum MoveOpcode implements LIROpcode {
-        MOVE;
-
-        public LIRInstruction create(CiValue result, CiValue input) {
-            assert result.kind == result.kind.stackKind() && result.kind != CiKind.Illegal;
-            CiValue[] inputs = new CiValue[] {input};
-            CiValue[] outputs = new CiValue[] {result};
-
-            if (isRegister(input) || isStackSlot(result)) {
-                return new AMD64MoveFromRegInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
-            } else {
-                return new AMD64MoveToRegInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
-            }
-        }
-    }
-
-    public enum SpillMoveOpcode implements StandardOpcode.MoveOpcode {
-        SPILL_MOVE;
-
-        @Override
-        public MoveInstruction create(CiValue result, CiValue input) {
-            assert result.kind == result.kind.stackKind() && result.kind != CiKind.Illegal;
-            CiValue[] inputs = new CiValue[] {input};
-            CiValue[] outputs = new CiValue[] {result};
-
-            return new AMD64SpillMoveInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
-        }
-    }
-
-    protected static class AMD64SpillMoveInstruction extends MoveInstruction {
-        public AMD64SpillMoveInstruction(LIROpcode opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
-            super(opcode, outputs, info, inputs, alives, temps);
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            move(tasm, (AMD64MacroAssembler) tasm.asm, getDest(), getSource());
-        }
-
-        @Override
-        public CiValue getSource() {
-            return input(0);
-        }
-        @Override
-        public CiValue getDest() {
-            return output(0);
-        }
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            if (mode == OperandMode.Input && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-            } else if (mode == OperandMode.Output && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-            }
-            throw Util.shouldNotReachHere();
-        }
-
-    }
-
-    protected static class AMD64MoveToRegInstruction extends MoveInstruction {
-        public AMD64MoveToRegInstruction(LIROpcode opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
-            super(opcode, outputs, info, inputs, alives, temps);
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            move(tasm, (AMD64MacroAssembler) tasm.asm, getDest(), getSource());
-        }
-
-        @Override
-        public CiValue getSource() {
-            return input(0);
-        }
-        @Override
-        public CiValue getDest() {
-            return output(0);
-        }
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            if (mode == OperandMode.Input && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-            } else if (mode == OperandMode.Output && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-            }
-            throw Util.shouldNotReachHere();
-        }
-    }
-
-    protected static class AMD64MoveFromRegInstruction extends MoveInstruction {
-        public AMD64MoveFromRegInstruction(LIROpcode opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
-            super(opcode, outputs, info, inputs, alives, temps);
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            move(tasm, (AMD64MacroAssembler) tasm.asm, getDest(), getSource());
-        }
-
-        @Override
-        public CiValue getSource() {
-            return input(0);
-        }
-        @Override
-        public CiValue getDest() {
-            return output(0);
-        }
-
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            if (mode == OperandMode.Input && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.RegisterHint);
-            } else if (mode == OperandMode.Output && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-            }
-            throw Util.shouldNotReachHere();
-        }
-    }
-
-    public enum LoadOpcode implements LIROpcode {
-        LOAD;
-
-        public LIRInstruction create(CiValue result, CiValue address, LIRDebugInfo info) {
-            CiValue[] inputs = new CiValue[] {address};
-            CiValue[] outputs = new CiValue[] {result};
-
-            return new AMD64LIRInstruction(this, outputs, info, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    load(tasm, masm, output(0), (CiAddress) input(0), info);
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Input && index == 0) {
-                        return EnumSet.of(OperandFlag.Address);
-                    }
-                    return super.flagsFor(mode, index);
-                }
-            };
-        }
-    }
-
-
-    public enum StoreOpcode implements LIROpcode {
-        STORE;
-
-        public LIRInstruction create(CiValue address, CiValue input, LIRDebugInfo info) {
-            CiValue[] inputs = new CiValue[] {address, input};
-
-            return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, info, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    store(tasm, masm, (CiAddress) input(0), input(1), info);
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Input && index == 0) {
-                        return EnumSet.of(OperandFlag.Address);
-                    } else if (mode == OperandMode.Input && index == 1) {
-                        return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
-                    }
-                    return super.flagsFor(mode, index);
-                }
-            };
-        }
-    }
-
-
-    public enum LeaOpcode implements LIROpcode {
-        LEA;
-
-        public LIRInstruction create(CiValue result, CiValue address) {
-            CiValue[] inputs = new CiValue[] {address};
-            CiValue[] outputs = new CiValue[] {result};
-
-            return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    masm.leaq(asLongReg(output(0)), tasm.asAddress(input(0)));
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Input && index == 0) {
-                        return EnumSet.of(OperandFlag.Address, OperandFlag.Stack, OperandFlag.Uninitialized);
-                    }
-                    return super.flagsFor(mode, index);
-                }
-            };
-        }
-    }
-
-
-    public enum MembarOpcode implements LIROpcode {
-        MEMBAR;
-
-        public LIRInstruction create(final int barriers) {
-            return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    masm.membar(barriers);
-                }
-            };
-        }
-    }
-
-
-    public enum NullCheckOpcode implements StandardOpcode.NullCheckOpcode {
-        NULL_CHECK;
-
-        @Override
-        public LIRInstruction create(Variable input, LIRDebugInfo info) {
-            CiValue[] inputs = new CiValue[] {input};
-
-            return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, info, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    tasm.recordImplicitException(masm.codeBuffer.position(), info);
-                    masm.nullCheck(asRegister(input(0)));
-                }
-            };
-        }
-    }
-
-
-    public enum CompareAndSwapOpcode implements LIROpcode {
-        CAS;
-
-        public LIRInstruction create(CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
-            CiValue[] inputs = new CiValue[] {address, cmpValue, newValue};
-            CiValue[] outputs = new CiValue[] {result};
-
-            return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-                @Override
-                public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                    compareAndSwap(tasm, masm, output(0), asAddress(input(0)), input(1), input(2));
-                }
-
-                @Override
-                protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                    if (mode == OperandMode.Input && index == 0) {
-                        return EnumSet.of(OperandFlag.Address);
-                    }
-                    return super.flagsFor(mode, index);
-                }
-            };
-        }
-    }
-
-    protected static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
-        if (isRegister(input)) {
-            if (isRegister(result)) {
-                reg2reg(masm, result, input);
-            } else if (isStackSlot(result)) {
-                reg2stack(tasm, masm, result, input);
-            } else {
-                throw Util.shouldNotReachHere();
-            }
-        } else if (isStackSlot(input)) {
-            if (isRegister(result)) {
-                stack2reg(tasm, masm, result, input);
-            } else {
-                throw Util.shouldNotReachHere();
-            }
-        } else if (isConstant(input)) {
-            if (isRegister(result)) {
-                const2reg(tasm, masm, result, (CiConstant) input);
-            } else if (isStackSlot(result)) {
-                const2stack(tasm, masm, result, (CiConstant) input);
-            } else {
-                throw Util.shouldNotReachHere();
-            }
-        } else {
-            throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static void reg2reg(AMD64MacroAssembler masm, CiValue result, CiValue input) {
-        if (input.equals(result)) {
-            return;
-        }
-        switch (result.kind) {
-            case Jsr:
-            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 Util.shouldNotReachHere("kind=" + result.kind);
-        }
-    }
-
-    private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
-        switch (result.kind) {
-            case Jsr:
-            case Int:    masm.movl(tasm.asAddress(result),   asRegister(input)); break;
-            case Long:   masm.movq(tasm.asAddress(result),   asRegister(input)); break;
-            case Float:  masm.movflt(tasm.asAddress(result), asFloatReg(input)); break;
-            case Double: masm.movsd(tasm.asAddress(result),  asDoubleReg(input)); break;
-            case Object: masm.movq(tasm.asAddress(result),   asRegister(input)); break;
-            default:     throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
-        switch (result.kind) {
-            case Jsr:
-            case Int:    masm.movl(asRegister(result),    tasm.asAddress(input)); break;
-            case Long:   masm.movq(asRegister(result),    tasm.asAddress(input)); break;
-            case Float:  masm.movflt(asFloatReg(result),  tasm.asAddress(input)); break;
-            case Double: masm.movdbl(asDoubleReg(result), tasm.asAddress(input)); break;
-            case Object: masm.movq(asRegister(result),    tasm.asAddress(input)); break;
-            default:     throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant c) {
-        switch (result.kind) {
-            case Jsr:
-            case Int:
-                // Do not optimize with an XOR as this instruction may be between
-                // a CMP and a Jcc in which case the XOR will modify the condition
-                // flags and interfere with the Jcc.
-                masm.movl(asRegister(result), tasm.asIntConst(c));
-                break;
-            case Long:
-                // Do not optimize with an XOR as this instruction may be between
-                // a CMP and a Jcc in which case the XOR will modify the condition
-                // flags and interfere with the Jcc.
-                masm.movq(asRegister(result), c.asLong());
-                break;
-            case Float:
-                // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
-                if (Float.floatToRawIntBits(c.asFloat()) == Float.floatToRawIntBits(0.0f)) {
-                    masm.xorps(asFloatReg(result), asFloatReg(result));
-                } else {
-                    masm.movflt(asFloatReg(result), tasm.asFloatConstRef(c));
-                }
-                break;
-            case Double:
-                // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
-                if (Double.doubleToRawLongBits(c.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
-                    masm.xorpd(asDoubleReg(result), asDoubleReg(result));
-                } else {
-                    masm.movdbl(asDoubleReg(result), tasm.asDoubleConstRef(c));
-                }
-                break;
-            case Object:
-                // Do not optimize with an XOR as this instruction may be between
-                // a CMP and a Jcc in which case the XOR will modify the condition
-                // flags and interfere with the Jcc.
-                if (c.isNull()) {
-                    masm.movq(asRegister(result), 0x0L);
-                } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(c, 0);
-                    masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
-                } else {
-                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(c, 0));
-                }
-                break;
-            default:
-                throw Util.shouldNotReachHere();
-        }
-    }
-
-    private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant c) {
-        switch (result.kind) {
-            case Jsr:
-            case Int:    masm.movl(tasm.asAddress(result), c.asInt()); break;
-            case Long:   masm.movlong(tasm.asAddress(result), c.asLong()); break;
-            case Float:  masm.movl(tasm.asAddress(result), floatToRawIntBits(c.asFloat())); break;
-            case Double: masm.movlong(tasm.asAddress(result), doubleToRawLongBits(c.asDouble())); break;
-            case Object:
-                if (c.isNull()) {
-                    masm.movlong(tasm.asAddress(result), 0L);
-                } else {
-                    throw Util.shouldNotReachHere("Non-null object constants must be in register");
-                }
-                break;
-            default:
-                throw Util.shouldNotReachHere();
-        }
-    }
-
-
-    protected static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress loadAddr, LIRDebugInfo info) {
-        if (info != null) {
-            tasm.recordImplicitException(masm.codeBuffer.position(), info);
-        }
-        switch (loadAddr.kind) {
-            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 Util.shouldNotReachHere();
-        }
-    }
-
-    protected static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiAddress storeAddr, CiValue input, LIRDebugInfo info) {
-        if (info != null) {
-            tasm.recordImplicitException(masm.codeBuffer.position(), info);
-        }
-
-        if (isRegister(input)) {
-            switch (storeAddr.kind) {
-                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 Util.shouldNotReachHere();
-            }
-        } else if (isConstant(input)) {
-            CiConstant c = (CiConstant) input;
-            switch (storeAddr.kind) {
-                case Boolean:
-                case Byte:   masm.movb(storeAddr, c.asInt() & 0xFF); break;
-                case Char:
-                case Short:  masm.movw(storeAddr, c.asInt() & 0xFFFF); break;
-                case Jsr:
-                case Int:    masm.movl(storeAddr, c.asInt()); break;
-                case Long:
-                    if (Util.isInt(c.asLong())) {
-                        masm.movslq(storeAddr, (int) c.asLong());
-                    } else {
-                        throw Util.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                case Float:  masm.movl(storeAddr, floatToRawIntBits(c.asFloat())); break;
-                case Double: throw Util.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                case Object:
-                    if (c.isNull()) {
-                        masm.movptr(storeAddr, 0);
-                    } else {
-                        throw Util.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                default:
-                    throw Util.shouldNotReachHere();
-            }
-
-        } else {
-            throw Util.shouldNotReachHere();
-        }
-    }
-
-    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
-        assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax;
-
-        if (tasm.target.isMP) {
-            masm.lock();
-        }
-        switch (cmpValue.kind) {
-            case Int:    masm.cmpxchgl(asRegister(newValue), address); break;
-            case Long:
-            case Object: masm.cmpxchgq(asRegister(newValue), address); break;
-            default:     throw Util.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MulOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64MulOpcode implements LIROpcode {
-    IMUL, LMUL;
-
-    public LIRInstruction create(CiValue result, CiValue x, CiValue y) {
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] alives = new CiValue[] {y};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, alives, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0), alive(0));
-            }
-
-            @Override
-            public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Input && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                } else if (mode == OperandMode.Alive && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
-                } else if (mode == OperandMode.Output && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    protected void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue y) {
-        assert sameRegister(x, y) || differentRegisters(result, y);
-        AMD64MoveOpcode.move(tasm, masm, result, x);
-
-        CiRegister dst = asRegister(result);
-        if (isRegister(y)) {
-            switch (this) {
-                case IMUL: masm.imull(dst, asRegister(y)); break;
-                case LMUL: masm.imulq(dst, asRegister(y)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else {
-            switch (this) {
-                case IMUL: masm.imull(dst, dst, tasm.asIntConst(y)); break;
-                case LMUL: masm.imulq(dst, dst, tasm.asIntConst(y)); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Op1Opcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64Op1Opcode implements LIROpcode {
-    INEG, LNEG;
-
-    public LIRInstruction create(CiValue result, CiValue x) {
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0));
-            }
-
-            @Override
-            public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Input && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                } else if (mode == OperandMode.Output && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
-        AMD64MoveOpcode.move(tasm, masm, result, x);
-        switch (this) {
-            case INEG: masm.negl(asIntReg(result)); break;
-            case LNEG: masm.negq(asLongReg(result)); break;
-            default:   throw Util.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ShiftOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64ShiftOpcode implements LIROpcode {
-    ISHL, ISHR, IUSHR,
-    LSHL, LSHR, LUSHR;
-
-    public LIRInstruction create(CiValue result, CiValue x, CiValue y) {
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] alives = new CiValue[] {y};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, alives, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0), alive(0));
-            }
-
-            @Override
-            public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-                if (mode == OperandMode.Input && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-                } else if (mode == OperandMode.Alive && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
-                } else if (mode == OperandMode.Output && index == 0) {
-                    return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-                }
-                return super.flagsFor(mode, index);
-            }
-        };
-    }
-
-    protected void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue y) {
-        assert sameRegister(x, y) || differentRegisters(result, y);
-        AMD64MoveOpcode.move(tasm, masm, result, x);
-
-        CiRegister dst = asRegister(result);
-        if (isRegister(y)) {
-            assert asRegister(y) == AMD64.rcx;
-            switch (this) {
-                case ISHL:  masm.shll(dst); break;
-                case ISHR:  masm.sarl(dst); break;
-                case IUSHR: masm.shrl(dst); break;
-                case LSHL:  masm.shlq(dst); break;
-                case LSHR:  masm.sarq(dst); break;
-                case LUSHR: masm.shrq(dst); break;
-                default:    throw Util.shouldNotReachHere();
-            }
-        } else if (isConstant(y)) {
-            switch (this) {
-                case ISHL:  masm.shll(dst, tasm.asIntConst(y) & 31); break;
-                case ISHR:  masm.sarl(dst, tasm.asIntConst(y) & 31); break;
-                case IUSHR: masm.shrl(dst, tasm.asIntConst(y) & 31); break;
-                case LSHL:  masm.shlq(dst, tasm.asIntConst(y) & 63); break;
-                case LSHR:  masm.sarq(dst, tasm.asIntConst(y) & 63); break;
-                case LUSHR: masm.shrq(dst, tasm.asIntConst(y) & 63); break;
-                default:   throw Util.shouldNotReachHere();
-            }
-        } else {
-            throw Util.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64StandardOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-
-/**
- * A collection of AMD64 specific opcodes that is convenient for a static import.
- * Since every defined opcode is in its own enum, accessing them without this class is
- * more verbose.
- */
-public class AMD64StandardOpcode {
-    public static final AMD64MoveOpcode.MoveOpcode MOVE = AMD64MoveOpcode.MoveOpcode.MOVE;
-    public static final AMD64MoveOpcode.LoadOpcode LOAD = AMD64MoveOpcode.LoadOpcode.LOAD;
-    public static final AMD64MoveOpcode.StoreOpcode STORE = AMD64MoveOpcode.StoreOpcode.STORE;
-    public static final AMD64MoveOpcode.LeaOpcode LEA = AMD64MoveOpcode.LeaOpcode.LEA;
-    public static final AMD64MoveOpcode.MembarOpcode MEMBAR = AMD64MoveOpcode.MembarOpcode.MEMBAR;
-    public static final AMD64MoveOpcode.NullCheckOpcode NULL_CHECK = AMD64MoveOpcode.NullCheckOpcode.NULL_CHECK;
-    public static final AMD64MoveOpcode.CompareAndSwapOpcode CAS = AMD64MoveOpcode.CompareAndSwapOpcode.CAS;
-
-    public static final AMD64ControlFlowOpcode.LabelOpcode LABEL = AMD64ControlFlowOpcode.LabelOpcode.LABEL;
-    public static final AMD64ControlFlowOpcode.ReturnOpcode RETURN = AMD64ControlFlowOpcode.ReturnOpcode.RETURN;
-    public static final AMD64ControlFlowOpcode.JumpOpcode JUMP = AMD64ControlFlowOpcode.JumpOpcode.JUMP;
-    public static final AMD64ControlFlowOpcode.BranchOpcode BRANCH = AMD64ControlFlowOpcode.BranchOpcode.BRANCH;
-    public static final AMD64ControlFlowOpcode.FloatBranchOpcode FLOAT_BRANCH = AMD64ControlFlowOpcode.FloatBranchOpcode.FLOAT_BRANCH;
-    public static final AMD64ControlFlowOpcode.TableSwitchOpcode TABLE_SWITCH = AMD64ControlFlowOpcode.TableSwitchOpcode.TABLE_SWITCH;
-    public static final AMD64ControlFlowOpcode.CondMoveOpcode CMOVE = AMD64ControlFlowOpcode.CondMoveOpcode.CMOVE;
-    public static final AMD64ControlFlowOpcode.FloatCondMoveOpcode FLOAT_CMOVE = AMD64ControlFlowOpcode.FloatCondMoveOpcode.FLOAT_CMOVE;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOp.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
+import static com.oracle.max.cri.ci.CiValue.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.cri.xir.CiXirAssembler.RuntimeCallInformation;
+import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
+import com.oracle.max.cri.xir.CiXirAssembler.XirLabel;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.util.*;
+
+public class AMD64XirOp extends LIRXirInstruction {
+    public AMD64XirOp(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+                        LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        super("XIR", snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, trueSuccessor, falseSuccessor);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm) {
+        AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm;
+
+        Label endLabel = null;
+        Label[] labels = new Label[snippet.template.labels.length];
+        for (int i = 0; i < labels.length; i++) {
+            labels[i] = new Label();
+            if (snippet.template.labels[i].name == XirLabel.TrueSuccessor) {
+                if (trueSuccessor == null) {
+                    assert endLabel == null;
+                    endLabel = new Label();
+                    labels[i] = endLabel;
+                } else {
+                    labels[i] = trueSuccessor.label();
+                }
+            } else if (snippet.template.labels[i].name == XirLabel.FalseSuccessor) {
+                if (falseSuccessor == null) {
+                    assert endLabel == null;
+                    endLabel = new Label();
+                    labels[i] = endLabel;
+                } else {
+                    labels[i] = falseSuccessor.label();
+                }
+            }
+        }
+        emitXirInstructions(tasm, masm, snippet.template.fastPath, labels, getOperands(), snippet.marks);
+        if (endLabel != null) {
+            masm.bind(endLabel);
+        }
+
+        if (snippet.template.slowPath != null) {
+            tasm.slowPaths.add(new SlowPath(labels));
+        }
+    }
+
+    private class SlowPath extends AMD64SlowPath {
+        public final Label[] labels;
+
+        public SlowPath(Label[] labels) {
+            this.labels = labels;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            int start = -1;
+            if (GraalOptions.TraceAssembler) {
+                TTY.println("Emitting slow path for XIR instruction " + snippet.template.name);
+                start = masm.codeBuffer.position();
+            }
+            emitXirInstructions(tasm, masm, snippet.template.slowPath, labels, getOperands(), snippet.marks);
+            masm.nop();
+            if (GraalOptions.TraceAssembler) {
+                TTY.println("From " + start + " to " + masm.codeBuffer.position());
+            }
+        }
+    }
+
+
+    protected void emitXirInstructions(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction[] instructions, Label[] labels, CiValue[] operands, Map<XirMark, Mark> marks) {
+        for (XirInstruction inst : instructions) {
+            switch (inst.op) {
+                case Add:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IADD, AMD64Arithmetic.LADD, AMD64Arithmetic.FADD, AMD64Arithmetic.DADD, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Sub:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.ISUB, AMD64Arithmetic.LSUB, AMD64Arithmetic.FSUB, AMD64Arithmetic.DSUB, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Div:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IDIV, AMD64Arithmetic.LDIV, AMD64Arithmetic.FDIV, AMD64Arithmetic.DDIV, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Mul:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IMUL, AMD64Arithmetic.LMUL, AMD64Arithmetic.FMUL, AMD64Arithmetic.DMUL, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Mod:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IREM, AMD64Arithmetic.LREM, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Shl:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.ISHL, AMD64Arithmetic.LSHL, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Sar:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.ISHR, AMD64Arithmetic.LSHR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Shr:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IUSHR, AMD64Arithmetic.LUSHR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case And:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IAND, AMD64Arithmetic.LAND, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Or:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IOR, AMD64Arithmetic.LOR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Xor:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IXOR, AMD64Arithmetic.LXOR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Mov: {
+                    CiValue result = operands[inst.result.index];
+                    CiValue source = operands[inst.x().index];
+                    AMD64Move.move(tasm, masm, result, source);
+                    break;
+                }
+
+                case PointerLoad: {
+                    CiValue result = operands[inst.result.index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiRegisterValue register = assureInRegister(tasm, masm, pointer);
+
+                    AMD64Move.load(tasm, masm, result, new CiAddress(inst.kind, register), (Boolean) inst.extra ? info : null);
+                    break;
+                }
+
+                case PointerStore: {
+                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.y().index]);
+                    CiValue pointer = operands[inst.x().index];
+                    assert isRegister(pointer);
+
+                    AMD64Move.store(tasm, masm, new CiAddress(inst.kind, pointer), value, (Boolean) inst.extra ? info : null);
+                    break;
+                }
+
+                case PointerLoadDisp: {
+                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
+                    boolean canTrap = addressInformation.canTrap;
+
+                    CiAddress.Scale scale = addressInformation.scale;
+                    int displacement = addressInformation.disp;
+
+                    CiValue result = operands[inst.result.index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue index = operands[inst.y().index];
+
+                    pointer = assureInRegister(tasm, masm, pointer);
+                    assert isRegister(pointer);
+
+                    CiAddress src;
+                    if (isConstant(index)) {
+                        assert index.kind == CiKind.Int;
+                        CiConstant constantIndex = (CiConstant) index;
+                        src = new CiAddress(inst.kind, pointer, constantIndex.asInt() * scale.value + displacement);
+                    } else {
+                        src = new CiAddress(inst.kind, pointer, index, scale, displacement);
+                    }
+
+                    AMD64Move.load(tasm, masm, result, src, canTrap ? info : null);
+                    break;
+                }
+
+                case LoadEffectiveAddress: {
+                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
+
+                    CiAddress.Scale scale = addressInformation.scale;
+                    int displacement = addressInformation.disp;
+
+                    CiValue result = operands[inst.result.index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue index = operands[inst.y().index];
+
+                    pointer = assureInRegister(tasm, masm, pointer);
+                    assert isRegister(pointer);
+                    CiAddress src = new CiAddress(CiKind.Illegal, pointer, index, scale, displacement);
+                    masm.leaq(asRegister(result), src);
+                    break;
+                }
+
+                case PointerStoreDisp: {
+                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
+                    boolean canTrap = addressInformation.canTrap;
+
+                    CiAddress.Scale scale = addressInformation.scale;
+                    int displacement = addressInformation.disp;
+
+                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.z().index]);
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue index = operands[inst.y().index];
+
+                    pointer = assureInRegister(tasm, masm, pointer);
+                    assert isRegister(pointer);
+
+                    CiAddress dst;
+                    if (isConstant(index)) {
+                        assert index.kind == CiKind.Int;
+                        CiConstant constantIndex = (CiConstant) index;
+                        dst = new CiAddress(inst.kind, pointer, IllegalValue, scale, constantIndex.asInt() * scale.value + displacement);
+                    } else {
+                        dst = new CiAddress(inst.kind, pointer, index, scale, displacement);
+                    }
+
+                    AMD64Move.store(tasm, masm, dst, value, canTrap ? info : null);
+                    break;
+                }
+
+                case RepeatMoveBytes:
+                    assert asRegister(operands[inst.x().index]).equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index];
+                    assert asRegister(operands[inst.y().index]).equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index];
+                    assert asRegister(operands[inst.z().index]).equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index];
+                    masm.repeatMoveBytes();
+                    break;
+
+                case RepeatMoveWords:
+                    assert asRegister(operands[inst.x().index]).equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index];
+                    assert asRegister(operands[inst.y().index]).equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index];
+                    assert asRegister(operands[inst.z().index]).equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index];
+                    masm.repeatMoveWords();
+                    break;
+
+                case PointerCAS:
+                    assert asRegister(operands[inst.x().index]).equals(AMD64.rax) : "wrong input x: " + operands[inst.x().index];
+
+                    CiValue exchangedVal = operands[inst.y().index];
+                    CiValue exchangedAddress = operands[inst.x().index];
+                    CiRegisterValue pointerRegister = assureInRegister(tasm, masm, exchangedAddress);
+                    CiAddress addr = new CiAddress(tasm.target.wordKind, pointerRegister);
+
+                    if ((Boolean) inst.extra && info != null) {
+                        tasm.recordImplicitException(masm.codeBuffer.position(), info);
+                    }
+                    masm.cmpxchgq(asRegister(exchangedVal), addr);
+
+                    break;
+
+                case CallRuntime: {
+                    CiKind[] signature = new CiKind[inst.arguments.length];
+                    for (int i = 0; i < signature.length; i++) {
+                        signature[i] = inst.arguments[i].kind;
+                    }
+
+                    CiCallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
+                    for (int i = 0; i < inst.arguments.length; i++) {
+                        CiValue argumentLocation = cc.locations[i];
+                        CiValue argumentSourceLocation = operands[inst.arguments[i].index];
+                        if (argumentLocation != argumentSourceLocation) {
+                            AMD64Move.move(tasm, masm, argumentLocation, argumentSourceLocation);
+                        }
+                    }
+
+                    RuntimeCallInformation runtimeCallInformation = (RuntimeCallInformation) inst.extra;
+                    AMD64Call.directCall(tasm, masm, runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
+
+                    if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) {
+                        CiRegister returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind);
+                        CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind());
+                        AMD64Move.move(tasm, masm, operands[inst.result.index], resultLocation);
+                    }
+                    break;
+                }
+                case Jmp: {
+                    if (inst.extra instanceof XirLabel) {
+                        Label label = labels[((XirLabel) inst.extra).index];
+                        masm.jmp(label);
+                    } else {
+                        AMD64Call.directJmp(tasm, masm, inst.extra);
+                    }
+                    break;
+                }
+                case DecAndJumpNotZero: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    CiValue value = operands[inst.x().index];
+                    if (value.kind == CiKind.Long) {
+                        masm.decq(asRegister(value));
+                    } else {
+                        assert value.kind == CiKind.Int;
+                        masm.decl(asRegister(value));
+                    }
+                    masm.jcc(ConditionFlag.notZero, label);
+                    break;
+                }
+                case Jeq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.equal, operands, label);
+                    break;
+                }
+                case Jneq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.notEqual, operands, label);
+                    break;
+                }
+
+                case Jgt: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.greater, operands, label);
+                    break;
+                }
+
+                case Jgteq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.greaterEqual, operands, label);
+                    break;
+                }
+
+                case Jugteq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.aboveEqual, operands, label);
+                    break;
+                }
+
+                case Jlt: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.less, operands, label);
+                    break;
+                }
+
+                case Jlteq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.lessEqual, operands, label);
+                    break;
+                }
+
+                case Jbset: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue offset = operands[inst.y().index];
+                    CiValue bit = operands[inst.z().index];
+                    assert isConstant(offset) && isConstant(bit);
+                    CiConstant constantOffset = (CiConstant) offset;
+                    CiConstant constantBit = (CiConstant) bit;
+                    CiAddress src = new CiAddress(inst.kind, pointer, constantOffset.asInt());
+                    masm.btli(src, constantBit.asInt());
+                    masm.jcc(ConditionFlag.aboveEqual, label);
+                    break;
+                }
+
+                case Bind: {
+                    XirLabel l = (XirLabel) inst.extra;
+                    Label label = labels[l.index];
+                    masm.bind(label);
+                    break;
+                }
+                case Safepoint: {
+                    assert info != null : "Must have debug info in order to create a safepoint.";
+                    tasm.recordSafepoint(masm.codeBuffer.position(), info);
+                    break;
+                }
+                case NullCheck: {
+                    tasm.recordImplicitException(masm.codeBuffer.position(), info);
+                    CiValue pointer = operands[inst.x().index];
+                    masm.nullCheck(asRegister(pointer));
+                    break;
+                }
+                case Align: {
+                    masm.align((Integer) inst.extra);
+                    break;
+                }
+                case StackOverflowCheck: {
+                    int frameSize = tasm.frameMap.frameSize();
+                    int lastFramePage = frameSize / tasm.target.pageSize;
+                    // emit multiple stack bangs for methods with frames larger than a page
+                    for (int i = 0; i <= lastFramePage; i++) {
+                        int offset = (i + GraalOptions.StackShadowPages) * tasm.target.pageSize;
+                        // Deduct 'frameSize' to handle frames larger than the shadow
+                        bangStackWithOffset(tasm, masm, offset - frameSize);
+                    }
+                    break;
+                }
+                case PushFrame: {
+                    int frameSize = tasm.frameMap.frameSize();
+                    masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0
+                    if (GraalOptions.ZapStackOnMethodEntry) {
+                        final int intSize = 4;
+                        for (int i = 0; i < frameSize / intSize; ++i) {
+                            masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1);
+                        }
+                    }
+                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+                    if (csl != null && csl.size != 0) {
+                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
+                        assert frameToCSA >= 0;
+                        masm.save(csl, frameToCSA);
+                    }
+                    break;
+                }
+                case PopFrame: {
+                    int frameSize = tasm.frameMap.frameSize();
+
+                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+                    if (csl != null && csl.size != 0) {
+                        tasm.targetMethod.setRegisterRestoreEpilogueOffset(masm.codeBuffer.position());
+                        // saved all registers, restore all registers
+                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
+                        masm.restore(csl, frameToCSA);
+                    }
+
+                    masm.incrementq(AMD64.rsp, frameSize);
+                    break;
+                }
+                case Push: {
+                    CiRegisterValue value = assureInRegister(tasm, masm, operands[inst.x().index]);
+                    masm.push(asRegister(value));
+                    break;
+                }
+                case Pop: {
+                    CiValue result = operands[inst.result.index];
+                    if (isRegister(result)) {
+                        masm.pop(asRegister(result));
+                    } else {
+                        CiRegister rscratch = tasm.frameMap.registerConfig.getScratchRegister();
+                        masm.pop(rscratch);
+                        AMD64Move.move(tasm, masm, result, rscratch.asValue());
+                    }
+                    break;
+                }
+                case Mark: {
+                    XirMark xmark = (XirMark) inst.extra;
+                    Mark[] references = new Mark[xmark.references.length];
+                    for (int i = 0; i < references.length; i++) {
+                        references[i] = marks.get(xmark.references[i]);
+                        assert references[i] != null;
+                    }
+                    Mark mark = tasm.recordMark(xmark.id, references);
+                    marks.put(xmark, mark);
+                    break;
+                }
+                case Nop: {
+                    for (int i = 0; i < (Integer) inst.extra; i++) {
+                        masm.nop();
+                    }
+                    break;
+                }
+                case RawBytes: {
+                    for (byte b : (byte[]) inst.extra) {
+                        masm.codeBuffer.emitByte(b & 0xff);
+                    }
+                    break;
+                }
+                case ShouldNotReachHere: {
+                    AMD64Call.shouldNotReachHere(tasm, masm);
+                    break;
+                }
+                default:
+                    throw Util.shouldNotReachHere("Unknown XIR operation " + inst.op);
+            }
+        }
+    }
+
+    private static void emitXirViaLir(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic intOp, AMD64Arithmetic longOp, AMD64Arithmetic floatOp,
+                    AMD64Arithmetic doubleOp, CiValue left, CiValue right, CiValue result) {
+        AMD64Arithmetic code;
+        switch (result.kind) {
+            case Int: code = intOp; break;
+            case Long: code = longOp; break;
+            case Float: code = floatOp; break;
+            case Double: code = doubleOp; break;
+            default: throw Util.shouldNotReachHere();
+        }
+        assert left == result;
+        if (isRegister(right) && right.kind != result.kind) {
+            // XIR is not strongly typed, so we can have a type mismatch that we have to fix here.
+            AMD64Arithmetic.emit(tasm, masm, code, result, asRegister(right).asValue(result.kind), null);
+        } else {
+            AMD64Arithmetic.emit(tasm, masm, code, result, right, null);
+        }
+    }
+
+    private static void emitXirCompare(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction inst, ConditionFlag cflag, CiValue[] ops, Label label) {
+        CiValue x = ops[inst.x().index];
+        CiValue y = ops[inst.y().index];
+        AMD64Compare code;
+        switch (x.kind) {
+            case Int: code = AMD64Compare.ICMP; break;
+            case Long: code = AMD64Compare.LCMP; break;
+            case Object: code = AMD64Compare.ACMP; break;
+            case Float: code = AMD64Compare.FCMP; break;
+            case Double: code = AMD64Compare.DCMP; break;
+            default: throw Util.shouldNotReachHere();
+        }
+        AMD64Compare.emit(tasm, masm, code, x, y);
+        masm.jcc(cflag, label);
+    }
+
+    /**
+     * @param offset the offset RSP at which to bang. Note that this offset is relative to RSP after RSP has been
+     *            adjusted to allocated the frame for the method. It denotes an offset "down" the stack.
+     *            For very large frames, this means that the offset may actually be negative (i.e. denoting
+     *            a slot "up" the stack above RSP).
+     */
+    private static void bangStackWithOffset(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int offset) {
+        masm.movq(new CiAddress(tasm.target.wordKind, AMD64.RSP, -offset), AMD64.rax);
+    }
+
+    private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) {
+        if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) {
+            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
+            AMD64Move.move(tasm, masm, register, value);
+            return register;
+        }
+        return value;
+    }
+
+    private static CiRegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue pointer) {
+        if (isConstant(pointer)) {
+            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind);
+            AMD64Move.move(tasm, masm, register, pointer);
+            return register;
+        }
+
+        assert isRegister(pointer) : "should be register, but is: " + pointer;
+        return (CiRegisterValue) pointer;
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,577 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
-import static com.oracle.max.cri.ci.CiValue.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.*;
-import com.oracle.max.cri.xir.CiXirAssembler.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64XirOpcode implements StandardOpcode.XirOpcode {
-    XIR;
-
-    public LIRInstruction create(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
-                        LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method) {
-        return new LIRXirInstruction(this, snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, method) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm) {
-                emit(tasm, (AMD64MacroAssembler) tasm.asm, this);
-            }
-        };
-    }
-
-    private static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, LIRXirInstruction op) {
-        XirSnippet snippet = op.snippet;
-        Label endLabel = null;
-        Label[] labels = new Label[snippet.template.labels.length];
-        for (int i = 0; i < labels.length; i++) {
-            labels[i] = new Label();
-            if (snippet.template.labels[i].name == XirLabel.TrueSuccessor) {
-                if (op.trueSuccessor() == null) {
-                    assert endLabel == null;
-                    endLabel = new Label();
-                    labels[i] = endLabel;
-                } else {
-                    labels[i] = op.trueSuccessor().label();
-                }
-            } else if (snippet.template.labels[i].name == XirLabel.FalseSuccessor) {
-                if (op.falseSuccessor() == null) {
-                    assert endLabel == null;
-                    endLabel = new Label();
-                    labels[i] = endLabel;
-                } else {
-                    labels[i] = op.falseSuccessor().label();
-                }
-            }
-        }
-        emitXirInstructions(tasm, masm, op, snippet.template.fastPath, labels, op.getOperands(), snippet.marks);
-        if (endLabel != null) {
-            masm.bind(endLabel);
-        }
-
-        if (snippet.template.slowPath != null) {
-            tasm.slowPaths.add(new SlowPath(op, labels, snippet.marks));
-        }
-    }
-
-    private static class SlowPath extends AMD64SlowPath {
-        public final LIRXirInstruction instruction;
-        public final Label[] labels;
-        public final Map<XirMark, Mark> marks;
-
-        public SlowPath(LIRXirInstruction instruction, Label[] labels, Map<XirMark, Mark> marks) {
-            this.instruction = instruction;
-            this.labels = labels;
-            this.marks = marks;
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            emitSlowPath(tasm, masm, this);
-        }
-    }
-
-
-    private static void emitSlowPath(TargetMethodAssembler tasm, AMD64MacroAssembler masm, SlowPath sp) {
-        int start = -1;
-        if (GraalOptions.TraceAssembler) {
-            TTY.println("Emitting slow path for XIR instruction " + sp.instruction.snippet.template.name);
-            start = masm.codeBuffer.position();
-        }
-        emitXirInstructions(tasm, masm, sp.instruction, sp.instruction.snippet.template.slowPath, sp.labels, sp.instruction.getOperands(), sp.marks);
-        masm.nop();
-        if (GraalOptions.TraceAssembler) {
-            TTY.println("From " + start + " to " + masm.codeBuffer.position());
-        }
-    }
-
-    protected static void emitXirInstructions(TargetMethodAssembler tasm, AMD64MacroAssembler masm, LIRXirInstruction xir, XirInstruction[] instructions, Label[] labels, CiValue[] operands, Map<XirMark, Mark> marks) {
-        LIRDebugInfo info = xir == null ? null : xir.info;
-        LIRDebugInfo infoAfter = xir == null ? null : xir.infoAfter;
-
-        for (XirInstruction inst : instructions) {
-            switch (inst.op) {
-                case Add:
-                    emitXirViaLir(tasm, masm, AMD64ArithmeticOpcode.IADD, AMD64ArithmeticOpcode.LADD, AMD64ArithmeticOpcode.FADD, AMD64ArithmeticOpcode.DADD, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Sub:
-                    emitXirViaLir(tasm, masm, AMD64ArithmeticOpcode.ISUB, AMD64ArithmeticOpcode.LSUB, AMD64ArithmeticOpcode.FSUB, AMD64ArithmeticOpcode.DSUB, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Div:
-                    emitXirViaLir(tasm, masm, AMD64DivOpcode.IDIV, AMD64DivOpcode.LDIV, AMD64ArithmeticOpcode.FDIV, AMD64ArithmeticOpcode.DDIV, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Mul:
-                    emitXirViaLir(tasm, masm, AMD64MulOpcode.IMUL, AMD64MulOpcode.LMUL, AMD64ArithmeticOpcode.FMUL, AMD64ArithmeticOpcode.DMUL, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Mod:
-                    emitXirViaLir(tasm, masm, AMD64DivOpcode.IREM, AMD64DivOpcode.LREM, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Shl:
-                    emitXirViaLir(tasm, masm, AMD64ShiftOpcode.ISHL, AMD64ShiftOpcode.LSHL, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Sar:
-                    emitXirViaLir(tasm, masm, AMD64ShiftOpcode.ISHR, AMD64ShiftOpcode.LSHR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Shr:
-                    emitXirViaLir(tasm, masm, AMD64ShiftOpcode.IUSHR, AMD64ShiftOpcode.LUSHR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case And:
-                    emitXirViaLir(tasm, masm, AMD64ArithmeticOpcode.IAND, AMD64ArithmeticOpcode.LAND, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Or:
-                    emitXirViaLir(tasm, masm, AMD64ArithmeticOpcode.IOR, AMD64ArithmeticOpcode.LOR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Xor:
-                    emitXirViaLir(tasm, masm, AMD64ArithmeticOpcode.IXOR, AMD64ArithmeticOpcode.LXOR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
-                    break;
-
-                case Mov: {
-                    CiValue result = operands[inst.result.index];
-                    CiValue source = operands[inst.x().index];
-                    AMD64MoveOpcode.move(tasm, masm, result, source);
-                    break;
-                }
-
-                case PointerLoad: {
-                    CiValue result = operands[inst.result.index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiRegisterValue register = assureInRegister(tasm, masm, pointer);
-
-                    AMD64MoveOpcode.load(tasm, masm, result, new CiAddress(inst.kind, register), (Boolean) inst.extra ? info : null);
-                    break;
-                }
-
-                case PointerStore: {
-                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.y().index]);
-                    CiValue pointer = operands[inst.x().index];
-                    assert isRegister(pointer);
-
-                    AMD64MoveOpcode.store(tasm, masm, new CiAddress(inst.kind, pointer), value, (Boolean) inst.extra ? info : null);
-                    break;
-                }
-
-                case PointerLoadDisp: {
-                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
-                    boolean canTrap = addressInformation.canTrap;
-
-                    CiAddress.Scale scale = addressInformation.scale;
-                    int displacement = addressInformation.disp;
-
-                    CiValue result = operands[inst.result.index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue index = operands[inst.y().index];
-
-                    pointer = assureInRegister(tasm, masm, pointer);
-                    assert isRegister(pointer);
-
-                    CiAddress src;
-                    if (isConstant(index)) {
-                        assert index.kind == CiKind.Int;
-                        CiConstant constantIndex = (CiConstant) index;
-                        src = new CiAddress(inst.kind, pointer, constantIndex.asInt() * scale.value + displacement);
-                    } else {
-                        src = new CiAddress(inst.kind, pointer, index, scale, displacement);
-                    }
-
-                    AMD64MoveOpcode.load(tasm, masm, result, src, canTrap ? info : null);
-                    break;
-                }
-
-                case LoadEffectiveAddress: {
-                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
-
-                    CiAddress.Scale scale = addressInformation.scale;
-                    int displacement = addressInformation.disp;
-
-                    CiValue result = operands[inst.result.index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue index = operands[inst.y().index];
-
-                    pointer = assureInRegister(tasm, masm, pointer);
-                    assert isRegister(pointer);
-                    CiAddress src = new CiAddress(CiKind.Illegal, pointer, index, scale, displacement);
-                    masm.leaq(asRegister(result), src);
-                    break;
-                }
-
-                case PointerStoreDisp: {
-                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
-                    boolean canTrap = addressInformation.canTrap;
-
-                    CiAddress.Scale scale = addressInformation.scale;
-                    int displacement = addressInformation.disp;
-
-                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.z().index]);
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue index = operands[inst.y().index];
-
-                    pointer = assureInRegister(tasm, masm, pointer);
-                    assert isRegister(pointer);
-
-                    CiAddress dst;
-                    if (isConstant(index)) {
-                        assert index.kind == CiKind.Int;
-                        CiConstant constantIndex = (CiConstant) index;
-                        dst = new CiAddress(inst.kind, pointer, IllegalValue, scale, constantIndex.asInt() * scale.value + displacement);
-                    } else {
-                        dst = new CiAddress(inst.kind, pointer, index, scale, displacement);
-                    }
-
-                    AMD64MoveOpcode.store(tasm, masm, dst, value, canTrap ? info : null);
-                    break;
-                }
-
-                case RepeatMoveBytes:
-                    assert asRegister(operands[inst.x().index]).equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index];
-                    assert asRegister(operands[inst.y().index]).equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index];
-                    assert asRegister(operands[inst.z().index]).equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index];
-                    masm.repeatMoveBytes();
-                    break;
-
-                case RepeatMoveWords:
-                    assert asRegister(operands[inst.x().index]).equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index];
-                    assert asRegister(operands[inst.y().index]).equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index];
-                    assert asRegister(operands[inst.z().index]).equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index];
-                    masm.repeatMoveWords();
-                    break;
-
-                case PointerCAS:
-                    assert asRegister(operands[inst.x().index]).equals(AMD64.rax) : "wrong input x: " + operands[inst.x().index];
-
-                    CiValue exchangedVal = operands[inst.y().index];
-                    CiValue exchangedAddress = operands[inst.x().index];
-                    CiRegisterValue pointerRegister = assureInRegister(tasm, masm, exchangedAddress);
-                    CiAddress addr = new CiAddress(tasm.target.wordKind, pointerRegister);
-
-                    if ((Boolean) inst.extra && info != null) {
-                        tasm.recordImplicitException(masm.codeBuffer.position(), info);
-                    }
-                    masm.cmpxchgq(asRegister(exchangedVal), addr);
-
-                    break;
-
-                case CallRuntime: {
-                    CiKind[] signature = new CiKind[inst.arguments.length];
-                    for (int i = 0; i < signature.length; i++) {
-                        signature[i] = inst.arguments[i].kind;
-                    }
-
-                    CiCallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
-                    for (int i = 0; i < inst.arguments.length; i++) {
-                        CiValue argumentLocation = cc.locations[i];
-                        CiValue argumentSourceLocation = operands[inst.arguments[i].index];
-                        if (argumentLocation != argumentSourceLocation) {
-                            AMD64MoveOpcode.move(tasm, masm, argumentLocation, argumentSourceLocation);
-                        }
-                    }
-
-                    RuntimeCallInformation runtimeCallInformation = (RuntimeCallInformation) inst.extra;
-                    AMD64CallOpcode.directCall(tasm, masm, runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
-
-                    if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) {
-                        CiRegister returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind);
-                        CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind());
-                        AMD64MoveOpcode.move(tasm, masm, operands[inst.result.index], resultLocation);
-                    }
-                    break;
-                }
-                case Jmp: {
-                    if (inst.extra instanceof XirLabel) {
-                        Label label = labels[((XirLabel) inst.extra).index];
-                        masm.jmp(label);
-                    } else {
-                        AMD64CallOpcode.directJmp(tasm, masm, inst.extra);
-                    }
-                    break;
-                }
-                case DecAndJumpNotZero: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    CiValue value = operands[inst.x().index];
-                    if (value.kind == CiKind.Long) {
-                        masm.decq(asRegister(value));
-                    } else {
-                        assert value.kind == CiKind.Int;
-                        masm.decl(asRegister(value));
-                    }
-                    masm.jcc(ConditionFlag.notZero, label);
-                    break;
-                }
-                case Jeq: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.equal, operands, label);
-                    break;
-                }
-                case Jneq: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.notEqual, operands, label);
-                    break;
-                }
-
-                case Jgt: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.greater, operands, label);
-                    break;
-                }
-
-                case Jgteq: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.greaterEqual, operands, label);
-                    break;
-                }
-
-                case Jugteq: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.aboveEqual, operands, label);
-                    break;
-                }
-
-                case Jlt: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.less, operands, label);
-                    break;
-                }
-
-                case Jlteq: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    emitXirCompare(tasm, masm, inst, ConditionFlag.lessEqual, operands, label);
-                    break;
-                }
-
-                case Jbset: {
-                    Label label = labels[((XirLabel) inst.extra).index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue offset = operands[inst.y().index];
-                    CiValue bit = operands[inst.z().index];
-                    assert isConstant(offset) && isConstant(bit);
-                    CiConstant constantOffset = (CiConstant) offset;
-                    CiConstant constantBit = (CiConstant) bit;
-                    CiAddress src = new CiAddress(inst.kind, pointer, constantOffset.asInt());
-                    masm.btli(src, constantBit.asInt());
-                    masm.jcc(ConditionFlag.aboveEqual, label);
-                    break;
-                }
-
-                case Bind: {
-                    XirLabel l = (XirLabel) inst.extra;
-                    Label label = labels[l.index];
-                    masm.bind(label);
-                    break;
-                }
-                case Safepoint: {
-                    assert info != null : "Must have debug info in order to create a safepoint.";
-                    tasm.recordSafepoint(masm.codeBuffer.position(), info);
-                    break;
-                }
-                case NullCheck: {
-                    tasm.recordImplicitException(masm.codeBuffer.position(), info);
-                    CiValue pointer = operands[inst.x().index];
-                    masm.nullCheck(asRegister(pointer));
-                    break;
-                }
-                case Align: {
-                    masm.align((Integer) inst.extra);
-                    break;
-                }
-                case StackOverflowCheck: {
-                    int frameSize = tasm.frameMap.frameSize();
-                    int lastFramePage = frameSize / tasm.target.pageSize;
-                    // emit multiple stack bangs for methods with frames larger than a page
-                    for (int i = 0; i <= lastFramePage; i++) {
-                        int offset = (i + GraalOptions.StackShadowPages) * tasm.target.pageSize;
-                        // Deduct 'frameSize' to handle frames larger than the shadow
-                        bangStackWithOffset(tasm, masm, offset - frameSize);
-                    }
-                    break;
-                }
-                case PushFrame: {
-                    int frameSize = tasm.frameMap.frameSize();
-                    masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0
-                    if (GraalOptions.ZapStackOnMethodEntry) {
-                        final int intSize = 4;
-                        for (int i = 0; i < frameSize / intSize; ++i) {
-                            masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1);
-                        }
-                    }
-                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
-                    if (csl != null && csl.size != 0) {
-                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
-                        assert frameToCSA >= 0;
-                        masm.save(csl, frameToCSA);
-                    }
-                    break;
-                }
-                case PopFrame: {
-                    int frameSize = tasm.frameMap.frameSize();
-
-                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
-                    if (csl != null && csl.size != 0) {
-                        tasm.targetMethod.setRegisterRestoreEpilogueOffset(masm.codeBuffer.position());
-                        // saved all registers, restore all registers
-                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
-                        masm.restore(csl, frameToCSA);
-                    }
-
-                    masm.incrementq(AMD64.rsp, frameSize);
-                    break;
-                }
-                case Push: {
-                    CiRegisterValue value = assureInRegister(tasm, masm, operands[inst.x().index]);
-                    masm.push(asRegister(value));
-                    break;
-                }
-                case Pop: {
-                    CiValue result = operands[inst.result.index];
-                    if (isRegister(result)) {
-                        masm.pop(asRegister(result));
-                    } else {
-                        CiRegister rscratch = tasm.frameMap.registerConfig.getScratchRegister();
-                        masm.pop(rscratch);
-                        AMD64MoveOpcode.move(tasm, masm, result, rscratch.asValue());
-                    }
-                    break;
-                }
-                case Mark: {
-                    XirMark xmark = (XirMark) inst.extra;
-                    Mark[] references = new Mark[xmark.references.length];
-                    for (int i = 0; i < references.length; i++) {
-                        references[i] = marks.get(xmark.references[i]);
-                        assert references[i] != null;
-                    }
-                    Mark mark = tasm.recordMark(xmark.id, references);
-                    marks.put(xmark, mark);
-                    break;
-                }
-                case Nop: {
-                    for (int i = 0; i < (Integer) inst.extra; i++) {
-                        masm.nop();
-                    }
-                    break;
-                }
-                case RawBytes: {
-                    for (byte b : (byte[]) inst.extra) {
-                        masm.codeBuffer.emitByte(b & 0xff);
-                    }
-                    break;
-                }
-                case ShouldNotReachHere: {
-                    AMD64CallOpcode.shouldNotReachHere(tasm, masm);
-                    break;
-                }
-                default:
-                    throw Util.shouldNotReachHere("Unknown XIR operation " + inst.op);
-            }
-        }
-    }
-
-    private static void emitXirViaLir(TargetMethodAssembler tasm, AMD64MacroAssembler masm, LIROpcode intOp, LIROpcode longOp, LIROpcode floatOp, LIROpcode doubleOp, CiValue left, CiValue right, CiValue result) {
-        LIROpcode code;
-        switch (result.kind) {
-            case Int: code = intOp; break;
-            case Long: code = longOp; break;
-            case Float: code = floatOp; break;
-            case Double: code = doubleOp; break;
-            default: throw Util.shouldNotReachHere();
-        }
-
-        if (code instanceof AMD64ArithmeticOpcode) {
-            ((AMD64ArithmeticOpcode) code).emit(tasm, masm, result, left, right);
-        } else if (code instanceof AMD64MulOpcode) {
-            ((AMD64MulOpcode) code).emit(tasm, masm, result, left, right);
-        } else if (code instanceof AMD64DivOpcode) {
-            ((AMD64DivOpcode) code).emit(tasm, masm, result, null, left, right);
-        } else if (code instanceof AMD64ShiftOpcode) {
-            ((AMD64ShiftOpcode) code).emit(tasm, masm, result, left, right);
-        }
-    }
-
-    private static void emitXirCompare(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction inst, ConditionFlag cflag, CiValue[] ops, Label label) {
-        CiValue x = ops[inst.x().index];
-        CiValue y = ops[inst.y().index];
-        AMD64CompareOpcode code;
-        switch (x.kind) {
-            case Int: code = AMD64CompareOpcode.ICMP; break;
-            case Long: code = AMD64CompareOpcode.LCMP; break;
-            case Object: code = AMD64CompareOpcode.ACMP; break;
-            case Float: code = AMD64CompareOpcode.FCMP; break;
-            case Double: code = AMD64CompareOpcode.DCMP; break;
-            default: throw Util.shouldNotReachHere();
-        }
-        code.emit(tasm, masm, x, y);
-        masm.jcc(cflag, label);
-    }
-
-    /**
-     * @param offset the offset RSP at which to bang. Note that this offset is relative to RSP after RSP has been
-     *            adjusted to allocated the frame for the method. It denotes an offset "down" the stack.
-     *            For very large frames, this means that the offset may actually be negative (i.e. denoting
-     *            a slot "up" the stack above RSP).
-     */
-    private static void bangStackWithOffset(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int offset) {
-        masm.movq(new CiAddress(tasm.target.wordKind, AMD64.RSP, -offset), AMD64.rax);
-    }
-
-    private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) {
-        if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) {
-            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
-            AMD64MoveOpcode.move(tasm, masm, register, value);
-            return register;
-        }
-        return value;
-    }
-
-    private static CiRegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue pointer) {
-        if (isConstant(pointer)) {
-            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind);
-            AMD64MoveOpcode.move(tasm, masm, register, pointer);
-            return register;
-        }
-
-        assert isRegister(pointer) : "should be register, but is: " + pointer;
-        return (CiRegisterValue) pointer;
-    }
-}
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotTargetMethod.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotTargetMethod.java	Thu Jan 26 12:23:00 2012 +0100
@@ -35,7 +35,7 @@
 public final class HotSpotTargetMethod extends CompilerObject {
 
     /**
-     * 
+     *
      */
     private static final long serialVersionUID = 7807321392203253218L;
     public final CiTargetMethod targetMethod;
@@ -45,7 +45,7 @@
     public final Site[] sites;
     public final ExceptionHandler[] exceptionHandlers;
 
-    private HotSpotTargetMethod(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod) {
+    public HotSpotTargetMethod(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod) {
         super(compiler);
         this.method = method;
         this.targetMethod = targetMethod;
@@ -100,10 +100,6 @@
         return result;
     }
 
-    public static HotSpotCompiledMethod installMethod(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod, boolean installCode) {
-        return compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, method, targetMethod), installCode);
-    }
-
     public static Object installStub(Compiler compiler, CiTargetMethod targetMethod, String name) {
         return compiler.getVMEntries().installStub(new HotSpotTargetMethod(compiler, targetMethod, name));
     }
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Thu Jan 26 12:23:00 2012 +0100
@@ -32,7 +32,6 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
-import com.oracle.max.graal.hotspot.*;
 import com.oracle.max.graal.hotspot.Compiler;
 import com.oracle.max.graal.hotspot.ri.*;
 import com.oracle.max.graal.hotspot.server.*;
@@ -182,7 +181,7 @@
                         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime());
                         plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                         CiTargetMethod result = compiler.getCompiler().compileMethod(method, -1, plan);
-                        HotSpotTargetMethod.installMethod(compiler, method, result, true);
+                        compiler.getRuntime().installMethod(method, result);
                     } catch (CiBailout bailout) {
                         if (GraalOptions.ExitVMOnBailout) {
                             bailout.printStackTrace(TTY.cachedOut);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/TailcallNode.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.nodes;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.target.amd64.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Performs a tail call to the specified target compiled method, with the parameter taken from the supplied FrameState.
+ */
+public class TailcallNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input private final FrameState frameState;
+    @Input private final ValueNode target;
+
+    /**
+     * Creates a TailcallNode.
+     * @param target points to the start of an nmethod
+     * @param frameState the parameters will be taken from this FrameState
+     */
+    public TailcallNode(ValueNode target, FrameState frameState) {
+        super(StampFactory.illegal());
+        this.target = target;
+        this.frameState = frameState;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        LIRGenerator gen = (LIRGenerator) generator;
+        HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
+        RiResolvedMethod method = frameState.method();
+        boolean isStatic = Modifier.isStatic(method.accessFlags());
+
+        CiKind[] signature = CiUtil.signatureToKinds(method.signature(), isStatic ? null : method.holder().kind(true));
+        CiCallingConvention cc = gen.frameMap().registerConfig.getCallingConvention(CiCallingConvention.Type.JavaCall, signature, gen.target(), false);
+        gen.frameMap().callsMethod(cc, CiCallingConvention.Type.JavaCall);
+        List<ValueNode> parameters = new ArrayList<>();
+        for (int i = 0; i < cc.locations.length; i++) {
+            parameters.add(frameState.localAt(i));
+        }
+        List<CiValue> argList = gen.visitInvokeArguments(cc, parameters, null);
+
+        CiValue entry = gen.emitLoad(new CiAddress(CiKind.Long, gen.operand(target), config.nmethodEntryOffset), false);
+
+        gen.append(new AMD64TailcallOp(argList, entry, cc.locations));
+    }
+}
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java	Thu Jan 26 12:23:00 2012 +0100
@@ -57,6 +57,7 @@
     private RiResolvedType holder;
     private byte[] code;
     private boolean canBeInlined;
+    private CiGenericCallback callback;
 
     private HotSpotMethodResolvedImpl() {
         super(null);
@@ -306,10 +307,16 @@
 
     @Override
     public boolean canBeInlined() {
-        return canBeInlined;
+        return canBeInlined && callback == null;
+    }
+    public void neverInline() {
+        this.canBeInlined = false;
     }
 
-    public void setCanBeInlined(boolean canBeInlined) {
-        this.canBeInlined = canBeInlined;
+    public CiGenericCallback callback() {
+        return callback;
+    }
+    public void setCallback(CiGenericCallback callback) {
+        this.callback = callback;
     }
 }
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Thu Jan 26 12:23:00 2012 +0100
@@ -34,12 +34,15 @@
 import com.oracle.max.cri.ri.RiType.Representation;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.cri.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.hotspot.*;
 import com.oracle.max.graal.hotspot.Compiler;
 import com.oracle.max.graal.hotspot.nodes.*;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
 import com.oracle.max.graal.nodes.calc.*;
 import com.oracle.max.graal.nodes.extended.*;
 import com.oracle.max.graal.nodes.java.*;
@@ -399,18 +402,82 @@
         return (RiResolvedMethod) compiler.getVMEntries().getRiMethod(reflectionMethod);
     }
 
-    public void installMethod(RiMethod method, CiTargetMethod code) {
-        HotSpotTargetMethod.installMethod(CompilerImpl.getInstance(), (HotSpotMethodResolved) method, code, true);
+    @Override
+    public void installMethod(RiResolvedMethod method, CiTargetMethod code) {
+        synchronized (method) {
+            if (((HotSpotMethodResolvedImpl) method).callback() == null) {
+                compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), true);
+            } else {
+                // callback stub is installed.
+            }
+        }
     }
 
     @Override
     public RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code) {
-        Compiler compilerInstance = CompilerImpl.getInstance();
-        return HotSpotTargetMethod.installMethod(compilerInstance, (HotSpotMethodResolved) method, code, false);
+        return compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), false);
+    }
+
+    public void installMethodCallback(RiResolvedMethod method, CiGenericCallback callback) {
+        synchronized (method) {
+            ((HotSpotMethodResolvedImpl) method).setCallback(callback);
+            CiTargetMethod callbackStub = createCallbackStub(method, callback);
+            compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, callbackStub), true);
+        }
     }
 
     @Override
     public RiRegisterConfig getGlobalStubRegisterConfig() {
         return globalStubRegConfig;
     }
+
+    private CiTargetMethod createCallbackStub(RiResolvedMethod method, CiGenericCallback callback) {
+        StructuredGraph graph = new StructuredGraph();
+        FrameStateBuilder frameState = new FrameStateBuilder(method, method.maxLocals(), method.maxStackSize(), graph);
+        ValueNode local0 = frameState.loadLocal(0);
+
+        FrameState initialFrameState = frameState.create(0);
+        graph.start().setStateAfter(initialFrameState);
+
+        ConstantNode callbackNode = ConstantNode.forObject(callback, this, graph);
+
+        RuntimeCallNode runtimeCall = graph.add(new RuntimeCallNode(CiRuntimeCall.GenericCallback, new ValueNode[] {callbackNode, local0}));
+        runtimeCall.setStateAfter(initialFrameState.duplicateModified(0, false, CiKind.Void, runtimeCall));
+
+        @SuppressWarnings("unused")
+        HotSpotCompiledMethod hotSpotCompiledMethod = new HotSpotCompiledMethod(null); // initialize class...
+        RiResolvedType compiledMethodClass = getType(HotSpotCompiledMethod.class);
+        RiResolvedField nmethodField = null;
+        for (RiResolvedField field : compiledMethodClass.declaredFields()) {
+            if (field.name().equals("nmethod")) {
+                nmethodField = field;
+                break;
+            }
+        }
+        assert nmethodField != null;
+        LoadFieldNode loadField = graph.add(new LoadFieldNode(runtimeCall, nmethodField));
+
+        CompareNode compare = graph.unique(new CompareNode(loadField, Condition.EQ, ConstantNode.forLong(0, graph)));
+
+        IfNode ifNull = graph.add(new IfNode(compare, 0.01));
+
+        BeginNode beginInvalidated = graph.add(new BeginNode());
+        DeoptimizeNode deoptInvalidated = graph.add(new DeoptimizeNode(DeoptAction.None));
+
+        BeginNode beginTailcall = graph.add(new BeginNode());
+        TailcallNode tailcall = graph.add(new TailcallNode(loadField, initialFrameState));
+        DeoptimizeNode deoptEnd = graph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile));
+
+        graph.start().setNext(runtimeCall);
+        runtimeCall.setNext(loadField);
+        loadField.setNext(ifNull);
+        ifNull.setTrueSuccessor(beginInvalidated);
+        ifNull.setFalseSuccessor(beginTailcall);
+        beginInvalidated.setNext(deoptInvalidated);
+        beginTailcall.setNext(tailcall);
+        tailcall.setNext(deoptEnd);
+
+        CiTargetMethod result = compiler.getCompiler().compileMethod(method, graph, -1, PhasePlan.DEFAULT);
+        return result;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/target/amd64/AMD64TailcallOp.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.hotspot.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.target.amd64.*;
+import com.oracle.max.graal.compiler.util.*;
+
+/**
+ * Performs a hard-coded tail call to the specified target, which normally should be an RiCompiledCode instance.
+ */
+public class AMD64TailcallOp extends AMD64LIRInstruction {
+    public AMD64TailcallOp(List<CiValue> parameters, CiValue target, CiValue[] callingConvention) {
+        super("TAILCALL", LIRInstruction.NO_OPERANDS, null, toArray(parameters, target), LIRInstruction.NO_OPERANDS, callingConvention.clone());
+        assert inputs.length == temps.length + 1;
+    }
+
+    private static CiValue[] toArray(List<CiValue> parameters, CiValue target) {
+        CiValue[] result = new CiValue[parameters.size() + 1];
+        parameters.toArray(result);
+        result[parameters.size()] = target;
+        return result;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // move all parameters to the correct positions, according to the calling convention
+        // TODO: These moves should not be part of the TAILCALL opcode, but emitted as separate MOVE instructions before.
+        for (int i = 0; i < inputs.length - 1; i++) {
+            assert inputs[i].kind == CiKind.Object || inputs[i].kind == CiKind.Int || inputs[i].kind == CiKind.Long : "only Object, int and long supported for now";
+            assert isRegister(temps[i]) : "too many parameters";
+            if (isRegister(inputs[i])) {
+                if (inputs[i] != temps[i]) {
+                    masm.movq(asRegister(temps[i]), asRegister(inputs[i]));
+                }
+            } else {
+                masm.movq(asRegister(temps[i]), tasm.asAddress(inputs[i]));
+            }
+        }
+        // destroy the current frame (now the return address is the top of stack)
+        masm.leave();
+
+        // jump to the target method
+        masm.jmp(asRegister(inputs[inputs.length - 1]));
+        masm.ensureUniquePC();
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Input && index == 0) {
+            return EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Stack);
+        } else if (mode == OperandMode.Temp && index == 0) {
+            return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+        }
+        throw Util.shouldNotReachHere();
+    }
+}
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/MathIntrinsicNode.java	Thu Jan 26 12:22:36 2012 +0100
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/MathIntrinsicNode.java	Thu Jan 26 12:23:00 2012 +0100
@@ -22,8 +22,11 @@
  */
 package com.oracle.max.graal.snippets.nodes;
 
+import static com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.*;
+
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.Op2RegCommutative;
 import com.oracle.max.graal.compiler.target.amd64.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.nodes.*;
@@ -61,13 +64,13 @@
         Variable input = gen.load(gen.operand(x()));
         Variable result = gen.newVariable(kind());
         switch (operation()) {
-            case ABS:   gen.append(AMD64LogicFloatOpcode.DAND.create(result, input, CiConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); break;
-            case SQRT:  gen.append(AMD64MathIntrinsicOpcode.SQRT.create(result, input)); break;
-            case LOG:   gen.append(AMD64MathIntrinsicOpcode.LOG.create(result, input)); break;
-            case LOG10: gen.append(AMD64MathIntrinsicOpcode.LOG10.create(result, input)); break;
-            case SIN:   gen.append(AMD64MathIntrinsicOpcode.SIN.create(result, input)); break;
-            case COS:   gen.append(AMD64MathIntrinsicOpcode.COS.create(result, input)); break;
-            case TAN:   gen.append(AMD64MathIntrinsicOpcode.TAN.create(result, input)); break;
+            case ABS:   gen.append(new Op2RegCommutative(DAND, result, input, CiConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); break;
+            case SQRT:  gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.SQRT, result, input)); break;
+            case LOG:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.LOG, result, input)); break;
+            case LOG10: gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.LOG10, result, input)); break;
+            case SIN:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.SIN, result, input)); break;
+            case COS:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.COS, result, input)); break;
+            case TAN:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.TAN, result, input)); break;
             default:    throw Util.shouldNotReachHere();
         }
         gen.setResult(this, result);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Thu Jan 26 12:23:00 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011, 2012, 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.max.graal.snippets.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.target.amd64.*;
+import com.oracle.max.graal.compiler.util.*;
+
+public class AMD64MathIntrinsicOp extends AMD64LIRInstruction {
+    public enum Opcode  {
+        SQRT,
+        SIN, COS, TAN,
+        LOG, LOG10;
+    }
+
+    public AMD64MathIntrinsicOp(Opcode opcode, CiValue result, CiValue input) {
+        super(opcode, new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        Opcode opcode = (Opcode) code;
+        CiValue result = output(0);
+        CiValue input = input(0);
+
+        switch (opcode) {
+            case SQRT:  masm.sqrtsd(asDoubleReg(result), asDoubleReg(input)); break;
+            case LOG:   masm.flog(asDoubleReg(result), asDoubleReg(input), false); break;
+            case LOG10: masm.flog(asDoubleReg(result), asDoubleReg(input), true); break;
+            case SIN:   masm.fsin(asDoubleReg(result), asDoubleReg(input)); break;
+            case COS:   masm.fcos(asDoubleReg(result), asDoubleReg(input)); break;
+            case TAN:   masm.ftan(asDoubleReg(result), asDoubleReg(input)); break;
+            default:    throw Util.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Input && index == 0) {
+            return EnumSet.of(OperandFlag.Register);
+        } else if (mode == OperandMode.Output && index == 0) {
+            return EnumSet.of(OperandFlag.Register);
+        }
+        throw Util.shouldNotReachHere();
+    }
+}
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOpcode.java	Thu Jan 26 12:22:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.max.graal.snippets.target.amd64;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.target.amd64.*;
-import com.oracle.max.graal.compiler.util.*;
-
-public enum AMD64MathIntrinsicOpcode implements LIROpcode {
-    SQRT,
-    SIN, COS, TAN,
-    LOG, LOG10;
-
-    public LIRInstruction create(Variable result, Variable input) {
-        CiValue[] inputs = new CiValue[] {input};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, asDoubleReg(output(0)), asDoubleReg(input(0)));
-            }
-        };
-    }
-
-    /**
-     * @param tasm
-     */
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiRegister result, CiRegister input) {
-        switch (this) {
-            case SQRT:  masm.sqrtsd(result, input); break;
-            case LOG:   masm.flog(result, input, false); break;
-            case LOG10: masm.flog(result, input, true); break;
-            case SIN:   masm.fsin(result, input); break;
-            case COS:   masm.fcos(result, input); break;
-            case TAN:   masm.ftan(result, input); break;
-            default:    throw Util.shouldNotReachHere();
-        }
-    }
-}
--- a/mx/commands.py	Thu Jan 26 12:22:36 2012 +0100
+++ b/mx/commands.py	Thu Jan 26 12:23:00 2012 +0100
@@ -369,6 +369,7 @@
     """run the GraalVM"""
 
     build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product'
+    mx.expand_project_in_args(args)  
     if mx.java().debug:
         args = ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000'] + args
     exe = join(_jdk(build), 'bin', mx.exe_suffix('java'))
@@ -508,7 +509,7 @@
     total.stop()
 
 def bench(args):
-    """run benchmarks and parse their ouput for results
+    """run benchmarks and parse their output for results
 
     Results are JSON formated : {group : {benchmark : score}}."""
     resultFile = None
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/callgraph.filter	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/callgraph.filter	Thu Jan 26 12:23:00 2012 +0100
@@ -1,3 +1,4 @@
 colorize("name", "<init>.*", yellow);
 colorize("name", "<clinit>.*", pink);
-colorize("leaf", "1", red);
+colorize("leaf", "1", lightGray);
+colorize("cutoff", "1", red);
--- a/src/share/vm/code/nmethod.cpp	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/vm/code/nmethod.cpp	Thu Jan 26 12:23:00 2012 +0100
@@ -1235,6 +1235,14 @@
     }
     _method = NULL;            // Clear the method of this dead nmethod
   }
+
+#ifdef GRAAL
+    if (_graal_compiled_method != NULL) {
+      HotSpotCompiledMethod::set_nmethod(_graal_compiled_method, 0);
+      _graal_compiled_method = NULL;
+    }
+#endif
+
   // Make the class unloaded - i.e., change state and notify sweeper
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (is_in_use()) {
--- a/src/share/vm/compiler/compileBroker.cpp	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/vm/compiler/compileBroker.cpp	Thu Jan 26 12:23:00 2012 +0100
@@ -1120,12 +1120,14 @@
                                blocking);*/
   }
 
+#ifdef GRAAL
   if (!JavaThread::current()->is_compiling()) {
     method->set_queued_for_compilation();
     GraalCompiler::instance()->compile_method(method, osr_bci, blocking);
   } else {
     // Recursive compile request => ignore.
   }
+#endif
 
   /*if (blocking) {
     wait_for_completion(task);
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Thu Jan 26 12:23:00 2012 +0100
@@ -275,10 +275,10 @@
 
   int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
   methodHandle method = getMethodFromHotSpotMethod(HotSpotTargetMethod::method(JNIHandles::resolve(target_method_obj))); 
-  {
-    nm = GraalEnv::register_method(method, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
-      &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, install_code);
-  }
+
+  nm = GraalEnv::register_method(method, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
+    &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, install_code);
+
   method->clear_queued_for_compilation();
 }
 
--- a/src/share/vm/graal/graalJavaAccess.hpp	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Thu Jan 26 12:23:00 2012 +0100
@@ -68,6 +68,7 @@
     int_field(HotSpotMethodResolved, maxLocals)                                         \
     int_field(HotSpotMethodResolved, maxStackSize)                                      \
     boolean_field(HotSpotMethodResolved, canBeInlined)                                  \
+    oop_field(HotSpotMethodResolved, callback, "Lcom/oracle/max/cri/ci/CiGenericCallback;") \
   end_class                                                                             \
   start_class(HotSpotType)                                                              \
     oop_field(HotSpotType, name, "Ljava/lang/String;")                                  \
--- a/src/share/vm/memory/heap.cpp	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/vm/memory/heap.cpp	Thu Jan 26 12:23:00 2012 +0100
@@ -127,7 +127,7 @@
   assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
 
   // reserve space for _segmap
-  if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) {
+  if (!_segmap.initialize(align_to_allocation_size(_number_of_reserved_segments), align_to_allocation_size(_number_of_committed_segments))) {
     return false;
   }
   assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "could not commit  enough space for segment map");
--- a/src/share/vm/runtime/java.cpp	Thu Jan 26 12:22:36 2012 +0100
+++ b/src/share/vm/runtime/java.cpp	Thu Jan 26 12:23:00 2012 +0100
@@ -425,9 +425,11 @@
   #define BEFORE_EXIT_DONE    2
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
+#ifdef GRAAL
   if (UseGraal) {
     GraalCompiler::instance()->exit();
   }
+#endif
 
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.