changeset 4525:681e969888a7

Separate LIR and new register allocator into separate projects
author Christian Wimmer <Christian.Wimmer@Oracle.com>
date Wed, 08 Feb 2012 19:25:29 -0800
parents dcc8f5c6f394
children 3a309467fc8e
files graal/com.oracle.max.asm/src/com/oracle/max/asm/NumUtil.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/Location.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/LocationMap.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/LocationUtil.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/MoveResolver.java graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/Location.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LocationMap.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LocationUtil.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/MoveResolver.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ComputeLinearScanOrder.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LIRInsertionBuffer.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/Block.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/BlockMap.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/CFGVerifier.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/ControlFlowGraph.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/Loop.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiResolver.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRVerifier.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LabelRef.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/StandardOp.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/ValueUtil.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/Variable.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockClosure.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/SchedulePhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Arithmetic.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Call.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Compare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompareToIntOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ControlFlow.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRInstruction.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MethodEndStub.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Move.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64SlowPath.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOp.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/target/amd64/AMD64TailcallOp.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Arithmetic.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Call.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Compare.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64CompareToIntOpcode.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64ControlFlow.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64LIRInstruction.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Move.java graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64SlowPath.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/FrameMap.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIR.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRDebugInfo.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRInsertionBuffer.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRInstruction.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRVerifier.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRXirInstruction.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LabelRef.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/StandardOp.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/ValueUtil.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/Variable.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/asm/TargetMethodAssembler.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/Block.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/BlockMap.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/CFGVerifier.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/ControlFlowGraph.java graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/Loop.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/MathIntrinsicNode.java graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphScheduleTest.java graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java mx/projects
diffstat 104 files changed, 7631 insertions(+), 7626 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/NumUtil.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/NumUtil.java	Wed Feb 08 19:25:29 2012 -0800
@@ -98,4 +98,8 @@
         assert isShort(v);
         return (short) v;
     }
+
+    public static int roundUp(int number, int mod) {
+        return ((number + mod - 1) / mod) * mod;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,123 @@
+/*
+ * 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.alloc.simple;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public abstract class AssignRegisters {
+    public final LIR lir;
+    public final FrameMap frameMap;
+
+    public AssignRegisters(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+    }
+
+    private CiBitMap curRegisterRefMap;
+    private CiBitMap curFrameRefMap;
+
+    public void execute() {
+        ValueProcedure useProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value); } };
+        ValueProcedure defProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value); } };
+        ValueProcedure setReferenceProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setReference(value); } };
+
+        Debug.log("==== start assign registers ====");
+        for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
+            Block block = lir.linearScanOrder().get(i);
+            Debug.log("start block %s", block);
+
+            curRegisterRefMap = frameMap.initRegisterRefMap();
+            curFrameRefMap = frameMap.initFrameRefMap();
+
+            // Put all values live at the end of the block into the reference map.
+            locationsForBlockEnd(block).forEachLocation(setReferenceProc);
+
+            for (int j = block.lir.size() - 1; j >= 0; j--) {
+                LIRInstruction op = block.lir.get(j);
+                Debug.log("  op %d %s", op.id(), op);
+
+                op.forEachOutput(defProc);
+                op.forEachTemp(defProc);
+                op.forEachState(useProc);
+                op.forEachAlive(useProc);
+
+                if (op.info != null) {
+                    Debug.log("    registerRefMap: %s  frameRefMap: %s", curRegisterRefMap, curFrameRefMap);
+                    op.info.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+
+                    if (op instanceof LIRXirInstruction) {
+                        LIRXirInstruction xir = (LIRXirInstruction) op;
+                        if (xir.infoAfter != null) {
+                            xir.infoAfter.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+                        }
+                    }
+                }
+
+                // Process input operands after assigning the reference map, so that input operands that are used
+                // for the last time at this instruction are not part of the reference map.
+                op.forEachInput(useProc);
+            }
+            Debug.log("end block %s", block);
+        }
+        Debug.log("==== end assign registers ====");
+    }
+
+    private CiValue use(CiValue value) {
+        Debug.log("    use %s", value);
+        if (isLocation(value)) {
+            CiValue location = asLocation(value).location;
+            frameMap.setReference(location, curRegisterRefMap, curFrameRefMap);
+            return location;
+        } else {
+            frameMap.setReference(value, curRegisterRefMap, curFrameRefMap);
+            return value;
+        }
+    }
+
+    private CiValue def(CiValue value) {
+        Debug.log("    def %s", value);
+        if (isLocation(value)) {
+            CiValue location = asLocation(value).location;
+            frameMap.clearReference(location, curRegisterRefMap, curFrameRefMap);
+            return location;
+        } else {
+            frameMap.clearReference(value, curRegisterRefMap, curFrameRefMap);
+            return value;
+        }
+    }
+
+    private CiValue setReference(CiValue value) {
+        Debug.log("    setReference %s", value);
+        frameMap.setReference(asLocation(value).location, curRegisterRefMap, curFrameRefMap);
+        return value;
+    }
+
+    protected abstract LocationMap locationsForBlockEnd(Block block);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,303 @@
+/*
+ * 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.alloc.simple;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public class DataFlowAnalysis {
+    private final LIR lir;
+    private final RiRegisterConfig registerConfig;
+
+    public DataFlowAnalysis(LIR lir, RiRegisterConfig registerConfig) {
+        this.lir = lir;
+        this.registerConfig = registerConfig;
+    }
+
+    public void execute() {
+        numberInstructions();
+        backwardDataFlow();
+    }
+
+
+    private List<Block> blocks() {
+        return lir.linearScanOrder();
+    }
+
+    private int numVariables() {
+        return lir.numVariables();
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+
+    private int[] definitions;
+    private BitSet[] blockLiveIn;
+    private Block[] opIdBlock;
+    private Object[] opIdKilledValues;
+
+
+    public BitSet liveIn(Block block) {
+        return blockLiveIn[block.getId()];
+    }
+    private void setLiveIn(Block block, BitSet liveIn) {
+        blockLiveIn[block.getId()] = liveIn;
+    }
+
+    private Block blockOf(int opId) {
+        return opIdBlock[opId >> 1];
+    }
+    private void setBlockOf(int opId, Block block) {
+        opIdBlock[opId >> 1] = block;
+    }
+
+    private Object killedValues(int opId) {
+        return opIdKilledValues[opId];
+    }
+    private void setKilledValues(int opId, Object killedValues) {
+        opIdKilledValues[opId] = killedValues;
+    }
+
+    public void forEachKilled(LIRInstruction op, boolean end, ValueProcedure proc) {
+        Object entry = killedValues(op.id() + (end ? 1 : 0));
+        if (entry == null) {
+            // Nothing to do
+        } else if (entry instanceof CiValue) {
+            CiValue newValue = proc.doValue((CiValue) entry, null, null);
+            assert newValue == entry : "procedure does not allow to change values";
+        } else {
+            CiValue[] values = (CiValue[]) entry;
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] != null) {
+                    CiValue newValue = proc.doValue(values[i], null, null);
+                    assert newValue == values[i] : "procedure does not allow to change values";
+                }
+            }
+        }
+    }
+
+    public int definition(Variable value) {
+        return definitions[value.index];
+    }
+
+    /**
+     * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}.
+     */
+    private void numberInstructions() {
+        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setDef(value); } };
+
+        int numInstructions = 0;
+        for (Block block : blocks()) {
+            numInstructions += block.lir.size();
+        }
+        opIdBlock = new Block[numInstructions];
+        opIdKilledValues = new Object[numInstructions << 1];
+        definitions = new int[numVariables()];
+
+        curOpId = 0;
+        for (Block block : blocks()) {
+            for (LIRInstruction op : block.lir) {
+                op.setId(curOpId);
+                setBlockOf(curOpId, block);
+
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+
+                curOpId += 2; // numbering of lirOps by two
+            }
+        }
+        assert curOpId == numInstructions << 1;
+    }
+
+    private CiValue setDef(CiValue value) {
+        if (isVariable(value)) {
+            assert definitions[asVariable(value).index] == 0 : "Variable defined twice";
+            definitions[asVariable(value).index] = curOpId;
+        }
+        return value;
+    }
+
+
+    private BitSet variableLive;
+    private BitSet registerLive;
+    private int curOpId;
+
+    private void backwardDataFlow() {
+        ValueProcedure inputProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId); } };
+        ValueProcedure aliveProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId + 1); } };
+        ValueProcedure tempProc =     new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, true); } };
+        ValueProcedure outputProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, false); } };
+
+        blockLiveIn = new BitSet[blocks().size()];
+        registerLive = new BitSet();
+
+        Debug.log("==== start backward data flow analysis ====");
+        for (int i = blocks().size() - 1; i >= 0; i--) {
+            Block block = blocks().get(i);
+            Debug.log("start block %s  loop %s", block, block.getLoop());
+
+            variableLive = new BitSet();
+            for (Block sux : block.getSuccessors()) {
+                BitSet suxLive = liveIn(sux);
+                if (suxLive != null) {
+                    Debug.log("  sux %s  suxLive: %s", sux, suxLive);
+                    variableLive.or(suxLive);
+                }
+            }
+
+            assert registerLive.isEmpty() : "no fixed register must be alive before processing a block";
+
+            for (int j = block.lir.size() - 1; j >= 0; j--) {
+                LIRInstruction op = block.lir.get(j);
+                curOpId = op.id();
+                Debug.log("  op %d %s  variableLive: %s  registerLive: %s", curOpId, op, variableLive, registerLive);
+
+                op.forEachOutput(outputProc);
+                op.forEachTemp(tempProc);
+                op.forEachState(aliveProc);
+                op.forEachAlive(aliveProc);
+                op.forEachInput(inputProc);
+            }
+
+            assert registerLive.isEmpty() : "no fixed register must be alive after processing a block";
+            assert liveIn(block) == null;
+            setLiveIn(block, variableLive);
+
+            if (block.isLoopHeader()) {
+                Debug.log("  loop header, propagating live set to loop blocks  variableLive: %s", variableLive);
+                // All variables that are live at the beginning of a loop are also live the whole loop.
+                // This is guaranteed by the SSA form.
+                for (Block loop : block.getLoop().blocks) {
+                    BitSet loopLiveIn = liveIn(loop);
+                    assert loopLiveIn != null : "All loop blocks must have been processed before the loop header";
+                    loopLiveIn.or(variableLive);
+                    Debug.log("    block %s  loopLiveIn %s", loop, loopLiveIn);
+                }
+            }
+
+            Debug.log("end block %s  variableLive: %s", block, variableLive);
+        }
+        Debug.log("==== end backward data flow analysis ====");
+    }
+
+    private CiValue use(CiValue value, int killOpId) {
+        Debug.log("    use %s", value);
+        if (isVariable(value)) {
+            int variableIdx = asVariable(value).index;
+            assert definitions[variableIdx] < curOpId;
+            if (!variableLive.get(variableIdx)) {
+                Debug.log("      set live variable %d", variableIdx);
+                variableLive.set(variableIdx);
+                kill(value, killOpId);
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (!registerLive.get(regNum)) {
+                Debug.log("      set live register %d", regNum);
+                registerLive.set(regNum);
+                kill(value, killOpId);
+            }
+        }
+        return value;
+    }
+
+    private CiValue def(CiValue value, boolean isTemp) {
+        Debug.log("    def %s", value);
+        if (isVariable(value)) {
+            int variableIdx = asVariable(value).index;
+            assert definitions[variableIdx] == curOpId;
+            if (variableLive.get(variableIdx)) {
+                Debug.log("      clear live variable %d", variableIdx);
+                assert !isTemp : "temp variable cannot be used after the operation";
+                variableLive.clear(variableIdx);
+            } else {
+                // Variable has never been used, so kill it immediately after the definition.
+                kill(value, curOpId + 1);
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (registerLive.get(regNum)) {
+                Debug.log("      clear live register %d", regNum);
+                assert !isTemp : "temp variable cannot be used after the operation";
+                registerLive.clear(regNum);
+            } else {
+                // Register has never been used, so kill it immediately after the definition.
+                kill(value, curOpId + 1);
+            }
+        }
+        return value;
+    }
+
+    private void kill(CiValue value, int opId) {
+        if (opId < 0) {
+            return;
+        }
+        if (isVariable(value)) {
+            int defOpId = definitions[asVariable(value).index];
+            assert defOpId > 0 && defOpId <= opId;
+
+            Block defBlock = blockOf(defOpId);
+            Block useBlock = blockOf(opId);
+
+            if (useBlock.getLoop() != null && useBlock.getLoop() != defBlock.getLoop()) {
+                // This is a value defined outside of the loop it is currently used in.  Therefore, it is live the whole loop
+                // and is not killed by the current instruction.
+                Debug.log("      no kill because use in %s, definition in %s", useBlock.getLoop(), defBlock.getLoop());
+                return;
+            }
+        }
+        Debug.log("      kill %s at %d", value, opId);
+
+        Object entry = killedValues(opId);
+        if (entry == null) {
+            setKilledValues(opId, value);
+        } else if (entry instanceof CiValue) {
+            setKilledValues(opId, new CiValue[] {(CiValue) entry, value});
+        } else {
+            CiValue[] killed = (CiValue[]) entry;
+            for (int i = 0; i < killed.length; i++) {
+                if (killed[i] == null) {
+                    killed[i] = value;
+                    return;
+                }
+            }
+            int oldLen = killed.length;
+            killed = Arrays.copyOf(killed, oldLen * 2);
+            setKilledValues(opId, killed);
+            killed[oldLen] = value;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,573 @@
+/*
+ * 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.alloc.simple;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public class LinearScanAllocator {
+    private final LIR lir;
+    private final FrameMap frameMap;
+
+    private final DataFlowAnalysis dataFlow;
+
+    public LinearScanAllocator(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+
+        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(lir, frameMap);
+
+        this.variableLastUse = new int[lir.numVariables()];
+    }
+
+    private class MoveResolverImpl extends MoveResolver {
+        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected CiValue scratchRegister(Variable spilled) {
+            GraalInternalError.shouldNotReachHere("needs working implementation");
+
+            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
+            for (CiRegister reg : availableRegs) {
+                if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
+                    return reg.asValue(spilled.kind);
+                }
+            }
+            throw new CiBailout("No register found");
+        }
+    }
+
+    private class ResolveDataFlowImpl extends ResolveDataFlow {
+        public ResolveDataFlowImpl(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
+            super(lir, moveResolver, dataFlow);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockBegin(Block block) {
+            return beginLocationsFor(block);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return endLocationsFor(block);
+        }
+    }
+
+    private class AssignRegistersImpl extends AssignRegisters {
+        public AssignRegistersImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return endLocationsFor(block);
+        }
+    }
+
+
+    private int maxRegisterNum() {
+        return frameMap.target.arch.registers.length;
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+
+    private final LocationMap[] blockBeginLocations;
+
+    private LocationMap beginLocationsFor(Block block) {
+        return blockBeginLocations[block.getId()];
+    }
+    private void setBeginLocationsFor(Block block, LocationMap locations) {
+        blockBeginLocations[block.getId()] = locations;
+    }
+
+    private final LocationMap[] blockEndLocations;
+
+    private LocationMap endLocationsFor(Block block) {
+        return blockEndLocations[block.getId()];
+    }
+    private void setEndLocationsFor(Block block, LocationMap locations) {
+        blockEndLocations[block.getId()] = locations;
+    }
+
+    private final int[] variableLastUse;
+
+    private int lastUseFor(Variable variable) {
+        return variableLastUse[variable.index];
+    }
+
+    private void setLastUseFor(Variable variable, int lastUse) {
+        variableLastUse[variable.index] = lastUse;
+    }
+
+    private MoveResolver moveResolver;
+    private LocationMap curLocations;
+    private CiValue[] curInRegisterState;
+    private CiValue[] curOutRegisterState;
+    private BitSet curLiveIn;
+    private int curOpId;
+    private boolean curPhiDefs;
+
+    private LocationMap canonicalSpillLocations;
+
+    public void execute() {
+        assert LIRVerifier.verify(true, lir, frameMap);
+
+        dataFlow.execute();
+        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
+
+        allocate();
+
+        IntervalPrinter.printAfterAllocation("After linear scan allocation", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
+
+        ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
+        resolveDataFlow.execute();
+        frameMap.finish();
+
+        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
+        assert RegisterVerifier.verify(lir, frameMap);
+
+        AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
+        assignRegisters.execute();
+
+        Debug.dump(lir, "After register asignment");
+        assert LIRVerifier.verify(false, lir, frameMap);
+    }
+
+    private void allocate() {
+        ValueProcedure recordUseProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return recordUse(value); } };
+        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
+        ValueProcedure unblockProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return unblock(value); } };
+        ValueProcedure killProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value); } };
+        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
+        ValueProcedure useProc =          new ValueProcedure() { @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); } };
+
+        Debug.log("==== start linear scan allocation ====");
+        canonicalSpillLocations = new LocationMap(lir.numVariables());
+        curInRegisterState = new CiValue[maxRegisterNum()];
+        curOutRegisterState = new CiValue[maxRegisterNum()];
+        for (Block block : lir.linearScanOrder()) {
+            Debug.log("start block %s %s", block, block.getLoop());
+
+            Arrays.fill(curOutRegisterState, null);
+            if (block.getDominator() != null) {
+                LocationMap dominatorState = endLocationsFor(block.getDominator());
+                curLocations = new LocationMap(dominatorState);
+                // Clear out all variables that are not live at the begin of this block
+                curLiveIn = dataFlow.liveIn(block);
+                curLocations.forEachLocation(killNonLiveProc);
+                assert checkInputState(block);
+            } else {
+                curLocations = new LocationMap(lir.numVariables());
+            }
+            Debug.log(logCurrentState());
+
+            for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) {
+                LIRInstruction op = block.lir.get(opIdx);
+                curOpId = op.id();
+                curPhiDefs = opIdx == 0;
+
+                Debug.log("  op %d %s", op.id(), op);
+
+                System.arraycopy(curOutRegisterState, 0, curInRegisterState, 0, curOutRegisterState.length);
+
+                // Unblock fixed registers that are only used for inputs in curOutRegisterState.
+                dataFlow.forEachKilled(op, false, unblockProc);
+                // Block fixed registers defined by this instruction in curOutRegisterState.
+                op.forEachTemp(blockProc);
+                op.forEachOutput(blockProc);
+
+                op.forEachInput(recordUseProc);
+                op.forEachAlive(recordUseProc);
+
+                moveResolver.init(block.lir, opIdx);
+                // Process Alive before Input because they are more restricted and the same variable can be Alive and Input.
+                op.forEachAlive(useProc);
+                op.forEachInput(useProc);
+
+                dataFlow.forEachKilled(op, false, killProc);
+
+                if (op.hasCall()) {
+                    spillCallerSaveRegisters();
+                }
+
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+
+                // Fixed temp and output registers can evict variables from their assigned register, allocate new location for them.
+                fixupEvicted();
+                // State values are the least critical and can get the leftover registers (or stack slots if no more register available).
+                op.forEachState(useProc);
+
+                if (opIdx == 0) {
+                    assert !moveResolver.hasMappings() : "cannot insert spill moves before label";
+                    setBeginLocationsFor(block, new LocationMap(curLocations));
+                }
+                moveResolver.resolve();
+
+                dataFlow.forEachKilled(op, true, unblockProc);
+                dataFlow.forEachKilled(op, true, killProc);
+
+                curOpId = -1;
+            }
+
+            assert endLocationsFor(block) == null;
+            setEndLocationsFor(block, curLocations);
+
+            logCurrentState();
+            Debug.log("end block %s", block);
+        }
+
+        moveResolver.finish();
+        Debug.log("==== end linear scan allocation ====");
+    }
+
+    private CiValue killNonLive(CiValue value) {
+        assert isLocation(value);
+        if (!curLiveIn.get(asLocation(value).variable.index)) {
+            return null;
+
+        } else if (isAllocatableRegister(asLocation(value).location)) {
+            int regNum = asRegister(asLocation(value).location).number;
+            assert curOutRegisterState[regNum] == null;
+            curOutRegisterState[regNum] = value;
+        }
+        return value;
+    }
+
+    private CiValue unblock(CiValue value) {
+        if (isAllocatableRegister(value)) {
+            Debug.log("    unblock register %s", value);
+            int regNum = asRegister(value).number;
+            assert curOutRegisterState[regNum] == value;
+            curOutRegisterState[regNum] = null;
+        }
+        return value;
+    }
+
+    private CiValue kill(CiValue value) {
+        if (isVariable(value)) {
+            Location location = curLocations.get(asVariable(value));
+            Debug.log("    kill location %s", location);
+            if (isRegister(location.location)) {
+                int regNum = asRegister(location.location).number;
+                if (curOutRegisterState[regNum] == location) {
+                    curOutRegisterState[regNum] = null;
+                }
+            }
+            curLocations.clear(asVariable(value));
+        }
+        return value;
+    }
+
+
+    private CiValue block(CiValue value) {
+        if (isAllocatableRegister(value)) {
+            Debug.log("    block %s", value);
+            int regNum = asRegister(value).number;
+            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof Location;
+            curOutRegisterState[regNum] = value;
+        }
+        return value;
+    }
+
+    private void spillCallerSaveRegisters() {
+        Debug.log("    spill caller save registers in curInRegisterState %s", Arrays.toString(curInRegisterState));
+        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
+            CiValue in = curInRegisterState[reg.number];
+            if (in != null && isLocation(in)) {
+                spill(asLocation(in));
+            }
+        }
+    }
+
+    private CiValue recordUse(CiValue value) {
+        if (isVariable(value)) {
+            assert lastUseFor(asVariable(value)) <= curOpId;
+            setLastUseFor(asVariable(value), curOpId);
+
+        }
+        return value;
+    }
+
+    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Input || mode == OperandMode.Alive;
+        if (isVariable(value)) {
+            // State values are not recorded beforehand because it does not matter if they are spilled. Still, it is necessary to record them as used now.
+            recordUse(value);
+
+            Location curLoc = curLocations.get(asVariable(value));
+            if (isStackSlot(curLoc.location) && flags.contains(OperandFlag.Stack)) {
+                Debug.log("    use %s %s: use current stack slot %s", mode, value, curLoc.location);
+                return curLoc;
+            }
+            if (isRegister(curLoc.location)) {
+                int regNum = asRegister(curLoc.location).number;
+                assert curInRegisterState[regNum] == curLoc;
+                if (mode == OperandMode.Input || curOutRegisterState[regNum] == curLoc) {
+                    Debug.log("    use %s %s: use current register %s", mode, value, curLoc.location);
+                    return curLoc;
+                }
+            }
+
+            Debug.log("    use %s %s", mode, value);
+
+            Location newLoc = allocateRegister(asVariable(value), mode, flags);
+            if (newLoc != curLoc) {
+                moveResolver.add(curLoc, newLoc);
+            }
+            return newLoc;
+        } else {
+            assert !isAllocatableRegister(value) || curInRegisterState[asRegister(value).number] == value;
+        }
+        return value;
+    }
+
+    private static final EnumSet<OperandFlag> SPILL_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+
+    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Temp || mode == OperandMode.Output;
+        if (isVariable(value)) {
+            Debug.log("    def %s %s", mode, value);
+            assert curLocations.get(asVariable(value)) == null;
+
+            Location newLoc = allocateRegister(asVariable(value), mode, flags);
+            return newLoc;
+        }
+        return value;
+    }
+
+
+    private void fixupEvicted() {
+        for (int i = 0; i < curInRegisterState.length; i++) {
+            CiValue in = curInRegisterState[i];
+            CiValue out = curOutRegisterState[i];
+
+            if (in != null && in != out && isLocation(in) && curLocations.get(asLocation(in).variable) == in) {
+                Debug.log("    %s was evicted by %s, need to allocate new location", in, out);
+                Location oldLoc = asLocation(in);
+                Location newLoc = allocateRegister(oldLoc.variable, OperandMode.Alive, SPILL_FLAGS);
+                assert oldLoc != newLoc;
+                moveResolver.add(oldLoc, newLoc);
+            }
+
+
+        }
+    }
+
+
+    private Location allocateRegister(final Variable variable, OperandMode mode, EnumSet<OperandFlag> flags) {
+//        if (flags.contains(OperandFlag.RegisterHint)) {
+//            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
+//                @Override
+//                public CiValue doValue(CiValue registerHint) {
+//                    Debug.log("      registerHint %s", registerHint);
+//                    CiRegister hint = null;
+//                    if (isRegister(registerHint)) {
+//                        hint = asRegister(registerHint);
+//                    } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
+//                        hint = asRegister(asLocation(registerHint).location);
+//                    }
+//                    if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) {
+//                        return selectRegister(hint, variable, inRegisterState, outRegisterState);
+//                    }
+//                    return null;
+//                }
+//            });
+//
+//            if (result != null) {
+//                return asLocation(result);
+//            }
+//        }
+//
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
+
+        Location bestSpillCandidate = null;
+        for (CiRegister reg : availableRegs) {
+            if (isFree(reg, mode)) {
+                return selectRegister(reg, variable, mode);
+            } else {
+                Location spillCandidate = spillCandidate(reg);
+                if (betterSpillCandidate(spillCandidate, bestSpillCandidate)) {
+                    bestSpillCandidate = spillCandidate;
+                }
+            }
+        }
+
+        if (flags.contains(OperandFlag.Stack) && betterSpillCandidate(curLocations.get(variable), bestSpillCandidate)) {
+            return selectSpillSlot(variable);
+        }
+
+        if (bestSpillCandidate == null) {
+            if (curPhiDefs) {
+                return selectSpillSlot(variable);
+            }
+
+            // This should not happen as long as all LIR instructions have fulfillable register constraints. But be safe in product mode and bail out.
+            assert false;
+            throw new CiBailout("No register available");
+        }
+
+        spill(bestSpillCandidate);
+
+        return selectRegister(asRegister(bestSpillCandidate.location), variable, mode);
+    }
+
+    private void spill(Location value) {
+        Location newLoc = spillLocation(value.variable);
+        Debug.log("      spill %s to %s", value, newLoc);
+        if (!curPhiDefs) {
+            moveResolver.add(value, newLoc);
+        }
+        curLocations.put(newLoc);
+
+        CiRegister reg = asRegister(value.location);
+        assert curInRegisterState[reg.number] == value;
+        curInRegisterState[reg.number] = null;
+        if (curOutRegisterState[reg.number] == value) {
+            curOutRegisterState[reg.number] = null;
+        }
+    }
+
+    private boolean isFree(CiRegister reg, OperandMode mode) {
+        switch (mode) {
+            case Input:  return curInRegisterState[reg.number] == null;
+            case Alive:  return curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null;
+            case Temp:   return curOutRegisterState[reg.number] == null;
+            case Output: return curOutRegisterState[reg.number] == null;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private Location spillCandidate(CiRegister reg) {
+        CiValue in = curInRegisterState[reg.number];
+        CiValue out = curOutRegisterState[reg.number];
+        if (in == out && in != null && isLocation(in) && lastUseFor(asLocation(in).variable) < curOpId) {
+            return asLocation(in);
+        }
+        return null;
+    }
+
+    private boolean betterSpillCandidate(Location loc, Location compare) {
+        if (loc == null) {
+            return false;
+        }
+        if (compare == null) {
+            return true;
+        }
+        if (canonicalSpillLocations.get(loc.variable) != null && canonicalSpillLocations.get(compare.variable) == null) {
+            return true;
+        }
+        return dataFlow.definition(loc.variable) < dataFlow.definition(compare.variable);
+    }
+
+    private Location spillLocation(Variable variable) {
+        Location result = canonicalSpillLocations.get(variable);
+        if (result == null) {
+            result = new Location(variable, frameMap.allocateSpillSlot(variable.kind));
+            canonicalSpillLocations.put(result);
+        }
+        return result;
+    }
+
+    private Location selectRegister(CiRegister reg, Variable variable, OperandMode mode) {
+        assert isFree(reg, mode);
+
+        Location loc = new Location(variable, reg.asValue(variable.kind));
+        if (mode == OperandMode.Input || mode == OperandMode.Alive) {
+            curInRegisterState[reg.number] = loc;
+        }
+        curOutRegisterState[reg.number] = loc;
+        curLocations.put(loc);
+        recordUse(variable);
+
+        Debug.log("      selected register %s", loc);
+        return loc;
+    }
+
+    private Location selectSpillSlot(Variable variable) {
+        Location loc = spillLocation(variable);
+        curLocations.put(loc);
+        recordUse(variable);
+
+        Debug.log("      selected spill slot %s", loc);
+        return loc;
+    }
+
+    private boolean checkInputState(final Block block) {
+        final BitSet liveState = new BitSet();
+        curLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                liveState.set(asLocation(value).variable.index);
+
+                for (Block pred : block.getPredecessors()) {
+                    LocationMap predState = endLocationsFor(pred);
+                    if (predState != null) {
+                        assert predState.get(asLocation(value).variable) != null;
+                    } else {
+                        assert block.isLoopHeader();
+                    }
+                }
+                return value;
+            }
+        });
+        assert liveState.equals(curLiveIn);
+        return true;
+    }
+
+
+    private String logCurrentState() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("  current lcoations: ");
+        curLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                sb.append(value).append(" ");
+                return value;
+            }
+        });
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,129 @@
+/*
+ * 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.alloc.simple;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public abstract class ResolveDataFlow {
+    public final LIR lir;
+    public final MoveResolver moveResolver;
+    public final DataFlowAnalysis dataFlow;
+
+    public ResolveDataFlow(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
+        this.lir = lir;
+        this.moveResolver = moveResolver;
+        this.dataFlow = dataFlow;
+    }
+
+    private LocationMap curFromLocations;
+
+    public void execute() {
+        ValueProcedure locMappingProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return locMapping(value); } };
+
+        Debug.log("==== start resolve data flow ====");
+        for (Block toBlock : lir.linearScanOrder()) {
+            PhiLabelOp phiDefs = null;
+            if (toBlock.lir.get(0) instanceof PhiLabelOp) {
+                phiDefs = (PhiLabelOp) toBlock.lir.get(0);
+            }
+
+            for (Block fromBlock : toBlock.getPredecessors()) {
+                Debug.log("start edge %s -> %s", fromBlock, toBlock);
+                findInsertPos(fromBlock, toBlock);
+
+                LocationMap toLocations = locationsForBlockBegin(toBlock);
+                curFromLocations = locationsForBlockEnd(fromBlock);
+                if (toLocations != curFromLocations) {
+                    toLocations.forEachLocation(locMappingProc);
+                }
+
+                if (phiDefs != null) {
+                    PhiJumpOp phiInputs = (PhiJumpOp) fromBlock.lir.get(fromBlock.lir.size() - 1);
+                    phiMapping(phiInputs.getPhiInputs(), phiDefs.getPhiDefinitions());
+                    phiInputs.markResolved();
+                }
+
+                moveResolver.resolve();
+                Debug.log("end edge %s -> %s", fromBlock, toBlock);
+            }
+
+            if (phiDefs != null) {
+                // Phi functions are resolved with moves now, so delete them.
+                phiDefs.markResolved();
+            }
+        }
+        moveResolver.finish();
+        Debug.log("==== end resolve data flow ====");
+    }
+
+    private CiValue locMapping(CiValue value) {
+        Location to = asLocation(value);
+        Location from = curFromLocations.get(to.variable);
+        if (value != from && from != null) {
+            moveResolver.add(from, to);
+        }
+        return value;
+    }
+
+    private void phiMapping(CiValue[] inputs, CiValue[] outputs) {
+        assert inputs.length == outputs.length;
+        for (int i = 0; i < inputs.length; i++) {
+            if (inputs[i] != outputs[i]) {
+                moveResolver.add(inputs[i], asLocation(outputs[i]));
+            }
+        }
+    }
+
+    private void findInsertPos(Block fromBlock, Block toBlock) {
+        assert fromBlock.getSuccessors().contains(toBlock) && toBlock.getPredecessors().contains(fromBlock);
+
+        if (fromBlock.numberOfSux() == 1) {
+            List<LIRInstruction> instructions = fromBlock.lir;
+            LIRInstruction instr = instructions.get(instructions.size() - 1);
+            assert instr instanceof StandardOp.JumpOp : "block does not end with an unconditional jump";
+            moveResolver.init(instructions, instructions.size() - 1);
+            Debug.log("  insert at end of %s before %d", fromBlock, instructions.size() - 1);
+
+        } else if (toBlock.numberOfPreds() == 1) {
+            moveResolver.init(toBlock.lir, 1);
+            Debug.log("  insert at beginning of %s before %d", toBlock, 1);
+
+        } else {
+            GraalInternalError.shouldNotReachHere("Critical edge not split");
+        }
+    }
+
+    protected abstract LocationMap locationsForBlockBegin(Block block);
+    protected abstract LocationMap locationsForBlockEnd(Block block);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,466 @@
+/*
+ * 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.alloc.simple;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public class SpillAllAllocator {
+    private final LIR lir;
+    private final FrameMap frameMap;
+
+    private final DataFlowAnalysis dataFlow;
+
+    public SpillAllAllocator(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+
+        this.dataFlow = new DataFlowAnalysis(lir, frameMap.registerConfig);
+        this.blockLocations = new LocationMap[lir.linearScanOrder().size()];
+        this.moveResolver = new MoveResolverImpl(lir, frameMap);
+    }
+
+    private class MoveResolverImpl extends MoveResolver {
+        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected CiValue scratchRegister(Variable spilled) {
+            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
+            for (CiRegister reg : availableRegs) {
+                if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
+                    return reg.asValue(spilled.kind);
+                }
+            }
+            throw new CiBailout("No register found");
+        }
+    }
+
+    private class ResolveDataFlowImpl extends ResolveDataFlow {
+        public ResolveDataFlowImpl(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
+            super(lir, moveResolver, dataFlow);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockBegin(Block block) {
+            assert block.numberOfPreds() > 0 && block.getDominator() != null;
+            return locationsFor(block.getDominator());
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return locationsFor(block);
+        }
+    }
+
+    private class AssignRegistersImpl extends AssignRegisters {
+        public AssignRegistersImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return locationsFor(block);
+        }
+    }
+
+
+    private int maxRegisterNum() {
+        return frameMap.target.arch.registers.length;
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+
+    private final LocationMap[] blockLocations;
+
+    private LocationMap locationsFor(Block block) {
+        return blockLocations[block.getId()];
+    }
+    private void setLocationsFor(Block block, LocationMap locations) {
+        blockLocations[block.getId()] = locations;
+    }
+
+    private MoveResolver moveResolver;
+    private LocationMap curStackLocations;
+    private LocationMap curRegisterLocations;
+    private Object[] curInRegisterState;
+    private Object[] curOutRegisterState;
+    private BitSet curLiveIn;
+    private LIRInstruction curInstruction;
+
+    public void execute() {
+        assert LIRVerifier.verify(true, lir, frameMap);
+
+        dataFlow.execute();
+        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
+
+        allocate();
+
+        IntervalPrinter.printAfterAllocation("After spill all allocation", lir, frameMap.registerConfig, dataFlow, blockLocations);
+
+        ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
+        resolveDataFlow.execute();
+        frameMap.finish();
+
+        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockLocations);
+        assert RegisterVerifier.verify(lir, frameMap);
+
+        AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
+        assignRegisters.execute();
+
+        Debug.dump(lir, "After register asignment");
+        assert LIRVerifier.verify(false, lir, frameMap);
+    }
+
+    private void allocate() {
+        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
+        ValueProcedure killBeginProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, false); } };
+        ValueProcedure killEndProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, true); } };
+        ValueProcedure killLocationProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killLocation(value); } };
+        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
+        ValueProcedure loadProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return load(value, mode, flags); } };
+        ValueProcedure spillProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return spill(value, mode, flags); } };
+        ValueProcedure useSlotProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return useSlot(value); } };
+
+        Debug.log("==== start spill all allocation ====");
+        curInRegisterState = new Object[maxRegisterNum()];
+        curOutRegisterState = new Object[maxRegisterNum()];
+        curRegisterLocations = new LocationMap(lir.numVariables());
+        for (Block block : lir.linearScanOrder()) {
+            Debug.log("start block %s %s", block, block.getLoop());
+            assert checkEmpty(curOutRegisterState);
+
+            if (block.getDominator() != null) {
+                LocationMap dominatorState = locationsFor(block.getDominator());
+                curStackLocations = new LocationMap(dominatorState);
+                // Clear out all variables that are not live at the begin of this block
+                curLiveIn = dataFlow.liveIn(block);
+                curStackLocations.forEachLocation(killNonLiveProc);
+                assert checkInputState(block);
+            } else {
+                curStackLocations = new LocationMap(lir.numVariables());
+            }
+            Debug.log(logCurrentState());
+
+            for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) {
+                LIRInstruction op = block.lir.get(opIdx);
+                curInstruction = op;
+                Debug.log("  op %d %s", op.id(), op);
+
+                assert curRegisterLocations.checkEmpty();
+
+                System.arraycopy(curOutRegisterState, 0, curInRegisterState, 0, curOutRegisterState.length);
+
+                // Block fixed registers that are defined by this instruction, so that they are no longer available for normal allocation.
+                op.forEachTemp(blockProc);
+                op.forEachOutput(blockProc);
+
+                moveResolver.init(block.lir, opIdx);
+                // Process Alive before Input because they are more restricted and the same variable can be Alive and Input.
+                op.forEachAlive(loadProc);
+                op.forEachInput(loadProc);
+                moveResolver.resolve();
+                op.forEachState(useSlotProc);
+
+                dataFlow.forEachKilled(op, false, killBeginProc);
+                assert !op.hasCall() || checkNoCallerSavedRegister() : "caller saved register in use accross call site";
+
+                moveResolver.init(block.lir, opIdx + 1);
+                op.forEachTemp(spillProc);
+                op.forEachOutput(spillProc);
+                moveResolver.resolve();
+
+                dataFlow.forEachKilled(op, true, killEndProc);
+                curRegisterLocations.forEachLocation(killLocationProc);
+
+                assert curRegisterLocations.checkEmpty();
+                curInstruction = null;
+            }
+            assert checkEmpty(curOutRegisterState);
+            assert locationsFor(block) == null;
+            setLocationsFor(block, curStackLocations);
+
+            logCurrentState();
+            Debug.log("end block %s", block);
+        }
+
+        moveResolver.finish();
+        Debug.log("==== end spill all allocation ====");
+    }
+
+    private CiValue killNonLive(CiValue value) {
+        assert isLocation(value);
+        if (!curLiveIn.get(asLocation(value).variable.index)) {
+            return null;
+        }
+        return value;
+    }
+
+    private CiValue kill(CiValue value, boolean end) {
+        if (isVariable(value)) {
+            Debug.log("    kill variable %s", value);
+
+            Variable variable = asVariable(value);
+            curStackLocations.clear(variable);
+
+            Location loc = curRegisterLocations.get(variable);
+            if (loc != null) {
+                killLocation(loc);
+                curRegisterLocations.clear(variable);
+
+                Debug.log("      location %s", loc);
+                assert isAllocatableRegister(loc.location);
+
+                int regNum = asRegister(loc.location).number;
+                if (curOutRegisterState[regNum] == loc) {
+                    curOutRegisterState[regNum] = null;
+                }
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            Debug.log("    kill register %s", value);
+            int regNum = asRegister(value).number;
+            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof LIRInstruction && curInstruction != null;
+
+            if (end || curOutRegisterState[regNum] != curInstruction) {
+                curOutRegisterState[regNum] = null;
+            }
+
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return value;
+    }
+
+    private CiValue killLocation(CiValue value) {
+        Debug.log("    kill location %s", value);
+        assert isAllocatableRegister(asLocation(value).location);
+
+        int regNum = asRegister(asLocation(value).location).number;
+        if (curOutRegisterState[regNum] == value) {
+            curOutRegisterState[regNum] = null;
+        }
+        return null;
+    }
+
+    private CiValue block(CiValue value) {
+        if (isAllocatableRegister(value)) {
+            Debug.log("    block %s", value);
+            int regNum = asRegister(value).number;
+            assert curInstruction != null;
+            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof LIRInstruction;
+            curOutRegisterState[regNum] = curInstruction;
+        }
+        return value;
+    }
+
+    private CiValue load(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Input || mode == OperandMode.Alive;
+        if (flags.contains(OperandFlag.Stack)) {
+            return useSlot(value);
+        }
+        if (isVariable(value)) {
+            Debug.log("    load %s", value);
+            Location regLoc = curRegisterLocations.get(asVariable(value));
+            if (regLoc != null) {
+                // This variable has already been processed before.
+                Debug.log("      found location %s", regLoc);
+            } else {
+                regLoc = allocateRegister(asVariable(value), curInRegisterState, mode == OperandMode.Alive ? curOutRegisterState : null, mode, flags);
+                Location stackLoc = curStackLocations.get(asVariable(value));
+                assert stackLoc != null;
+                moveResolver.add(stackLoc, regLoc);
+            }
+            return regLoc;
+        } else {
+            assert !isAllocatableRegister(value) || curInRegisterState[asRegister(value).number] instanceof LIRInstruction;
+            return value;
+        }
+    }
+
+    private CiValue spill(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Temp || mode == OperandMode.Output;
+        if (flags.contains(OperandFlag.Stack)) {
+            return defSlot(value);
+        }
+        if (isVariable(value)) {
+            Debug.log("    spill %s", value);
+            assert curStackLocations.get(asVariable(value)) == null;
+            Location regLoc = allocateRegister(asVariable(value), null, curOutRegisterState, mode, flags);
+            if (mode == OperandMode.Output) {
+                Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
+                curStackLocations.put(stackLoc);
+                moveResolver.add(regLoc, stackLoc);
+            }
+            return regLoc;
+        } else {
+            assert !isAllocatableRegister(value) || curOutRegisterState[asRegister(value).number] == curInstruction && curInstruction != null;
+            return value;
+        }
+    }
+
+    private CiValue useSlot(CiValue value) {
+        if (isVariable(value)) {
+            Debug.log("    useSlot %s", value);
+            Location stackLoc = curStackLocations.get(asVariable(value));
+            assert stackLoc != null;
+            Debug.log("      slot %s", stackLoc);
+            return stackLoc;
+        } else {
+            return value;
+        }
+    }
+
+    private CiValue defSlot(CiValue value) {
+        if (isVariable(value)) {
+            Debug.log("    assignSlot %s", value);
+            Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
+            assert curStackLocations.get(asVariable(value)) == null;
+            curStackLocations.put(stackLoc);
+            Debug.log("      slot %s", stackLoc);
+            return stackLoc;
+        } else {
+            return value;
+        }
+    }
+
+    private Location allocateRegister(final Variable variable, final Object[] inRegisterState, final Object[] outRegisterState, OperandMode mode, EnumSet<OperandFlag> flags) {
+        if (flags.contains(OperandFlag.RegisterHint)) {
+            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
+                @Override
+                public CiValue doValue(CiValue registerHint) {
+                    Debug.log("      registerHint %s", registerHint);
+                    CiRegister hint = null;
+                    if (isRegister(registerHint)) {
+                        hint = asRegister(registerHint);
+                    } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
+                        hint = asRegister(asLocation(registerHint).location);
+                    }
+                    if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) {
+                        return selectRegister(hint, variable, inRegisterState, outRegisterState);
+                    }
+                    return null;
+                }
+            });
+
+            if (result != null) {
+                return asLocation(result);
+            }
+        }
+
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
+
+        for (CiRegister reg : availableRegs) {
+            if (isFree(reg, inRegisterState, outRegisterState)) {
+                return selectRegister(reg, variable, inRegisterState, outRegisterState);
+            }
+
+        }
+        throw new CiBailout("No register found");
+    }
+
+    private static boolean isFree(CiRegister reg, Object[] inRegisterState, Object[] outRegisterState) {
+        return (inRegisterState == null || inRegisterState[reg.number] == null) && (outRegisterState == null || outRegisterState[reg.number] == null);
+    }
+
+    private Location selectRegister(CiRegister reg, Variable variable, Object[] inRegisterState, Object[] outRegisterState) {
+        Location loc = new Location(variable, reg.asValue(variable.kind));
+        if (inRegisterState != null) {
+            inRegisterState[reg.number] = loc;
+        }
+        if (outRegisterState != null) {
+            outRegisterState[reg.number] = loc;
+        }
+        assert curRegisterLocations.get(variable) == null;
+        curRegisterLocations.put(loc);
+        Debug.log("      selected register %s", loc);
+        return loc;
+    }
+
+    private boolean checkInputState(final Block block) {
+        final BitSet liveState = new BitSet();
+        curStackLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                liveState.set(asLocation(value).variable.index);
+
+                for (Block pred : block.getPredecessors()) {
+                    LocationMap predState = locationsFor(pred);
+                    if (predState != null) {
+                        assert predState.get(asLocation(value).variable) == value;
+                    } else {
+                        assert block.isLoopHeader();
+                    }
+                }
+                return value;
+            }
+        });
+        assert liveState.equals(curLiveIn);
+        return true;
+    }
+
+    private boolean checkNoCallerSavedRegister() {
+        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
+            assert curOutRegisterState[reg.number] == null || curOutRegisterState[reg.number] == curInstruction : "caller saved register in use accross call site";
+        }
+        return true;
+    }
+
+    private static boolean checkEmpty(Object[] array) {
+        for (Object o : array) {
+            assert o == null;
+        }
+        return true;
+    }
+
+
+    private String logCurrentState() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("  curVariableLocations: ");
+        curStackLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                sb.append(value).append(" ");
+                return value;
+            }
+        });
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,274 @@
+/*
+ * 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.alloc.util;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.alloc.simple.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public final class IntervalPrinter {
+
+    public static void printBeforeAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
+        if (Debug.isDumpEnabled()) {
+            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, null);
+            Debug.dump(lir, label);
+            Debug.dump(printer.execute(), label);
+        }
+    }
+
+    public static void printAfterAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+        if (Debug.isDumpEnabled()) {
+            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, blockEndLocations);
+            Debug.dump(lir, label);
+            Debug.dump(printer.execute(), label);
+        }
+    }
+
+
+    public static class Range {
+        public final int from;
+        public final int to;
+
+        public Range(int from, int to) {
+            this.from = from;
+            this.to = to;
+        }
+    }
+
+    public static class UsePosition {
+        public final int pos;
+        public final String kind;
+
+        public UsePosition(int pos, String kind) {
+            this.pos = pos;
+            this.kind = kind;
+        }
+    }
+
+    public static class Interval {
+        public final String name;
+        public final String description;
+        public final String variable;
+        public final String type;
+        public final List<Range> ranges;
+        public final List<UsePosition> uses;
+
+        protected final int orderNum;
+        protected int lastTo;
+
+        public Interval(int orderNum, String name, String description, String variable, String type) {
+            this.orderNum = orderNum;
+            this.name = name;
+            this.description = description;
+            this.variable = variable;
+            this.type = type;
+            this.ranges = new ArrayList<>();
+            this.uses = new ArrayList<>();
+        }
+    }
+
+
+    private final LIR lir;
+    private final RiRegisterConfig registerConfig;
+    private final DataFlowAnalysis dataFlow;
+    private final LocationMap[] blockEndLocations;
+    private final Variable[] variables;
+    private final Map<String, Interval> intervals;
+
+    private IntervalPrinter(LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+        this.lir = lir;
+        this.registerConfig = registerConfig;
+        this.dataFlow = dataFlow;
+        this.blockEndLocations = blockEndLocations;
+        this.variables = new Variable[lir.numVariables()];
+        this.intervals = new HashMap<>();
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+    private int curOpId;
+    private String curUseKind;
+
+    public Interval[] execute() {
+        ValueProcedure varProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return var(value); } };
+
+        for (Block block : lir.linearScanOrder()) {
+            for (LIRInstruction op : block.lir) {
+                op.forEachOutput(varProc);
+            }
+        }
+
+        ValueProcedure useProc = new ValueProcedure() { @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, flags); } };
+
+        intervals.put("call", new Interval(-2, "call", "", "call", "hasCall"));
+        intervals.put("st", new Interval(-1, "st", "", "st", "hasState"));
+
+        for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
+            Block block = lir.linearScanOrder().get(i);
+
+            curOpId = block.getLastLirInstructionId() + 2;
+            for (Block sux : block.getSuccessors()) {
+                BitSet suxIn = dataFlow.liveIn(sux);
+                for (int idx = suxIn.nextSetBit(0); idx >= 0; idx = suxIn.nextSetBit(idx + 1)) {
+                    if (blockEndLocations != null) {
+                        out(blockEndLocations[block.getId()].get(variables[idx]));
+                    } else {
+                        out(variables[idx]);
+                    }
+                }
+            }
+
+            for (int j = block.lir.size() - 1; j >= 0; j--) {
+                LIRInstruction op = block.lir.get(j);
+                if (op.id() >= 0) {
+                    curOpId = op.id();
+                } else {
+                    curOpId = (curOpId - 1) | 1;
+                }
+
+                op.forEachOutput(defProc);
+                op.forEachTemp(defProc);
+                op.forEachInput(useProc);
+                op.forEachAlive(useProc);
+                curUseKind = "L";
+                op.forEachState(useProc);
+                curUseKind = null;
+
+                if (op.hasCall()) {
+                    intervals.get("call").ranges.add(new Range(curOpId, curOpId + 1));
+                }
+                if (op.info != null) {
+                    intervals.get("st").ranges.add(new Range(curOpId, curOpId + 1));
+                }
+            }
+
+            for (Interval interval : intervals.values()) {
+                if (interval.lastTo != 0) {
+                    interval.ranges.add(new Range(block.getFirstLirInstructionId(), interval.lastTo));
+                    interval.lastTo = 0;
+                }
+            }
+        }
+
+        Interval[] intervalsArray = intervals.values().toArray(new Interval[0]);
+        Arrays.sort(intervalsArray, new Comparator<Interval>() {
+            @Override
+            public int compare(Interval o1, Interval o2) {
+                return o1.orderNum - o2.orderNum;
+            }
+        });
+        return intervalsArray;
+    }
+
+    public CiValue var(CiValue value) {
+        if (isLocation(value)) {
+            variables[asLocation(value).variable.index] = asLocation(value).variable;
+        } else if (isVariable(value)) {
+            variables[asVariable(value).index] = asVariable(value);
+        }
+        return value;
+    }
+
+    private Interval findInterval(CiValue value) {
+        Interval interval;
+        if (isLocation(value)) {
+            Interval parent = findInterval(asLocation(value).variable);
+            String name = "v" + asLocation(value).variable.index + ":" + asLocation(value).location;
+            String description = isStackSlot(asLocation(value).location) ? "stack" : "";
+            interval = new Interval(asLocation(value).variable.index * 2 + 1001, name, description, parent.name, value.kind.javaName);
+
+        } else if (isVariable(value)) {
+            interval = new Interval(asVariable(value).index * 2 + 1000, value.toString(), "", value.toString(), value.kind.javaName);
+
+        } else if (isAllocatableRegister(value)) {
+            interval = new Interval(asRegister(value).number, asRegister(value).toString(), "", asRegister(value).toString(), "fixed");
+
+        } else {
+            return null;
+        }
+
+        Interval existing = intervals.get(interval.name);
+        if (existing != null) {
+            return existing;
+        }
+        intervals.put(interval.name, interval);
+        return interval;
+    }
+
+    private String useKind(EnumSet<OperandFlag> flags) {
+        if (curUseKind != null) {
+            return curUseKind;
+        } else if (flags.contains(OperandFlag.Stack)) {
+            return "S";
+        } else {
+            return "M";
+        }
+    }
+
+    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        Interval interval = findInterval(value);
+        if (interval != null) {
+            if (interval.uses.size() == 0 || interval.uses.get(interval.uses.size() - 1).pos != curOpId) {
+                interval.uses.add(new UsePosition(curOpId, useKind(flags)));
+            }
+            if (interval.lastTo == 0) {
+                interval.lastTo = curOpId + (mode == OperandMode.Alive ? 1 : 0);
+            }
+        }
+        return value;
+    }
+
+    private CiValue def(CiValue value, EnumSet<OperandFlag> flags) {
+        Interval interval = findInterval(value);
+        if (interval != null) {
+            interval.uses.add(new UsePosition(curOpId, useKind(flags)));
+            if (interval.lastTo == 0) {
+                interval.ranges.add(new Range(curOpId, curOpId + 1));
+            } else {
+                interval.ranges.add(new Range(curOpId, interval.lastTo));
+            }
+            interval.lastTo = 0;
+        }
+        return value;
+    }
+
+    private CiValue out(CiValue value) {
+        Interval interval = findInterval(value);
+        if (interval != null) {
+            interval.lastTo = curOpId;
+        }
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/Location.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * 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.alloc.util;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+
+public class Location extends CiValue {
+    private static final long serialVersionUID = -1786677729152726126L;
+
+    public final Variable variable;
+    public final CiValue location;
+
+    public Location(Variable variable, CiValue location) {
+        super(variable.kind);
+        this.variable = variable;
+        this.location = location;
+
+        assert variable.kind == location.kind;
+    }
+
+    @Override
+    public String toString() {
+        return variable + "[" + location + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/LocationMap.java	Wed Feb 08 19:25:29 2012 -0800
@@ -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.alloc.util;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+
+public class LocationMap {
+    private final Location[] locations;
+
+    public LocationMap(int numVariables) {
+        locations = new Location[numVariables];
+    }
+
+    public LocationMap(LocationMap template) {
+        locations = Arrays.copyOf(template.locations, template.locations.length);
+    }
+
+    public Location get(Variable variable) {
+        assert locations[variable.index] == null || locations[variable.index].variable == variable;
+        return locations[variable.index];
+    }
+
+    public void put(Location location) {
+        locations[location.variable.index] = location;
+    }
+
+    public void clear(Variable variable) {
+        locations[variable.index] = null;
+    }
+
+    public void forEachLocation(ValueProcedure proc) {
+        for (int i = 0; i < locations.length; i++) {
+            if (locations[i] != null) {
+                CiValue newValue = proc.doValue(locations[i], null, null);
+                assert newValue == null || asLocation(newValue).variable == locations[i].variable;
+                locations[i] = (Location) newValue;
+            }
+        }
+    }
+
+    public boolean checkEmpty() {
+        for (int i = 0; i < locations.length; i++) {
+            assert locations[i] == null;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/LocationUtil.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * 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.alloc.util;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+
+public class LocationUtil extends ValueUtil {
+
+    public static boolean isLocation(CiValue value) {
+        assert value != null;
+        return value instanceof Location;
+    }
+
+    public static Location asLocation(CiValue value) {
+        assert value != null;
+        return (Location) value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/MoveResolver.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,342 @@
+/*
+ * 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.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+
+public abstract class MoveResolver {
+    private final LIR lir;
+    private final FrameMap frameMap;
+    private final int[] registersBlocked;
+    private final Map<CiValue, Integer> valuesBlocked;
+    private final List<CiValue> mappingFrom;
+    private final List<Location> mappingTo;
+    private final LIRInsertionBuffer insertionBuffer;
+    private int insertPos;
+
+    public MoveResolver(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+
+        registersBlocked = new int[frameMap.target.arch.registers.length];
+        valuesBlocked = new HashMap<>();
+
+        mappingFrom = new ArrayList<>();
+        mappingTo = new ArrayList<>();
+        insertionBuffer = new LIRInsertionBuffer();
+        insertPos = -1;
+
+        assert checkEmpty();
+    }
+
+    public void init(List<LIRInstruction> newInsertList, int newInsertPos) {
+        assert checkEmpty();
+
+        if (insertionBuffer.lirList() != newInsertList) {
+            // Block changed, so append insertionBuffer because it is bound to a specific block
+            finish();
+            insertionBuffer.init(newInsertList);
+        }
+        insertPos = newInsertPos;
+
+        assert checkValid();
+    }
+
+    public void add(CiValue from, Location to) {
+        assert checkValid();
+        assert isLocation(from) || isConstant(from);
+        assert from != to;
+
+        Debug.log("mr    add mapping from %s to %s", from, to);
+        mappingFrom.add(from);
+        mappingTo.add(to);
+
+        assert checkValid();
+    }
+
+    public boolean hasMappings() {
+        return mappingFrom.size() > 0;
+    }
+
+    public void resolve() {
+        assert checkValid();
+
+        if (mappingFrom.size() == 1) {
+            // If there is only one mapping, it is trivial that this mapping is safe to resolve.
+            Debug.log("mr    resolve  mappings: %d", mappingFrom.size());
+            insertMove(mappingFrom.get(0), mappingTo.get(0));
+            mappingFrom.remove(0);
+            mappingTo.remove(0);
+        } else if (mappingFrom.size() > 1) {
+            Debug.log("mr    resolve  mappings: %d", mappingFrom.size());
+            doResolve();
+        }
+        insertPos = -1;
+
+        assert checkEmpty();
+    }
+
+    public void finish() {
+        assert checkEmpty();
+
+        if (insertionBuffer.initialized()) {
+            insertionBuffer.finish();
+        }
+
+        assert !insertionBuffer.initialized() : "must be uninitialized now";
+        assert checkEmpty();
+    }
+
+
+    private void doResolve() {
+        // Block all registers and stack slots that are used as inputs of a move.
+        // When a register is blocked, no move to this register is emitted.
+        // This is necessary for detecting cycles in moves.
+        for (CiValue from : mappingFrom) {
+            block(from);
+        }
+
+        while (mappingFrom.size() > 0) {
+            boolean processed = false;
+            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
+                CiValue from = mappingFrom.get(i);
+                Location to = mappingTo.get(i);
+
+                if (safeToProcessMove(from, to)) {
+                    insertMove(from, to);
+                    unblock(from);
+                    mappingFrom.remove(i);
+                    mappingTo.remove(i);
+                    processed = true;
+                }
+            }
+
+            if (!processed) {
+                // No move could be processed because there is a cycle in the move list
+                // (e.g., r1 -> r2, r2 -> r1), so one location must be spilled.
+                spill();
+            }
+        }
+    }
+
+    private void spill() {
+        Location spillCandidate = null;
+        int exchangeCandidate = -1;
+        int exchangeOther = -1;
+
+        for (int i = mappingFrom.size() - 1; i >= 0; i--) {
+            CiValue from = mappingFrom.get(i);
+            Location to = mappingTo.get(i);
+            assert !safeToProcessMove(from, to) : "would not be in this code otherwise";
+
+            if (isConstant(from)) {
+                continue;
+            }
+            CiValue fromLoc = asLocation(from).location;
+
+            // Check if we can insert an exchange to save us from spilling.
+            if (isRegister(fromLoc) && isRegister(to) && asRegister(fromLoc) != asRegister(to) && blockedCount(to) == 1) {
+                for (int j = mappingFrom.size() - 1; j >= 0; j--) {
+                    CiValue possibleOther = mappingFrom.get(j);
+                    if (isLocation(possibleOther)) {
+                        if (asLocation(possibleOther).location == to.location) {
+                            assert exchangeCandidate == -1 : "must not find twice because of blocked check above";
+                            exchangeCandidate = i;
+                            exchangeOther = j;
+                        } else if (i != j && asLocation(possibleOther).location == fromLoc) {
+                            // From is read multiple times, so exchange would be too complicated.
+                            exchangeCandidate = -1;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (exchangeCandidate != -1) {
+                // Already found a result, no need to search further
+                break;
+            }
+            if (spillCandidate == null || isStackSlot(spillCandidate.location)) {
+                // this interval cannot be processed now because target is not free
+                spillCandidate = asLocation(from);
+            }
+        }
+
+        if (exchangeCandidate != -1) {
+            Location from = asLocation(mappingFrom.get(exchangeCandidate));
+            Location to = mappingTo.get(exchangeCandidate);
+            Location other = asLocation(mappingFrom.get(exchangeOther));
+
+            Location newOther = new Location(other.variable, from.variable);
+            mappingFrom.set(exchangeOther, newOther);
+
+            insertExchange(newOther, to);
+            unblock(to);
+            mappingFrom.remove(exchangeCandidate);
+            mappingTo.remove(exchangeCandidate);
+
+        } else {
+            assert spillCandidate != null : "no location for spilling found";
+
+            Location spillLocation = new Location(spillCandidate.variable, frameMap.allocateSpillSlot(spillCandidate.kind));
+            insertMove(spillCandidate, spillLocation);
+
+            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
+                if (mappingFrom.get(i) == spillCandidate) {
+                    mappingFrom.set(i, spillLocation);
+                    unblock(spillCandidate);
+                    block(spillLocation);
+                }
+            }
+            assert blockedCount(spillCandidate) == 0 : "register must be unblocked after spilling";
+        }
+    }
+
+    private void block(CiValue value) {
+        if (isLocation(value)) {
+            CiValue location = asLocation(value).location;
+            if (isRegister(location)) {
+                registersBlocked[asRegister(location).number]++;
+            } else {
+                Integer count = valuesBlocked.get(location);
+                valuesBlocked.put(location, count == null ? 1 : count + 1);
+            }
+        }
+    }
+
+    private void unblock(CiValue value) {
+        if (isLocation(value)) {
+            assert blockedCount(asLocation(value)) > 0;
+            CiValue location = asLocation(value).location;
+            if (isRegister(location)) {
+                registersBlocked[asRegister(location).number]--;
+            } else {
+                Integer count = valuesBlocked.remove(location);
+                if (count > 1) {
+                    valuesBlocked.put(location, count - 1);
+                }
+            }
+        }
+    }
+
+    private int blockedCount(Location value) {
+        CiValue location = asLocation(value).location;
+        if (isRegister(location)) {
+            return registersBlocked[asRegister(location).number];
+        } else {
+            Integer count = valuesBlocked.get(location);
+            return count == null ? 0 : count;
+        }
+    }
+
+    private boolean safeToProcessMove(CiValue from, Location to) {
+        int count = blockedCount(to);
+        return count == 0 || (count == 1 && isLocation(from) && asLocation(from).location == to.location);
+    }
+
+    private void insertExchange(Location from, Location to) {
+        Debug.log("mr      XCHG %s, %s", from, to);
+        // TODO create XCHG instruction and use it here
+        insertionBuffer.append(insertPos, null);
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void insertMove(CiValue src, Location dst) {
+        if (isStackSlot(dst.location) && isLocation(src) && isStackSlot(asLocation(src).location)) {
+            // Move between two stack slots. We need a temporary registers. If the allocator can give
+            // us a free register, we need two moves: src->scratch, scratch->dst
+            // If the allocator cannot give us a free register (it returns a Location in this case),
+            // we need to spill the scratch register first, so we need four moves in total.
+
+            CiValue scratch = scratchRegister(dst.variable);
+
+            Location scratchSaved = null;
+            CiValue scratchRegister = scratch;
+            if (isLocation(scratch)) {
+                scratchSaved = new Location(asLocation(scratch).variable, frameMap.allocateSpillSlot(scratch.kind));
+                insertMove(scratch, scratchSaved);
+                scratchRegister = asLocation(scratch).location;
+            }
+            assert isRegister(scratchRegister);
+
+            Location scratchLocation = new Location(dst.variable, scratchRegister);
+            insertMove(src, scratchLocation);
+            insertMove(scratchLocation, dst);
+
+            if (scratchSaved != null) {
+                insertMove(scratchSaved, asLocation(scratch));
+            }
+
+        } else {
+            Debug.log("mr      MOV %s -> %s", src, dst);
+            insertionBuffer.append(insertPos, lir.spillMoveFactory.createMove(dst,  src));
+        }
+    }
+
+    /**
+     * Provides a register that can be used by the move resolver. If the returned value is a
+     * {@link CiRegisterValue}, the register can be overwritten without precautions. If the
+     * returned value is a {@link Location}, it needs to be spilled and rescued itself.
+     */
+    protected abstract CiValue scratchRegister(Variable spilled);
+
+    private boolean checkEmpty() {
+        assert insertPos == -1;
+        assert mappingFrom.size() == 0 && mappingTo.size() == 0;
+        for (int registerBlocked : registersBlocked) {
+            assert registerBlocked == 0;
+        }
+        assert valuesBlocked.size() == 0;
+        return true;
+    }
+
+    private boolean checkValid() {
+        assert insertPos != -1;
+        for (int registerBlocked : registersBlocked) {
+            assert registerBlocked == 0;
+        }
+        assert mappingFrom.size() == mappingTo.size();
+        assert insertionBuffer.initialized() && insertPos != -1;
+
+        for (int i = 0; i < mappingTo.size(); i++) {
+            CiValue from = mappingFrom.get(i);
+            Location to = mappingTo.get(i);
+
+            assert from.kind.stackKind() == to.kind;
+
+            for (int j = i + 1; j < mappingTo.size(); j++) {
+                Location otherTo = mappingTo.get(j);
+                assert to != otherTo && to.variable != otherTo.variable && to.location != otherTo.location : "Cannot write to same location twice";
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,248 @@
+/*
+ * 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.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public final class RegisterVerifier {
+    private final FrameMap frameMap;
+
+    /**
+     * All blocks that must be processed.
+     */
+    private final List<Block> workList;
+
+    /**
+     * Saved information of previous check.
+     * <br>
+     * State mapping: mapping from registers and stack slots ({@link CiRegister} and {@link Integer} stack slot offsets) to the
+     * value that is currently contained in there ({@link Location} for operands that were variables; {@link CiRegisterValue} or
+     * {@link CiStackSlot} for operands that used fixed registers or stack slots).
+     */
+    private final Map<Object, CiValue>[] blockStates;
+
+    private void addToWorkList(Block block) {
+        if (!workList.contains(block)) {
+            workList.add(block);
+        }
+    }
+
+    private Map<Object, CiValue> stateFor(Block block) {
+        return blockStates[block.getId()];
+    }
+
+    private void setStateFor(Block block, Map<Object, CiValue> savedState) {
+        blockStates[block.getId()] = savedState;
+    }
+
+    private static Map<Object, CiValue> copy(Map<Object, CiValue> inputState) {
+        return new HashMap<>(inputState);
+    }
+
+    public static boolean verify(LIR lir, FrameMap frameMap) {
+        RegisterVerifier verifier = new RegisterVerifier(lir, frameMap);
+        verifier.verify(lir.cfg.getStartBlock());
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    private RegisterVerifier(LIR lir, FrameMap frameMap) {
+        this.frameMap = frameMap;
+        this.workList = new LinkedList<>();
+        this.blockStates = new Map[lir.linearScanOrder().size()];
+    }
+
+    private Map<Object, CiValue> curInputState;
+
+    private void verify(Block startBlock) {
+        ValueProcedure useProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, flags); } };
+        ValueProcedure tempProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return temp(value); } };
+        ValueProcedure outputProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return output(value); } };
+
+        curInputState = new HashMap<>();
+        setStateFor(startBlock, curInputState);
+        addToWorkList(startBlock);
+
+        Debug.log("==== start verify register allocation ====");
+        do {
+            Block block = workList.remove(0);
+
+            // Must copy state because it is modified.
+            curInputState = copy(stateFor(block));
+            Debug.log("start block %s %s", block, block.getLoop());
+            Debug.log(logCurrentState());
+
+            for (LIRInstruction op : block.lir) {
+                Debug.log("  op %d %s", op.id(), op);
+
+                op.forEachInput(useProc);
+                if (op.hasCall()) {
+                    invalidateRegisters();
+                }
+                op.forEachAlive(useProc);
+                op.forEachState(useProc);
+                op.forEachTemp(tempProc);
+                op.forEachOutput(outputProc);
+            }
+
+            for (Block succ : block.getSuccessors()) {
+                processSuccessor(succ);
+            }
+
+            Debug.log("end block %s", block);
+        } while (!workList.isEmpty());
+        Debug.log("==== end verify register allocation ====");
+    }
+
+    private void processSuccessor(Block succ) {
+        Map<Object, CiValue> savedState = stateFor(succ);
+        if (savedState == null) {
+            // Block was not processed before, so set initial inputState.
+            Debug.log("  successor %s: initial visit", succ);
+            setStateFor(succ, copy(curInputState));
+            addToWorkList(succ);
+
+        } else {
+            // This block was already processed before.
+            // Check if new inputState is consistent with savedState.
+            Debug.log("  successor %s: state present", succ);
+            Iterator<Map.Entry<Object, CiValue>> iter = savedState.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<Object, CiValue> entry = iter.next();
+                CiValue savedValue = entry.getValue();
+                CiValue inputValue = curInputState.get(entry.getKey());
+
+                if (savedValue != inputValue) {
+                    // Current inputState and previous savedState assume a different value in this register.
+                    // Assume that this register is invalid and remove it from the saved state.
+                    Debug.log("    invalididating %s because it is inconsistent with %s", savedValue, inputValue);
+                    iter.remove();
+                    // Must re-visit this block.
+                    addToWorkList(succ);
+                }
+            }
+        }
+    }
+
+    private void invalidateRegisters() {
+        // Invalidate all caller save registers at calls.
+        Iterator<Object> iter = curInputState.keySet().iterator();
+        while (iter.hasNext()) {
+            Object value1 = iter.next();
+            if (value1 instanceof CiRegister && frameMap.registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) {
+                Debug.log("    remove caller save register %s", value1);
+                iter.remove();
+            }
+        }
+    }
+
+    /**
+     * Gets the mapping key for a value. The key should be as narrow as possible, e.g., it should not
+     * include the kind of the value because we do not want to distinguish between the same register with
+     * different kinds.
+     */
+    private Object key(CiValue value) {
+        if (isLocation(value)) {
+            return key(asLocation(value).location);
+        } else if (isRegister(value)) {
+            return asRegister(value);
+        } else if (isStackSlot(value)) {
+            return Integer.valueOf(frameMap.offsetForStackSlot(asStackSlot(value)));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private boolean isIgnoredRegister(CiValue value) {
+        return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+    private CiValue use(CiValue value, EnumSet<OperandFlag> flags) {
+        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            CiValue actual = curInputState.get(key(value));
+            if (actual == null && flags.contains(OperandFlag.Uninitialized)) {
+                // OK, since uninitialized values are allowed explicitly.
+            } else if (value != actual) {
+                Debug.log("Error in register allocation: %s != %s for key %s", value, actual, key(value));
+                Debug.log(logCurrentState());
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+        return value;
+    }
+
+    private CiValue temp(CiValue value) {
+        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            Debug.log("    temp %s -> remove key %s", value, key(value));
+            curInputState.remove(key(value));
+        }
+        return value;
+    }
+
+    private CiValue output(CiValue value) {
+        if (value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            Debug.log("    output %s -> set key %s", value, key(value));
+            curInputState.put(key(value), value);
+        }
+        return value;
+    }
+
+
+    private String logCurrentState() {
+        ArrayList<Object> keys = new ArrayList<>(curInputState.keySet());
+        Collections.sort(keys, new Comparator<Object>() {
+            @Override
+            public int compare(Object o1, Object o2) {
+                if (o1 instanceof CiRegister) {
+                    if (o2 instanceof CiRegister) {
+                        return ((CiRegister) o1).number - ((CiRegister) o2).number;
+                    } else {
+                        return -1;
+                    }
+                } else {
+                    if (o2 instanceof CiRegister) {
+                        return 1;
+                    } else {
+                        return ((Integer) o1).intValue() - ((Integer) o2).intValue();
+                    }
+                }
+            }
+        });
+
+        StringBuilder sb = new StringBuilder("    state: ");
+        for (Object key : keys) {
+            sb.append(key).append("=").append(curInputState.get(key)).append(" ");
+        }
+        return sb.toString();
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +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.alloc.simple;
-
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.alloc.util.*;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
-import com.oracle.max.graal.debug.*;
-
-public abstract class AssignRegisters {
-    public final LIR lir;
-    public final FrameMap frameMap;
-
-    public AssignRegisters(LIR lir, FrameMap frameMap) {
-        this.lir = lir;
-        this.frameMap = frameMap;
-    }
-
-    private CiBitMap curRegisterRefMap;
-    private CiBitMap curFrameRefMap;
-
-    public void execute() {
-        ValueProcedure useProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value); } };
-        ValueProcedure defProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value); } };
-        ValueProcedure setReferenceProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setReference(value); } };
-
-        Debug.log("==== start assign registers ====");
-        for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
-            Block block = lir.linearScanOrder().get(i);
-            Debug.log("start block %s", block);
-
-            curRegisterRefMap = frameMap.initRegisterRefMap();
-            curFrameRefMap = frameMap.initFrameRefMap();
-
-            // Put all values live at the end of the block into the reference map.
-            locationsForBlockEnd(block).forEachLocation(setReferenceProc);
-
-            for (int j = block.lir.size() - 1; j >= 0; j--) {
-                LIRInstruction op = block.lir.get(j);
-                Debug.log("  op %d %s", op.id(), op);
-
-                op.forEachOutput(defProc);
-                op.forEachTemp(defProc);
-                op.forEachState(useProc);
-                op.forEachAlive(useProc);
-
-                if (op.info != null) {
-                    Debug.log("    registerRefMap: %s  frameRefMap: %s", curRegisterRefMap, curFrameRefMap);
-                    op.info.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
-
-                    if (op instanceof LIRXirInstruction) {
-                        LIRXirInstruction xir = (LIRXirInstruction) op;
-                        if (xir.infoAfter != null) {
-                            xir.infoAfter.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
-                        }
-                    }
-                }
-
-                // Process input operands after assigning the reference map, so that input operands that are used
-                // for the last time at this instruction are not part of the reference map.
-                op.forEachInput(useProc);
-            }
-            Debug.log("end block %s", block);
-        }
-        Debug.log("==== end assign registers ====");
-    }
-
-    private CiValue use(CiValue value) {
-        Debug.log("    use %s", value);
-        if (isLocation(value)) {
-            CiValue location = asLocation(value).location;
-            frameMap.setReference(location, curRegisterRefMap, curFrameRefMap);
-            return location;
-        } else {
-            frameMap.setReference(value, curRegisterRefMap, curFrameRefMap);
-            return value;
-        }
-    }
-
-    private CiValue def(CiValue value) {
-        Debug.log("    def %s", value);
-        if (isLocation(value)) {
-            CiValue location = asLocation(value).location;
-            frameMap.clearReference(location, curRegisterRefMap, curFrameRefMap);
-            return location;
-        } else {
-            frameMap.clearReference(value, curRegisterRefMap, curFrameRefMap);
-            return value;
-        }
-    }
-
-    private CiValue setReference(CiValue value) {
-        Debug.log("    setReference %s", value);
-        frameMap.setReference(asLocation(value).location, curRegisterRefMap, curFrameRefMap);
-        return value;
-    }
-
-    protected abstract LocationMap locationsForBlockEnd(Block block);
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,304 +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.alloc.simple;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.alloc.*;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
-import com.oracle.max.graal.debug.*;
-
-public class DataFlowAnalysis {
-    private final LIR lir;
-    private final RiRegisterConfig registerConfig;
-
-    public DataFlowAnalysis(LIR lir, RiRegisterConfig registerConfig) {
-        this.lir = lir;
-        this.registerConfig = registerConfig;
-    }
-
-    public void execute() {
-        numberInstructions();
-        backwardDataFlow();
-    }
-
-
-    private List<Block> blocks() {
-        return lir.linearScanOrder();
-    }
-
-    private int numVariables() {
-        return lir.numVariables();
-    }
-
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
-    }
-
-
-    private int[] definitions;
-    private BitSet[] blockLiveIn;
-    private Block[] opIdBlock;
-    private Object[] opIdKilledValues;
-
-
-    public BitSet liveIn(Block block) {
-        return blockLiveIn[block.getId()];
-    }
-    private void setLiveIn(Block block, BitSet liveIn) {
-        blockLiveIn[block.getId()] = liveIn;
-    }
-
-    private Block blockOf(int opId) {
-        return opIdBlock[opId >> 1];
-    }
-    private void setBlockOf(int opId, Block block) {
-        opIdBlock[opId >> 1] = block;
-    }
-
-    private Object killedValues(int opId) {
-        return opIdKilledValues[opId];
-    }
-    private void setKilledValues(int opId, Object killedValues) {
-        opIdKilledValues[opId] = killedValues;
-    }
-
-    public void forEachKilled(LIRInstruction op, boolean end, ValueProcedure proc) {
-        Object entry = killedValues(op.id() + (end ? 1 : 0));
-        if (entry == null) {
-            // Nothing to do
-        } else if (entry instanceof CiValue) {
-            CiValue newValue = proc.doValue((CiValue) entry, null, null);
-            assert newValue == entry : "procedure does not allow to change values";
-        } else {
-            CiValue[] values = (CiValue[]) entry;
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] != null) {
-                    CiValue newValue = proc.doValue(values[i], null, null);
-                    assert newValue == values[i] : "procedure does not allow to change values";
-                }
-            }
-        }
-    }
-
-    public int definition(Variable value) {
-        return definitions[value.index];
-    }
-
-    /**
-     * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}.
-     */
-    private void numberInstructions() {
-        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setDef(value); } };
-
-        int numInstructions = 0;
-        for (Block block : blocks()) {
-            numInstructions += block.lir.size();
-        }
-        opIdBlock = new Block[numInstructions];
-        opIdKilledValues = new Object[numInstructions << 1];
-        definitions = new int[numVariables()];
-
-        curOpId = 0;
-        for (Block block : blocks()) {
-            for (LIRInstruction op : block.lir) {
-                op.setId(curOpId);
-                setBlockOf(curOpId, block);
-
-                op.forEachTemp(defProc);
-                op.forEachOutput(defProc);
-
-                curOpId += 2; // numbering of lirOps by two
-            }
-        }
-        assert curOpId == numInstructions << 1;
-    }
-
-    private CiValue setDef(CiValue value) {
-        if (isVariable(value)) {
-            assert definitions[asVariable(value).index] == 0 : "Variable defined twice";
-            definitions[asVariable(value).index] = curOpId;
-        }
-        return value;
-    }
-
-
-    private BitSet variableLive;
-    private BitSet registerLive;
-    private int curOpId;
-
-    private void backwardDataFlow() {
-        ValueProcedure inputProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId); } };
-        ValueProcedure aliveProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId + 1); } };
-        ValueProcedure tempProc =     new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, true); } };
-        ValueProcedure outputProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, false); } };
-
-        blockLiveIn = new BitSet[blocks().size()];
-        registerLive = new BitSet();
-
-        Debug.log("==== start backward data flow analysis ====");
-        for (int i = blocks().size() - 1; i >= 0; i--) {
-            Block block = blocks().get(i);
-            Debug.log("start block %s  loop %s", block, block.getLoop());
-
-            variableLive = new BitSet();
-            for (Block sux : block.getSuccessors()) {
-                BitSet suxLive = liveIn(sux);
-                if (suxLive != null) {
-                    Debug.log("  sux %s  suxLive: %s", sux, suxLive);
-                    variableLive.or(suxLive);
-                }
-            }
-
-            assert registerLive.isEmpty() : "no fixed register must be alive before processing a block";
-
-            for (int j = block.lir.size() - 1; j >= 0; j--) {
-                LIRInstruction op = block.lir.get(j);
-                curOpId = op.id();
-                Debug.log("  op %d %s  variableLive: %s  registerLive: %s", curOpId, op, variableLive, registerLive);
-
-                op.forEachOutput(outputProc);
-                op.forEachTemp(tempProc);
-                op.forEachState(aliveProc);
-                op.forEachAlive(aliveProc);
-                op.forEachInput(inputProc);
-            }
-
-            assert registerLive.isEmpty() : "no fixed register must be alive after processing a block";
-            assert liveIn(block) == null;
-            setLiveIn(block, variableLive);
-
-            if (block.isLoopHeader()) {
-                Debug.log("  loop header, propagating live set to loop blocks  variableLive: %s", variableLive);
-                // All variables that are live at the beginning of a loop are also live the whole loop.
-                // This is guaranteed by the SSA form.
-                for (Block loop : block.getLoop().blocks) {
-                    BitSet loopLiveIn = liveIn(loop);
-                    assert loopLiveIn != null : "All loop blocks must have been processed before the loop header";
-                    loopLiveIn.or(variableLive);
-                    Debug.log("    block %s  loopLiveIn %s", loop, loopLiveIn);
-                }
-            }
-
-            Debug.log("end block %s  variableLive: %s", block, variableLive);
-        }
-        Debug.log("==== end backward data flow analysis ====");
-    }
-
-    private CiValue use(CiValue value, int killOpId) {
-        Debug.log("    use %s", value);
-        if (isVariable(value)) {
-            int variableIdx = asVariable(value).index;
-            assert definitions[variableIdx] < curOpId;
-            if (!variableLive.get(variableIdx)) {
-                Debug.log("      set live variable %d", variableIdx);
-                variableLive.set(variableIdx);
-                kill(value, killOpId);
-            }
-
-        } else if (isAllocatableRegister(value)) {
-            int regNum = asRegister(value).number;
-            if (!registerLive.get(regNum)) {
-                Debug.log("      set live register %d", regNum);
-                registerLive.set(regNum);
-                kill(value, killOpId);
-            }
-        }
-        return value;
-    }
-
-    private CiValue def(CiValue value, boolean isTemp) {
-        Debug.log("    def %s", value);
-        if (isVariable(value)) {
-            int variableIdx = asVariable(value).index;
-            assert definitions[variableIdx] == curOpId;
-            if (variableLive.get(variableIdx)) {
-                Debug.log("      clear live variable %d", variableIdx);
-                assert !isTemp : "temp variable cannot be used after the operation";
-                variableLive.clear(variableIdx);
-            } else {
-                // Variable has never been used, so kill it immediately after the definition.
-                kill(value, curOpId + 1);
-            }
-
-        } else if (isAllocatableRegister(value)) {
-            int regNum = asRegister(value).number;
-            if (registerLive.get(regNum)) {
-                Debug.log("      clear live register %d", regNum);
-                assert !isTemp : "temp variable cannot be used after the operation";
-                registerLive.clear(regNum);
-            } else {
-                // Register has never been used, so kill it immediately after the definition.
-                kill(value, curOpId + 1);
-            }
-        }
-        return value;
-    }
-
-    private void kill(CiValue value, int opId) {
-        if (opId < 0) {
-            return;
-        }
-        if (isVariable(value)) {
-            int defOpId = definitions[asVariable(value).index];
-            assert defOpId > 0 && defOpId <= opId;
-
-            Block defBlock = blockOf(defOpId);
-            Block useBlock = blockOf(opId);
-
-            if (useBlock.getLoop() != null && useBlock.getLoop() != defBlock.getLoop()) {
-                // This is a value defined outside of the loop it is currently used in.  Therefore, it is live the whole loop
-                // and is not killed by the current instruction.
-                Debug.log("      no kill because use in %s, definition in %s", useBlock.getLoop(), defBlock.getLoop());
-                return;
-            }
-        }
-        Debug.log("      kill %s at %d", value, opId);
-
-        Object entry = killedValues(opId);
-        if (entry == null) {
-            setKilledValues(opId, value);
-        } else if (entry instanceof CiValue) {
-            setKilledValues(opId, new CiValue[] {(CiValue) entry, value});
-        } else {
-            CiValue[] killed = (CiValue[]) entry;
-            for (int i = 0; i < killed.length; i++) {
-                if (killed[i] == null) {
-                    killed[i] = value;
-                    return;
-                }
-            }
-            int oldLen = killed.length;
-            killed = Arrays.copyOf(killed, oldLen * 2);
-            setKilledValues(opId, killed);
-            killed[oldLen] = value;
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,575 +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.alloc.simple;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
-import com.oracle.max.graal.alloc.util.*;
-import com.oracle.max.graal.compiler.cfg.*;
-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.debug.*;
-import com.oracle.max.graal.graph.*;
-
-public class LinearScanAllocator {
-    private final LIR lir;
-    private final FrameMap frameMap;
-
-    private final DataFlowAnalysis dataFlow;
-
-    public LinearScanAllocator(LIR lir, FrameMap frameMap) {
-        this.lir = lir;
-        this.frameMap = frameMap;
-
-        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(lir, frameMap);
-
-        this.variableLastUse = new int[lir.numVariables()];
-    }
-
-    private class MoveResolverImpl extends MoveResolver {
-        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
-            super(lir, frameMap);
-        }
-
-        @Override
-        protected CiValue scratchRegister(Variable spilled) {
-            GraalInternalError.shouldNotReachHere("needs working implementation");
-
-            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
-            for (CiRegister reg : availableRegs) {
-                if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
-                    return reg.asValue(spilled.kind);
-                }
-            }
-            throw new CiBailout("No register found");
-        }
-    }
-
-    private class ResolveDataFlowImpl extends ResolveDataFlow {
-        public ResolveDataFlowImpl(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
-            super(lir, moveResolver, dataFlow);
-        }
-
-        @Override
-        protected LocationMap locationsForBlockBegin(Block block) {
-            return beginLocationsFor(block);
-        }
-
-        @Override
-        protected LocationMap locationsForBlockEnd(Block block) {
-            return endLocationsFor(block);
-        }
-    }
-
-    private class AssignRegistersImpl extends AssignRegisters {
-        public AssignRegistersImpl(LIR lir, FrameMap frameMap) {
-            super(lir, frameMap);
-        }
-
-        @Override
-        protected LocationMap locationsForBlockEnd(Block block) {
-            return endLocationsFor(block);
-        }
-    }
-
-
-    private int maxRegisterNum() {
-        return frameMap.target.arch.registers.length;
-    }
-
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
-    }
-
-
-    private final LocationMap[] blockBeginLocations;
-
-    private LocationMap beginLocationsFor(Block block) {
-        return blockBeginLocations[block.getId()];
-    }
-    private void setBeginLocationsFor(Block block, LocationMap locations) {
-        blockBeginLocations[block.getId()] = locations;
-    }
-
-    private final LocationMap[] blockEndLocations;
-
-    private LocationMap endLocationsFor(Block block) {
-        return blockEndLocations[block.getId()];
-    }
-    private void setEndLocationsFor(Block block, LocationMap locations) {
-        blockEndLocations[block.getId()] = locations;
-    }
-
-    private final int[] variableLastUse;
-
-    private int lastUseFor(Variable variable) {
-        return variableLastUse[variable.index];
-    }
-
-    private void setLastUseFor(Variable variable, int lastUse) {
-        variableLastUse[variable.index] = lastUse;
-    }
-
-    private MoveResolver moveResolver;
-    private LocationMap curLocations;
-    private CiValue[] curInRegisterState;
-    private CiValue[] curOutRegisterState;
-    private BitSet curLiveIn;
-    private int curOpId;
-    private boolean curPhiDefs;
-
-    private LocationMap canonicalSpillLocations;
-
-    public void execute() {
-        assert LIRVerifier.verify(true, lir, frameMap);
-
-        dataFlow.execute();
-        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
-
-        allocate();
-
-        IntervalPrinter.printAfterAllocation("After linear scan allocation", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
-
-        ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
-        resolveDataFlow.execute();
-        frameMap.finish();
-
-        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
-        assert RegisterVerifier.verify(lir, frameMap);
-
-        AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
-        assignRegisters.execute();
-
-        Debug.dump(lir, "After register asignment");
-        assert LIRVerifier.verify(false, lir, frameMap);
-    }
-
-    private void allocate() {
-        ValueProcedure recordUseProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return recordUse(value); } };
-        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
-        ValueProcedure unblockProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return unblock(value); } };
-        ValueProcedure killProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value); } };
-        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
-        ValueProcedure useProc =          new ValueProcedure() { @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); } };
-
-        Debug.log("==== start linear scan allocation ====");
-        canonicalSpillLocations = new LocationMap(lir.numVariables());
-        curInRegisterState = new CiValue[maxRegisterNum()];
-        curOutRegisterState = new CiValue[maxRegisterNum()];
-        for (Block block : lir.linearScanOrder()) {
-            Debug.log("start block %s %s", block, block.getLoop());
-
-            Arrays.fill(curOutRegisterState, null);
-            if (block.getDominator() != null) {
-                LocationMap dominatorState = endLocationsFor(block.getDominator());
-                curLocations = new LocationMap(dominatorState);
-                // Clear out all variables that are not live at the begin of this block
-                curLiveIn = dataFlow.liveIn(block);
-                curLocations.forEachLocation(killNonLiveProc);
-                assert checkInputState(block);
-            } else {
-                curLocations = new LocationMap(lir.numVariables());
-            }
-            Debug.log(logCurrentState());
-
-            for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) {
-                LIRInstruction op = block.lir.get(opIdx);
-                curOpId = op.id();
-                curPhiDefs = opIdx == 0;
-
-                Debug.log("  op %d %s", op.id(), op);
-
-                System.arraycopy(curOutRegisterState, 0, curInRegisterState, 0, curOutRegisterState.length);
-
-                // Unblock fixed registers that are only used for inputs in curOutRegisterState.
-                dataFlow.forEachKilled(op, false, unblockProc);
-                // Block fixed registers defined by this instruction in curOutRegisterState.
-                op.forEachTemp(blockProc);
-                op.forEachOutput(blockProc);
-
-                op.forEachInput(recordUseProc);
-                op.forEachAlive(recordUseProc);
-
-                moveResolver.init(block.lir, opIdx);
-                // Process Alive before Input because they are more restricted and the same variable can be Alive and Input.
-                op.forEachAlive(useProc);
-                op.forEachInput(useProc);
-
-                dataFlow.forEachKilled(op, false, killProc);
-
-                if (op.hasCall()) {
-                    spillCallerSaveRegisters();
-                }
-
-                op.forEachTemp(defProc);
-                op.forEachOutput(defProc);
-
-                // Fixed temp and output registers can evict variables from their assigned register, allocate new location for them.
-                fixupEvicted();
-                // State values are the least critical and can get the leftover registers (or stack slots if no more register available).
-                op.forEachState(useProc);
-
-                if (opIdx == 0) {
-                    assert !moveResolver.hasMappings() : "cannot insert spill moves before label";
-                    setBeginLocationsFor(block, new LocationMap(curLocations));
-                }
-                moveResolver.resolve();
-
-                dataFlow.forEachKilled(op, true, unblockProc);
-                dataFlow.forEachKilled(op, true, killProc);
-
-                curOpId = -1;
-            }
-
-            assert endLocationsFor(block) == null;
-            setEndLocationsFor(block, curLocations);
-
-            logCurrentState();
-            Debug.log("end block %s", block);
-        }
-
-        moveResolver.finish();
-        Debug.log("==== end linear scan allocation ====");
-    }
-
-    private CiValue killNonLive(CiValue value) {
-        assert isLocation(value);
-        if (!curLiveIn.get(asLocation(value).variable.index)) {
-            return null;
-
-        } else if (isAllocatableRegister(asLocation(value).location)) {
-            int regNum = asRegister(asLocation(value).location).number;
-            assert curOutRegisterState[regNum] == null;
-            curOutRegisterState[regNum] = value;
-        }
-        return value;
-    }
-
-    private CiValue unblock(CiValue value) {
-        if (isAllocatableRegister(value)) {
-            Debug.log("    unblock register %s", value);
-            int regNum = asRegister(value).number;
-            assert curOutRegisterState[regNum] == value;
-            curOutRegisterState[regNum] = null;
-        }
-        return value;
-    }
-
-    private CiValue kill(CiValue value) {
-        if (isVariable(value)) {
-            Location location = curLocations.get(asVariable(value));
-            Debug.log("    kill location %s", location);
-            if (isRegister(location.location)) {
-                int regNum = asRegister(location.location).number;
-                if (curOutRegisterState[regNum] == location) {
-                    curOutRegisterState[regNum] = null;
-                }
-            }
-            curLocations.clear(asVariable(value));
-        }
-        return value;
-    }
-
-
-    private CiValue block(CiValue value) {
-        if (isAllocatableRegister(value)) {
-            Debug.log("    block %s", value);
-            int regNum = asRegister(value).number;
-            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof Location;
-            curOutRegisterState[regNum] = value;
-        }
-        return value;
-    }
-
-    private void spillCallerSaveRegisters() {
-        Debug.log("    spill caller save registers in curInRegisterState %s", Arrays.toString(curInRegisterState));
-        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
-            CiValue in = curInRegisterState[reg.number];
-            if (in != null && isLocation(in)) {
-                spill(asLocation(in));
-            }
-        }
-    }
-
-    private CiValue recordUse(CiValue value) {
-        if (isVariable(value)) {
-            assert lastUseFor(asVariable(value)) <= curOpId;
-            setLastUseFor(asVariable(value), curOpId);
-
-        }
-        return value;
-    }
-
-    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        assert mode == OperandMode.Input || mode == OperandMode.Alive;
-        if (isVariable(value)) {
-            // State values are not recorded beforehand because it does not matter if they are spilled. Still, it is necessary to record them as used now.
-            recordUse(value);
-
-            Location curLoc = curLocations.get(asVariable(value));
-            if (isStackSlot(curLoc.location) && flags.contains(OperandFlag.Stack)) {
-                Debug.log("    use %s %s: use current stack slot %s", mode, value, curLoc.location);
-                return curLoc;
-            }
-            if (isRegister(curLoc.location)) {
-                int regNum = asRegister(curLoc.location).number;
-                assert curInRegisterState[regNum] == curLoc;
-                if (mode == OperandMode.Input || curOutRegisterState[regNum] == curLoc) {
-                    Debug.log("    use %s %s: use current register %s", mode, value, curLoc.location);
-                    return curLoc;
-                }
-            }
-
-            Debug.log("    use %s %s", mode, value);
-
-            Location newLoc = allocateRegister(asVariable(value), mode, flags);
-            if (newLoc != curLoc) {
-                moveResolver.add(curLoc, newLoc);
-            }
-            return newLoc;
-        } else {
-            assert !isAllocatableRegister(value) || curInRegisterState[asRegister(value).number] == value;
-        }
-        return value;
-    }
-
-    private static final EnumSet<OperandFlag> SPILL_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-
-    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        assert mode == OperandMode.Temp || mode == OperandMode.Output;
-        if (isVariable(value)) {
-            Debug.log("    def %s %s", mode, value);
-            assert curLocations.get(asVariable(value)) == null;
-
-            Location newLoc = allocateRegister(asVariable(value), mode, flags);
-            return newLoc;
-        }
-        return value;
-    }
-
-
-    private void fixupEvicted() {
-        for (int i = 0; i < curInRegisterState.length; i++) {
-            CiValue in = curInRegisterState[i];
-            CiValue out = curOutRegisterState[i];
-
-            if (in != null && in != out && isLocation(in) && curLocations.get(asLocation(in).variable) == in) {
-                Debug.log("    %s was evicted by %s, need to allocate new location", in, out);
-                Location oldLoc = asLocation(in);
-                Location newLoc = allocateRegister(oldLoc.variable, OperandMode.Alive, SPILL_FLAGS);
-                assert oldLoc != newLoc;
-                moveResolver.add(oldLoc, newLoc);
-            }
-
-
-        }
-    }
-
-
-    private Location allocateRegister(final Variable variable, OperandMode mode, EnumSet<OperandFlag> flags) {
-//        if (flags.contains(OperandFlag.RegisterHint)) {
-//            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
-//                @Override
-//                public CiValue doValue(CiValue registerHint) {
-//                    Debug.log("      registerHint %s", registerHint);
-//                    CiRegister hint = null;
-//                    if (isRegister(registerHint)) {
-//                        hint = asRegister(registerHint);
-//                    } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
-//                        hint = asRegister(asLocation(registerHint).location);
-//                    }
-//                    if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) {
-//                        return selectRegister(hint, variable, inRegisterState, outRegisterState);
-//                    }
-//                    return null;
-//                }
-//            });
-//
-//            if (result != null) {
-//                return asLocation(result);
-//            }
-//        }
-//
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
-
-        Location bestSpillCandidate = null;
-        for (CiRegister reg : availableRegs) {
-            if (isFree(reg, mode)) {
-                return selectRegister(reg, variable, mode);
-            } else {
-                Location spillCandidate = spillCandidate(reg);
-                if (betterSpillCandidate(spillCandidate, bestSpillCandidate)) {
-                    bestSpillCandidate = spillCandidate;
-                }
-            }
-        }
-
-        if (flags.contains(OperandFlag.Stack) && betterSpillCandidate(curLocations.get(variable), bestSpillCandidate)) {
-            return selectSpillSlot(variable);
-        }
-
-        if (bestSpillCandidate == null) {
-            if (curPhiDefs) {
-                return selectSpillSlot(variable);
-            }
-
-            // This should not happen as long as all LIR instructions have fulfillable register constraints. But be safe in product mode and bail out.
-            assert false;
-            throw new CiBailout("No register available");
-        }
-
-        spill(bestSpillCandidate);
-
-        return selectRegister(asRegister(bestSpillCandidate.location), variable, mode);
-    }
-
-    private void spill(Location value) {
-        Location newLoc = spillLocation(value.variable);
-        Debug.log("      spill %s to %s", value, newLoc);
-        if (!curPhiDefs) {
-            moveResolver.add(value, newLoc);
-        }
-        curLocations.put(newLoc);
-
-        CiRegister reg = asRegister(value.location);
-        assert curInRegisterState[reg.number] == value;
-        curInRegisterState[reg.number] = null;
-        if (curOutRegisterState[reg.number] == value) {
-            curOutRegisterState[reg.number] = null;
-        }
-    }
-
-    private boolean isFree(CiRegister reg, OperandMode mode) {
-        switch (mode) {
-            case Input:  return curInRegisterState[reg.number] == null;
-            case Alive:  return curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null;
-            case Temp:   return curOutRegisterState[reg.number] == null;
-            case Output: return curOutRegisterState[reg.number] == null;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    private Location spillCandidate(CiRegister reg) {
-        CiValue in = curInRegisterState[reg.number];
-        CiValue out = curOutRegisterState[reg.number];
-        if (in == out && in != null && isLocation(in) && lastUseFor(asLocation(in).variable) < curOpId) {
-            return asLocation(in);
-        }
-        return null;
-    }
-
-    private boolean betterSpillCandidate(Location loc, Location compare) {
-        if (loc == null) {
-            return false;
-        }
-        if (compare == null) {
-            return true;
-        }
-        if (canonicalSpillLocations.get(loc.variable) != null && canonicalSpillLocations.get(compare.variable) == null) {
-            return true;
-        }
-        return dataFlow.definition(loc.variable) < dataFlow.definition(compare.variable);
-    }
-
-    private Location spillLocation(Variable variable) {
-        Location result = canonicalSpillLocations.get(variable);
-        if (result == null) {
-            result = new Location(variable, frameMap.allocateSpillSlot(variable.kind));
-            canonicalSpillLocations.put(result);
-        }
-        return result;
-    }
-
-    private Location selectRegister(CiRegister reg, Variable variable, OperandMode mode) {
-        assert isFree(reg, mode);
-
-        Location loc = new Location(variable, reg.asValue(variable.kind));
-        if (mode == OperandMode.Input || mode == OperandMode.Alive) {
-            curInRegisterState[reg.number] = loc;
-        }
-        curOutRegisterState[reg.number] = loc;
-        curLocations.put(loc);
-        recordUse(variable);
-
-        Debug.log("      selected register %s", loc);
-        return loc;
-    }
-
-    private Location selectSpillSlot(Variable variable) {
-        Location loc = spillLocation(variable);
-        curLocations.put(loc);
-        recordUse(variable);
-
-        Debug.log("      selected spill slot %s", loc);
-        return loc;
-    }
-
-    private boolean checkInputState(final Block block) {
-        final BitSet liveState = new BitSet();
-        curLocations.forEachLocation(new ValueProcedure() {
-            @Override
-            public CiValue doValue(CiValue value) {
-                liveState.set(asLocation(value).variable.index);
-
-                for (Block pred : block.getPredecessors()) {
-                    LocationMap predState = endLocationsFor(pred);
-                    if (predState != null) {
-                        assert predState.get(asLocation(value).variable) != null;
-                    } else {
-                        assert block.isLoopHeader();
-                    }
-                }
-                return value;
-            }
-        });
-        assert liveState.equals(curLiveIn);
-        return true;
-    }
-
-
-    private String logCurrentState() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("  current lcoations: ");
-        curLocations.forEachLocation(new ValueProcedure() {
-            @Override
-            public CiValue doValue(CiValue value) {
-                sb.append(value).append(" ");
-                return value;
-            }
-        });
-        return sb.toString();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +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.alloc.simple;
-
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.alloc.util.*;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
-import com.oracle.max.graal.compiler.lir.StandardOp.PhiJumpOp;
-import com.oracle.max.graal.compiler.lir.StandardOp.PhiLabelOp;
-import com.oracle.max.graal.debug.*;
-import com.oracle.max.graal.graph.*;
-
-public abstract class ResolveDataFlow {
-    public final LIR lir;
-    public final MoveResolver moveResolver;
-    public final DataFlowAnalysis dataFlow;
-
-    public ResolveDataFlow(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
-        this.lir = lir;
-        this.moveResolver = moveResolver;
-        this.dataFlow = dataFlow;
-    }
-
-    private LocationMap curFromLocations;
-
-    public void execute() {
-        ValueProcedure locMappingProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return locMapping(value); } };
-
-        Debug.log("==== start resolve data flow ====");
-        for (Block toBlock : lir.linearScanOrder()) {
-            PhiLabelOp phiDefs = null;
-            if (toBlock.lir.get(0) instanceof PhiLabelOp) {
-                phiDefs = (PhiLabelOp) toBlock.lir.get(0);
-            }
-
-            for (Block fromBlock : toBlock.getPredecessors()) {
-                Debug.log("start edge %s -> %s", fromBlock, toBlock);
-                findInsertPos(fromBlock, toBlock);
-
-                LocationMap toLocations = locationsForBlockBegin(toBlock);
-                curFromLocations = locationsForBlockEnd(fromBlock);
-                if (toLocations != curFromLocations) {
-                    toLocations.forEachLocation(locMappingProc);
-                }
-
-                if (phiDefs != null) {
-                    PhiJumpOp phiInputs = (PhiJumpOp) fromBlock.lir.get(fromBlock.lir.size() - 1);
-                    phiMapping(phiInputs.getPhiInputs(), phiDefs.getPhiDefinitions());
-                    phiInputs.markResolved();
-                }
-
-                moveResolver.resolve();
-                Debug.log("end edge %s -> %s", fromBlock, toBlock);
-            }
-
-            if (phiDefs != null) {
-                // Phi functions are resolved with moves now, so delete them.
-                phiDefs.markResolved();
-            }
-        }
-        moveResolver.finish();
-        Debug.log("==== end resolve data flow ====");
-    }
-
-    private CiValue locMapping(CiValue value) {
-        Location to = asLocation(value);
-        Location from = curFromLocations.get(to.variable);
-        if (value != from && from != null) {
-            moveResolver.add(from, to);
-        }
-        return value;
-    }
-
-    private void phiMapping(CiValue[] inputs, CiValue[] outputs) {
-        assert inputs.length != outputs.length;
-        for (int i = 0; i < inputs.length; i++) {
-            if (inputs[i] != outputs[i]) {
-                moveResolver.add(inputs[i], asLocation(outputs[i]));
-            }
-        }
-    }
-
-    private void findInsertPos(Block fromBlock, Block toBlock) {
-        assert fromBlock.getSuccessors().contains(toBlock) && toBlock.getPredecessors().contains(fromBlock);
-
-        if (fromBlock.numberOfSux() == 1) {
-            List<LIRInstruction> instructions = fromBlock.lir;
-            LIRInstruction instr = instructions.get(instructions.size() - 1);
-            assert instr instanceof StandardOp.JumpOp : "block does not end with an unconditional jump";
-            moveResolver.init(instructions, instructions.size() - 1);
-            Debug.log("  insert at end of %s before %d", fromBlock, instructions.size() - 1);
-
-        } else if (toBlock.numberOfPreds() == 1) {
-            moveResolver.init(toBlock.lir, 1);
-            Debug.log("  insert at beginning of %s before %d", toBlock, 1);
-
-        } else {
-            GraalInternalError.shouldNotReachHere("Critical edge not split");
-        }
-    }
-
-    protected abstract LocationMap locationsForBlockBegin(Block block);
-    protected abstract LocationMap locationsForBlockEnd(Block block);
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +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.alloc.simple;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
-import com.oracle.max.graal.alloc.util.*;
-import com.oracle.max.graal.compiler.cfg.*;
-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.debug.*;
-import com.oracle.max.graal.graph.*;
-
-public class SpillAllAllocator {
-    private final LIR lir;
-    private final FrameMap frameMap;
-
-    private final DataFlowAnalysis dataFlow;
-
-    public SpillAllAllocator(LIR lir, FrameMap frameMap) {
-        this.lir = lir;
-        this.frameMap = frameMap;
-
-        this.dataFlow = new DataFlowAnalysis(lir, frameMap.registerConfig);
-        this.blockLocations = new LocationMap[lir.linearScanOrder().size()];
-        this.moveResolver = new MoveResolverImpl(lir, frameMap);
-    }
-
-    private class MoveResolverImpl extends MoveResolver {
-        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
-            super(lir, frameMap);
-        }
-
-        @Override
-        protected CiValue scratchRegister(Variable spilled) {
-            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
-            for (CiRegister reg : availableRegs) {
-                if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
-                    return reg.asValue(spilled.kind);
-                }
-            }
-            throw new CiBailout("No register found");
-        }
-    }
-
-    private class ResolveDataFlowImpl extends ResolveDataFlow {
-        public ResolveDataFlowImpl(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
-            super(lir, moveResolver, dataFlow);
-        }
-
-        @Override
-        protected LocationMap locationsForBlockBegin(Block block) {
-            assert block.numberOfPreds() > 0 && block.getDominator() != null;
-            return locationsFor(block.getDominator());
-        }
-
-        @Override
-        protected LocationMap locationsForBlockEnd(Block block) {
-            return locationsFor(block);
-        }
-    }
-
-    private class AssignRegistersImpl extends AssignRegisters {
-        public AssignRegistersImpl(LIR lir, FrameMap frameMap) {
-            super(lir, frameMap);
-        }
-
-        @Override
-        protected LocationMap locationsForBlockEnd(Block block) {
-            return locationsFor(block);
-        }
-    }
-
-
-    private int maxRegisterNum() {
-        return frameMap.target.arch.registers.length;
-    }
-
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
-    }
-
-
-    private final LocationMap[] blockLocations;
-
-    private LocationMap locationsFor(Block block) {
-        return blockLocations[block.getId()];
-    }
-    private void setLocationsFor(Block block, LocationMap locations) {
-        blockLocations[block.getId()] = locations;
-    }
-
-    private MoveResolver moveResolver;
-    private LocationMap curStackLocations;
-    private LocationMap curRegisterLocations;
-    private Object[] curInRegisterState;
-    private Object[] curOutRegisterState;
-    private BitSet curLiveIn;
-    private LIRInstruction curInstruction;
-
-    public void execute() {
-        assert LIRVerifier.verify(true, lir, frameMap);
-
-        dataFlow.execute();
-        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
-
-        allocate();
-
-        IntervalPrinter.printAfterAllocation("After spill all allocation", lir, frameMap.registerConfig, dataFlow, blockLocations);
-
-        ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
-        resolveDataFlow.execute();
-        frameMap.finish();
-
-        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockLocations);
-        assert RegisterVerifier.verify(lir, frameMap);
-
-        AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
-        assignRegisters.execute();
-
-        Debug.dump(lir, "After register asignment");
-        assert LIRVerifier.verify(false, lir, frameMap);
-    }
-
-    private void allocate() {
-        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
-        ValueProcedure killBeginProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, false); } };
-        ValueProcedure killEndProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, true); } };
-        ValueProcedure killLocationProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killLocation(value); } };
-        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
-        ValueProcedure loadProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return load(value, mode, flags); } };
-        ValueProcedure spillProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return spill(value, mode, flags); } };
-        ValueProcedure useSlotProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return useSlot(value); } };
-
-        Debug.log("==== start spill all allocation ====");
-        curInRegisterState = new Object[maxRegisterNum()];
-        curOutRegisterState = new Object[maxRegisterNum()];
-        curRegisterLocations = new LocationMap(lir.numVariables());
-        for (Block block : lir.linearScanOrder()) {
-            Debug.log("start block %s %s", block, block.getLoop());
-            assert checkEmpty(curOutRegisterState);
-
-            if (block.getDominator() != null) {
-                LocationMap dominatorState = locationsFor(block.getDominator());
-                curStackLocations = new LocationMap(dominatorState);
-                // Clear out all variables that are not live at the begin of this block
-                curLiveIn = dataFlow.liveIn(block);
-                curStackLocations.forEachLocation(killNonLiveProc);
-                assert checkInputState(block);
-            } else {
-                curStackLocations = new LocationMap(lir.numVariables());
-            }
-            Debug.log(logCurrentState());
-
-            for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) {
-                LIRInstruction op = block.lir.get(opIdx);
-                curInstruction = op;
-                Debug.log("  op %d %s", op.id(), op);
-
-                assert curRegisterLocations.checkEmpty();
-
-                System.arraycopy(curOutRegisterState, 0, curInRegisterState, 0, curOutRegisterState.length);
-
-                // Block fixed registers that are defined by this instruction, so that they are no longer available for normal allocation.
-                op.forEachTemp(blockProc);
-                op.forEachOutput(blockProc);
-
-                moveResolver.init(block.lir, opIdx);
-                // Process Alive before Input because they are more restricted and the same variable can be Alive and Input.
-                op.forEachAlive(loadProc);
-                op.forEachInput(loadProc);
-                moveResolver.resolve();
-                op.forEachState(useSlotProc);
-
-                dataFlow.forEachKilled(op, false, killBeginProc);
-                assert !op.hasCall() || checkNoCallerSavedRegister() : "caller saved register in use accross call site";
-
-                moveResolver.init(block.lir, opIdx + 1);
-                op.forEachTemp(spillProc);
-                op.forEachOutput(spillProc);
-                moveResolver.resolve();
-
-                dataFlow.forEachKilled(op, true, killEndProc);
-                curRegisterLocations.forEachLocation(killLocationProc);
-
-                assert curRegisterLocations.checkEmpty();
-                curInstruction = null;
-            }
-            assert checkEmpty(curOutRegisterState);
-            assert locationsFor(block) == null;
-            setLocationsFor(block, curStackLocations);
-
-            logCurrentState();
-            Debug.log("end block %s", block);
-        }
-
-        moveResolver.finish();
-        Debug.log("==== end spill all allocation ====");
-    }
-
-    private CiValue killNonLive(CiValue value) {
-        assert isLocation(value);
-        if (!curLiveIn.get(asLocation(value).variable.index)) {
-            return null;
-        }
-        return value;
-    }
-
-    private CiValue kill(CiValue value, boolean end) {
-        if (isVariable(value)) {
-            Debug.log("    kill variable %s", value);
-
-            Variable variable = asVariable(value);
-            curStackLocations.clear(variable);
-
-            Location loc = curRegisterLocations.get(variable);
-            if (loc != null) {
-                killLocation(loc);
-                curRegisterLocations.clear(variable);
-
-                Debug.log("      location %s", loc);
-                assert isAllocatableRegister(loc.location);
-
-                int regNum = asRegister(loc.location).number;
-                if (curOutRegisterState[regNum] == loc) {
-                    curOutRegisterState[regNum] = null;
-                }
-            }
-
-        } else if (isAllocatableRegister(value)) {
-            Debug.log("    kill register %s", value);
-            int regNum = asRegister(value).number;
-            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof LIRInstruction && curInstruction != null;
-
-            if (end || curOutRegisterState[regNum] != curInstruction) {
-                curOutRegisterState[regNum] = null;
-            }
-
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-        return value;
-    }
-
-    private CiValue killLocation(CiValue value) {
-        Debug.log("    kill location %s", value);
-        assert isAllocatableRegister(asLocation(value).location);
-
-        int regNum = asRegister(asLocation(value).location).number;
-        if (curOutRegisterState[regNum] == value) {
-            curOutRegisterState[regNum] = null;
-        }
-        return null;
-    }
-
-    private CiValue block(CiValue value) {
-        if (isAllocatableRegister(value)) {
-            Debug.log("    block %s", value);
-            int regNum = asRegister(value).number;
-            assert curInstruction != null;
-            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof LIRInstruction;
-            curOutRegisterState[regNum] = curInstruction;
-        }
-        return value;
-    }
-
-    private CiValue load(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        assert mode == OperandMode.Input || mode == OperandMode.Alive;
-        if (flags.contains(OperandFlag.Stack)) {
-            return useSlot(value);
-        }
-        if (isVariable(value)) {
-            Debug.log("    load %s", value);
-            Location regLoc = curRegisterLocations.get(asVariable(value));
-            if (regLoc != null) {
-                // This variable has already been processed before.
-                Debug.log("      found location %s", regLoc);
-            } else {
-                regLoc = allocateRegister(asVariable(value), curInRegisterState, mode == OperandMode.Alive ? curOutRegisterState : null, mode, flags);
-                Location stackLoc = curStackLocations.get(asVariable(value));
-                assert stackLoc != null;
-                moveResolver.add(stackLoc, regLoc);
-            }
-            return regLoc;
-        } else {
-            assert !isAllocatableRegister(value) || curInRegisterState[asRegister(value).number] instanceof LIRInstruction;
-            return value;
-        }
-    }
-
-    private CiValue spill(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        assert mode == OperandMode.Temp || mode == OperandMode.Output;
-        if (flags.contains(OperandFlag.Stack)) {
-            return defSlot(value);
-        }
-        if (isVariable(value)) {
-            Debug.log("    spill %s", value);
-            assert curStackLocations.get(asVariable(value)) == null;
-            Location regLoc = allocateRegister(asVariable(value), null, curOutRegisterState, mode, flags);
-            if (mode == OperandMode.Output) {
-                Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
-                curStackLocations.put(stackLoc);
-                moveResolver.add(regLoc, stackLoc);
-            }
-            return regLoc;
-        } else {
-            assert !isAllocatableRegister(value) || curOutRegisterState[asRegister(value).number] == curInstruction && curInstruction != null;
-            return value;
-        }
-    }
-
-    private CiValue useSlot(CiValue value) {
-        if (isVariable(value)) {
-            Debug.log("    useSlot %s", value);
-            Location stackLoc = curStackLocations.get(asVariable(value));
-            assert stackLoc != null;
-            Debug.log("      slot %s", stackLoc);
-            return stackLoc;
-        } else {
-            return value;
-        }
-    }
-
-    private CiValue defSlot(CiValue value) {
-        if (isVariable(value)) {
-            Debug.log("    assignSlot %s", value);
-            Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
-            assert curStackLocations.get(asVariable(value)) == null;
-            curStackLocations.put(stackLoc);
-            Debug.log("      slot %s", stackLoc);
-            return stackLoc;
-        } else {
-            return value;
-        }
-    }
-
-    private Location allocateRegister(final Variable variable, final Object[] inRegisterState, final Object[] outRegisterState, OperandMode mode, EnumSet<OperandFlag> flags) {
-        if (flags.contains(OperandFlag.RegisterHint)) {
-            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
-                @Override
-                public CiValue doValue(CiValue registerHint) {
-                    Debug.log("      registerHint %s", registerHint);
-                    CiRegister hint = null;
-                    if (isRegister(registerHint)) {
-                        hint = asRegister(registerHint);
-                    } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
-                        hint = asRegister(asLocation(registerHint).location);
-                    }
-                    if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) {
-                        return selectRegister(hint, variable, inRegisterState, outRegisterState);
-                    }
-                    return null;
-                }
-            });
-
-            if (result != null) {
-                return asLocation(result);
-            }
-        }
-
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
-
-        for (CiRegister reg : availableRegs) {
-            if (isFree(reg, inRegisterState, outRegisterState)) {
-                return selectRegister(reg, variable, inRegisterState, outRegisterState);
-            }
-
-        }
-        throw new CiBailout("No register found");
-    }
-
-    private static boolean isFree(CiRegister reg, Object[] inRegisterState, Object[] outRegisterState) {
-        return (inRegisterState == null || inRegisterState[reg.number] == null) && (outRegisterState == null || outRegisterState[reg.number] == null);
-    }
-
-    private Location selectRegister(CiRegister reg, Variable variable, Object[] inRegisterState, Object[] outRegisterState) {
-        Location loc = new Location(variable, reg.asValue(variable.kind));
-        if (inRegisterState != null) {
-            inRegisterState[reg.number] = loc;
-        }
-        if (outRegisterState != null) {
-            outRegisterState[reg.number] = loc;
-        }
-        assert curRegisterLocations.get(variable) == null;
-        curRegisterLocations.put(loc);
-        Debug.log("      selected register %s", loc);
-        return loc;
-    }
-
-    private boolean checkInputState(final Block block) {
-        final BitSet liveState = new BitSet();
-        curStackLocations.forEachLocation(new ValueProcedure() {
-            @Override
-            public CiValue doValue(CiValue value) {
-                liveState.set(asLocation(value).variable.index);
-
-                for (Block pred : block.getPredecessors()) {
-                    LocationMap predState = locationsFor(pred);
-                    if (predState != null) {
-                        assert predState.get(asLocation(value).variable) == value;
-                    } else {
-                        assert block.isLoopHeader();
-                    }
-                }
-                return value;
-            }
-        });
-        assert liveState.equals(curLiveIn);
-        return true;
-    }
-
-    private boolean checkNoCallerSavedRegister() {
-        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
-            assert curOutRegisterState[reg.number] == null || curOutRegisterState[reg.number] == curInstruction : "caller saved register in use accross call site";
-        }
-        return true;
-    }
-
-    private static boolean checkEmpty(Object[] array) {
-        for (Object o : array) {
-            assert o == null;
-        }
-        return true;
-    }
-
-
-    private String logCurrentState() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("  curVariableLocations: ");
-        curStackLocations.forEachLocation(new ValueProcedure() {
-            @Override
-            public CiValue doValue(CiValue value) {
-                sb.append(value).append(" ");
-                return value;
-            }
-        });
-        return sb.toString();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +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.alloc.util;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.alloc.simple.*;
-import com.oracle.max.graal.compiler.cfg.*;
-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.debug.*;
-
-public final class IntervalPrinter {
-
-    public static void printBeforeAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
-        if (Debug.isDumpEnabled()) {
-            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, null);
-            Debug.dump(lir, label);
-            Debug.dump(printer.execute(), label);
-        }
-    }
-
-    public static void printAfterAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
-        if (Debug.isDumpEnabled()) {
-            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, blockEndLocations);
-            Debug.dump(lir, label);
-            Debug.dump(printer.execute(), label);
-        }
-    }
-
-
-    public static class Range {
-        public final int from;
-        public final int to;
-
-        public Range(int from, int to) {
-            this.from = from;
-            this.to = to;
-        }
-    }
-
-    public static class UsePosition {
-        public final int pos;
-        public final String kind;
-
-        public UsePosition(int pos, String kind) {
-            this.pos = pos;
-            this.kind = kind;
-        }
-    }
-
-    public static class Interval {
-        public final String name;
-        public final String description;
-        public final String variable;
-        public final String type;
-        public final List<Range> ranges;
-        public final List<UsePosition> uses;
-
-        protected final int orderNum;
-        protected int lastTo;
-
-        public Interval(int orderNum, String name, String description, String variable, String type) {
-            this.orderNum = orderNum;
-            this.name = name;
-            this.description = description;
-            this.variable = variable;
-            this.type = type;
-            this.ranges = new ArrayList<>();
-            this.uses = new ArrayList<>();
-        }
-    }
-
-
-    private final LIR lir;
-    private final RiRegisterConfig registerConfig;
-    private final DataFlowAnalysis dataFlow;
-    private final LocationMap[] blockEndLocations;
-    private final Variable[] variables;
-    private final Map<String, Interval> intervals;
-
-    private IntervalPrinter(LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
-        this.lir = lir;
-        this.registerConfig = registerConfig;
-        this.dataFlow = dataFlow;
-        this.blockEndLocations = blockEndLocations;
-        this.variables = new Variable[lir.numVariables()];
-        this.intervals = new HashMap<>();
-    }
-
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
-    }
-
-    private int curOpId;
-    private String curUseKind;
-
-    public Interval[] execute() {
-        ValueProcedure varProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return var(value); } };
-
-        for (Block block : lir.linearScanOrder()) {
-            for (LIRInstruction op : block.lir) {
-                op.forEachOutput(varProc);
-            }
-        }
-
-        ValueProcedure useProc = new ValueProcedure() { @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, flags); } };
-
-        intervals.put("call", new Interval(-2, "call", "", "call", "hasCall"));
-        intervals.put("st", new Interval(-1, "st", "", "st", "hasState"));
-
-        for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
-            Block block = lir.linearScanOrder().get(i);
-
-            curOpId = block.getLastLirInstructionId() + 2;
-            for (Block sux : block.getSuccessors()) {
-                BitSet suxIn = dataFlow.liveIn(sux);
-                for (int idx = suxIn.nextSetBit(0); idx >= 0; idx = suxIn.nextSetBit(idx + 1)) {
-                    if (blockEndLocations != null) {
-                        out(blockEndLocations[block.getId()].get(variables[idx]));
-                    } else {
-                        out(variables[idx]);
-                    }
-                }
-            }
-
-            for (int j = block.lir.size() - 1; j >= 0; j--) {
-                LIRInstruction op = block.lir.get(j);
-                if (op.id() >= 0) {
-                    curOpId = op.id();
-                } else {
-                    curOpId = (curOpId - 1) | 1;
-                }
-
-                op.forEachOutput(defProc);
-                op.forEachTemp(defProc);
-                op.forEachInput(useProc);
-                op.forEachAlive(useProc);
-                curUseKind = "L";
-                op.forEachState(useProc);
-                curUseKind = null;
-
-                if (op.hasCall()) {
-                    intervals.get("call").ranges.add(new Range(curOpId, curOpId + 1));
-                }
-                if (op.info != null) {
-                    intervals.get("st").ranges.add(new Range(curOpId, curOpId + 1));
-                }
-            }
-
-            for (Interval interval : intervals.values()) {
-                if (interval.lastTo != 0) {
-                    interval.ranges.add(new Range(block.getFirstLirInstructionId(), interval.lastTo));
-                    interval.lastTo = 0;
-                }
-            }
-        }
-
-        Interval[] intervalsArray = intervals.values().toArray(new Interval[0]);
-        Arrays.sort(intervalsArray, new Comparator<Interval>() {
-            @Override
-            public int compare(Interval o1, Interval o2) {
-                return o1.orderNum - o2.orderNum;
-            }
-        });
-        return intervalsArray;
-    }
-
-    public CiValue var(CiValue value) {
-        if (isLocation(value)) {
-            variables[asLocation(value).variable.index] = asLocation(value).variable;
-        } else if (isVariable(value)) {
-            variables[asVariable(value).index] = asVariable(value);
-        }
-        return value;
-    }
-
-    private Interval findInterval(CiValue value) {
-        Interval interval;
-        if (isLocation(value)) {
-            Interval parent = findInterval(asLocation(value).variable);
-            String name = "v" + asLocation(value).variable.index + ":" + asLocation(value).location;
-            String description = isStackSlot(asLocation(value).location) ? "stack" : "";
-            interval = new Interval(asLocation(value).variable.index * 2 + 1001, name, description, parent.name, value.kind.javaName);
-
-        } else if (isVariable(value)) {
-            interval = new Interval(asVariable(value).index * 2 + 1000, value.toString(), "", value.toString(), value.kind.javaName);
-
-        } else if (isAllocatableRegister(value)) {
-            interval = new Interval(asRegister(value).number, asRegister(value).toString(), "", asRegister(value).toString(), "fixed");
-
-        } else {
-            return null;
-        }
-
-        Interval existing = intervals.get(interval.name);
-        if (existing != null) {
-            return existing;
-        }
-        intervals.put(interval.name, interval);
-        return interval;
-    }
-
-    private String useKind(EnumSet<OperandFlag> flags) {
-        if (curUseKind != null) {
-            return curUseKind;
-        } else if (flags.contains(OperandFlag.Stack)) {
-            return "S";
-        } else {
-            return "M";
-        }
-    }
-
-    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-        Interval interval = findInterval(value);
-        if (interval != null) {
-            if (interval.uses.size() == 0 || interval.uses.get(interval.uses.size() - 1).pos != curOpId) {
-                interval.uses.add(new UsePosition(curOpId, useKind(flags)));
-            }
-            if (interval.lastTo == 0) {
-                interval.lastTo = curOpId + (mode == OperandMode.Alive ? 1 : 0);
-            }
-        }
-        return value;
-    }
-
-    private CiValue def(CiValue value, EnumSet<OperandFlag> flags) {
-        Interval interval = findInterval(value);
-        if (interval != null) {
-            interval.uses.add(new UsePosition(curOpId, useKind(flags)));
-            if (interval.lastTo == 0) {
-                interval.ranges.add(new Range(curOpId, curOpId + 1));
-            } else {
-                interval.ranges.add(new Range(curOpId, interval.lastTo));
-            }
-            interval.lastTo = 0;
-        }
-        return value;
-    }
-
-    private CiValue out(CiValue value) {
-        Interval interval = findInterval(value);
-        if (interval != null) {
-            interval.lastTo = curOpId;
-        }
-        return value;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/Location.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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.alloc.util;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.lir.*;
-
-public class Location extends CiValue {
-    private static final long serialVersionUID = -1786677729152726126L;
-
-    public final Variable variable;
-    public final CiValue location;
-
-    public Location(Variable variable, CiValue location) {
-        super(variable.kind);
-        this.variable = variable;
-        this.location = location;
-
-        assert variable.kind == location.kind;
-    }
-
-    @Override
-    public String toString() {
-        return variable + "[" + location + "]";
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LocationMap.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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.alloc.util;
-
-import static com.oracle.max.graal.alloc.util.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
-
-public class LocationMap {
-    private final Location[] locations;
-
-    public LocationMap(int numVariables) {
-        locations = new Location[numVariables];
-    }
-
-    public LocationMap(LocationMap template) {
-        locations = Arrays.copyOf(template.locations, template.locations.length);
-    }
-
-    public Location get(Variable variable) {
-        assert locations[variable.index] == null || locations[variable.index].variable == variable;
-        return locations[variable.index];
-    }
-
-    public void put(Location location) {
-        locations[location.variable.index] = location;
-    }
-
-    public void clear(Variable variable) {
-        locations[variable.index] = null;
-    }
-
-    public void forEachLocation(ValueProcedure proc) {
-        for (int i = 0; i < locations.length; i++) {
-            if (locations[i] != null) {
-                CiValue newValue = proc.doValue(locations[i], null, null);
-                assert newValue == null || asLocation(newValue).variable == locations[i].variable;
-                locations[i] = (Location) newValue;
-            }
-        }
-    }
-
-    public boolean checkEmpty() {
-        for (int i = 0; i < locations.length; i++) {
-            assert locations[i] == null;
-        }
-        return true;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LocationUtil.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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.alloc.util;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.lir.*;
-
-public class LocationUtil extends ValueUtil {
-
-    public static boolean isLocation(CiValue value) {
-        assert value != null;
-        return value instanceof Location;
-    }
-
-    public static Location asLocation(CiValue value) {
-        assert value != null;
-        return (Location) value;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/MoveResolver.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +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.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.alloc.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.debug.*;
-import com.oracle.max.graal.graph.*;
-
-public abstract class MoveResolver {
-    private final LIR lir;
-    private final FrameMap frameMap;
-    private final int[] registersBlocked;
-    private final Map<CiValue, Integer> valuesBlocked;
-    private final List<CiValue> mappingFrom;
-    private final List<Location> mappingTo;
-    private final LIRInsertionBuffer insertionBuffer;
-    private int insertPos;
-
-    public MoveResolver(LIR lir, FrameMap frameMap) {
-        this.lir = lir;
-        this.frameMap = frameMap;
-
-        registersBlocked = new int[frameMap.target.arch.registers.length];
-        valuesBlocked = new HashMap<>();
-
-        mappingFrom = new ArrayList<>();
-        mappingTo = new ArrayList<>();
-        insertionBuffer = new LIRInsertionBuffer();
-        insertPos = -1;
-
-        assert checkEmpty();
-    }
-
-    public void init(List<LIRInstruction> newInsertList, int newInsertPos) {
-        assert checkEmpty();
-
-        if (insertionBuffer.lirList() != newInsertList) {
-            // Block changed, so append insertionBuffer because it is bound to a specific block
-            finish();
-            insertionBuffer.init(newInsertList);
-        }
-        insertPos = newInsertPos;
-
-        assert checkValid();
-    }
-
-    public void add(CiValue from, Location to) {
-        assert checkValid();
-        assert isLocation(from) || isConstant(from);
-        assert from != to;
-
-        Debug.log("mr    add mapping from %s to %s", from, to);
-        mappingFrom.add(from);
-        mappingTo.add(to);
-
-        assert checkValid();
-    }
-
-    public boolean hasMappings() {
-        return mappingFrom.size() > 0;
-    }
-
-    public void resolve() {
-        assert checkValid();
-
-        if (mappingFrom.size() == 1) {
-            // If there is only one mapping, it is trivial that this mapping is safe to resolve.
-            Debug.log("mr    resolve  mappings: %d", mappingFrom.size());
-            insertMove(mappingFrom.get(0), mappingTo.get(0));
-            mappingFrom.remove(0);
-            mappingTo.remove(0);
-        } else if (mappingFrom.size() > 1) {
-            Debug.log("mr    resolve  mappings: %d", mappingFrom.size());
-            doResolve();
-        }
-        insertPos = -1;
-
-        assert checkEmpty();
-    }
-
-    public void finish() {
-        assert checkEmpty();
-
-        if (insertionBuffer.initialized()) {
-            insertionBuffer.finish();
-        }
-
-        assert !insertionBuffer.initialized() : "must be uninitialized now";
-        assert checkEmpty();
-    }
-
-
-    private void doResolve() {
-        // Block all registers and stack slots that are used as inputs of a move.
-        // When a register is blocked, no move to this register is emitted.
-        // This is necessary for detecting cycles in moves.
-        for (CiValue from : mappingFrom) {
-            block(from);
-        }
-
-        while (mappingFrom.size() > 0) {
-            boolean processed = false;
-            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
-                CiValue from = mappingFrom.get(i);
-                Location to = mappingTo.get(i);
-
-                if (safeToProcessMove(from, to)) {
-                    insertMove(from, to);
-                    unblock(from);
-                    mappingFrom.remove(i);
-                    mappingTo.remove(i);
-                    processed = true;
-                }
-            }
-
-            if (!processed) {
-                // No move could be processed because there is a cycle in the move list
-                // (e.g., r1 -> r2, r2 -> r1), so one location must be spilled.
-                spill();
-            }
-        }
-    }
-
-    private void spill() {
-        Location spillCandidate = null;
-        int exchangeCandidate = -1;
-        int exchangeOther = -1;
-
-        for (int i = mappingFrom.size() - 1; i >= 0; i--) {
-            CiValue from = mappingFrom.get(i);
-            Location to = mappingTo.get(i);
-            assert !safeToProcessMove(from, to) : "would not be in this code otherwise";
-
-            if (isConstant(from)) {
-                continue;
-            }
-            CiValue fromLoc = asLocation(from).location;
-
-            // Check if we can insert an exchange to save us from spilling.
-            if (isRegister(fromLoc) && isRegister(to) && asRegister(fromLoc) != asRegister(to) && blockedCount(to) == 1) {
-                for (int j = mappingFrom.size() - 1; j >= 0; j--) {
-                    CiValue possibleOther = mappingFrom.get(j);
-                    if (isLocation(possibleOther)) {
-                        if (asLocation(possibleOther).location == to.location) {
-                            assert exchangeCandidate == -1 : "must not find twice because of blocked check above";
-                            exchangeCandidate = i;
-                            exchangeOther = j;
-                        } else if (i != j && asLocation(possibleOther).location == fromLoc) {
-                            // From is read multiple times, so exchange would be too complicated.
-                            exchangeCandidate = -1;
-                            break;
-                        }
-                    }
-                }
-            }
-
-            if (exchangeCandidate != -1) {
-                // Already found a result, no need to search further
-                break;
-            }
-            if (spillCandidate == null || isStackSlot(spillCandidate.location)) {
-                // this interval cannot be processed now because target is not free
-                spillCandidate = asLocation(from);
-            }
-        }
-
-        if (exchangeCandidate != -1) {
-            Location from = asLocation(mappingFrom.get(exchangeCandidate));
-            Location to = mappingTo.get(exchangeCandidate);
-            Location other = asLocation(mappingFrom.get(exchangeOther));
-
-            Location newOther = new Location(other.variable, from.variable);
-            mappingFrom.set(exchangeOther, newOther);
-
-            insertExchange(newOther, to);
-            unblock(to);
-            mappingFrom.remove(exchangeCandidate);
-            mappingTo.remove(exchangeCandidate);
-
-        } else {
-            assert spillCandidate != null : "no location for spilling found";
-
-            Location spillLocation = new Location(spillCandidate.variable, frameMap.allocateSpillSlot(spillCandidate.kind));
-            insertMove(spillCandidate, spillLocation);
-
-            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
-                if (mappingFrom.get(i) == spillCandidate) {
-                    mappingFrom.set(i, spillLocation);
-                    unblock(spillCandidate);
-                    block(spillLocation);
-                }
-            }
-            assert blockedCount(spillCandidate) == 0 : "register must be unblocked after spilling";
-        }
-    }
-
-    private void block(CiValue value) {
-        if (isLocation(value)) {
-            CiValue location = asLocation(value).location;
-            if (isRegister(location)) {
-                registersBlocked[asRegister(location).number]++;
-            } else {
-                Integer count = valuesBlocked.get(location);
-                valuesBlocked.put(location, count == null ? 1 : count + 1);
-            }
-        }
-    }
-
-    private void unblock(CiValue value) {
-        if (isLocation(value)) {
-            assert blockedCount(asLocation(value)) > 0;
-            CiValue location = asLocation(value).location;
-            if (isRegister(location)) {
-                registersBlocked[asRegister(location).number]--;
-            } else {
-                Integer count = valuesBlocked.remove(location);
-                if (count > 1) {
-                    valuesBlocked.put(location, count - 1);
-                }
-            }
-        }
-    }
-
-    private int blockedCount(Location value) {
-        CiValue location = asLocation(value).location;
-        if (isRegister(location)) {
-            return registersBlocked[asRegister(location).number];
-        } else {
-            Integer count = valuesBlocked.get(location);
-            return count == null ? 0 : count;
-        }
-    }
-
-    private boolean safeToProcessMove(CiValue from, Location to) {
-        int count = blockedCount(to);
-        return count == 0 || (count == 1 && isLocation(from) && asLocation(from).location == to.location);
-    }
-
-    private void insertExchange(Location from, Location to) {
-        Debug.log("mr      XCHG %s, %s", from, to);
-        // TODO create XCHG instruction and use it here
-        insertionBuffer.append(insertPos, null);
-        throw GraalInternalError.unimplemented();
-    }
-
-    private void insertMove(CiValue src, Location dst) {
-        if (isStackSlot(dst.location) && isLocation(src) && isStackSlot(asLocation(src).location)) {
-            // Move between two stack slots. We need a temporary registers. If the allocator can give
-            // us a free register, we need two moves: src->scratch, scratch->dst
-            // If the allocator cannot give us a free register (it returns a Location in this case),
-            // we need to spill the scratch register first, so we need four moves in total.
-
-            CiValue scratch = scratchRegister(dst.variable);
-
-            Location scratchSaved = null;
-            CiValue scratchRegister = scratch;
-            if (isLocation(scratch)) {
-                scratchSaved = new Location(asLocation(scratch).variable, frameMap.allocateSpillSlot(scratch.kind));
-                insertMove(scratch, scratchSaved);
-                scratchRegister = asLocation(scratch).location;
-            }
-            assert isRegister(scratchRegister);
-
-            Location scratchLocation = new Location(dst.variable, scratchRegister);
-            insertMove(src, scratchLocation);
-            insertMove(scratchLocation, dst);
-
-            if (scratchSaved != null) {
-                insertMove(scratchSaved, asLocation(scratch));
-            }
-
-        } else {
-            Debug.log("mr      MOV %s -> %s", src, dst);
-            insertionBuffer.append(insertPos, lir.spillMoveFactory.createMove(dst,  src));
-        }
-    }
-
-    /**
-     * Provides a register that can be used by the move resolver. If the returned value is a
-     * {@link CiRegisterValue}, the register can be overwritten without precautions. If the
-     * returned value is a {@link Location}, it needs to be spilled and rescued itself.
-     */
-    protected abstract CiValue scratchRegister(Variable spilled);
-
-    private boolean checkEmpty() {
-        assert insertPos == -1;
-        assert mappingFrom.size() == 0 && mappingTo.size() == 0;
-        for (int registerBlocked : registersBlocked) {
-            assert registerBlocked == 0;
-        }
-        assert valuesBlocked.size() == 0;
-        return true;
-    }
-
-    private boolean checkValid() {
-        assert insertPos != -1;
-        for (int registerBlocked : registersBlocked) {
-            assert registerBlocked == 0;
-        }
-        assert mappingFrom.size() == mappingTo.size();
-        assert insertionBuffer.initialized() && insertPos != -1;
-
-        for (int i = 0; i < mappingTo.size(); i++) {
-            CiValue from = mappingFrom.get(i);
-            Location to = mappingTo.get(i);
-
-            assert from.kind.stackKind() == to.kind;
-
-            for (int j = i + 1; j < mappingTo.size(); j++) {
-                Location otherTo = mappingTo.get(j);
-                assert to != otherTo && to.variable != otherTo.variable && to.location != otherTo.location : "Cannot write to same location twice";
-            }
-        }
-        return true;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,250 +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.LocationUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.cfg.*;
-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.debug.*;
-import com.oracle.max.graal.graph.*;
-
-public final class RegisterVerifier {
-    private final FrameMap frameMap;
-
-    /**
-     * All blocks that must be processed.
-     */
-    private final List<Block> workList;
-
-    /**
-     * Saved information of previous check.
-     * <br>
-     * State mapping: mapping from registers and stack slots ({@link CiRegister} and {@link Integer} stack slot offsets) to the
-     * value that is currently contained in there ({@link Location} for operands that were variables; {@link CiRegisterValue} or
-     * {@link CiStackSlot} for operands that used fixed registers or stack slots).
-     */
-    private final Map<Object, CiValue>[] blockStates;
-
-    private void addToWorkList(Block block) {
-        if (!workList.contains(block)) {
-            workList.add(block);
-        }
-    }
-
-    private Map<Object, CiValue> stateFor(Block block) {
-        return blockStates[block.getId()];
-    }
-
-    private void setStateFor(Block block, Map<Object, CiValue> savedState) {
-        blockStates[block.getId()] = savedState;
-    }
-
-    private static Map<Object, CiValue> copy(Map<Object, CiValue> inputState) {
-        return new HashMap<>(inputState);
-    }
-
-    public static boolean verify(LIR lir, FrameMap frameMap) {
-        RegisterVerifier verifier = new RegisterVerifier(lir, frameMap);
-        verifier.verify(lir.cfg.getStartBlock());
-        return true;
-    }
-
-    @SuppressWarnings("unchecked")
-    private RegisterVerifier(LIR lir, FrameMap frameMap) {
-        this.frameMap = frameMap;
-        this.workList = new LinkedList<>();
-        this.blockStates = new Map[lir.linearScanOrder().size()];
-    }
-
-    private Map<Object, CiValue> curInputState;
-
-    private void verify(Block startBlock) {
-        ValueProcedure useProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, flags); } };
-        ValueProcedure tempProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return temp(value); } };
-        ValueProcedure outputProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return output(value); } };
-
-        curInputState = new HashMap<>();
-        setStateFor(startBlock, curInputState);
-        addToWorkList(startBlock);
-
-        Debug.log("==== start verify register allocation ====");
-        do {
-            Block block = workList.remove(0);
-
-            // Must copy state because it is modified.
-            curInputState = copy(stateFor(block));
-            Debug.log("start block %s %s", block, block.getLoop());
-            Debug.log(logCurrentState());
-
-            for (LIRInstruction op : block.lir) {
-                Debug.log("  op %d %s", op.id(), op);
-
-                op.forEachInput(useProc);
-                if (op.hasCall()) {
-                    invalidateRegisters();
-                }
-                op.forEachAlive(useProc);
-                op.forEachState(useProc);
-                op.forEachTemp(tempProc);
-                op.forEachOutput(outputProc);
-            }
-
-            for (Block succ : block.getSuccessors()) {
-                processSuccessor(succ);
-            }
-
-            Debug.log("end block %s", block);
-        } while (!workList.isEmpty());
-        Debug.log("==== end verify register allocation ====");
-    }
-
-    private void processSuccessor(Block succ) {
-        Map<Object, CiValue> savedState = stateFor(succ);
-        if (savedState == null) {
-            // Block was not processed before, so set initial inputState.
-            Debug.log("  successor %s: initial visit", succ);
-            setStateFor(succ, copy(curInputState));
-            addToWorkList(succ);
-
-        } else {
-            // This block was already processed before.
-            // Check if new inputState is consistent with savedState.
-            Debug.log("  successor %s: state present", succ);
-            Iterator<Map.Entry<Object, CiValue>> iter = savedState.entrySet().iterator();
-            while (iter.hasNext()) {
-                Map.Entry<Object, CiValue> entry = iter.next();
-                CiValue savedValue = entry.getValue();
-                CiValue inputValue = curInputState.get(entry.getKey());
-
-                if (savedValue != inputValue) {
-                    // Current inputState and previous savedState assume a different value in this register.
-                    // Assume that this register is invalid and remove it from the saved state.
-                    Debug.log("    invalididating %s because it is inconsistent with %s", savedValue, inputValue);
-                    iter.remove();
-                    // Must re-visit this block.
-                    addToWorkList(succ);
-                }
-            }
-        }
-    }
-
-    private void invalidateRegisters() {
-        // Invalidate all caller save registers at calls.
-        Iterator<Object> iter = curInputState.keySet().iterator();
-        while (iter.hasNext()) {
-            Object value1 = iter.next();
-            if (value1 instanceof CiRegister && frameMap.registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) {
-                Debug.log("    remove caller save register %s", value1);
-                iter.remove();
-            }
-        }
-    }
-
-    /**
-     * Gets the mapping key for a value. The key should be as narrow as possible, e.g., it should not
-     * include the kind of the value because we do not want to distinguish between the same register with
-     * different kinds.
-     */
-    private Object key(CiValue value) {
-        if (isLocation(value)) {
-            return key(asLocation(value).location);
-        } else if (isRegister(value)) {
-            return asRegister(value);
-        } else if (isStackSlot(value)) {
-            return Integer.valueOf(frameMap.offsetForStackSlot(asStackSlot(value)));
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    private boolean isIgnoredRegister(CiValue value) {
-        return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
-    }
-
-    private CiValue use(CiValue value, EnumSet<OperandFlag> flags) {
-        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
-            CiValue actual = curInputState.get(key(value));
-            if (actual == null && flags.contains(OperandFlag.Uninitialized)) {
-                // OK, since uninitialized values are allowed explicitly.
-            } else if (value != actual) {
-                Debug.log("Error in register allocation: %s != %s for key %s", value, actual, key(value));
-                Debug.log(logCurrentState());
-                throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-        return value;
-    }
-
-    private CiValue temp(CiValue value) {
-        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
-            Debug.log("    temp %s -> remove key %s", value, key(value));
-            curInputState.remove(key(value));
-        }
-        return value;
-    }
-
-    private CiValue output(CiValue value) {
-        if (value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
-            Debug.log("    output %s -> set key %s", value, key(value));
-            curInputState.put(key(value), value);
-        }
-        return value;
-    }
-
-
-    private String logCurrentState() {
-        ArrayList<Object> keys = new ArrayList<>(curInputState.keySet());
-        Collections.sort(keys, new Comparator<Object>() {
-            @Override
-            public int compare(Object o1, Object o2) {
-                if (o1 instanceof CiRegister) {
-                    if (o2 instanceof CiRegister) {
-                        return ((CiRegister) o1).number - ((CiRegister) o2).number;
-                    } else {
-                        return -1;
-                    }
-                } else {
-                    if (o2 instanceof CiRegister) {
-                        return 1;
-                    } else {
-                        return ((Integer) o1).intValue() - ((Integer) o2).intValue();
-                    }
-                }
-            }
-        });
-
-        StringBuilder sb = new StringBuilder("    state: ");
-        for (Object key : keys) {
-            sb.append(key).append("=").append(curInputState.get(key)).append(" ");
-        }
-        return sb.toString();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Wed Feb 08 19:25:29 2012 -0800
@@ -31,16 +31,16 @@
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.graal.alloc.simple.*;
 import com.oracle.max.graal.compiler.alloc.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.target.*;
 import com.oracle.max.graal.cri.*;
 import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 
 public class GraalCompiler {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ComputeLinearScanOrder.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ComputeLinearScanOrder.java	Wed Feb 08 19:25:29 2012 -0800
@@ -27,8 +27,8 @@
 
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 public final class ComputeLinearScanOrder {
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Wed Feb 08 19:25:29 2012 -0800
@@ -24,10 +24,10 @@
 
 import java.util.*;
 
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 /**
  * This class performs basic optimizations on the control flow graph after LIR generation.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Wed Feb 08 19:25:29 2012 -0800
@@ -24,9 +24,9 @@
 
 import java.util.*;
 
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.StandardOp.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 /**
  * This class optimizes moves, particularly those that result from eliminating SSA form.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java	Wed Feb 08 19:25:29 2012 -0800
@@ -29,8 +29,8 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.lir.*;
 
 /**
  * Represents an interval in the {@linkplain LinearScan linear scan register allocator}.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LIRInsertionBuffer.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +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.
- */
-package com.oracle.max.graal.compiler.alloc;
-
-import java.util.*;
-
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
-
-/**
- * A buffer to enqueue updates to a list. This avoids frequent re-sizing of the list and copying of list elements
- * when insertions are done at multiple positions of the list. Additionally, it ensures that the list is not modified
- * while it is, e.g., iterated, and instead only modified once after the iteration is done.
- * <br>
- * The buffer uses internal data structures to store the enqueued updates. To avoid allocations, a buffer can be re-used.
- * Call the methods in the following order:
- * {@link #init()}, {@link #append()}, {@link #append()}, ..., {@link #finish()}, {@link #init()}, ...
- * <br>
- * Note: This class does not depend on LIRInstruction, so we could make it a generic utility class.
- */
-public final class LIRInsertionBuffer {
-
-    /**
-     * The lir list where ops of this buffer should be inserted later (null when uninitialized).
-     */
-    private List<LIRInstruction> lir;
-
-    /**
-     * List of insertion points. index and count are stored alternately:
-     * indexAndCount[i * 2]: the index into lir list where "count" ops should be inserted
-     * indexAndCount[i * 2 + 1]: the number of ops to be inserted at index
-     */
-    private final IntList indexAndCount;
-
-    /**
-     * The LIROps to be inserted.
-     */
-    private final List<LIRInstruction> ops;
-
-
-    public LIRInsertionBuffer() {
-        indexAndCount = new IntList(8);
-        ops = new ArrayList<>(8);
-    }
-
-    /**
-     * Initialize this buffer. This method must be called before using {@link #append()}.
-     */
-    public void init(List<LIRInstruction> newLir) {
-        assert !initialized() : "already initialized";
-        assert indexAndCount.size() == 0 && ops.size() == 0;
-        this.lir = newLir;
-    }
-
-    public boolean initialized() {
-        return lir != null;
-    }
-
-    public List<LIRInstruction> lirList() {
-        return lir;
-    }
-
-    /**
-     * Enqueue a new instruction that will be appended to the instruction list when {@link #finish()} is called.
-     * The new instruction is added <b>before</b> the existing instruction with the given index. This method can only be called
-     * with increasing values of index, e.g., once an instruction was appended with index 4, subsequent instructions can
-     * only be appended with index 4 or higher.
-     */
-    public void append(int index, LIRInstruction op) {
-        int i = numberOfInsertionPoints() - 1;
-        if (i < 0 || indexAt(i) < index) {
-            appendNew(index, 1);
-        } else {
-            assert indexAt(i) == index : "can append LIROps in ascending order only";
-            assert countAt(i) > 0 : "check";
-            setCountAt(i, countAt(i) + 1);
-        }
-        ops.add(op);
-
-        assert verify();
-    }
-
-    /**
-     * Append all enqueued instructions to the instruction list. After that, {@link init()} can be called again to re-use this buffer.
-     */
-    public void finish() {
-        if (ops.size() > 0) {
-            int n = lir.size();
-            // increase size of instructions list
-            for (int i = 0; i < ops.size(); i++) {
-                lir.add(null);
-            }
-            // insert ops from buffer into instructions list
-            int opIndex = ops.size() - 1;
-            int ipIndex = numberOfInsertionPoints() - 1;
-            int fromIndex = n - 1;
-            int toIndex = lir.size() - 1;
-            while (ipIndex >= 0) {
-                int index = indexAt(ipIndex);
-                // make room after insertion point
-                while (fromIndex >= index) {
-                    lir.set(toIndex--, lir.get(fromIndex--));
-                }
-                // insert ops from buffer
-                for (int i = countAt(ipIndex); i > 0; i--) {
-                    lir.set(toIndex--, ops.get(opIndex--));
-                }
-                ipIndex--;
-            }
-            indexAndCount.clear();
-            ops.clear();
-        }
-        lir = null;
-    }
-
-    private void appendNew(int index, int count) {
-        indexAndCount.add(index);
-        indexAndCount.add(count);
-    }
-
-    private void setCountAt(int i, int value) {
-        indexAndCount.set((i << 1) + 1, value);
-    }
-
-    private int numberOfInsertionPoints() {
-        assert indexAndCount.size() % 2 == 0 : "must have a count for each index";
-        return indexAndCount.size() >> 1;
-    }
-
-    private int indexAt(int i) {
-        return indexAndCount.get((i << 1));
-    }
-
-    private int countAt(int i) {
-        return indexAndCount.get((i << 1) + 1);
-    }
-
-    private boolean verify() {
-        int sum = 0;
-        int prevIdx = -1;
-
-        for (int i = 0; i < numberOfInsertionPoints(); i++) {
-            assert prevIdx < indexAt(i) : "index must be ordered ascending";
-            sum += countAt(i);
-        }
-        assert sum == ops.size() : "wrong total sum";
-        return true;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Wed Feb 08 19:25:29 2012 -0800
@@ -35,16 +35,14 @@
 import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding;
 import com.oracle.max.graal.compiler.alloc.Interval.RegisterPriority;
 import com.oracle.max.graal.compiler.alloc.Interval.SpillState;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.compiler.gen.*;
-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.StandardOp.MoveOp;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 /**
  * An implementation of the linear scan register allocator algorithm described
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Wed Feb 08 19:25:29 2012 -0800
@@ -35,10 +35,10 @@
 import com.oracle.max.graal.compiler.alloc.Interval.RegisterPriority;
 import com.oracle.max.graal.compiler.alloc.Interval.SpillState;
 import com.oracle.max.graal.compiler.alloc.Interval.State;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.util.*;
-import com.oracle.max.graal.compiler.lir.StandardOp.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 /**
  */
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Wed Feb 08 19:25:29 2012 -0800
@@ -29,7 +29,7 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.lir.*;
 
 /**
  */
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java	Wed Feb 08 19:25:29 2012 -0800
@@ -29,10 +29,10 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 /**
  */
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +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.asm;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIR.SlowPath;
-import com.oracle.max.graal.debug.*;
-import com.oracle.max.graal.graph.*;
-
-public class TargetMethodAssembler {
-
-    private static class ExceptionInfo {
-        public final int codeOffset;
-        public final LabelRef exceptionEdge;
-
-        public ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
-            this.codeOffset = pcOffset;
-            this.exceptionEdge = exceptionEdge;
-        }
-    }
-
-    public final AbstractAssembler asm;
-    public final CiTargetMethod targetMethod;
-    public final CiTarget target;
-    public final RiRuntime runtime;
-    public final FrameMap frameMap;
-    public final List<SlowPath> slowPaths;
-
-    private List<ExceptionInfo> exceptionInfoList;
-    private int lastSafepointPos;
-
-    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
-        this.target = target;
-        this.runtime = runtime;
-        this.frameMap = frameMap;
-        this.slowPaths = slowPaths;
-        this.asm = asm;
-        this.targetMethod = new CiTargetMethod();
-        // 0 is a valid pc for safepoints in template methods
-        this.lastSafepointPos = -1;
-    }
-
-    public void setFrameSize(int frameSize) {
-        targetMethod.setFrameSize(frameSize);
-    }
-
-    public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) {
-        return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
-    }
-
-    public void blockComment(String s) {
-        targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s));
-    }
-
-    public CiTargetMethod finishTargetMethod(Object name, boolean isStub) {
-        // Install code, data and frame size
-        targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
-
-        // Record exception handlers if they exist
-        if (exceptionInfoList != null) {
-            for (ExceptionInfo ei : exceptionInfoList) {
-                int codeOffset = ei.codeOffset;
-                targetMethod.recordExceptionHandler(codeOffset, -1, 0, ei.exceptionEdge.label().position(), -1, null);
-            }
-        }
-
-        Debug.metric("TargetMethods").increment();
-        Debug.metric("CodeBytesEmitted").add(targetMethod.targetCodeSize());
-        Debug.metric("SafepointsEmitted").add(targetMethod.safepoints.size());
-        Debug.metric("DataPatches").add(targetMethod.dataReferences.size());
-        Debug.metric("ExceptionHandlersEmitted").add(targetMethod.exceptionHandlers.size());
-
-        Debug.log("Finished target method %s, isStub %d", name, isStub);
-/*
-        if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
-            Util.printSection("Target Method", Util.SECTION_CHARACTER);
-            TTY.println("Name: " + name);
-            TTY.println("Frame size: " + targetMethod.frameSize());
-            TTY.println("Register size: " + asm.target.arch.registerReferenceMapBitCount);
-
-            if (GraalOptions.PrintCodeBytes) {
-                Util.printSection("Code", Util.SUB_SECTION_CHARACTER);
-                TTY.println("Code: %d bytes", targetMethod.targetCodeSize());
-                Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), GraalOptions.PrintAssemblyBytesPerLine);
-            }
-
-            Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER);
-            String disassembly = runtime.disassemble(targetMethod);
-            TTY.println(disassembly);
-            boolean noDis = disassembly == null || disassembly.length() == 0;
-
-            Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER);
-            for (CiTargetMethod.Safepoint x : targetMethod.safepoints) {
-                TTY.println(x.toString());
-                if (noDis && x.debugInfo != null) {
-                    TTY.println(CiUtil.indent(x.debugInfo.toString(), "  "));
-                }
-            }
-
-            Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER);
-            for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) {
-                TTY.println(x.toString());
-            }
-
-            Util.printSection("Marks", Util.SUB_SECTION_CHARACTER);
-            for (CiTargetMethod.Mark x : targetMethod.marks) {
-                TTY.println(x.toString());
-            }
-
-            Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER);
-            for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) {
-                TTY.println(x.toString());
-            }
-        }
-*/
-
-        return targetMethod;
-    }
-
-    public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) {
-        if (info != null) {
-            if (info.exceptionEdge != null) {
-                if (exceptionInfoList == null) {
-                    exceptionInfoList = new ArrayList<>(4);
-                }
-                exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge));
-            }
-        }
-    }
-
-    public void recordImplicitException(int pcOffset, LIRDebugInfo info) {
-        // record an implicit exception point
-        if (info != null) {
-            assert lastSafepointPos < pcOffset : lastSafepointPos + "<" + pcOffset;
-            lastSafepointPos = pcOffset;
-            targetMethod.recordSafepoint(pcOffset, info.debugInfo());
-            assert info.exceptionEdge == null;
-        }
-    }
-
-    public void recordDirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
-        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
-        assert lastSafepointPos < posAfter;
-        lastSafepointPos = posAfter;
-        targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, true);
-    }
-
-    public void recordIndirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
-        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
-        assert lastSafepointPos < posAfter;
-        lastSafepointPos = posAfter;
-        targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false);
-    }
-
-    public void recordSafepoint(int pos, LIRDebugInfo info) {
-        // safepoints always need debug info
-        CiDebugInfo debugInfo = info.debugInfo();
-        assert lastSafepointPos < pos;
-        lastSafepointPos = pos;
-        targetMethod.recordSafepoint(pos, debugInfo);
-    }
-
-    public CiAddress recordDataReferenceInCode(CiConstant data, int alignment) {
-        assert data != null;
-        int pos = asm.codeBuffer.position();
-        Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
-        targetMethod.recordDataReference(pos, data, alignment);
-        return CiAddress.Placeholder;
-    }
-
-    public int lastSafepointPos() {
-        return lastSafepointPos;
-    }
-
-
-    /**
-     * Returns the integer value of any constants that can be represented by a 32-bit integer value,
-     * including long constants that fit into the 32-bit range.
-     */
-    public int asIntConst(CiValue value) {
-        assert (value.kind.stackKind() == CiKind.Int || value.kind == CiKind.Jsr || value.kind == CiKind.Long) && isConstant(value);
-        long c = ((CiConstant) value).asLong();
-        if (!(NumUtil.isInt(c))) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-        return (int) c;
-    }
-
-    /**
-     * Returns the address of a float constant that is embedded as a data references into the code.
-     */
-    public CiAddress asFloatConstRef(CiValue value) {
-        return asFloatConstRef(value, 4);
-    }
-
-    public CiAddress asFloatConstRef(CiValue value, int alignment) {
-        assert value.kind == CiKind.Float && isConstant(value);
-        return recordDataReferenceInCode((CiConstant) value, alignment);
-    }
-
-    /**
-     * Returns the address of a double constant that is embedded as a data references into the code.
-     */
-    public CiAddress asDoubleConstRef(CiValue value) {
-        return asDoubleConstRef(value, 8);
-    }
-
-    public CiAddress asDoubleConstRef(CiValue value, int alignment) {
-        assert value.kind == CiKind.Double && isConstant(value);
-        return recordDataReferenceInCode((CiConstant) value, alignment);
-    }
-
-    /**
-     * Returns the address of a long constant that is embedded as a data references into the code.
-     */
-    public CiAddress asLongConstRef(CiValue value) {
-        assert value.kind == CiKind.Long && isConstant(value);
-        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;
-            return new CiAddress(slot.kind, frameMap.registerConfig.getFrameRegister().asValue(), frameMap.offsetForStackSlot(slot));
-        }
-        return (CiAddress) value;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/Block.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +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.cfg;
-
-import java.util.*;
-
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.nodes.*;
-import com.oracle.max.graal.nodes.java.*;
-
-public class Block {
-    protected int id;
-
-    protected BeginNode beginNode;
-    protected Node endNode;
-    protected Loop loop;
-    protected double probability;
-
-    protected List<Block> predecessors;
-    protected List<Block> successors;
-
-    protected Block dominator;
-    protected List<Block> dominated;
-    protected Block postdominator;
-
-    // Fields that still need to be worked on, try to remove them later.
-    public List<LIRInstruction> lir;
-    public boolean align;
-    public int linearScanNumber;
-
-    public Block() {
-        id = ControlFlowGraph.BLOCK_ID_INITIAL;
-    }
-
-    public int getId() {
-        assert id >= 0;
-        return id;
-    }
-
-    public BeginNode getBeginNode() {
-        return beginNode;
-    }
-
-    public Node getEndNode() {
-        return endNode;
-    }
-
-    public Loop getLoop() {
-        return loop;
-    }
-
-    public int getLoopDepth() {
-        return loop == null ? 0 : loop.depth;
-    }
-
-    public boolean isLoopHeader() {
-        return getBeginNode() instanceof LoopBeginNode;
-    }
-
-    public boolean isLoopEnd() {
-        return getEndNode() instanceof LoopEndNode;
-    }
-
-    public boolean isExceptionEntry() {
-        return getBeginNode().next() instanceof ExceptionObjectNode;
-    }
-
-    public List<Block> getPredecessors() {
-        return predecessors;
-    }
-
-    public List<Block> getSuccessors() {
-        return successors;
-    }
-
-    public Block getDominator() {
-        return dominator;
-    }
-
-    public List<Block> getDominated() {
-        if (dominated == null) {
-            return Collections.emptyList();
-        }
-        return dominated;
-    }
-
-    public Block getPostdominator() {
-        return postdominator;
-    }
-
-    private class NodeIterator implements Iterator<Node> {
-        private Node cur;
-
-        public NodeIterator() {
-            cur = getBeginNode();
-        }
-
-        @Override
-        public boolean hasNext() {
-            return cur != null;
-        }
-
-        @Override
-        public Node next() {
-            Node result = cur;
-            if (cur == getEndNode()) {
-                cur = null;
-            } else {
-                cur = ((FixedWithNextNode) cur).next();
-            }
-            assert !(cur instanceof BeginNode);
-            return result;
-        }
-
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public Iterable<Node> getNodes() {
-        return new Iterable<Node>() {
-            @Override
-            public Iterator<Node> iterator() {
-                return new NodeIterator();
-            }
-        };
-    }
-
-    public int getFirstLirInstructionId() {
-        int result = lir.get(0).id();
-        assert result >= 0;
-        return result;
-    }
-
-    public int getLastLirInstructionId() {
-        int result = lir.get(lir.size() - 1).id();
-        assert result >= 0;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "B" + id;
-    }
-
-
-// to be inlined later on
-    public int numberOfPreds() {
-        return getPredecessors().size();
-    }
-
-    public int numberOfSux() {
-        return getSuccessors().size();
-    }
-
-    public Block predAt(int i) {
-        return getPredecessors().get(i);
-    }
-
-    public Block suxAt(int i) {
-        return getSuccessors().get(i);
-    }
-// end to be inlined later on
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/BlockMap.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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.cfg;
-
-public class BlockMap<T> {
-    private final T[] data;
-
-    @SuppressWarnings("unchecked")
-    public BlockMap(ControlFlowGraph cfg) {
-        data = (T[]) new Object[cfg.getBlocks().length];
-    }
-
-    public T get(Block block) {
-        return data[block.getId()];
-    }
-
-    public void put(Block block, T value) {
-        data[block.getId()] = value;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/CFGVerifier.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.cfg;
-
-public class CFGVerifier {
-    public static boolean verify(ControlFlowGraph cfg) {
-        for (Block block : cfg.getBlocks()) {
-            assert cfg.getBlocks()[block.getId()] == block;
-
-            for (Block pred : block.getPredecessors()) {
-                assert pred.getSuccessors().contains(block);
-                assert pred.getId() < block.getId() || pred.isLoopEnd();
-            }
-
-            for (Block sux : block.getSuccessors()) {
-                assert sux.getPredecessors().contains(block);
-                assert sux.getId() > block.getId() || sux.isLoopHeader();
-            }
-
-            if (block.getDominator() != null) {
-                assert block.getDominator().getId() < block.getId();
-                assert block.getDominator().getDominated().contains(block);
-            }
-            for (Block dominated : block.getDominated()) {
-                assert dominated.getId() > block.getId();
-                assert dominated.getDominator() == block;
-            }
-
-            assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().header == block;
-        }
-
-        if (cfg.getLoops() != null) {
-            for (Loop loop : cfg.getLoops()) {
-                assert loop.header.isLoopHeader();
-
-                for (Block block : loop.blocks) {
-                    assert block.getId() >= loop.header.getId();
-
-                    Loop blockLoop = block.getLoop();
-                    while (blockLoop != loop) {
-                        blockLoop = blockLoop.parent;
-                        assert blockLoop != null;
-                    }
-                }
-
-                for (Block block : loop.exits) {
-                    assert block.getId() >= loop.header.getId();
-
-                    Loop blockLoop = block.getLoop();
-                    while (blockLoop != null) {
-                        blockLoop = blockLoop.parent;
-                        assert blockLoop != loop;
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/ControlFlowGraph.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +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.cfg;
-
-import java.util.*;
-
-import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.nodes.*;
-
-public class ControlFlowGraph {
-
-    public final StructuredGraph graph;
-
-    private final NodeMap<Block> nodeToBlock;
-    private Block[] reversePostOrder;
-    private Loop[] loops;
-
-    public static ControlFlowGraph compute(StructuredGraph graph, boolean connectBlocks, boolean computeLoops, boolean computeDominators, boolean computePostdominators) {
-        ControlFlowGraph cfg = new ControlFlowGraph(graph);
-        cfg.identifyBlocks();
-        if (connectBlocks || computeLoops || computeDominators || computePostdominators) {
-            cfg.connectBlocks();
-        }
-        if (computeLoops) {
-            cfg.computeLoopInformation();
-        }
-        if (computeDominators) {
-            cfg.computeDominators();
-        }
-        if (computePostdominators) {
-            cfg.computePostdominators();
-        }
-        assert CFGVerifier.verify(cfg);
-        return cfg;
-    }
-
-    protected ControlFlowGraph(StructuredGraph graph) {
-        this.graph = graph;
-        this.nodeToBlock = graph.createNodeMap();
-    }
-
-    public Block[] getBlocks() {
-        return reversePostOrder;
-    }
-
-    public Block getStartBlock() {
-        return reversePostOrder[0];
-    }
-
-    public NodeMap<Block> getNodeToBlock() {
-        return nodeToBlock;
-    }
-
-    public Block blockFor(Node node) {
-        return nodeToBlock.get(node);
-    }
-
-    public Loop[] getLoops() {
-        return loops;
-    }
-
-    protected static final int BLOCK_ID_INITIAL = -1;
-    protected static final int BLOCK_ID_VISITED = -2;
-
-    private void identifyBlocks() {
-        // Find all block headers
-        int numBlocks = 0;
-        for (Node node : graph.getNodes()) {
-            if (node instanceof BeginNode) {
-                Block block = new Block();
-                numBlocks++;
-
-                block.beginNode = (BeginNode) node;
-                Node cur = node;
-                do {
-                    assert !cur.isDeleted();
-                    block.endNode = cur;
-
-                    assert nodeToBlock.get(cur) == null;
-                    nodeToBlock.set(cur, block);
-                    if (cur instanceof MergeNode) {
-                        for (PhiNode phi : ((MergeNode) cur).phis()) {
-                            nodeToBlock.set(phi, block);
-                        }
-                    }
-
-                    if (cur instanceof FixedNode) {
-                        double probability = ((FixedNode) cur).probability();
-                        if (probability > block.probability) {
-                            block.probability = probability;
-                        }
-                    }
-
-                    Node next = null;
-                    for (Node sux : cur.successors()) {
-                        if (sux != null && !(sux instanceof BeginNode)) {
-                            assert next == null;
-                            next = sux;
-                        }
-                    }
-                    cur = next;
-                } while (cur != null);
-            }
-        }
-
-        // Compute reverse postorder.
-        reversePostOrder = new Block[numBlocks];
-        int reversePostOrderId = numBlocks - 1;
-
-        ArrayList<Block> stack = new ArrayList<>();
-        stack.add(blockFor(graph.start()));
-
-        do {
-            Block block = stack.get(stack.size() - 1);
-            if (block.id == BLOCK_ID_INITIAL) {
-                // First time we see this block: push all successors.
-                for (Node suxNode : block.getEndNode().cfgSuccessors()) {
-                    Block suxBlock = blockFor(suxNode);
-                    assert suxBlock.id != BLOCK_ID_VISITED;
-                    if (suxBlock.id == BLOCK_ID_INITIAL) {
-                        stack.add(suxBlock);
-                    }
-                }
-                block.id = BLOCK_ID_VISITED;
-            } else if (block.id == BLOCK_ID_VISITED) {
-                // Second time we see this block: All successors haved been processed, so insert block into reverse postorder list.
-                stack.remove(stack.size() - 1);
-                reversePostOrder[reversePostOrderId] = block;
-                block.id = reversePostOrderId;
-                reversePostOrderId--;
-            } else {
-                throw GraalInternalError.shouldNotReachHere();
-            }
-        } while (!stack.isEmpty());
-        assert reversePostOrderId == -1;
-    }
-
-    // Connect blocks (including loop backward edges).
-    private void connectBlocks() {
-        for (Block block : reversePostOrder) {
-            List<Block> predecessors = new ArrayList<>();
-            for (Node predNode : block.getBeginNode().cfgPredecessors()) {
-                predecessors.add(nodeToBlock.get(predNode));
-            }
-            if (block.getBeginNode() instanceof LoopBeginNode) {
-                predecessors.add(nodeToBlock.get(((LoopBeginNode) block.getBeginNode()).loopEnd()));
-            }
-            block.predecessors = predecessors;
-
-            List<Block> successors = new ArrayList<>();
-            for (Node suxNode : block.getEndNode().cfgSuccessors()) {
-                successors.add(nodeToBlock.get(suxNode));
-            }
-            if (block.getEndNode() instanceof LoopEndNode) {
-                successors.add(nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin()));
-            }
-            block.successors = successors;
-        }
-    }
-
-    private void computeLoopInformation() {
-        List<Loop> loopsList = new ArrayList<>();
-        for (Block block : reversePostOrder) {
-            Node beginNode = block.getBeginNode();
-            if (beginNode instanceof LoopBeginNode) {
-                Loop loop = new Loop(block.getLoop(), loopsList.size(), block);
-                loopsList.add(loop);
-
-                LoopEndNode end = ((LoopBeginNode) beginNode).loopEnd();
-                Block endBlock = nodeToBlock.get(end);
-                computeLoopBlocks(endBlock, loop);
-            }
-        }
-        loops = loopsList.toArray(new Loop[loopsList.size()]);
-
-        for (Loop loop : loops) {
-            for (Block block : loop.blocks) {
-                for (Block sux : block.getSuccessors()) {
-                    if (sux.getLoopDepth() < loop.depth) {
-                        loop.exits.add(sux);
-                    }
-                }
-            }
-        }
-    }
-
-    private void computeLoopBlocks(Block block, Loop loop) {
-        if (block.getLoop() == loop) {
-            return;
-        }
-        assert block.loop == loop.parent;
-        block.loop = loop;
-
-        assert !loop.blocks.contains(block);
-        loop.blocks.add(block);
-
-        if (block != loop.header) {
-            for (Block pred : block.getPredecessors()) {
-                computeLoopBlocks(pred, loop);
-            }
-        }
-    }
-
-    private void computeDominators() {
-        assert reversePostOrder[0].getPredecessors().size() == 0 : "start block has no predecessor and therefore no dominator";
-        for (int i = 1; i < reversePostOrder.length; i++) {
-            Block block = reversePostOrder[i];
-            List<Block> predecessors = block.getPredecessors();
-            assert predecessors.size() > 0;
-
-            if (block.isLoopHeader()) {
-                // Loop headers have exactly one non-loop predecessor, and that is the dominator.
-                setDominator(block, predecessors.get(0));
-                continue;
-            }
-
-            Block dominator = predecessors.get(0);
-            for (int j = 1; j < predecessors.size(); j++) {
-                Block pred = predecessors.get(j);
-                dominator = commonDominator(dominator, pred);
-            }
-            setDominator(block, dominator);
-        }
-    }
-
-    private static void setDominator(Block block, Block dominator) {
-        block.dominator = dominator;
-        if (dominator.dominated == null) {
-            dominator.dominated = new ArrayList<>();
-        }
-        dominator.dominated.add(block);
-    }
-
-    public static Block commonDominator(Block a, Block b) {
-        Block iterA = a;
-        Block iterB = b;
-        while (iterA != iterB) {
-            if (iterA.getId() > iterB.getId()) {
-                iterA = iterA.getDominator();
-            } else {
-                assert iterB.getId() > iterA.getId();
-                iterB = iterB.getDominator();
-            }
-        }
-        return iterA;
-    }
-
-    private void computePostdominators() {
-        for (Block block : reversePostOrder) {
-            if (block.isLoopEnd()) {
-                // We do not want the loop header registered as the postdominator of the loop end.
-                continue;
-            }
-            Block postdominator = null;
-            for (Block sux : block.getSuccessors()) {
-                if (sux.isExceptionEntry()) {
-                    // We ignore exception handlers.
-                } else if (postdominator == null) {
-                    postdominator = sux;
-                } else {
-                    postdominator = commonPostdominator(postdominator, sux);
-                }
-            }
-            block.postdominator = postdominator;
-        }
-    }
-
-    private static Block commonPostdominator(Block a, Block b) {
-        Block iterA = a;
-        Block iterB = b;
-        while (iterA != iterB) {
-            if (iterA.getId() < iterB.getId()) {
-                iterA = iterA.getPostdominator();
-                if (iterA == null) {
-                    return null;
-                }
-            } else {
-                assert iterB.getId() < iterA.getId();
-                iterB = iterB.getPostdominator();
-                if (iterB == null) {
-                    return null;
-                }
-            }
-        }
-        return iterA;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/cfg/Loop.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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.cfg;
-
-import java.util.*;
-
-public class Loop {
-    public final Loop parent;
-    public final List<Loop> children;
-
-    public final int depth;
-    public final int index;
-    public final Block header;
-    public final List<Block> blocks;
-    public final List<Block> exits;
-
-    protected Loop(Loop parent, int index, Block header) {
-        this.parent = parent;
-        if (parent != null) {
-            this.depth = parent.depth + 1;
-            parent.children.add(this);
-        } else {
-            this.depth = 1;
-        }
-        this.index = index;
-        this.header = header;
-        this.blocks = new ArrayList<>();
-        this.children = new ArrayList<>();
-        this.exits = new ArrayList<>();
-    }
-
-    @Override
-    public String toString() {
-        return "loop " + index + " depth " + depth + (parent != null ? " outer " + parent.index : "");
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java	Wed Feb 08 19:25:29 2012 -0800
@@ -27,8 +27,8 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.gen.LIRGenerator.LockScope;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.virtual.*;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Feb 08 19:25:29 2012 -0800
@@ -26,7 +26,7 @@
 import static com.oracle.max.cri.ci.CiValue.*;
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.cri.util.MemoryBarriers.*;
-import static com.oracle.max.graal.compiler.lir.ValueUtil.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -46,12 +46,12 @@
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.StandardOp.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
 import com.oracle.max.graal.nodes.PhiNode.PhiType;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiResolver.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiResolver.java	Wed Feb 08 19:25:29 2012 -0800
@@ -23,7 +23,7 @@
 package com.oracle.max.graal.compiler.gen;
 
 import static com.oracle.max.cri.ci.CiValue.*;
-import static com.oracle.max.graal.compiler.lir.ValueUtil.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
 
 import java.util.*;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +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.CiCallingConvention.Type;
-import com.oracle.max.cri.ri.*;
-
-/**
- * This class is used to build the stack frame layout for a compiled method.
- * A {@link CiStackSlot} is used to index slots of the frame relative to the stack pointer.
- * The frame size is only fixed after register allocation when all spill slots have
- * been allocated. Both the outgoing argument area and the spill are can grow until then.
- * Therefore, outgoing arguments are indexed from the stack pointer, while spill slots
- * are indexed from the beginning of the frame (and the total frame size has to be added
- * to get the actual offset from the stack pointer).
- * <br>
- * This is the format of a stack frame:
- * <pre>
- *   Base       Contents
- *
- *            :                                :  -----
- *   caller   | incoming overflow argument n   |    ^
- *   frame    :     ...                        :    | positive
- *            | incoming overflow argument 0   |    | offsets
- *   ---------+--------------------------------+---------------------
- *            | return address                 |    |            ^
- *   current  +--------------------------------+    |            |    -----
- *   frame    |                                |    |            |      ^
- *            : callee save area               :    |            |      |
- *            |                                |    |            |      |
- *            +--------------------------------+    |            |      |
- *            | spill slot 0                   |    | negative   |      |
- *            :     ...                        :    v offsets    |      |
- *            | spill slot n                   |  -----        total  frame
- *            +--------------------------------+               frame  size
- *            | alignment padding              |               size     |
- *            +--------------------------------+  -----          |      |
- *            | outgoing overflow argument n   |    ^            |      |
- *            :     ...                        :    | positive   |      |
- *            | outgoing overflow argument 0   |    | offsets    v      v
- *    %sp-->  +--------------------------------+---------------------------
- *
- * </pre>
- * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size
- * of such a block may be greater than the size of a normal spill slot or the word size.
- * <br>
- * A runtime has two ways to reserve space in the stack frame for its own use: <ul>
- * <li>A memory block somewhere in the frame of size {@link RiRuntime#getCustomStackAreaSize()}. The offset
- *     to this block is returned in {@link CiTargetMethod#customStackAreaOffset()}.
- * <li>At the beginning of the overflow argument area: The calling convention can specify that the first
- *     overflow stack argument is not at offset 0, but at a specified offset o. Use
- *     {@link RiRuntime#getMinimumOutgoingSize()} to make sure that call-free methods also have this space
- *     reserved. Then the VM can use memory the memory at offset 0 relative to the stack pointer.
- * </ul>
- */
-public final class FrameMap {
-    public final RiRuntime runtime;
-    public final CiTarget target;
-    public final RiRegisterConfig registerConfig;
-
-    /**
-     * The final frame size, not including the size of the return address.
-     * The value is only set after register allocation is complete, i.e., after all spill slots have been allocated.
-     */
-    private int frameSize;
-
-    /**
-     * Size of the area occupied by spill slots and other stack-allocated memory blocks.
-     */
-    private int spillSize;
-
-    /**
-     * Size of the area occupied by outgoing overflow arguments.
-     * This value is adjusted as calling conventions for outgoing calls are retrieved.
-     */
-    private int outgoingSize;
-
-    /**
-     * The list of stack areas allocated in this frame that are present in every reference map.
-     */
-    private final List<CiStackSlot> objectStackBlocks;
-
-    /**
-     * The stack area reserved for use by the VM, or {@code null} if the VM does not request stack space.
-     */
-    private final CiStackSlot customArea;
-
-    /**
-     * Creates a new frame map for the specified method.
-     */
-    public FrameMap(RiRuntime runtime, CiTarget target, RiRegisterConfig registerConfig) {
-        this.runtime = runtime;
-        this.target = target;
-        this.registerConfig = registerConfig;
-        this.frameSize = -1;
-        this.spillSize = returnAddressSize() + calleeSaveAreaSize();
-        this.outgoingSize = runtime.getMinimumOutgoingSize();
-        this.objectStackBlocks = new ArrayList<>();
-        this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false);
-    }
-
-
-    private int returnAddressSize() {
-        return target.arch.returnAddressSize;
-    }
-
-    private int calleeSaveAreaSize() {
-        CiCalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
-        return csl != null ? csl.size : 0;
-    }
-
-    /**
-     * Gets the frame size of the compiled frame, not including the size of the return address.
-     * @return The size of the frame (in bytes).
-     */
-    public int frameSize() {
-        assert frameSize != -1 : "frame size not computed yet";
-        return frameSize;
-    }
-
-    /**
-     * Gets the total frame size of the compiled frame, including the size of the return address.
-     * @return The total size of the frame (in bytes).
-     */
-    public int totalFrameSize() {
-        return frameSize() + returnAddressSize();
-    }
-
-    /**
-     * Sets the frame size for this frame.
-     * @param frameSize The frame size (in bytes).
-     */
-    public void setFrameSize(int frameSize) {
-        assert this.frameSize == -1 : "must only be set once";
-        this.frameSize = frameSize;
-    }
-
-    /**
-     * Computes the frame size for this frame. After this method has been called, methods that change the
-     * frame size cannot be called anymore, e.g., no more spill slots or outgoing arguments can be requested.
-     */
-    public void finish() {
-        setFrameSize(target.alignFrameSize(outgoingSize + spillSize - returnAddressSize()));
-    }
-
-    /**
-     * Computes the offset of a stack slot relative to the frame register.
-     * This is also the bit index of stack slots in the reference map.
-     *
-     * @param slot a stack slot
-     * @return the offset of the stack slot
-     */
-    public int offsetForStackSlot(CiStackSlot slot) {
-        assert (!slot.rawAddFrameSize() && slot.rawOffset() < outgoingSize) ||
-            (slot.rawAddFrameSize() && slot.rawOffset() < 0 && -slot.rawOffset() <= spillSize) ||
-            (slot.rawAddFrameSize() && slot.rawOffset() >= 0);
-        return slot.offset(totalFrameSize());
-    }
-
-    /**
-     * Gets the offset to the stack area where callee-saved registers are stored.
-     * @return The offset to the callee save area (in bytes).
-     */
-    public int offsetToCalleeSaveArea() {
-        return frameSize() - calleeSaveAreaSize();
-    }
-
-    /**
-     * Gets the offset of the stack area stack block reserved for use by the VM, or -1 if the VM does not request stack space.
-     * @return The offset to the custom area (in bytes).
-     */
-    public int offsetToCustomArea() {
-        return customArea == null ? -1 : offsetForStackSlot(customArea);
-    }
-
-    /**
-     * Informs the frame map that the compiled code calls a particular method, which
-     * may need stack space for outgoing arguments.
-     * @param cc The calling convention for the called method.
-     * @param type The type of calling convention.
-     */
-    public void callsMethod(CiCallingConvention cc, Type type) {
-        // TODO look at the actual stack offsets?
-        assert type.out;
-        reserveOutgoing(cc.stackSize);
-    }
-
-    /**
-     * Reserves space for stack-based outgoing arguments.
-     * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
-     */
-    public void reserveOutgoing(int argsSize) {
-        assert frameSize == -1 : "frame size must not yet be fixed";
-        outgoingSize = Math.max(outgoingSize, argsSize);
-    }
-
-    private CiStackSlot getSlot(CiKind kind, int additionalOffset) {
-        return CiStackSlot.get(kind, -spillSize + additionalOffset, true);
-    }
-
-    private static int roundUp(int number, int mod) {
-        return ((number + mod - 1) / mod) * mod;
-    }
-
-    /**
-     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned on its natural alignment,
-     * i.e., an 8-byte spill slot is aligned at an 8-byte boundary.
-     * @param kind The kind of the spill slot to be reserved.
-     * @return A spill slot denoting the reserved memory area.
-     */
-    public CiStackSlot allocateSpillSlot(CiKind kind) {
-        assert frameSize == -1 : "frame size must not yet be fixed";
-        int size = target.sizeInBytes(kind);
-        spillSize = roundUp(spillSize + size, size);
-        return getSlot(kind, 0);
-    }
-
-    /**
-     * Reserves a block of memory in the frame of the method being compiled. The returned block is aligned on a word boundary.
-     * If the requested size is 0, the method returns {@code null}.
-     *
-     * @param size The size to reserve (in bytes).
-     * @param refs Specifies if the block is all references. If true, the block will be in all reference maps for this method.
-     *             The caller is responsible to initialize the memory block before the first instruction that uses a reference map.
-     * @return A stack slot describing the begin of the memory block.
-     */
-    public CiStackSlot allocateStackBlock(int size, boolean refs) {
-        assert frameSize == -1 : "frame size must not yet be fixed";
-        if (size == 0) {
-            return null;
-        }
-        spillSize = roundUp(spillSize + size, target.wordSize);
-
-        if (refs) {
-            assert size % target.wordSize == 0;
-            CiStackSlot result = getSlot(CiKind.Object, 0);
-            objectStackBlocks.add(result);
-            for (int i = target.wordSize; i < size; i += target.wordSize) {
-                objectStackBlocks.add(getSlot(CiKind.Object, i));
-            }
-            return result;
-
-        } else {
-            return getSlot(target.wordKind, 0);
-        }
-    }
-
-
-    private int frameRefMapIndex(CiStackSlot slot) {
-        assert offsetForStackSlot(slot) % target.wordSize == 0;
-        return offsetForStackSlot(slot) / target.wordSize;
-    }
-
-    /**
-     * Initializes a reference map that covers all registers of the target architecture.
-     */
-    public CiBitMap initRegisterRefMap() {
-        return new CiBitMap(target.arch.registerReferenceMapBitCount);
-    }
-
-    /**
-     * Initializes a reference map. Initially, the size is large enough to cover all the
-     * slots in the frame. If the method has incoming reference arguments on the stack,
-     * the reference map might grow later when such a reference is set.
-     */
-    public CiBitMap initFrameRefMap() {
-        CiBitMap frameRefMap = new CiBitMap(frameSize() / target.wordSize);
-        for (CiStackSlot slot : objectStackBlocks) {
-            setReference(slot, null, frameRefMap);
-        }
-        return frameRefMap;
-    }
-
-    /**
-     * Marks the specified location as a reference in the reference map of the debug information.
-     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
-     * {@link CiConstant} is automatically tracked.
-     *
-     * @param location The location to be added to the reference map.
-     * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
-     * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
-     */
-    public void setReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
-        if (location.kind == CiKind.Object) {
-            if (isRegister(location)) {
-                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
-                registerRefMap.set(asRegister(location).number);
-            } else if (isStackSlot(location)) {
-                int index = frameRefMapIndex(asStackSlot(location));
-                frameRefMap.grow(index + 1);
-                frameRefMap.set(index);
-            } else {
-                assert isConstant(location);
-            }
-        }
-    }
-
-    /**
-     * Clears the specified location as a reference in the reference map of the debug information.
-     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
-     * {@link CiConstant} is automatically tracked.
-     *
-     * @param location The location to be removed from the reference map.
-     * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
-     * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
-     */
-    public void clearReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
-        if (location.kind == CiKind.Object) {
-            if (location instanceof CiRegisterValue) {
-                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
-                registerRefMap.clear(asRegister(location).number);
-            } else if (isStackSlot(location)) {
-                int index = frameRefMapIndex(asStackSlot(location));
-                if (index < frameRefMap.size()) {
-                    frameRefMap.clear(index);
-                }
-            } else {
-                assert isConstant(location);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +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 java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.cfg.*;
-import com.oracle.max.graal.debug.*;
-import com.oracle.max.graal.graph.*;
-
-/**
- * This class implements the overall container for the LIR graph
- * and directs its construction, optimization, and finalization.
- */
-public class LIR {
-
-    public final ControlFlowGraph cfg;
-
-    /**
-     * The nodes for the blocks.
-     * TODO: This should go away, we want all nodes connected with a next-pointer.
-     */
-    private final BlockMap<List<Node>> nodesFor;
-
-    /**
-     * The linear-scan ordered list of blocks.
-     */
-    private final List<Block> linearScanOrder;
-
-    /**
-     * The order in which the code is emitted.
-     */
-    private final List<Block> codeEmittingOrder;
-
-
-    public final List<SlowPath> slowPaths;
-
-    public final List<SlowPath> deoptimizationStubs;
-
-    /**
-     * The last slow path emitted, which can be used emit marker bytes.
-     */
-    public SlowPath methodEndMarker;
-
-    private int numVariables;
-
-    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);
-    }
-
-    /**
-     * Creates a new LIR instance for the specified compilation.
-     * @param numLoops number of loops
-     * @param compilation the compilation
-     */
-    public LIR(ControlFlowGraph cfg, BlockMap<List<Node>> nodesFor, List<Block> linearScanOrder, List<Block> codeEmittingOrder) {
-        this.cfg = cfg;
-        this.nodesFor = nodesFor;
-        this.codeEmittingOrder = codeEmittingOrder;
-        this.linearScanOrder = linearScanOrder;
-
-        slowPaths = new ArrayList<>();
-        deoptimizationStubs = new ArrayList<>();
-    }
-
-    public List<Node> nodesFor(Block block) {
-        return nodesFor.get(block);
-    }
-
-    /**
-     * Gets the linear scan ordering of blocks as a list.
-     * @return the blocks in linear scan order
-     */
-    public List<Block> linearScanOrder() {
-        return linearScanOrder;
-    }
-
-    public List<Block> codeEmittingOrder() {
-        return codeEmittingOrder;
-    }
-
-    public int numVariables() {
-        return numVariables;
-    }
-
-    public int nextVariable() {
-        return numVariables++;
-    }
-
-    public void emitCode(TargetMethodAssembler tasm) {
-        for (Block b : codeEmittingOrder()) {
-            emitBlock(tasm, b);
-        }
-
-        // generate code for slow cases
-        for (SlowPath sp : slowPaths) {
-            emitSlowPath(tasm, sp);
-        }
-        // generate deoptimization stubs
-        for (SlowPath sp : deoptimizationStubs) {
-            emitSlowPath(tasm, sp);
-        }
-        // generate traps at the end of the method
-        emitSlowPath(tasm, methodEndMarker);
-    }
-
-    private static void emitBlock(TargetMethodAssembler tasm, Block block) {
-        if (Debug.isDumpEnabled()) {
-            tasm.blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
-        }
-
-        for (LIRInstruction op : block.lir) {
-            if (Debug.isDumpEnabled()) {
-                tasm.blockComment(String.format("%d %s", op.id(), op));
-            }
-
-            emitOp(tasm, op);
-        }
-    }
-
-    private static void emitOp(TargetMethodAssembler tasm, LIRInstruction op) {
-        try {
-            try {
-                op.emitCode(tasm);
-            } catch (AssertionError t) {
-                throw new GraalInternalError(t);
-            } catch (RuntimeException t) {
-                throw new GraalInternalError(t);
-            }
-        } catch (GraalInternalError e) {
-            throw e.addContext("lir instruction", op);
-        }
-    }
-
-    private static void emitSlowPath(TargetMethodAssembler tasm, SlowPath sp) {
-        if (Debug.isDumpEnabled()) {
-            tasm.blockComment(String.format("slow case %s", sp.getClass().getName()));
-        }
-        sp.emitCode(tasm);
-    }
-
-/*
-    private int lastDecodeStart;
-
-    private void printAssembly(TargetMethodAssembler tasm) {
-        byte[] currentBytes = tasm.asm.codeBuffer.copyData(lastDecodeStart, tasm.asm.codeBuffer.position());
-        if (currentBytes.length > 0) {
-            String disasm = tasm.runtime.disassemble(currentBytes, lastDecodeStart);
-            if (disasm.length() != 0) {
-                TTY.println(disasm);
-            } else {
-                TTY.println("Code [+%d]: %d bytes", lastDecodeStart, currentBytes.length);
-                Util.printBytes(lastDecodeStart, currentBytes, GraalOptions.PrintAssemblyBytesPerLine);
-            }
-        }
-        lastDecodeStart = tasm.asm.codeBuffer.position();
-    }
-
-
-    public static void printBlock(Block x) {
-        // print block id
-        TTY.print("B%d ", x.getId());
-
-        // print flags
-        if (x.isLoopHeader()) {
-            TTY.print("lh ");
-        }
-        if (x.isLoopEnd()) {
-            TTY.print("le ");
-        }
-
-        // print block bci range
-        TTY.print("[%d, %d] ", -1, -1);
-
-        // print predecessors and successors
-        if (x.numberOfPreds() > 0) {
-            TTY.print("preds: ");
-            for (int i = 0; i < x.numberOfPreds(); i++) {
-                TTY.print("B%d ", x.predAt(i).getId());
-            }
-        }
-
-        if (x.numberOfSux() > 0) {
-            TTY.print("sux: ");
-            for (int i = 0; i < x.numberOfSux(); i++) {
-                TTY.print("B%d ", x.suxAt(i).getId());
-            }
-        }
-
-        TTY.println();
-    }
-
-    public static void printLIR(List<Block> blocks) {
-        if (TTY.isSuppressed()) {
-            return;
-        }
-        TTY.println("LIR:");
-        int i;
-        for (i = 0; i < blocks.size(); i++) {
-            Block bb = blocks.get(i);
-            printBlock(bb);
-            TTY.println("__id_Instruction___________________________________________");
-            for (LIRInstruction op : bb.lir) {
-                TTY.println(op.toStringWithIdPrefix());
-                TTY.println();
-            }
-            TTY.println();
-        }
-    }
-*/
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +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.graal.compiler.lir.LIRInstruction.*;
-import static com.oracle.max.graal.compiler.lir.ValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
-
-/**
- * This class represents garbage collection and deoptimization information attached to a LIR instruction.
- */
-public class LIRDebugInfo {
-    public final CiFrame topFrame;
-    private final CiVirtualObject[] virtualObjects;
-    private final List<CiStackSlot> pointerSlots;
-    public final LabelRef exceptionEdge;
-    private CiDebugInfo debugInfo;
-
-    public LIRDebugInfo(CiFrame topFrame, CiVirtualObject[] virtualObjects, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
-        this.topFrame = topFrame;
-        this.virtualObjects = virtualObjects;
-        this.pointerSlots = pointerSlots;
-        this.exceptionEdge = exceptionEdge;
-    }
-
-    public boolean hasDebugInfo() {
-        return debugInfo != null;
-    }
-
-    public CiDebugInfo debugInfo() {
-        assert debugInfo != null : "debug info not allocated yet";
-        return debugInfo;
-    }
-
-    /**
-     * Iterates the frame state and calls the {@link ValueProcedure} for every variable.
-     *
-     * @param proc The procedure called for variables.
-     */
-    public void forEachState(ValueProcedure proc) {
-        for (CiFrame cur = topFrame; cur != null; cur = cur.caller()) {
-            processValues(cur.values, proc);
-        }
-        if (virtualObjects != null) {
-            for (CiVirtualObject obj : virtualObjects) {
-                processValues(obj.values(), proc);
-            }
-        }
-    }
-
-    /**
-     * We filter out constant and illegal values ourself before calling the procedure, so {@link OperandFlag#Constant} and {@link OperandFlag#Illegal} need not be set.
-     */
-    private static final EnumSet<OperandFlag> STATE_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-
-    private void processValues(CiValue[] values, ValueProcedure proc) {
-        for (int i = 0; i < values.length; i++) {
-            CiValue value = values[i];
-            if (value instanceof CiMonitorValue) {
-                CiMonitorValue monitor = (CiMonitorValue) value;
-                if (processed(monitor.owner)) {
-                    monitor.owner = proc.doValue(monitor.owner, OperandMode.Alive, STATE_FLAGS);
-                }
-
-            } else if (processed(value)) {
-                values[i] = proc.doValue(value, OperandMode.Alive, STATE_FLAGS);
-            }
-        }
-    }
-
-    private boolean processed(CiValue value) {
-        if (isIllegal(value)) {
-            // Ignore dead local variables.
-            return false;
-        } else if (isConstant(value)) {
-            // Ignore constants, the register allocator does not need to see them.
-            return false;
-        } else if (isVirtualObject(value)) {
-            assert Arrays.asList(virtualObjects).contains(value);
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-
-    public void finish(CiBitMap registerRefMap, CiBitMap frameRefMap, FrameMap frameMap) {
-        debugInfo = new CiDebugInfo(topFrame, registerRefMap, frameRefMap);
-
-        // Add additional stack slots for outgoing method parameters.
-        if (pointerSlots != null) {
-            for (CiStackSlot v : pointerSlots) {
-                frameMap.setReference(v, registerRefMap, frameRefMap);
-            }
-        }
-    }
-
-
-    @Override
-    public String toString() {
-        return debugInfo != null ? debugInfo.toString() : topFrame.toString();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,447 +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.graal.compiler.asm.*;
-import com.oracle.max.graal.graph.*;
-
-/**
- * The {@code LIRInstruction} class definition.
- */
-public abstract class LIRInstruction {
-
-    public static final CiValue[] NO_OPERANDS = {};
-
-    /**
-     * Iterator for iterating over a list of values. Subclasses must overwrite one of the doValue methods.
-     * Clients of the class must only call the doValue method that takes additional parameters.
-     */
-    public abstract static class ValueProcedure {
-        /**
-         * Iterator method to be overwritten. This version of the iterator does not take additional parameters
-         * to keep the signature short.
-         *
-         * @param value The value that is iterated.
-         * @return The new value to replace the value that was passed in.
-         */
-        protected CiValue doValue(CiValue value) {
-            throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten");
-        }
-
-        /**
-         * Iterator method to be overwritten. This version of the iterator gets additional parameters about the
-         * processed value.
-         *
-         * @param value The value that is iterated.
-         * @param mode The operand mode for the value.
-         * @param flags A set of flags for the value.
-         * @return The new value to replace the value that was passed in.
-         */
-        public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
-            return doValue(value);
-        }
-    }
-
-
-    /**
-     * Constants denoting how a LIR instruction uses an operand.
-     */
-    public enum OperandMode {
-        /**
-         * The value must have been defined before. It is alive before the instruction until the beginning of the
-         * instruction, but not necessarily throughout the instruction. A register assigned to it can also be assigend
-         * to a Temp or Output operand. The value can be used again after the instruction, so the instruction must not
-         * modify the register.
-         */
-        Input,
-
-        /**
-         * The value must have been defined before. It is alive before the instruction and throughout the instruction. A
-         * register assigned to it cannot be assigned to a Temp or Output operand. The value can be used again after the
-         * instruction, so the instruction must not modify the register.
-         */
-        Alive,
-
-        /**
-         * The value must not have been defined before, and must not be used after the instruction. The instruction can
-         * do whatever it wants with the register assigned to it (or not use it at all).
-         */
-        Temp,
-
-        /**
-         * The value must not have been defined before. The instruction has to assign a value to the register. The
-         * value can (and most likely will) be used after the instruction.
-         */
-        Output,
-    }
-
-    /**
-     * Flags for an operand.
-     */
-    public enum OperandFlag {
-        /**
-         * The value can be a {@link CiRegisterValue}.
-         */
-        Register,
-
-        /**
-         * The value can be a {@link CiStackSlot}.
-         */
-        Stack,
-
-        /**
-         * The value can be a {@link CiAddress}.
-         */
-        Address,
-
-        /**
-         * The value can be a {@link CiConstant}.
-         */
-        Constant,
-
-        /**
-         * The value can be {@link CiValue#IllegalValue}.
-         */
-        Illegal,
-
-        /**
-         * The register allocator should try to assign a certain register to improve code quality.
-         * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints.
-         */
-        RegisterHint,
-
-        /**
-         * The value can be uninitialized, e.g., a stack slot that has not written to before. This is only
-         * used to avoid false positives in verification code.
-         */
-        Uninitialized,
-    }
-
-    /**
-     * For validity checking of the operand flags defined by instruction subclasses.
-     */
-    private static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS;
-
-    static {
-        ALLOWED_FLAGS = new EnumMap<>(OperandMode.class);
-        ALLOWED_FLAGS.put(OperandMode.Input,  EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized));
-        ALLOWED_FLAGS.put(OperandMode.Alive,  EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized));
-        ALLOWED_FLAGS.put(OperandMode.Temp,   EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint));
-        ALLOWED_FLAGS.put(OperandMode.Output, EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Illegal, OperandFlag.RegisterHint));
-    }
-
-    /**
-     * The opcode of this instruction.
-     */
-    protected final Object code;
-
-    /**
-     * The output operands for this instruction (modified by the register allocator).
-     */
-    protected CiValue[] outputs;
-
-    /**
-     * The input operands for this instruction (modified by the register allocator).
-     */
-    protected CiValue[] inputs;
-
-    /**
-     * The alive operands for this instruction (modified by the register allocator).
-     */
-    protected CiValue[] alives;
-
-    /**
-     * The temp operands for this instruction (modified by the register allocator).
-     */
-    protected CiValue[] temps;
-
-    /**
-     * Used to emit debug information.
-     */
-    public final LIRDebugInfo info;
-
-    /**
-     * Instruction id for register allocation.
-     */
-    private int id;
-
-    /**
-     * Constructs a new LIR instruction that has input and temp operands.
-     *
-     * @param opcode the opcode of the new instruction
-     * @param outputs the operands that holds the operation results of this instruction.
-     * @param info the {@link LIRDebugInfo} info that is to be preserved for the instruction. This will be {@code null} when no debug info is required for the instruction.
-     * @param inputs the input operands for the instruction.
-     * @param temps the temp operands for the instruction.
-     */
-    public LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
-        this.code = opcode;
-        this.outputs = outputs;
-        this.inputs = inputs;
-        this.alives = alives;
-        this.temps = temps;
-        this.info = info;
-        this.id = -1;
-    }
-
-    public abstract void emitCode(TargetMethodAssembler tasm);
-
-
-    public final int id() {
-        return id;
-    }
-
-    public final void setId(int id) {
-        this.id = id;
-    }
-
-    /**
-     * Gets an input operand of this instruction.
-     *
-     * @param index the index of the operand requested.
-     * @return the {@code index}'th input operand.
-     */
-    protected final CiValue input(int index) {
-        return inputs[index];
-    }
-
-    /**
-     * Gets an alive operand of this instruction.
-     *
-     * @param index the index of the operand requested.
-     * @return the {@code index}'th alive operand.
-     */
-    protected final CiValue alive(int index) {
-        return alives[index];
-    }
-
-    /**
-     * Gets a temp operand of this instruction.
-     *
-     * @param index the index of the operand requested.
-     * @return the {@code index}'th temp operand.
-     */
-    protected final CiValue temp(int index) {
-        return temps[index];
-    }
-
-    /**
-     * Gets the result operand for this instruction.
-     *
-     * @return return the result operand
-     */
-    protected final CiValue output(int index) {
-        return outputs[index];
-    }
-
-    /**
-     * Gets the instruction name.
-     */
-    public String name() {
-        return code.toString();
-    }
-
-    public boolean hasOperands() {
-        return inputs.length > 0 || alives.length > 0 || temps.length > 0 || outputs.length > 0 || info != null || hasCall();
-    }
-
-    private static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
-
-    private void forEach(CiValue[] values, OperandMode mode, ValueProcedure proc) {
-        for (int i = 0; i < values.length; i++) {
-            assert ALLOWED_FLAGS.get(mode).containsAll(flagsFor(mode, i));
-
-            CiValue value = values[i];
-            if (isAddress(value)) {
-                assert flagsFor(mode, i).contains(OperandFlag.Address);
-                CiAddress address = asAddress(value);
-                address.base = proc.doValue(address.base, mode, ADDRESS_FLAGS);
-                address.index = proc.doValue(address.index, mode, ADDRESS_FLAGS);
-            } else {
-                values[i] = proc.doValue(values[i], mode, flagsFor(mode, i));
-            }
-        }
-    }
-
-    public final void forEachInput(ValueProcedure proc) {
-        forEach(inputs, OperandMode.Input, proc);
-    }
-
-    public final void forEachAlive(ValueProcedure proc) {
-        forEach(alives, OperandMode.Alive, proc);
-    }
-
-    public final void forEachTemp(ValueProcedure proc) {
-        forEach(temps, OperandMode.Temp, proc);
-    }
-
-    public final void forEachOutput(ValueProcedure proc) {
-        forEach(outputs, OperandMode.Output, proc);
-    }
-
-    public final void forEachState(ValueProcedure proc) {
-        if (info != null) {
-            info.forEachState(proc);
-
-            if (this instanceof LIRXirInstruction) {
-                LIRXirInstruction xir = (LIRXirInstruction) this;
-                if (xir.infoAfter != null) {
-                    xir.infoAfter.forEachState(proc);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true when this instruction is a call instruction that destroys all caller-saved registers.
-     */
-    public final boolean hasCall() {
-        return this instanceof StandardOp.CallOp;
-    }
-
-    /**
-     * Iterates all register hints for the specified value, i.e., all preferred candidates for the register to be
-     * assigned to the value.
-     * <br>
-     * Subclasses can override this method. The default implementation processes all Input operands as the hints for
-     * an Output operand, and all Output operands as the hints for an Input operand.
-     *
-     * @param value The value the hints are needed for.
-     * @param mode The operand mode of the value.
-     * @param proc The procedure invoked for all the hints. If the procedure returns a non-null value, the iteration is stopped
-     *             and the value is returned by this method, i.e., clients can stop the iteration once a suitable hint has been found.
-     * @return The non-null value returned by the procedure, or null.
-     */
-    public CiValue forEachRegisterHint(CiValue value, OperandMode mode, ValueProcedure proc) {
-        CiValue[] hints;
-        if (mode == OperandMode.Input) {
-            hints = outputs;
-        } else if (mode == OperandMode.Output) {
-            hints = inputs;
-        } else {
-            return null;
-        }
-
-        for (int i = 0; i < hints.length; i++) {
-            CiValue result = proc.doValue(hints[i], null, null);
-            if (result != null) {
-                return result;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Used by the register allocator to decide which kind of location can be assigned to the operand.
-     * @param mode The kind of operand.
-     * @param index The index of the operand.
-     * @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 abstract EnumSet<OperandFlag> flagsFor(OperandMode mode, int index);
-
-    protected void verify() {
-    }
-
-
-    public final String toStringWithIdPrefix() {
-        if (id != -1) {
-            return String.format("%4d %s", id, toString());
-        }
-        return "     " + toString();
-    }
-
-    /**
-     * Gets the operation performed by this instruction in terms of its operands as a string.
-     */
-    public String operationString() {
-        StringBuilder buf = new StringBuilder();
-        String sep = "";
-        if (outputs.length > 1) {
-            buf.append("(");
-        }
-        for (CiValue output : outputs) {
-            buf.append(sep).append(output);
-            sep = ", ";
-        }
-        if (outputs.length > 1) {
-            buf.append(")");
-        }
-        if (outputs.length > 0) {
-            buf.append(" = ");
-        }
-
-        if (inputs.length + alives.length != 1) {
-            buf.append("(");
-        }
-        sep = "";
-        for (CiValue input : inputs) {
-            buf.append(sep).append(input);
-            sep = ", ";
-        }
-        for (CiValue input : alives) {
-            buf.append(sep).append(input).append(" ~");
-            sep = ", ";
-        }
-        if (inputs.length + alives.length != 1) {
-            buf.append(")");
-        }
-
-        if (temps.length > 0) {
-            buf.append(" [");
-        }
-        sep = "";
-        for (CiValue temp : temps) {
-            buf.append(sep).append(temp);
-            sep = ", ";
-        }
-        if (temps.length > 0) {
-            buf.append("]");
-        }
-        return buf.toString();
-    }
-
-    protected void appendDebugInfo(StringBuilder buf) {
-        if (info != null) {
-            buf.append(" [bci:");
-            String sep = "";
-            for (CiFrame cur = info.topFrame; cur != null; cur = cur.caller()) {
-                buf.append(sep).append(cur.bci);
-                sep = ",";
-            }
-            buf.append("]");
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder buf = new StringBuilder(name()).append(' ').append(operationString());
-        appendDebugInfo(buf);
-        return buf.toString();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRVerifier.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,243 +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 static com.oracle.max.graal.compiler.lir.ValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.cfg.*;
-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.graph.*;
-
-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.getId()];
-    }
-    private void setLiveOutFor(Block block, BitSet liveOut) {
-        blockLiveOut[block.getId()] = 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 Block curBlock;
-    private Object curInstruction;
-    private BitSet curRegistersDefined;
-
-    private void verify() {
-        ValueProcedure useProc = new ValueProcedure() { @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 (Block block : lir.linearScanOrder()) {
-            curBlock = block;
-            curVariablesLive = new BitSet();
-            curRegistersLive = new CiValue[maxRegisterNum()];
-
-            if (block.getDominator() != null) {
-                curVariablesLive.or(liveOutFor(block.getDominator()));
-            }
-
-            assert block.lir.get(0) instanceof StandardOp.LabelOp : "block must start with label";
-            if (block.numberOfPreds() > 1) {
-                assert block.lir.get(0) instanceof StandardOp.PhiLabelOp : "phi mapping required for multiple predecessors";
-                CiValue[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
-                if (!beforeRegisterAllocation) {
-                    assert phiDefinitions.length == 0;
-                }
-                for (Block pred : block.getPredecessors()) {
-                    assert pred.numberOfSux() == 1;
-                    LIRInstruction last = pred.lir.get(pred.lir.size() - 1);
-                    assert last instanceof StandardOp.PhiJumpOp : "phi mapping required for multiple successors";
-                    CiValue[] phiUses = ((StandardOp.PhiJumpOp) last).getPhiInputs();
-                    if (!beforeRegisterAllocation) {
-                        assert phiUses.length == 0;
-                    }
-                }
-            }
-
-            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;
-            }
-
-            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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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.xir.*;
-import com.oracle.max.graal.graph.*;
-
-public abstract class LIRXirInstruction extends LIRInstruction {
-
-    public final CiValue[] originalOperands;
-    public final int outputOperandIndex;
-    public final int[] inputOperandIndices;
-    public final int[] tempOperandIndices;
-    public final XirSnippet snippet;
-    public final LIRDebugInfo infoAfter;
-    public final LabelRef trueSuccessor;
-    public final LabelRef falseSuccessor;
-
-    public LIRXirInstruction(Object opcode,
-                             XirSnippet snippet,
-                             CiValue[] originalOperands,
-                             CiValue outputOperand,
-                             CiValue[] inputs, CiValue[] temps,
-                             int[] inputOperandIndices, int[] tempOperandIndices,
-                             int outputOperandIndex,
-                             LIRDebugInfo info,
-                             LIRDebugInfo infoAfter,
-                             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.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;
-    }
-
-    @Override
-    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);
-        }
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public CiValue[] getOperands() {
-        for (int i = 0; i < inputOperandIndices.length; i++) {
-            originalOperands[inputOperandIndices[i]] = alive(i);
-        }
-        for (int i = 0; i < tempOperandIndices.length; i++) {
-            originalOperands[tempOperandIndices[i]] = temp(i);
-        }
-        if (outputOperandIndex != -1) {
-            originalOperands[outputOperandIndex] = output(0);
-        }
-        return originalOperands;
-    }
-
-    @Override
-    public String name() {
-        return "XIR: " + snippet.template;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LabelRef.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +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;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.graal.compiler.cfg.*;
-
-/**
- * LIR instructions such as JUMP and BRANCH need to reference their target {@link Block}. However,
- * direct references are not possible since the control flow graph (and therefore successors lists) can
- * be changed by optimizations - and fixing the instructions is error prone.
- * Therefore, we only reference of block B from block A only via the tuple (A, successor-index-of-B), i.e.,
- * indirectly by storing the index into the successor list of A.
- * Note that therefore it is not allowed to reorder the successor list!
- *
- * Labels of out-of-line stubs can be referenced directly, therefore it is also possible to construct a
- * LabelRef for a Label directly via {@link #forLabel}.
- */
-public abstract class LabelRef {
-
-    public abstract Label label();
-
-    /**
-     * Returns a new reference to a statically defined label.
-     * @param label The label that is always returned.
-     * @return The newly created label reference.
-     */
-    public static LabelRef forLabel(final Label label) {
-       return new LabelRef() {
-           @Override
-           public Label label() {
-               return label;
-           }
-
-           @Override
-           public String toString() {
-               return label.toString();
-           }
-       };
-    }
-
-    /**
-     * Returns a new reference to a successor of the given block.
-     * This allows to reference the given successor even when the successor list
-     * is modified between the creation of the reference and the call to {@link #getLabel}.
-     * @param block The base block that contains the successor list.
-     * @param suxIndex The index of the successor.
-     * @return The newly created label reference.
-     */
-    public static LabelRef forSuccessor(final Block block, final int suxIndex) {
-        return new LabelRef() {
-            @Override
-            public Label label() {
-                return ((StandardOp.LabelOp) block.suxAt(suxIndex).lir.get(0)).getLabel();
-            }
-
-            @Override
-            public String toString() {
-                return suxIndex < block.numberOfSux() ? block.suxAt(suxIndex).toString() : "?" + block + ":" + suxIndex + "?";
-            }
-        };
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/StandardOp.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +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.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.graph.*;
-
-/**
- * A collection of machine-independent LIR operations, as well as interfaces to be implemented for specific kinds or LIR
- * operations.
- */
-public class StandardOp {
-
-    private static CiValue[] EMPTY = new CiValue[0];
-
-    /**
-     * LIR operation that defines the position of a label.
-     * The first operation of every block must implement this interface.
-     */
-    public static class LabelOp extends LIRInstruction {
-        private final Label label;
-        private final boolean align;
-
-        protected LabelOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, Label label, boolean align) {
-            super(opcode, outputs, info, inputs, alives, temps);
-            this.label = label;
-            this.align = align;
-        }
-
-        public LabelOp(Label label, boolean align) {
-            this("LABEL", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            if (align) {
-                tasm.asm.align(tasm.target.wordSize);
-            }
-            tasm.asm.bind(label);
-        }
-
-        @Override
-        public String operationString() {
-            return label.toString() + " " + super.operationString();
-        }
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-
-        public Label getLabel() {
-            return label;
-        }
-    }
-
-    public static class PhiLabelOp extends LabelOp {
-        public PhiLabelOp(Label label, boolean align, CiValue[] phiDefinitions) {
-            super("PHI_LABEL", phiDefinitions, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
-        }
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            if (mode == OperandMode.Output) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
-            }
-            throw GraalInternalError.shouldNotReachHere();
-        }
-
-        public void markResolved() {
-            outputs = EMPTY;
-        }
-
-        public CiValue[] getPhiDefinitions() {
-            return outputs;
-        }
-    }
-
-    /**
-     * 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 static class JumpOp extends LIRInstruction {
-        private final LabelRef destination;
-
-        protected JumpOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, LabelRef destination) {
-            super(opcode, outputs, info, inputs, alives, temps);
-            this.destination = destination;
-        }
-
-        public JumpOp(LabelRef destination, LIRDebugInfo info) {
-            this("JUMP", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, destination);
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            tasm.asm.jmp(destination.label());
-        }
-
-        @Override
-        public String operationString() {
-            return  destination + " " + super.operationString();
-        }
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-
-        public LabelRef destination() {
-            return destination;
-        }
-    }
-
-    public static class PhiJumpOp extends JumpOp {
-        public PhiJumpOp(LabelRef destination, CiValue[] phiInputs) {
-            super("PHI_JUMP", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, phiInputs, LIRInstruction.NO_OPERANDS, destination);
-        }
-
-        @Override
-        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
-            if (mode == OperandMode.Alive) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
-            }
-            throw GraalInternalError.shouldNotReachHere();
-        }
-
-        public void markResolved() {
-            alives = EMPTY;
-        }
-
-        public CiValue[] getPhiInputs() {
-            return alives;
-        }
-    }
-
-    /**
-     * 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 GraalInternalError.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/ValueUtil.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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 com.oracle.max.cri.ci.*;
-
-public class ValueUtil extends CiValueUtil {
-
-    public static boolean isVariable(CiValue value) {
-        assert value != null;
-        return value instanceof Variable;
-    }
-
-    public static Variable asVariable(CiValue value) {
-        assert value != null;
-        return (Variable) value;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/Variable.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2010, 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.*;
-
-/**
- * Represents a value that is yet to be bound to a machine location (such as
- * a {@link CiRegisterValue} or {@link CiStackSlot}) by a register allocator.
- */
-public final class Variable extends CiValue {
-    private static final long serialVersionUID = 4507578431686109809L;
-
-    /**
-     * The identifier of the variable. This is a non-zero index in a contiguous 0-based name space.
-     */
-    public final int index;
-
-    /**
-     * The type of register that this variable needs to get assigned.
-     */
-    public final CiRegister.RegisterFlag flag;
-
-    /**
-     * Creates a new variable.
-     * @param kind
-     * @param index
-     */
-    public Variable(CiKind kind, int index, CiRegister.RegisterFlag flag) {
-        super(kind);
-        assert kind == kind.stackKind() : "Variables can be only created for stack kinds";
-        assert index >= 0;
-        this.index = index;
-        this.flag = flag;
-    }
-
-    @Override
-    public int hashCode() {
-        return (index << 4) | kind.ordinal();
-    }
-
-    @Override
-    public String toString() {
-        return "v" + index + kindSuffix();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Wed Feb 08 19:25:29 2012 -0800
@@ -25,9 +25,9 @@
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.PhiNode.PhiType;
 import com.oracle.max.graal.nodes.extended.*;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Wed Feb 08 19:25:29 2012 -0800
@@ -23,9 +23,9 @@
 package com.oracle.max.graal.compiler.phases;
 
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.cri.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.spi.*;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockClosure.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockClosure.java	Wed Feb 08 19:25:29 2012 -0800
@@ -22,7 +22,7 @@
  */
 package com.oracle.max.graal.compiler.schedule;
 
-import com.oracle.max.graal.compiler.cfg.*;
+import com.oracle.max.graal.lir.cfg.*;
 
 /**
  * The {@code BlockClosure} interface represents a closure for iterating over blocks.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/SchedulePhase.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/SchedulePhase.java	Wed Feb 08 19:25:29 2012 -0800
@@ -27,10 +27,10 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.graph.Node.Verbosity;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.extended.*;
 import com.oracle.max.graal.nodes.virtual.*;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Wed Feb 08 19:25:29 2012 -0800
@@ -29,8 +29,8 @@
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
 
 /**
  * The {@code Backend} class represents a compiler backend for Graal.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Arithmetic.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,559 +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.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.graph.*;
-
-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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 Op2Reg extends AMD64LIRInstruction {
-        public Op2Reg(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.Constant);
-            } else if (mode == OperandMode.Output && index == 0) {
-                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
-            }
-            throw GraalInternalError.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 GraalInternalError.shouldNotReachHere();
-        }
-
-        @Override
-        protected void verify() {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = input(1);
-
-            super.verify();
-            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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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/AMD64Backend.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java	Wed Feb 08 19:25:29 2012 -0800
@@ -28,9 +28,9 @@
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.target.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
 
 /**
  * The {@code X86Backend} class represents the backend for the AMD64 architecture.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Call.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +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.graph.*;
-
-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 GraalInternalError.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 GraalInternalError.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/AMD64Compare.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +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.graph.*;
-
-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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompareToIntOpcode.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +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.AMD64Assembler.ConditionFlag;
-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.graph.*;
-
-/**
- * Implementation of the Java bytecodes that compare a long, float, or double value and produce the
- * 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 {
-    CMP2INT, CMP2INT_UG, CMP2INT_UL;
-
-    public LIRInstruction create(CiValue result) {
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
-            @Override
-            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 GraalInternalError.shouldNotReachHere();
-            }
-        };
-    }
-
-    private void emit(AMD64MacroAssembler masm, CiValue result) {
-        CiRegister dest = asIntReg(result);
-        Label high = new Label();
-        Label low = new Label();
-        Label done = new Label();
-
-        // comparison is done by a separate LIR instruction before
-        switch (this) {
-            case CMP2INT:
-                masm.jcc(ConditionFlag.greater, high);
-                masm.jcc(ConditionFlag.less, low);
-                break;
-            case CMP2INT_UG:
-                masm.jcc(ConditionFlag.parity, high);
-                masm.jcc(ConditionFlag.above, high);
-                masm.jcc(ConditionFlag.below, low);
-                break;
-            case CMP2INT_UL:
-                masm.jcc(ConditionFlag.parity, low);
-                masm.jcc(ConditionFlag.above, high);
-                masm.jcc(ConditionFlag.below, low);
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-
-        // equal -> 0
-        masm.xorptr(dest, dest);
-        masm.jmp(done);
-
-        // greater -> 1
-        masm.bind(high);
-        masm.xorptr(dest, dest);
-        masm.incrementl(dest, 1);
-        masm.jmp(done);
-
-        // less -> -1
-        masm.bind(low);
-        masm.xorptr(dest, dest);
-        masm.decrementl(dest, 1);
-
-        masm.bind(done);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ControlFlow.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,383 +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.graph.*;
-import com.oracle.max.graal.nodes.calc.*;
-
-public class AMD64ControlFlow {
-
-    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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Feb 08 19:25:29 2012 -0800
@@ -28,9 +28,10 @@
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
 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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
 
 public class AMD64DeoptimizationStub extends AMD64SlowPath {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Feb 08 19:25:29 2012 -0800
@@ -24,9 +24,9 @@
 package com.oracle.max.graal.compiler.target.amd64;
 
 import static com.oracle.max.cri.ci.CiValueUtil.*;
-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.lir.amd64.AMD64Arithmetic.*;
+import static com.oracle.max.graal.lir.amd64.AMD64Compare.*;
+import static com.oracle.max.graal.lir.amd64.AMD64CompareToIntOpcode.*;
 
 import java.util.*;
 
@@ -38,35 +38,35 @@
 import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.StandardOp.JumpOp;
-import com.oracle.max.graal.compiler.lir.StandardOp.LabelOp;
-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.Op2Reg;
-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.AMD64Call.DirectCallOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Call.IndirectCallOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Compare.CompareOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.BranchOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.CondMoveOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.FloatBranchOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.FloatCondMoveOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.ReturnOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64ControlFlow.TableSwitchOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.CompareAndSwapOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.LeaOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.LoadOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.MembarOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.MoveFromRegOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.MoveToRegOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.NullCheckOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.SpillMoveOp;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Move.StoreOp;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.JumpOp;
+import com.oracle.max.graal.lir.StandardOp.LabelOp;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.DivOp;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op1Reg;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op1Stack;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op2Stack;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.ShiftOp;
+import com.oracle.max.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.max.graal.lir.amd64.AMD64Call.IndirectCallOp;
+import com.oracle.max.graal.lir.amd64.AMD64Compare.CompareOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.BranchOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.LeaOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.LoadOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.MembarOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.MoveFromRegOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.MoveToRegOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.NullCheckOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.SpillMoveOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.calc.*;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRInstruction.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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 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.*;
-
-/**
- * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
- */
-public abstract class AMD64LIRInstruction extends LIRInstruction {
-
-    public AMD64LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
-        super(opcode, outputs, info, inputs, alives, temps);
-    }
-
-    @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
-    }
-
-    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MethodEndStub.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MethodEndStub.java	Wed Feb 08 19:25:29 2012 -0800
@@ -24,7 +24,8 @@
 
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
 
 public class AMD64MethodEndStub extends AMD64SlowPath {
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Move.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,486 +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 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.*;
-import com.oracle.max.graal.graph.*;
-
-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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
-            }
-        } else if (isStackSlot(input)) {
-            if (isRegister(result)) {
-                stack2reg(tasm, masm, result, input);
-            } else {
-                throw GraalInternalError.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 GraalInternalError.shouldNotReachHere();
-            }
-        } else {
-            throw GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere("Non-null object constants must be in register");
-                }
-                break;
-            default:
-                throw GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                case Float:  masm.movl(storeAddr, floatToRawIntBits(c.asFloat())); break;
-                case Double: throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                case Object:
-                    if (c.isNull()) {
-                        masm.movptr(storeAddr, 0);
-                    } else {
-                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                    }
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, 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 GraalInternalError.shouldNotReachHere();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64SlowPath.java	Wed Feb 08 18:19:09 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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.target.amd64;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.lir.*;
-
-/**
- * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
- */
-public abstract class AMD64SlowPath implements LIR.SlowPath {
-    @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
-    }
-
-    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOp.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOp.java	Wed Feb 08 19:25:29 2012 -0800
@@ -39,9 +39,10 @@
 import com.oracle.max.cri.xir.CiXirAssembler.XirLabel;
 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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
 
 public class AMD64XirOp extends LIRXirInstruction {
     public AMD64XirOp(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/target/amd64/AMD64TailcallOp.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/target/amd64/AMD64TailcallOp.java	Wed Feb 08 19:25:29 2012 -0800
@@ -28,10 +28,10 @@
 
 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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
 
 /**
  * Performs a hard-coded tail call to the specified target, which normally should be an RiCompiledCode instance.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Arithmetic.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,559 @@
+/*
+ * 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.lir.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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 Op2Reg extends AMD64LIRInstruction {
+        public Op2Reg(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.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            super.verify();
+            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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public 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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Call.java	Wed Feb 08 19:25:29 2012 -0800
@@ -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.lir.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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static void callAlignment(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // 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) {
+        boolean assertions = false;
+        assert (assertions = true) == true;
+
+        if (assertions) {
+            directCall(tasm, masm, CiRuntimeCall.Debug, null);
+            masm.hlt();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Compare.java	Wed Feb 08 19:25:29 2012 -0800
@@ -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.lir.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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+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 GraalInternalError.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);
+        }
+    }
+
+    public 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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64CompareToIntOpcode.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,107 @@
+/*
+ * 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.lir.amd64;
+
+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.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * Implementation of the Java bytecodes that compare a long, float, or double value and produce the
+ * 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 {
+    CMP2INT, CMP2INT_UG, CMP2INT_UL;
+
+    public LIRInstruction create(CiValue result) {
+        CiValue[] outputs = new CiValue[] {result};
+
+        return new AMD64LIRInstruction(this, outputs, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
+            @Override
+            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 GraalInternalError.shouldNotReachHere();
+            }
+        };
+    }
+
+    private void emit(AMD64MacroAssembler masm, CiValue result) {
+        CiRegister dest = asIntReg(result);
+        Label high = new Label();
+        Label low = new Label();
+        Label done = new Label();
+
+        // comparison is done by a separate LIR instruction before
+        switch (this) {
+            case CMP2INT:
+                masm.jcc(ConditionFlag.greater, high);
+                masm.jcc(ConditionFlag.less, low);
+                break;
+            case CMP2INT_UG:
+                masm.jcc(ConditionFlag.parity, high);
+                masm.jcc(ConditionFlag.above, high);
+                masm.jcc(ConditionFlag.below, low);
+                break;
+            case CMP2INT_UL:
+                masm.jcc(ConditionFlag.parity, low);
+                masm.jcc(ConditionFlag.above, high);
+                masm.jcc(ConditionFlag.below, low);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+
+        // equal -> 0
+        masm.xorptr(dest, dest);
+        masm.jmp(done);
+
+        // greater -> 1
+        masm.bind(high);
+        masm.xorptr(dest, dest);
+        masm.incrementl(dest, 1);
+        masm.jmp(done);
+
+        // less -> -1
+        masm.bind(low);
+        masm.xorptr(dest, dest);
+        masm.decrementl(dest, 1);
+
+        masm.bind(done);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64ControlFlow.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,383 @@
+/*
+ * 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.lir.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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+public class AMD64ControlFlow {
+
+    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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64LIRInstruction.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * 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.lir.amd64;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
+ */
+public abstract class AMD64LIRInstruction extends LIRInstruction {
+
+    public AMD64LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+        super(opcode, outputs, info, inputs, alives, temps);
+    }
+
+    @Override
+    public final void emitCode(TargetMethodAssembler tasm) {
+        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Move.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,486 @@
+/*
+ * 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.lir.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.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.asm.*;
+
+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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public 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 GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isStackSlot(input)) {
+            if (isRegister(result)) {
+                stack2reg(tasm, masm, result, input);
+            } else {
+                throw GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            throw GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere("Non-null object constants must be in register");
+                }
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public 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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public 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 GraalInternalError.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 (NumUtil.isInt(c.asLong())) {
+                        masm.movslq(storeAddr, (int) c.asLong());
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                case Float:  masm.movl(storeAddr, floatToRawIntBits(c.asFloat())); break;
+                case Double: throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                case Object:
+                    if (c.isNull()) {
+                        masm.movptr(storeAddr, 0);
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, 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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64SlowPath.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * 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.lir.amd64;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
+ */
+public abstract class AMD64SlowPath implements LIR.SlowPath {
+    @Override
+    public final void emitCode(TargetMethodAssembler tasm) {
+        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/FrameMap.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,344 @@
+/*
+ * 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.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiCallingConvention.Type;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * This class is used to build the stack frame layout for a compiled method.
+ * A {@link CiStackSlot} is used to index slots of the frame relative to the stack pointer.
+ * The frame size is only fixed after register allocation when all spill slots have
+ * been allocated. Both the outgoing argument area and the spill are can grow until then.
+ * Therefore, outgoing arguments are indexed from the stack pointer, while spill slots
+ * are indexed from the beginning of the frame (and the total frame size has to be added
+ * to get the actual offset from the stack pointer).
+ * <br>
+ * This is the format of a stack frame:
+ * <pre>
+ *   Base       Contents
+ *
+ *            :                                :  -----
+ *   caller   | incoming overflow argument n   |    ^
+ *   frame    :     ...                        :    | positive
+ *            | incoming overflow argument 0   |    | offsets
+ *   ---------+--------------------------------+---------------------
+ *            | return address                 |    |            ^
+ *   current  +--------------------------------+    |            |    -----
+ *   frame    |                                |    |            |      ^
+ *            : callee save area               :    |            |      |
+ *            |                                |    |            |      |
+ *            +--------------------------------+    |            |      |
+ *            | spill slot 0                   |    | negative   |      |
+ *            :     ...                        :    v offsets    |      |
+ *            | spill slot n                   |  -----        total  frame
+ *            +--------------------------------+               frame  size
+ *            | alignment padding              |               size     |
+ *            +--------------------------------+  -----          |      |
+ *            | outgoing overflow argument n   |    ^            |      |
+ *            :     ...                        :    | positive   |      |
+ *            | outgoing overflow argument 0   |    | offsets    v      v
+ *    %sp-->  +--------------------------------+---------------------------
+ *
+ * </pre>
+ * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size
+ * of such a block may be greater than the size of a normal spill slot or the word size.
+ * <br>
+ * A runtime has two ways to reserve space in the stack frame for its own use: <ul>
+ * <li>A memory block somewhere in the frame of size {@link RiRuntime#getCustomStackAreaSize()}. The offset
+ *     to this block is returned in {@link CiTargetMethod#customStackAreaOffset()}.
+ * <li>At the beginning of the overflow argument area: The calling convention can specify that the first
+ *     overflow stack argument is not at offset 0, but at a specified offset o. Use
+ *     {@link RiRuntime#getMinimumOutgoingSize()} to make sure that call-free methods also have this space
+ *     reserved. Then the VM can use memory the memory at offset 0 relative to the stack pointer.
+ * </ul>
+ */
+public final class FrameMap {
+    public final RiRuntime runtime;
+    public final CiTarget target;
+    public final RiRegisterConfig registerConfig;
+
+    /**
+     * The final frame size, not including the size of the return address.
+     * The value is only set after register allocation is complete, i.e., after all spill slots have been allocated.
+     */
+    private int frameSize;
+
+    /**
+     * Size of the area occupied by spill slots and other stack-allocated memory blocks.
+     */
+    private int spillSize;
+
+    /**
+     * Size of the area occupied by outgoing overflow arguments.
+     * This value is adjusted as calling conventions for outgoing calls are retrieved.
+     */
+    private int outgoingSize;
+
+    /**
+     * The list of stack areas allocated in this frame that are present in every reference map.
+     */
+    private final List<CiStackSlot> objectStackBlocks;
+
+    /**
+     * The stack area reserved for use by the VM, or {@code null} if the VM does not request stack space.
+     */
+    private final CiStackSlot customArea;
+
+    /**
+     * Creates a new frame map for the specified method.
+     */
+    public FrameMap(RiRuntime runtime, CiTarget target, RiRegisterConfig registerConfig) {
+        this.runtime = runtime;
+        this.target = target;
+        this.registerConfig = registerConfig;
+        this.frameSize = -1;
+        this.spillSize = returnAddressSize() + calleeSaveAreaSize();
+        this.outgoingSize = runtime.getMinimumOutgoingSize();
+        this.objectStackBlocks = new ArrayList<>();
+        this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false);
+    }
+
+
+    private int returnAddressSize() {
+        return target.arch.returnAddressSize;
+    }
+
+    private int calleeSaveAreaSize() {
+        CiCalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
+        return csl != null ? csl.size : 0;
+    }
+
+    /**
+     * Gets the frame size of the compiled frame, not including the size of the return address.
+     * @return The size of the frame (in bytes).
+     */
+    public int frameSize() {
+        assert frameSize != -1 : "frame size not computed yet";
+        return frameSize;
+    }
+
+    /**
+     * Gets the total frame size of the compiled frame, including the size of the return address.
+     * @return The total size of the frame (in bytes).
+     */
+    public int totalFrameSize() {
+        return frameSize() + returnAddressSize();
+    }
+
+    /**
+     * Sets the frame size for this frame.
+     * @param frameSize The frame size (in bytes).
+     */
+    public void setFrameSize(int frameSize) {
+        assert this.frameSize == -1 : "must only be set once";
+        this.frameSize = frameSize;
+    }
+
+    /**
+     * Computes the frame size for this frame. After this method has been called, methods that change the
+     * frame size cannot be called anymore, e.g., no more spill slots or outgoing arguments can be requested.
+     */
+    public void finish() {
+        setFrameSize(target.alignFrameSize(outgoingSize + spillSize - returnAddressSize()));
+    }
+
+    /**
+     * Computes the offset of a stack slot relative to the frame register.
+     * This is also the bit index of stack slots in the reference map.
+     *
+     * @param slot a stack slot
+     * @return the offset of the stack slot
+     */
+    public int offsetForStackSlot(CiStackSlot slot) {
+        assert (!slot.rawAddFrameSize() && slot.rawOffset() < outgoingSize) ||
+            (slot.rawAddFrameSize() && slot.rawOffset() < 0 && -slot.rawOffset() <= spillSize) ||
+            (slot.rawAddFrameSize() && slot.rawOffset() >= 0);
+        return slot.offset(totalFrameSize());
+    }
+
+    /**
+     * Gets the offset to the stack area where callee-saved registers are stored.
+     * @return The offset to the callee save area (in bytes).
+     */
+    public int offsetToCalleeSaveArea() {
+        return frameSize() - calleeSaveAreaSize();
+    }
+
+    /**
+     * Gets the offset of the stack area stack block reserved for use by the VM, or -1 if the VM does not request stack space.
+     * @return The offset to the custom area (in bytes).
+     */
+    public int offsetToCustomArea() {
+        return customArea == null ? -1 : offsetForStackSlot(customArea);
+    }
+
+    /**
+     * Informs the frame map that the compiled code calls a particular method, which
+     * may need stack space for outgoing arguments.
+     * @param cc The calling convention for the called method.
+     * @param type The type of calling convention.
+     */
+    public void callsMethod(CiCallingConvention cc, Type type) {
+        // TODO look at the actual stack offsets?
+        assert type.out;
+        reserveOutgoing(cc.stackSize);
+    }
+
+    /**
+     * Reserves space for stack-based outgoing arguments.
+     * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
+     */
+    public void reserveOutgoing(int argsSize) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        outgoingSize = Math.max(outgoingSize, argsSize);
+    }
+
+    private CiStackSlot getSlot(CiKind kind, int additionalOffset) {
+        return CiStackSlot.get(kind, -spillSize + additionalOffset, true);
+    }
+
+    /**
+     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned on its natural alignment,
+     * i.e., an 8-byte spill slot is aligned at an 8-byte boundary.
+     * @param kind The kind of the spill slot to be reserved.
+     * @return A spill slot denoting the reserved memory area.
+     */
+    public CiStackSlot allocateSpillSlot(CiKind kind) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        int size = target.sizeInBytes(kind);
+        spillSize = NumUtil.roundUp(spillSize + size, size);
+        return getSlot(kind, 0);
+    }
+
+    /**
+     * Reserves a block of memory in the frame of the method being compiled. The returned block is aligned on a word boundary.
+     * If the requested size is 0, the method returns {@code null}.
+     *
+     * @param size The size to reserve (in bytes).
+     * @param refs Specifies if the block is all references. If true, the block will be in all reference maps for this method.
+     *             The caller is responsible to initialize the memory block before the first instruction that uses a reference map.
+     * @return A stack slot describing the begin of the memory block.
+     */
+    public CiStackSlot allocateStackBlock(int size, boolean refs) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        if (size == 0) {
+            return null;
+        }
+        spillSize = NumUtil.roundUp(spillSize + size, target.wordSize);
+
+        if (refs) {
+            assert size % target.wordSize == 0;
+            CiStackSlot result = getSlot(CiKind.Object, 0);
+            objectStackBlocks.add(result);
+            for (int i = target.wordSize; i < size; i += target.wordSize) {
+                objectStackBlocks.add(getSlot(CiKind.Object, i));
+            }
+            return result;
+
+        } else {
+            return getSlot(target.wordKind, 0);
+        }
+    }
+
+
+    private int frameRefMapIndex(CiStackSlot slot) {
+        assert offsetForStackSlot(slot) % target.wordSize == 0;
+        return offsetForStackSlot(slot) / target.wordSize;
+    }
+
+    /**
+     * Initializes a reference map that covers all registers of the target architecture.
+     */
+    public CiBitMap initRegisterRefMap() {
+        return new CiBitMap(target.arch.registerReferenceMapBitCount);
+    }
+
+    /**
+     * Initializes a reference map. Initially, the size is large enough to cover all the
+     * slots in the frame. If the method has incoming reference arguments on the stack,
+     * the reference map might grow later when such a reference is set.
+     */
+    public CiBitMap initFrameRefMap() {
+        CiBitMap frameRefMap = new CiBitMap(frameSize() / target.wordSize);
+        for (CiStackSlot slot : objectStackBlocks) {
+            setReference(slot, null, frameRefMap);
+        }
+        return frameRefMap;
+    }
+
+    /**
+     * Marks the specified location as a reference in the reference map of the debug information.
+     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
+     * {@link CiConstant} is automatically tracked.
+     *
+     * @param location The location to be added to the reference map.
+     * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
+     * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
+     */
+    public void setReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+        if (location.kind == CiKind.Object) {
+            if (isRegister(location)) {
+                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
+                registerRefMap.set(asRegister(location).number);
+            } else if (isStackSlot(location)) {
+                int index = frameRefMapIndex(asStackSlot(location));
+                frameRefMap.grow(index + 1);
+                frameRefMap.set(index);
+            } else {
+                assert isConstant(location);
+            }
+        }
+    }
+
+    /**
+     * Clears the specified location as a reference in the reference map of the debug information.
+     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
+     * {@link CiConstant} is automatically tracked.
+     *
+     * @param location The location to be removed from the reference map.
+     * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
+     * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
+     */
+    public void clearReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+        if (location.kind == CiKind.Object) {
+            if (location instanceof CiRegisterValue) {
+                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
+                registerRefMap.clear(asRegister(location).number);
+            } else if (isStackSlot(location)) {
+                int index = frameRefMapIndex(asStackSlot(location));
+                if (index < frameRefMap.size()) {
+                    frameRefMap.clear(index);
+                }
+            } else {
+                assert isConstant(location);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIR.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,240 @@
+/*
+ * 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.lir;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * This class implements the overall container for the LIR graph
+ * and directs its construction, optimization, and finalization.
+ */
+public class LIR {
+
+    public final ControlFlowGraph cfg;
+
+    /**
+     * The nodes for the blocks.
+     * TODO: This should go away, we want all nodes connected with a next-pointer.
+     */
+    private final BlockMap<List<Node>> nodesFor;
+
+    /**
+     * The linear-scan ordered list of blocks.
+     */
+    private final List<Block> linearScanOrder;
+
+    /**
+     * The order in which the code is emitted.
+     */
+    private final List<Block> codeEmittingOrder;
+
+
+    public final List<SlowPath> slowPaths;
+
+    public final List<SlowPath> deoptimizationStubs;
+
+    /**
+     * The last slow path emitted, which can be used emit marker bytes.
+     */
+    public SlowPath methodEndMarker;
+
+    private int numVariables;
+
+    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);
+    }
+
+    /**
+     * Creates a new LIR instance for the specified compilation.
+     * @param numLoops number of loops
+     * @param compilation the compilation
+     */
+    public LIR(ControlFlowGraph cfg, BlockMap<List<Node>> nodesFor, List<Block> linearScanOrder, List<Block> codeEmittingOrder) {
+        this.cfg = cfg;
+        this.nodesFor = nodesFor;
+        this.codeEmittingOrder = codeEmittingOrder;
+        this.linearScanOrder = linearScanOrder;
+
+        slowPaths = new ArrayList<>();
+        deoptimizationStubs = new ArrayList<>();
+    }
+
+    public List<Node> nodesFor(Block block) {
+        return nodesFor.get(block);
+    }
+
+    /**
+     * Gets the linear scan ordering of blocks as a list.
+     * @return the blocks in linear scan order
+     */
+    public List<Block> linearScanOrder() {
+        return linearScanOrder;
+    }
+
+    public List<Block> codeEmittingOrder() {
+        return codeEmittingOrder;
+    }
+
+    public int numVariables() {
+        return numVariables;
+    }
+
+    public int nextVariable() {
+        return numVariables++;
+    }
+
+    public void emitCode(TargetMethodAssembler tasm) {
+        for (Block b : codeEmittingOrder()) {
+            emitBlock(tasm, b);
+        }
+
+        // generate code for slow cases
+        for (SlowPath sp : slowPaths) {
+            emitSlowPath(tasm, sp);
+        }
+        // generate deoptimization stubs
+        for (SlowPath sp : deoptimizationStubs) {
+            emitSlowPath(tasm, sp);
+        }
+        // generate traps at the end of the method
+        emitSlowPath(tasm, methodEndMarker);
+    }
+
+    private static void emitBlock(TargetMethodAssembler tasm, Block block) {
+        if (Debug.isDumpEnabled()) {
+            tasm.blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
+        }
+
+        for (LIRInstruction op : block.lir) {
+            if (Debug.isDumpEnabled()) {
+                tasm.blockComment(String.format("%d %s", op.id(), op));
+            }
+
+            emitOp(tasm, op);
+        }
+    }
+
+    private static void emitOp(TargetMethodAssembler tasm, LIRInstruction op) {
+        try {
+            try {
+                op.emitCode(tasm);
+            } catch (AssertionError t) {
+                throw new GraalInternalError(t);
+            } catch (RuntimeException t) {
+                throw new GraalInternalError(t);
+            }
+        } catch (GraalInternalError e) {
+            throw e.addContext("lir instruction", op);
+        }
+    }
+
+    private static void emitSlowPath(TargetMethodAssembler tasm, SlowPath sp) {
+        if (Debug.isDumpEnabled()) {
+            tasm.blockComment(String.format("slow case %s", sp.getClass().getName()));
+        }
+        sp.emitCode(tasm);
+    }
+
+/*
+    private int lastDecodeStart;
+
+    private void printAssembly(TargetMethodAssembler tasm) {
+        byte[] currentBytes = tasm.asm.codeBuffer.copyData(lastDecodeStart, tasm.asm.codeBuffer.position());
+        if (currentBytes.length > 0) {
+            String disasm = tasm.runtime.disassemble(currentBytes, lastDecodeStart);
+            if (disasm.length() != 0) {
+                TTY.println(disasm);
+            } else {
+                TTY.println("Code [+%d]: %d bytes", lastDecodeStart, currentBytes.length);
+                Util.printBytes(lastDecodeStart, currentBytes, GraalOptions.PrintAssemblyBytesPerLine);
+            }
+        }
+        lastDecodeStart = tasm.asm.codeBuffer.position();
+    }
+
+
+    public static void printBlock(Block x) {
+        // print block id
+        TTY.print("B%d ", x.getId());
+
+        // print flags
+        if (x.isLoopHeader()) {
+            TTY.print("lh ");
+        }
+        if (x.isLoopEnd()) {
+            TTY.print("le ");
+        }
+
+        // print block bci range
+        TTY.print("[%d, %d] ", -1, -1);
+
+        // print predecessors and successors
+        if (x.numberOfPreds() > 0) {
+            TTY.print("preds: ");
+            for (int i = 0; i < x.numberOfPreds(); i++) {
+                TTY.print("B%d ", x.predAt(i).getId());
+            }
+        }
+
+        if (x.numberOfSux() > 0) {
+            TTY.print("sux: ");
+            for (int i = 0; i < x.numberOfSux(); i++) {
+                TTY.print("B%d ", x.suxAt(i).getId());
+            }
+        }
+
+        TTY.println();
+    }
+
+    public static void printLIR(List<Block> blocks) {
+        if (TTY.isSuppressed()) {
+            return;
+        }
+        TTY.println("LIR:");
+        int i;
+        for (i = 0; i < blocks.size(); i++) {
+            Block bb = blocks.get(i);
+            printBlock(bb);
+            TTY.println("__id_Instruction___________________________________________");
+            for (LIRInstruction op : bb.lir) {
+                TTY.println(op.toStringWithIdPrefix());
+                TTY.println();
+            }
+            TTY.println();
+        }
+    }
+*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRDebugInfo.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,128 @@
+/*
+ * 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.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.max.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.max.graal.lir.LIRInstruction.ValueProcedure;
+
+/**
+ * This class represents garbage collection and deoptimization information attached to a LIR instruction.
+ */
+public class LIRDebugInfo {
+    public final CiFrame topFrame;
+    private final CiVirtualObject[] virtualObjects;
+    private final List<CiStackSlot> pointerSlots;
+    public final LabelRef exceptionEdge;
+    private CiDebugInfo debugInfo;
+
+    public LIRDebugInfo(CiFrame topFrame, CiVirtualObject[] virtualObjects, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
+        this.topFrame = topFrame;
+        this.virtualObjects = virtualObjects;
+        this.pointerSlots = pointerSlots;
+        this.exceptionEdge = exceptionEdge;
+    }
+
+    public boolean hasDebugInfo() {
+        return debugInfo != null;
+    }
+
+    public CiDebugInfo debugInfo() {
+        assert debugInfo != null : "debug info not allocated yet";
+        return debugInfo;
+    }
+
+    /**
+     * Iterates the frame state and calls the {@link ValueProcedure} for every variable.
+     *
+     * @param proc The procedure called for variables.
+     */
+    public void forEachState(ValueProcedure proc) {
+        for (CiFrame cur = topFrame; cur != null; cur = cur.caller()) {
+            processValues(cur.values, proc);
+        }
+        if (virtualObjects != null) {
+            for (CiVirtualObject obj : virtualObjects) {
+                processValues(obj.values(), proc);
+            }
+        }
+    }
+
+    /**
+     * We filter out constant and illegal values ourself before calling the procedure, so {@link OperandFlag#Constant} and {@link OperandFlag#Illegal} need not be set.
+     */
+    private static final EnumSet<OperandFlag> STATE_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+
+    private void processValues(CiValue[] values, ValueProcedure proc) {
+        for (int i = 0; i < values.length; i++) {
+            CiValue value = values[i];
+            if (value instanceof CiMonitorValue) {
+                CiMonitorValue monitor = (CiMonitorValue) value;
+                if (processed(monitor.owner)) {
+                    monitor.owner = proc.doValue(monitor.owner, OperandMode.Alive, STATE_FLAGS);
+                }
+
+            } else if (processed(value)) {
+                values[i] = proc.doValue(value, OperandMode.Alive, STATE_FLAGS);
+            }
+        }
+    }
+
+    private boolean processed(CiValue value) {
+        if (isIllegal(value)) {
+            // Ignore dead local variables.
+            return false;
+        } else if (isConstant(value)) {
+            // Ignore constants, the register allocator does not need to see them.
+            return false;
+        } else if (isVirtualObject(value)) {
+            assert Arrays.asList(virtualObjects).contains(value);
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+
+    public void finish(CiBitMap registerRefMap, CiBitMap frameRefMap, FrameMap frameMap) {
+        debugInfo = new CiDebugInfo(topFrame, registerRefMap, frameRefMap);
+
+        // Add additional stack slots for outgoing method parameters.
+        if (pointerSlots != null) {
+            for (CiStackSlot v : pointerSlots) {
+                frameMap.setReference(v, registerRefMap, frameRefMap);
+            }
+        }
+    }
+
+
+    @Override
+    public String toString() {
+        return debugInfo != null ? debugInfo.toString() : topFrame.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRInsertionBuffer.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+package com.oracle.max.graal.lir;
+
+import java.util.*;
+
+/**
+ * A buffer to enqueue updates to a list. This avoids frequent re-sizing of the list and copying of list elements
+ * when insertions are done at multiple positions of the list. Additionally, it ensures that the list is not modified
+ * while it is, e.g., iterated, and instead only modified once after the iteration is done.
+ * <br>
+ * The buffer uses internal data structures to store the enqueued updates. To avoid allocations, a buffer can be re-used.
+ * Call the methods in the following order:
+ * {@link #init()}, {@link #append()}, {@link #append()}, ..., {@link #finish()}, {@link #init()}, ...
+ * <br>
+ * Note: This class does not depend on LIRInstruction, so we could make it a generic utility class.
+ */
+public final class LIRInsertionBuffer {
+
+    /**
+     * The lir list where ops of this buffer should be inserted later (null when uninitialized).
+     */
+    private List<LIRInstruction> lir;
+
+    /**
+     * List of insertion points. index and count are stored alternately:
+     * indexAndCount[i * 2]: the index into lir list where "count" ops should be inserted
+     * indexAndCount[i * 2 + 1]: the number of ops to be inserted at index
+     */
+    private final List<Integer> indexAndCount;
+
+    /**
+     * The LIROps to be inserted.
+     */
+    private final List<LIRInstruction> ops;
+
+
+    public LIRInsertionBuffer() {
+        indexAndCount = new ArrayList<>(8);
+        ops = new ArrayList<>(8);
+    }
+
+    /**
+     * Initialize this buffer. This method must be called before using {@link #append()}.
+     */
+    public void init(List<LIRInstruction> newLir) {
+        assert !initialized() : "already initialized";
+        assert indexAndCount.size() == 0 && ops.size() == 0;
+        this.lir = newLir;
+    }
+
+    public boolean initialized() {
+        return lir != null;
+    }
+
+    public List<LIRInstruction> lirList() {
+        return lir;
+    }
+
+    /**
+     * Enqueue a new instruction that will be appended to the instruction list when {@link #finish()} is called.
+     * The new instruction is added <b>before</b> the existing instruction with the given index. This method can only be called
+     * with increasing values of index, e.g., once an instruction was appended with index 4, subsequent instructions can
+     * only be appended with index 4 or higher.
+     */
+    public void append(int index, LIRInstruction op) {
+        int i = numberOfInsertionPoints() - 1;
+        if (i < 0 || indexAt(i) < index) {
+            appendNew(index, 1);
+        } else {
+            assert indexAt(i) == index : "can append LIROps in ascending order only";
+            assert countAt(i) > 0 : "check";
+            setCountAt(i, countAt(i) + 1);
+        }
+        ops.add(op);
+
+        assert verify();
+    }
+
+    /**
+     * Append all enqueued instructions to the instruction list. After that, {@link init()} can be called again to re-use this buffer.
+     */
+    public void finish() {
+        if (ops.size() > 0) {
+            int n = lir.size();
+            // increase size of instructions list
+            for (int i = 0; i < ops.size(); i++) {
+                lir.add(null);
+            }
+            // insert ops from buffer into instructions list
+            int opIndex = ops.size() - 1;
+            int ipIndex = numberOfInsertionPoints() - 1;
+            int fromIndex = n - 1;
+            int toIndex = lir.size() - 1;
+            while (ipIndex >= 0) {
+                int index = indexAt(ipIndex);
+                // make room after insertion point
+                while (fromIndex >= index) {
+                    lir.set(toIndex--, lir.get(fromIndex--));
+                }
+                // insert ops from buffer
+                for (int i = countAt(ipIndex); i > 0; i--) {
+                    lir.set(toIndex--, ops.get(opIndex--));
+                }
+                ipIndex--;
+            }
+            indexAndCount.clear();
+            ops.clear();
+        }
+        lir = null;
+    }
+
+    private void appendNew(int index, int count) {
+        indexAndCount.add(index);
+        indexAndCount.add(count);
+    }
+
+    private void setCountAt(int i, int value) {
+        indexAndCount.set((i << 1) + 1, value);
+    }
+
+    private int numberOfInsertionPoints() {
+        assert indexAndCount.size() % 2 == 0 : "must have a count for each index";
+        return indexAndCount.size() >> 1;
+    }
+
+    private int indexAt(int i) {
+        return indexAndCount.get((i << 1));
+    }
+
+    private int countAt(int i) {
+        return indexAndCount.get((i << 1) + 1);
+    }
+
+    private boolean verify() {
+        int sum = 0;
+        int prevIdx = -1;
+
+        for (int i = 0; i < numberOfInsertionPoints(); i++) {
+            assert prevIdx < indexAt(i) : "index must be ordered ascending";
+            sum += countAt(i);
+        }
+        assert sum == ops.size() : "wrong total sum";
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRInstruction.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,447 @@
+/*
+ * 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.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * The {@code LIRInstruction} class definition.
+ */
+public abstract class LIRInstruction {
+
+    public static final CiValue[] NO_OPERANDS = {};
+
+    /**
+     * Iterator for iterating over a list of values. Subclasses must overwrite one of the doValue methods.
+     * Clients of the class must only call the doValue method that takes additional parameters.
+     */
+    public abstract static class ValueProcedure {
+        /**
+         * Iterator method to be overwritten. This version of the iterator does not take additional parameters
+         * to keep the signature short.
+         *
+         * @param value The value that is iterated.
+         * @return The new value to replace the value that was passed in.
+         */
+        protected CiValue doValue(CiValue value) {
+            throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten");
+        }
+
+        /**
+         * Iterator method to be overwritten. This version of the iterator gets additional parameters about the
+         * processed value.
+         *
+         * @param value The value that is iterated.
+         * @param mode The operand mode for the value.
+         * @param flags A set of flags for the value.
+         * @return The new value to replace the value that was passed in.
+         */
+        public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            return doValue(value);
+        }
+    }
+
+
+    /**
+     * Constants denoting how a LIR instruction uses an operand.
+     */
+    public enum OperandMode {
+        /**
+         * The value must have been defined before. It is alive before the instruction until the beginning of the
+         * instruction, but not necessarily throughout the instruction. A register assigned to it can also be assigend
+         * to a Temp or Output operand. The value can be used again after the instruction, so the instruction must not
+         * modify the register.
+         */
+        Input,
+
+        /**
+         * The value must have been defined before. It is alive before the instruction and throughout the instruction. A
+         * register assigned to it cannot be assigned to a Temp or Output operand. The value can be used again after the
+         * instruction, so the instruction must not modify the register.
+         */
+        Alive,
+
+        /**
+         * The value must not have been defined before, and must not be used after the instruction. The instruction can
+         * do whatever it wants with the register assigned to it (or not use it at all).
+         */
+        Temp,
+
+        /**
+         * The value must not have been defined before. The instruction has to assign a value to the register. The
+         * value can (and most likely will) be used after the instruction.
+         */
+        Output,
+    }
+
+    /**
+     * Flags for an operand.
+     */
+    public enum OperandFlag {
+        /**
+         * The value can be a {@link CiRegisterValue}.
+         */
+        Register,
+
+        /**
+         * The value can be a {@link CiStackSlot}.
+         */
+        Stack,
+
+        /**
+         * The value can be a {@link CiAddress}.
+         */
+        Address,
+
+        /**
+         * The value can be a {@link CiConstant}.
+         */
+        Constant,
+
+        /**
+         * The value can be {@link CiValue#IllegalValue}.
+         */
+        Illegal,
+
+        /**
+         * The register allocator should try to assign a certain register to improve code quality.
+         * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints.
+         */
+        RegisterHint,
+
+        /**
+         * The value can be uninitialized, e.g., a stack slot that has not written to before. This is only
+         * used to avoid false positives in verification code.
+         */
+        Uninitialized,
+    }
+
+    /**
+     * For validity checking of the operand flags defined by instruction subclasses.
+     */
+    private static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS;
+
+    static {
+        ALLOWED_FLAGS = new EnumMap<>(OperandMode.class);
+        ALLOWED_FLAGS.put(OperandMode.Input,  EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized));
+        ALLOWED_FLAGS.put(OperandMode.Alive,  EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized));
+        ALLOWED_FLAGS.put(OperandMode.Temp,   EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint));
+        ALLOWED_FLAGS.put(OperandMode.Output, EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Illegal, OperandFlag.RegisterHint));
+    }
+
+    /**
+     * The opcode of this instruction.
+     */
+    protected final Object code;
+
+    /**
+     * The output operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] outputs;
+
+    /**
+     * The input operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] inputs;
+
+    /**
+     * The alive operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] alives;
+
+    /**
+     * The temp operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] temps;
+
+    /**
+     * Used to emit debug information.
+     */
+    public final LIRDebugInfo info;
+
+    /**
+     * Instruction id for register allocation.
+     */
+    private int id;
+
+    /**
+     * Constructs a new LIR instruction that has input and temp operands.
+     *
+     * @param opcode the opcode of the new instruction
+     * @param outputs the operands that holds the operation results of this instruction.
+     * @param info the {@link LIRDebugInfo} info that is to be preserved for the instruction. This will be {@code null} when no debug info is required for the instruction.
+     * @param inputs the input operands for the instruction.
+     * @param temps the temp operands for the instruction.
+     */
+    public LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+        this.code = opcode;
+        this.outputs = outputs;
+        this.inputs = inputs;
+        this.alives = alives;
+        this.temps = temps;
+        this.info = info;
+        this.id = -1;
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm);
+
+
+    public final int id() {
+        return id;
+    }
+
+    public final void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets an input operand of this instruction.
+     *
+     * @param index the index of the operand requested.
+     * @return the {@code index}'th input operand.
+     */
+    protected final CiValue input(int index) {
+        return inputs[index];
+    }
+
+    /**
+     * Gets an alive operand of this instruction.
+     *
+     * @param index the index of the operand requested.
+     * @return the {@code index}'th alive operand.
+     */
+    protected final CiValue alive(int index) {
+        return alives[index];
+    }
+
+    /**
+     * Gets a temp operand of this instruction.
+     *
+     * @param index the index of the operand requested.
+     * @return the {@code index}'th temp operand.
+     */
+    protected final CiValue temp(int index) {
+        return temps[index];
+    }
+
+    /**
+     * Gets the result operand for this instruction.
+     *
+     * @return return the result operand
+     */
+    protected final CiValue output(int index) {
+        return outputs[index];
+    }
+
+    /**
+     * Gets the instruction name.
+     */
+    public String name() {
+        return code.toString();
+    }
+
+    public boolean hasOperands() {
+        return inputs.length > 0 || alives.length > 0 || temps.length > 0 || outputs.length > 0 || info != null || hasCall();
+    }
+
+    private static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+
+    private void forEach(CiValue[] values, OperandMode mode, ValueProcedure proc) {
+        for (int i = 0; i < values.length; i++) {
+            assert ALLOWED_FLAGS.get(mode).containsAll(flagsFor(mode, i));
+
+            CiValue value = values[i];
+            if (isAddress(value)) {
+                assert flagsFor(mode, i).contains(OperandFlag.Address);
+                CiAddress address = asAddress(value);
+                address.base = proc.doValue(address.base, mode, ADDRESS_FLAGS);
+                address.index = proc.doValue(address.index, mode, ADDRESS_FLAGS);
+            } else {
+                values[i] = proc.doValue(values[i], mode, flagsFor(mode, i));
+            }
+        }
+    }
+
+    public final void forEachInput(ValueProcedure proc) {
+        forEach(inputs, OperandMode.Input, proc);
+    }
+
+    public final void forEachAlive(ValueProcedure proc) {
+        forEach(alives, OperandMode.Alive, proc);
+    }
+
+    public final void forEachTemp(ValueProcedure proc) {
+        forEach(temps, OperandMode.Temp, proc);
+    }
+
+    public final void forEachOutput(ValueProcedure proc) {
+        forEach(outputs, OperandMode.Output, proc);
+    }
+
+    public final void forEachState(ValueProcedure proc) {
+        if (info != null) {
+            info.forEachState(proc);
+
+            if (this instanceof LIRXirInstruction) {
+                LIRXirInstruction xir = (LIRXirInstruction) this;
+                if (xir.infoAfter != null) {
+                    xir.infoAfter.forEachState(proc);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true when this instruction is a call instruction that destroys all caller-saved registers.
+     */
+    public final boolean hasCall() {
+        return this instanceof StandardOp.CallOp;
+    }
+
+    /**
+     * Iterates all register hints for the specified value, i.e., all preferred candidates for the register to be
+     * assigned to the value.
+     * <br>
+     * Subclasses can override this method. The default implementation processes all Input operands as the hints for
+     * an Output operand, and all Output operands as the hints for an Input operand.
+     *
+     * @param value The value the hints are needed for.
+     * @param mode The operand mode of the value.
+     * @param proc The procedure invoked for all the hints. If the procedure returns a non-null value, the iteration is stopped
+     *             and the value is returned by this method, i.e., clients can stop the iteration once a suitable hint has been found.
+     * @return The non-null value returned by the procedure, or null.
+     */
+    public CiValue forEachRegisterHint(CiValue value, OperandMode mode, ValueProcedure proc) {
+        CiValue[] hints;
+        if (mode == OperandMode.Input) {
+            hints = outputs;
+        } else if (mode == OperandMode.Output) {
+            hints = inputs;
+        } else {
+            return null;
+        }
+
+        for (int i = 0; i < hints.length; i++) {
+            CiValue result = proc.doValue(hints[i], null, null);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Used by the register allocator to decide which kind of location can be assigned to the operand.
+     * @param mode The kind of operand.
+     * @param index The index of the operand.
+     * @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 abstract EnumSet<OperandFlag> flagsFor(OperandMode mode, int index);
+
+    protected void verify() {
+    }
+
+
+    public final String toStringWithIdPrefix() {
+        if (id != -1) {
+            return String.format("%4d %s", id, toString());
+        }
+        return "     " + toString();
+    }
+
+    /**
+     * Gets the operation performed by this instruction in terms of its operands as a string.
+     */
+    public String operationString() {
+        StringBuilder buf = new StringBuilder();
+        String sep = "";
+        if (outputs.length > 1) {
+            buf.append("(");
+        }
+        for (CiValue output : outputs) {
+            buf.append(sep).append(output);
+            sep = ", ";
+        }
+        if (outputs.length > 1) {
+            buf.append(")");
+        }
+        if (outputs.length > 0) {
+            buf.append(" = ");
+        }
+
+        if (inputs.length + alives.length != 1) {
+            buf.append("(");
+        }
+        sep = "";
+        for (CiValue input : inputs) {
+            buf.append(sep).append(input);
+            sep = ", ";
+        }
+        for (CiValue input : alives) {
+            buf.append(sep).append(input).append(" ~");
+            sep = ", ";
+        }
+        if (inputs.length + alives.length != 1) {
+            buf.append(")");
+        }
+
+        if (temps.length > 0) {
+            buf.append(" [");
+        }
+        sep = "";
+        for (CiValue temp : temps) {
+            buf.append(sep).append(temp);
+            sep = ", ";
+        }
+        if (temps.length > 0) {
+            buf.append("]");
+        }
+        return buf.toString();
+    }
+
+    protected void appendDebugInfo(StringBuilder buf) {
+        if (info != null) {
+            buf.append(" [bci:");
+            String sep = "";
+            for (CiFrame cur = info.topFrame; cur != null; cur = cur.caller()) {
+                buf.append(sep).append(cur.bci);
+                sep = ",";
+            }
+            buf.append("]");
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder(name()).append(' ').append(operationString());
+        appendDebugInfo(buf);
+        return buf.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRVerifier.java	Wed Feb 08 19:25:29 2012 -0800
@@ -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.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+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.getId()];
+    }
+    private void setLiveOutFor(Block block, BitSet liveOut) {
+        blockLiveOut[block.getId()] = 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 Block curBlock;
+    private Object curInstruction;
+    private BitSet curRegistersDefined;
+
+    private void verify() {
+        ValueProcedure useProc = new ValueProcedure() { @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 (Block block : lir.linearScanOrder()) {
+            curBlock = block;
+            curVariablesLive = new BitSet();
+            curRegistersLive = new CiValue[maxRegisterNum()];
+
+            if (block.getDominator() != null) {
+                curVariablesLive.or(liveOutFor(block.getDominator()));
+            }
+
+            assert block.lir.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+            if (block.numberOfPreds() > 1) {
+                assert block.lir.get(0) instanceof StandardOp.PhiLabelOp : "phi mapping required for multiple predecessors";
+                CiValue[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
+                if (!beforeRegisterAllocation) {
+                    assert phiDefinitions.length == 0;
+                }
+                for (Block pred : block.getPredecessors()) {
+                    assert pred.numberOfSux() == 1;
+                    LIRInstruction last = pred.lir.get(pred.lir.size() - 1);
+                    assert last instanceof StandardOp.PhiJumpOp : "phi mapping required for multiple successors";
+                    CiValue[] phiUses = ((StandardOp.PhiJumpOp) last).getPhiInputs();
+                    if (!beforeRegisterAllocation) {
+                        assert phiUses.length == 0;
+                    }
+                }
+            }
+
+            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;
+            }
+
+            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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.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 GraalInternalError.shouldNotReachHere();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRXirInstruction.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,96 @@
+/*
+ * 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.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.graph.*;
+
+public abstract class LIRXirInstruction extends LIRInstruction {
+
+    public final CiValue[] originalOperands;
+    public final int outputOperandIndex;
+    public final int[] inputOperandIndices;
+    public final int[] tempOperandIndices;
+    public final XirSnippet snippet;
+    public final LIRDebugInfo infoAfter;
+    public final LabelRef trueSuccessor;
+    public final LabelRef falseSuccessor;
+
+    public LIRXirInstruction(Object opcode,
+                             XirSnippet snippet,
+                             CiValue[] originalOperands,
+                             CiValue outputOperand,
+                             CiValue[] inputs, CiValue[] temps,
+                             int[] inputOperandIndices, int[] tempOperandIndices,
+                             int outputOperandIndex,
+                             LIRDebugInfo info,
+                             LIRDebugInfo infoAfter,
+                             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.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;
+    }
+
+    @Override
+    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);
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public CiValue[] getOperands() {
+        for (int i = 0; i < inputOperandIndices.length; i++) {
+            originalOperands[inputOperandIndices[i]] = alive(i);
+        }
+        for (int i = 0; i < tempOperandIndices.length; i++) {
+            originalOperands[tempOperandIndices[i]] = temp(i);
+        }
+        if (outputOperandIndex != -1) {
+            originalOperands[outputOperandIndex] = output(0);
+        }
+        return originalOperands;
+    }
+
+    @Override
+    public String name() {
+        return "XIR: " + snippet.template;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LabelRef.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,83 @@
+/*
+ * 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.lir;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * LIR instructions such as JUMP and BRANCH need to reference their target {@link Block}. However,
+ * direct references are not possible since the control flow graph (and therefore successors lists) can
+ * be changed by optimizations - and fixing the instructions is error prone.
+ * Therefore, we only reference of block B from block A only via the tuple (A, successor-index-of-B), i.e.,
+ * indirectly by storing the index into the successor list of A.
+ * Note that therefore it is not allowed to reorder the successor list!
+ *
+ * Labels of out-of-line stubs can be referenced directly, therefore it is also possible to construct a
+ * LabelRef for a Label directly via {@link #forLabel}.
+ */
+public abstract class LabelRef {
+
+    public abstract Label label();
+
+    /**
+     * Returns a new reference to a statically defined label.
+     * @param label The label that is always returned.
+     * @return The newly created label reference.
+     */
+    public static LabelRef forLabel(final Label label) {
+       return new LabelRef() {
+           @Override
+           public Label label() {
+               return label;
+           }
+
+           @Override
+           public String toString() {
+               return label.toString();
+           }
+       };
+    }
+
+    /**
+     * Returns a new reference to a successor of the given block.
+     * This allows to reference the given successor even when the successor list
+     * is modified between the creation of the reference and the call to {@link #getLabel}.
+     * @param block The base block that contains the successor list.
+     * @param suxIndex The index of the successor.
+     * @return The newly created label reference.
+     */
+    public static LabelRef forSuccessor(final Block block, final int suxIndex) {
+        return new LabelRef() {
+            @Override
+            public Label label() {
+                return ((StandardOp.LabelOp) block.suxAt(suxIndex).lir.get(0)).getLabel();
+            }
+
+            @Override
+            public String toString() {
+                return suxIndex < block.numberOfSux() ? block.suxAt(suxIndex).toString() : "?" + block + ":" + suxIndex + "?";
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/StandardOp.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,211 @@
+/*
+ * 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.lir;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * A collection of machine-independent LIR operations, as well as interfaces to be implemented for specific kinds or LIR
+ * operations.
+ */
+public class StandardOp {
+
+    private static CiValue[] EMPTY = new CiValue[0];
+
+    /**
+     * LIR operation that defines the position of a label.
+     * The first operation of every block must implement this interface.
+     */
+    public static class LabelOp extends LIRInstruction {
+        private final Label label;
+        private final boolean align;
+
+        protected LabelOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, Label label, boolean align) {
+            super(opcode, outputs, info, inputs, alives, temps);
+            this.label = label;
+            this.align = align;
+        }
+
+        public LabelOp(Label label, boolean align) {
+            this("LABEL", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm) {
+            if (align) {
+                tasm.asm.align(tasm.target.wordSize);
+            }
+            tasm.asm.bind(label);
+        }
+
+        @Override
+        public String operationString() {
+            return label.toString() + " " + super.operationString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public Label getLabel() {
+            return label;
+        }
+    }
+
+    public static class PhiLabelOp extends LabelOp {
+        public PhiLabelOp(Label label, boolean align, CiValue[] phiDefinitions) {
+            super("PHI_LABEL", phiDefinitions, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public void markResolved() {
+            outputs = EMPTY;
+        }
+
+        public CiValue[] getPhiDefinitions() {
+            return outputs;
+        }
+    }
+
+    /**
+     * 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 static class JumpOp extends LIRInstruction {
+        private final LabelRef destination;
+
+        protected JumpOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, LabelRef destination) {
+            super(opcode, outputs, info, inputs, alives, temps);
+            this.destination = destination;
+        }
+
+        public JumpOp(LabelRef destination, LIRDebugInfo info) {
+            this("JUMP", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, destination);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm) {
+            tasm.asm.jmp(destination.label());
+        }
+
+        @Override
+        public String operationString() {
+            return  destination + " " + super.operationString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public LabelRef destination() {
+            return destination;
+        }
+    }
+
+    public static class PhiJumpOp extends JumpOp {
+        public PhiJumpOp(LabelRef destination, CiValue[] phiInputs) {
+            super("PHI_JUMP", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, phiInputs, LIRInstruction.NO_OPERANDS, destination);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public void markResolved() {
+            alives = EMPTY;
+        }
+
+        public CiValue[] getPhiInputs() {
+            return alives;
+        }
+    }
+
+    /**
+     * 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 GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/ValueUtil.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * 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.lir;
+
+import com.oracle.max.cri.ci.*;
+
+public class ValueUtil extends CiValueUtil {
+
+    public static boolean isVariable(CiValue value) {
+        assert value != null;
+        return value instanceof Variable;
+    }
+
+    public static Variable asVariable(CiValue value) {
+        assert value != null;
+        return (Variable) value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/Variable.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, 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.lir;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a value that is yet to be bound to a machine location (such as
+ * a {@link CiRegisterValue} or {@link CiStackSlot}) by a register allocator.
+ */
+public final class Variable extends CiValue {
+    private static final long serialVersionUID = 4507578431686109809L;
+
+    /**
+     * The identifier of the variable. This is a non-zero index in a contiguous 0-based name space.
+     */
+    public final int index;
+
+    /**
+     * The type of register that this variable needs to get assigned.
+     */
+    public final CiRegister.RegisterFlag flag;
+
+    /**
+     * Creates a new variable.
+     * @param kind
+     * @param index
+     */
+    public Variable(CiKind kind, int index, CiRegister.RegisterFlag flag) {
+        super(kind);
+        assert kind == kind.stackKind() : "Variables can be only created for stack kinds";
+        assert index >= 0;
+        this.index = index;
+        this.flag = flag;
+    }
+
+    @Override
+    public int hashCode() {
+        return (index << 4) | kind.ordinal();
+    }
+
+    @Override
+    public String toString() {
+        return "v" + index + kindSuffix();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/asm/TargetMethodAssembler.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,280 @@
+/*
+ * 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.lir.asm;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIR.*;
+
+public class TargetMethodAssembler {
+
+    private static class ExceptionInfo {
+        public final int codeOffset;
+        public final LabelRef exceptionEdge;
+
+        public ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
+            this.codeOffset = pcOffset;
+            this.exceptionEdge = exceptionEdge;
+        }
+    }
+
+    public final AbstractAssembler asm;
+    public final CiTargetMethod targetMethod;
+    public final CiTarget target;
+    public final RiRuntime runtime;
+    public final FrameMap frameMap;
+    public final List<SlowPath> slowPaths;
+
+    private List<ExceptionInfo> exceptionInfoList;
+    private int lastSafepointPos;
+
+    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
+        this.target = target;
+        this.runtime = runtime;
+        this.frameMap = frameMap;
+        this.slowPaths = slowPaths;
+        this.asm = asm;
+        this.targetMethod = new CiTargetMethod();
+        // 0 is a valid pc for safepoints in template methods
+        this.lastSafepointPos = -1;
+    }
+
+    public void setFrameSize(int frameSize) {
+        targetMethod.setFrameSize(frameSize);
+    }
+
+    public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) {
+        return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
+    }
+
+    public void blockComment(String s) {
+        targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s));
+    }
+
+    public CiTargetMethod finishTargetMethod(Object name, boolean isStub) {
+        // Install code, data and frame size
+        targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
+
+        // Record exception handlers if they exist
+        if (exceptionInfoList != null) {
+            for (ExceptionInfo ei : exceptionInfoList) {
+                int codeOffset = ei.codeOffset;
+                targetMethod.recordExceptionHandler(codeOffset, -1, 0, ei.exceptionEdge.label().position(), -1, null);
+            }
+        }
+
+        Debug.metric("TargetMethods").increment();
+        Debug.metric("CodeBytesEmitted").add(targetMethod.targetCodeSize());
+        Debug.metric("SafepointsEmitted").add(targetMethod.safepoints.size());
+        Debug.metric("DataPatches").add(targetMethod.dataReferences.size());
+        Debug.metric("ExceptionHandlersEmitted").add(targetMethod.exceptionHandlers.size());
+
+        Debug.log("Finished target method %s, isStub %d", name, isStub);
+/*
+        if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
+            Util.printSection("Target Method", Util.SECTION_CHARACTER);
+            TTY.println("Name: " + name);
+            TTY.println("Frame size: " + targetMethod.frameSize());
+            TTY.println("Register size: " + asm.target.arch.registerReferenceMapBitCount);
+
+            if (GraalOptions.PrintCodeBytes) {
+                Util.printSection("Code", Util.SUB_SECTION_CHARACTER);
+                TTY.println("Code: %d bytes", targetMethod.targetCodeSize());
+                Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), GraalOptions.PrintAssemblyBytesPerLine);
+            }
+
+            Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER);
+            String disassembly = runtime.disassemble(targetMethod);
+            TTY.println(disassembly);
+            boolean noDis = disassembly == null || disassembly.length() == 0;
+
+            Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.Safepoint x : targetMethod.safepoints) {
+                TTY.println(x.toString());
+                if (noDis && x.debugInfo != null) {
+                    TTY.println(CiUtil.indent(x.debugInfo.toString(), "  "));
+                }
+            }
+
+            Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) {
+                TTY.println(x.toString());
+            }
+
+            Util.printSection("Marks", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.Mark x : targetMethod.marks) {
+                TTY.println(x.toString());
+            }
+
+            Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) {
+                TTY.println(x.toString());
+            }
+        }
+*/
+
+        return targetMethod;
+    }
+
+    public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) {
+        if (info != null) {
+            if (info.exceptionEdge != null) {
+                if (exceptionInfoList == null) {
+                    exceptionInfoList = new ArrayList<>(4);
+                }
+                exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge));
+            }
+        }
+    }
+
+    public void recordImplicitException(int pcOffset, LIRDebugInfo info) {
+        // record an implicit exception point
+        if (info != null) {
+            assert lastSafepointPos < pcOffset : lastSafepointPos + "<" + pcOffset;
+            lastSafepointPos = pcOffset;
+            targetMethod.recordSafepoint(pcOffset, info.debugInfo());
+            assert info.exceptionEdge == null;
+        }
+    }
+
+    public void recordDirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
+        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        assert lastSafepointPos < posAfter;
+        lastSafepointPos = posAfter;
+        targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, true);
+    }
+
+    public void recordIndirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
+        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        assert lastSafepointPos < posAfter;
+        lastSafepointPos = posAfter;
+        targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false);
+    }
+
+    public void recordSafepoint(int pos, LIRDebugInfo info) {
+        // safepoints always need debug info
+        CiDebugInfo debugInfo = info.debugInfo();
+        assert lastSafepointPos < pos;
+        lastSafepointPos = pos;
+        targetMethod.recordSafepoint(pos, debugInfo);
+    }
+
+    public CiAddress recordDataReferenceInCode(CiConstant data, int alignment) {
+        assert data != null;
+        int pos = asm.codeBuffer.position();
+        Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
+        targetMethod.recordDataReference(pos, data, alignment);
+        return CiAddress.Placeholder;
+    }
+
+    public int lastSafepointPos() {
+        return lastSafepointPos;
+    }
+
+
+    /**
+     * Returns the integer value of any constants that can be represented by a 32-bit integer value,
+     * including long constants that fit into the 32-bit range.
+     */
+    public int asIntConst(CiValue value) {
+        assert (value.kind.stackKind() == CiKind.Int || value.kind == CiKind.Jsr || value.kind == CiKind.Long) && isConstant(value);
+        long c = ((CiConstant) value).asLong();
+        if (!(NumUtil.isInt(c))) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return (int) c;
+    }
+
+    /**
+     * Returns the address of a float constant that is embedded as a data references into the code.
+     */
+    public CiAddress asFloatConstRef(CiValue value) {
+        return asFloatConstRef(value, 4);
+    }
+
+    public CiAddress asFloatConstRef(CiValue value, int alignment) {
+        assert value.kind == CiKind.Float && isConstant(value);
+        return recordDataReferenceInCode((CiConstant) value, alignment);
+    }
+
+    /**
+     * Returns the address of a double constant that is embedded as a data references into the code.
+     */
+    public CiAddress asDoubleConstRef(CiValue value) {
+        return asDoubleConstRef(value, 8);
+    }
+
+    public CiAddress asDoubleConstRef(CiValue value, int alignment) {
+        assert value.kind == CiKind.Double && isConstant(value);
+        return recordDataReferenceInCode((CiConstant) value, alignment);
+    }
+
+    /**
+     * Returns the address of a long constant that is embedded as a data references into the code.
+     */
+    public CiAddress asLongConstRef(CiValue value) {
+        assert value.kind == CiKind.Long && isConstant(value);
+        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;
+            return new CiAddress(slot.kind, frameMap.registerConfig.getFrameRegister().asValue(), frameMap.offsetForStackSlot(slot));
+        }
+        return (CiAddress) value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/Block.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,186 @@
+/*
+ * 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.lir.cfg;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public class Block {
+    protected int id;
+
+    protected BeginNode beginNode;
+    protected Node endNode;
+    protected Loop loop;
+    protected double probability;
+
+    protected List<Block> predecessors;
+    protected List<Block> successors;
+
+    protected Block dominator;
+    protected List<Block> dominated;
+    protected Block postdominator;
+
+    // Fields that still need to be worked on, try to remove them later.
+    public List<LIRInstruction> lir;
+    public boolean align;
+    public int linearScanNumber;
+
+    public Block() {
+        id = ControlFlowGraph.BLOCK_ID_INITIAL;
+    }
+
+    public int getId() {
+        assert id >= 0;
+        return id;
+    }
+
+    public BeginNode getBeginNode() {
+        return beginNode;
+    }
+
+    public Node getEndNode() {
+        return endNode;
+    }
+
+    public Loop getLoop() {
+        return loop;
+    }
+
+    public int getLoopDepth() {
+        return loop == null ? 0 : loop.depth;
+    }
+
+    public boolean isLoopHeader() {
+        return getBeginNode() instanceof LoopBeginNode;
+    }
+
+    public boolean isLoopEnd() {
+        return getEndNode() instanceof LoopEndNode;
+    }
+
+    public boolean isExceptionEntry() {
+        return getBeginNode().next() instanceof ExceptionObjectNode;
+    }
+
+    public List<Block> getPredecessors() {
+        return predecessors;
+    }
+
+    public List<Block> getSuccessors() {
+        return successors;
+    }
+
+    public Block getDominator() {
+        return dominator;
+    }
+
+    public List<Block> getDominated() {
+        if (dominated == null) {
+            return Collections.emptyList();
+        }
+        return dominated;
+    }
+
+    public Block getPostdominator() {
+        return postdominator;
+    }
+
+    private class NodeIterator implements Iterator<Node> {
+        private Node cur;
+
+        public NodeIterator() {
+            cur = getBeginNode();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return cur != null;
+        }
+
+        @Override
+        public Node next() {
+            Node result = cur;
+            if (cur == getEndNode()) {
+                cur = null;
+            } else {
+                cur = ((FixedWithNextNode) cur).next();
+            }
+            assert !(cur instanceof BeginNode);
+            return result;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public Iterable<Node> getNodes() {
+        return new Iterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new NodeIterator();
+            }
+        };
+    }
+
+    public int getFirstLirInstructionId() {
+        int result = lir.get(0).id();
+        assert result >= 0;
+        return result;
+    }
+
+    public int getLastLirInstructionId() {
+        int result = lir.get(lir.size() - 1).id();
+        assert result >= 0;
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "B" + id;
+    }
+
+
+// to be inlined later on
+    public int numberOfPreds() {
+        return getPredecessors().size();
+    }
+
+    public int numberOfSux() {
+        return getSuccessors().size();
+    }
+
+    public Block predAt(int i) {
+        return getPredecessors().get(i);
+    }
+
+    public Block suxAt(int i) {
+        return getSuccessors().get(i);
+    }
+// end to be inlined later on
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/BlockMap.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * 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.lir.cfg;
+
+public class BlockMap<T> {
+    private final T[] data;
+
+    @SuppressWarnings("unchecked")
+    public BlockMap(ControlFlowGraph cfg) {
+        data = (T[]) new Object[cfg.getBlocks().length];
+    }
+
+    public T get(Block block) {
+        return data[block.getId()];
+    }
+
+    public void put(Block block, T value) {
+        data[block.getId()] = value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/CFGVerifier.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,80 @@
+/*
+ * 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.lir.cfg;
+
+public class CFGVerifier {
+    public static boolean verify(ControlFlowGraph cfg) {
+        for (Block block : cfg.getBlocks()) {
+            assert cfg.getBlocks()[block.getId()] == block;
+
+            for (Block pred : block.getPredecessors()) {
+                assert pred.getSuccessors().contains(block);
+                assert pred.getId() < block.getId() || pred.isLoopEnd();
+            }
+
+            for (Block sux : block.getSuccessors()) {
+                assert sux.getPredecessors().contains(block);
+                assert sux.getId() > block.getId() || sux.isLoopHeader();
+            }
+
+            if (block.getDominator() != null) {
+                assert block.getDominator().getId() < block.getId();
+                assert block.getDominator().getDominated().contains(block);
+            }
+            for (Block dominated : block.getDominated()) {
+                assert dominated.getId() > block.getId();
+                assert dominated.getDominator() == block;
+            }
+
+            assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().header == block;
+        }
+
+        if (cfg.getLoops() != null) {
+            for (Loop loop : cfg.getLoops()) {
+                assert loop.header.isLoopHeader();
+
+                for (Block block : loop.blocks) {
+                    assert block.getId() >= loop.header.getId();
+
+                    Loop blockLoop = block.getLoop();
+                    while (blockLoop != loop) {
+                        blockLoop = blockLoop.parent;
+                        assert blockLoop != null;
+                    }
+                }
+
+                for (Block block : loop.exits) {
+                    assert block.getId() >= loop.header.getId();
+
+                    Loop blockLoop = block.getLoop();
+                    while (blockLoop != null) {
+                        blockLoop = blockLoop.parent;
+                        assert blockLoop != loop;
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/ControlFlowGraph.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,307 @@
+/*
+ * 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.lir.cfg;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public class ControlFlowGraph {
+
+    public final StructuredGraph graph;
+
+    private final NodeMap<Block> nodeToBlock;
+    private Block[] reversePostOrder;
+    private Loop[] loops;
+
+    public static ControlFlowGraph compute(StructuredGraph graph, boolean connectBlocks, boolean computeLoops, boolean computeDominators, boolean computePostdominators) {
+        ControlFlowGraph cfg = new ControlFlowGraph(graph);
+        cfg.identifyBlocks();
+        if (connectBlocks || computeLoops || computeDominators || computePostdominators) {
+            cfg.connectBlocks();
+        }
+        if (computeLoops) {
+            cfg.computeLoopInformation();
+        }
+        if (computeDominators) {
+            cfg.computeDominators();
+        }
+        if (computePostdominators) {
+            cfg.computePostdominators();
+        }
+        assert CFGVerifier.verify(cfg);
+        return cfg;
+    }
+
+    protected ControlFlowGraph(StructuredGraph graph) {
+        this.graph = graph;
+        this.nodeToBlock = graph.createNodeMap();
+    }
+
+    public Block[] getBlocks() {
+        return reversePostOrder;
+    }
+
+    public Block getStartBlock() {
+        return reversePostOrder[0];
+    }
+
+    public NodeMap<Block> getNodeToBlock() {
+        return nodeToBlock;
+    }
+
+    public Block blockFor(Node node) {
+        return nodeToBlock.get(node);
+    }
+
+    public Loop[] getLoops() {
+        return loops;
+    }
+
+    protected static final int BLOCK_ID_INITIAL = -1;
+    protected static final int BLOCK_ID_VISITED = -2;
+
+    private void identifyBlocks() {
+        // Find all block headers
+        int numBlocks = 0;
+        for (Node node : graph.getNodes()) {
+            if (node instanceof BeginNode) {
+                Block block = new Block();
+                numBlocks++;
+
+                block.beginNode = (BeginNode) node;
+                Node cur = node;
+                do {
+                    assert !cur.isDeleted();
+                    block.endNode = cur;
+
+                    assert nodeToBlock.get(cur) == null;
+                    nodeToBlock.set(cur, block);
+                    if (cur instanceof MergeNode) {
+                        for (PhiNode phi : ((MergeNode) cur).phis()) {
+                            nodeToBlock.set(phi, block);
+                        }
+                    }
+
+                    if (cur instanceof FixedNode) {
+                        double probability = ((FixedNode) cur).probability();
+                        if (probability > block.probability) {
+                            block.probability = probability;
+                        }
+                    }
+
+                    Node next = null;
+                    for (Node sux : cur.successors()) {
+                        if (sux != null && !(sux instanceof BeginNode)) {
+                            assert next == null;
+                            next = sux;
+                        }
+                    }
+                    cur = next;
+                } while (cur != null);
+            }
+        }
+
+        // Compute reverse postorder.
+        reversePostOrder = new Block[numBlocks];
+        int reversePostOrderId = numBlocks - 1;
+
+        ArrayList<Block> stack = new ArrayList<>();
+        stack.add(blockFor(graph.start()));
+
+        do {
+            Block block = stack.get(stack.size() - 1);
+            if (block.id == BLOCK_ID_INITIAL) {
+                // First time we see this block: push all successors.
+                for (Node suxNode : block.getEndNode().cfgSuccessors()) {
+                    Block suxBlock = blockFor(suxNode);
+                    assert suxBlock.id != BLOCK_ID_VISITED;
+                    if (suxBlock.id == BLOCK_ID_INITIAL) {
+                        stack.add(suxBlock);
+                    }
+                }
+                block.id = BLOCK_ID_VISITED;
+            } else if (block.id == BLOCK_ID_VISITED) {
+                // Second time we see this block: All successors haved been processed, so insert block into reverse postorder list.
+                stack.remove(stack.size() - 1);
+                reversePostOrder[reversePostOrderId] = block;
+                block.id = reversePostOrderId;
+                reversePostOrderId--;
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } while (!stack.isEmpty());
+        assert reversePostOrderId == -1;
+    }
+
+    // Connect blocks (including loop backward edges).
+    private void connectBlocks() {
+        for (Block block : reversePostOrder) {
+            List<Block> predecessors = new ArrayList<>();
+            for (Node predNode : block.getBeginNode().cfgPredecessors()) {
+                predecessors.add(nodeToBlock.get(predNode));
+            }
+            if (block.getBeginNode() instanceof LoopBeginNode) {
+                predecessors.add(nodeToBlock.get(((LoopBeginNode) block.getBeginNode()).loopEnd()));
+            }
+            block.predecessors = predecessors;
+
+            List<Block> successors = new ArrayList<>();
+            for (Node suxNode : block.getEndNode().cfgSuccessors()) {
+                successors.add(nodeToBlock.get(suxNode));
+            }
+            if (block.getEndNode() instanceof LoopEndNode) {
+                successors.add(nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin()));
+            }
+            block.successors = successors;
+        }
+    }
+
+    private void computeLoopInformation() {
+        List<Loop> loopsList = new ArrayList<>();
+        for (Block block : reversePostOrder) {
+            Node beginNode = block.getBeginNode();
+            if (beginNode instanceof LoopBeginNode) {
+                Loop loop = new Loop(block.getLoop(), loopsList.size(), block);
+                loopsList.add(loop);
+
+                LoopEndNode end = ((LoopBeginNode) beginNode).loopEnd();
+                Block endBlock = nodeToBlock.get(end);
+                computeLoopBlocks(endBlock, loop);
+            }
+        }
+        loops = loopsList.toArray(new Loop[loopsList.size()]);
+
+        for (Loop loop : loops) {
+            for (Block block : loop.blocks) {
+                for (Block sux : block.getSuccessors()) {
+                    if (sux.getLoopDepth() < loop.depth) {
+                        loop.exits.add(sux);
+                    }
+                }
+            }
+        }
+    }
+
+    private void computeLoopBlocks(Block block, Loop loop) {
+        if (block.getLoop() == loop) {
+            return;
+        }
+        assert block.loop == loop.parent;
+        block.loop = loop;
+
+        assert !loop.blocks.contains(block);
+        loop.blocks.add(block);
+
+        if (block != loop.header) {
+            for (Block pred : block.getPredecessors()) {
+                computeLoopBlocks(pred, loop);
+            }
+        }
+    }
+
+    private void computeDominators() {
+        assert reversePostOrder[0].getPredecessors().size() == 0 : "start block has no predecessor and therefore no dominator";
+        for (int i = 1; i < reversePostOrder.length; i++) {
+            Block block = reversePostOrder[i];
+            List<Block> predecessors = block.getPredecessors();
+            assert predecessors.size() > 0;
+
+            if (block.isLoopHeader()) {
+                // Loop headers have exactly one non-loop predecessor, and that is the dominator.
+                setDominator(block, predecessors.get(0));
+                continue;
+            }
+
+            Block dominator = predecessors.get(0);
+            for (int j = 1; j < predecessors.size(); j++) {
+                Block pred = predecessors.get(j);
+                dominator = commonDominator(dominator, pred);
+            }
+            setDominator(block, dominator);
+        }
+    }
+
+    private static void setDominator(Block block, Block dominator) {
+        block.dominator = dominator;
+        if (dominator.dominated == null) {
+            dominator.dominated = new ArrayList<>();
+        }
+        dominator.dominated.add(block);
+    }
+
+    public static Block commonDominator(Block a, Block b) {
+        Block iterA = a;
+        Block iterB = b;
+        while (iterA != iterB) {
+            if (iterA.getId() > iterB.getId()) {
+                iterA = iterA.getDominator();
+            } else {
+                assert iterB.getId() > iterA.getId();
+                iterB = iterB.getDominator();
+            }
+        }
+        return iterA;
+    }
+
+    private void computePostdominators() {
+        for (Block block : reversePostOrder) {
+            if (block.isLoopEnd()) {
+                // We do not want the loop header registered as the postdominator of the loop end.
+                continue;
+            }
+            Block postdominator = null;
+            for (Block sux : block.getSuccessors()) {
+                if (sux.isExceptionEntry()) {
+                    // We ignore exception handlers.
+                } else if (postdominator == null) {
+                    postdominator = sux;
+                } else {
+                    postdominator = commonPostdominator(postdominator, sux);
+                }
+            }
+            block.postdominator = postdominator;
+        }
+    }
+
+    private static Block commonPostdominator(Block a, Block b) {
+        Block iterA = a;
+        Block iterB = b;
+        while (iterA != iterB) {
+            if (iterA.getId() < iterB.getId()) {
+                iterA = iterA.getPostdominator();
+                if (iterA == null) {
+                    return null;
+                }
+            } else {
+                assert iterB.getId() < iterA.getId();
+                iterB = iterB.getPostdominator();
+                if (iterB == null) {
+                    return null;
+                }
+            }
+        }
+        return iterA;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/Loop.java	Wed Feb 08 19:25:29 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * 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.lir.cfg;
+
+import java.util.*;
+
+public class Loop {
+    public final Loop parent;
+    public final List<Loop> children;
+
+    public final int depth;
+    public final int index;
+    public final Block header;
+    public final List<Block> blocks;
+    public final List<Block> exits;
+
+    protected Loop(Loop parent, int index, Block header) {
+        this.parent = parent;
+        if (parent != null) {
+            this.depth = parent.depth + 1;
+            parent.children.add(this);
+        } else {
+            this.depth = 1;
+        }
+        this.index = index;
+        this.header = header;
+        this.blocks = new ArrayList<>();
+        this.children = new ArrayList<>();
+        this.exits = new ArrayList<>();
+    }
+
+    @Override
+    public String toString() {
+        return "loop " + index + " depth " + depth + (parent != null ? " outer " + parent.index : "");
+    }
+}
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Wed Feb 08 19:25:29 2012 -0800
@@ -33,15 +33,15 @@
 import com.oracle.max.graal.alloc.util.*;
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.alloc.Interval.UsePosList;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.graph.Node.Verbosity;
 import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.max.graal.graph.NodeClass.Position;
 import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.calc.*;
 
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Wed Feb 08 19:25:29 2012 -0800
@@ -31,10 +31,10 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.lir.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Wed Feb 08 19:25:29 2012 -0800
@@ -27,13 +27,13 @@
 import java.util.Map.Entry;
 
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.graph.Node.Verbosity;
 import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.max.graal.graph.NodeClass.Position;
 import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/MathIntrinsicNode.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/MathIntrinsicNode.java	Wed Feb 08 19:25:29 2012 -0800
@@ -22,13 +22,13 @@
  */
 package com.oracle.max.graal.snippets.nodes;
 
-import static com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.*;
+import static com.oracle.max.graal.lir.amd64.AMD64Arithmetic.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.target.amd64.AMD64Arithmetic.Op2Reg;
 import com.oracle.max.graal.compiler.target.amd64.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.calc.*;
 import com.oracle.max.graal.nodes.spi.*;
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Wed Feb 08 19:25:29 2012 -0800
@@ -28,10 +28,10 @@
 
 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.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
 
 public class AMD64MathIntrinsicOp extends AMD64LIRInstruction {
     public enum Opcode  {
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphScheduleTest.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphScheduleTest.java	Wed Feb 08 19:25:29 2012 -0800
@@ -26,9 +26,9 @@
 
 import org.junit.*;
 
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 
 public class GraphScheduleTest extends GraphTest {
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java	Wed Feb 08 18:19:09 2012 -0800
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java	Wed Feb 08 19:25:29 2012 -0800
@@ -24,9 +24,9 @@
 
 import org.junit.*;
 
-import com.oracle.max.graal.compiler.cfg.*;
 import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 
 public class NestedLoopTest extends GraphTest {
--- a/mx/projects	Wed Feb 08 18:19:09 2012 -0800
+++ b/mx/projects	Wed Feb 08 19:25:29 2012 -0800
@@ -60,6 +60,24 @@
 project@com.oracle.max.graal.debug@sourceDirs=src
 project@com.oracle.max.graal.debug@checkstyle=com.oracle.max.graal.graph
 
+# graal.lir
+project@com.oracle.max.graal.lir@subDir=graal
+project@com.oracle.max.graal.lir@sourceDirs=src
+project@com.oracle.max.graal.lir@dependencies=com.oracle.max.asm,com.oracle.max.graal.nodes
+project@com.oracle.max.graal.lir@checkstyle=com.oracle.max.graal.graph
+
+# graal.lir.amd64
+project@com.oracle.max.graal.lir.amd64@subDir=graal
+project@com.oracle.max.graal.lir.amd64@sourceDirs=src
+project@com.oracle.max.graal.lir.amd64@dependencies=com.oracle.max.graal.lir
+project@com.oracle.max.graal.lir.amd64@checkstyle=com.oracle.max.graal.graph
+
+# graal.alloc
+project@com.oracle.max.graal.alloc@subDir=graal
+project@com.oracle.max.graal.alloc@sourceDirs=src
+project@com.oracle.max.graal.alloc@dependencies=com.oracle.max.graal.lir
+project@com.oracle.max.graal.alloc@checkstyle=com.oracle.max.graal.graph
+
 # graal.snippets
 project@com.oracle.max.graal.snippets@subDir=graal
 project@com.oracle.max.graal.snippets@sourceDirs=src,test
@@ -75,7 +93,7 @@
 # graal.compiler
 project@com.oracle.max.graal.compiler@subDir=graal
 project@com.oracle.max.graal.compiler@sourceDirs=src
-project@com.oracle.max.graal.compiler@dependencies=com.oracle.max.asm,com.oracle.max.graal.nodes
+project@com.oracle.max.graal.compiler@dependencies=com.oracle.max.graal.lir.amd64,com.oracle.max.graal.alloc
 project@com.oracle.max.graal.compiler@checkstyle=com.oracle.max.graal.graph
 
 # graal.java