changeset 6496:16d1411409b4

moved AMD64 specific code into com.oracle.graal.compiler.amd64
author Doug Simon <doug.simon@oracle.com>
date Wed, 03 Oct 2012 16:49:51 +0200
parents 75f130f2b30f
children 64b7dd2075c0
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitScanOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64BitScanOp.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64ByteSwapOp.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java mx/projects src/share/vm/runtime/arguments.cpp
diffstat 18 files changed, 988 insertions(+), 938 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Oct 03 16:49:51 2012 +0200
@@ -0,0 +1,76 @@
+/*
+ * 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.graal.compiler.target.amd64;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.amd64.*;
+
+public class AMD64DeoptimizationStub extends AMD64Code {
+    public final Label label = new Label();
+    public final LIRFrameState info;
+    public final DeoptimizationAction action;
+    public final DeoptimizationReason reason;
+    public final Object deoptInfo;
+
+    public AMD64DeoptimizationStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info, Object deoptInfo) {
+        this.action = action;
+        this.reason = reason;
+        this.info = info;
+        this.deoptInfo = deoptInfo;
+    }
+
+    private static ArrayList<Object> keepAlive = new ArrayList<>();
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // TODO (cwimmer): we want to get rid of a generally reserved scratch register.
+        Register scratch = tasm.frameMap.registerConfig.getScratchRegister();
+
+        masm.bind(label);
+        if (GraalOptions.CreateDeoptInfo && deoptInfo != null) {
+            masm.nop();
+            keepAlive.add(deoptInfo.toString());
+            AMD64Move.move(tasm, masm, scratch.asValue(), Constant.forObject(deoptInfo));
+            // TODO Make this an explicit calling convention instead of using a scratch register
+            AMD64Call.directCall(tasm, masm, RuntimeCall.SetDeoptInfo, info);
+        }
+
+        masm.movl(scratch, tasm.runtime.encodeDeoptActionAndReason(action, reason));
+        // TODO Make this an explicit calling convention instead of using a scratch register
+        AMD64Call.directCall(tasm, masm, RuntimeCall.Deoptimize, info);
+        AMD64Call.shouldNotReachHere(tasm, masm);
+    }
+
+    @Override
+    public String description() {
+        return "deopt stub[reason=" + reason + ", action=" + action + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Oct 03 16:49:51 2012 +0200
@@ -0,0 +1,688 @@
+/*
+ * 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.graal.compiler.target.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*;
+import static com.oracle.graal.lir.amd64.AMD64Compare.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.compiler.util.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.JumpOp;
+import com.oracle.graal.lir.StandardOp.LabelOp;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivOp;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Reg;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Stack;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op2Stack;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.ShiftOp;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp;
+import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.SequentialSwitchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.SwitchRangesOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode;
+import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
+import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
+import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
+import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
+import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
+import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
+import com.oracle.graal.lir.amd64.AMD64Move.NullCheckOp;
+import com.oracle.graal.lir.amd64.AMD64Move.SpillMoveOp;
+import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.amd64.*;
+import com.oracle.max.asm.amd64.AMD64Assembler.ConditionFlag;
+
+/**
+ * This class implements the AMD64 specific portion of the LIR generator.
+ */
+public abstract class AMD64LIRGenerator extends LIRGenerator {
+
+    private static final RegisterValue RAX_I = AMD64.rax.asValue(Kind.Int);
+    private static final RegisterValue RAX_L = AMD64.rax.asValue(Kind.Long);
+    private static final RegisterValue RDX_I = AMD64.rdx.asValue(Kind.Int);
+    private static final RegisterValue RDX_L = AMD64.rdx.asValue(Kind.Long);
+    private static final RegisterValue RCX_I = AMD64.rcx.asValue(Kind.Int);
+
+    public static class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
+        @Override
+        public LIRInstruction createMove(Value result, Value input) {
+            return new SpillMoveOp(result, input);
+        }
+
+        @Override
+        public LIRInstruction createExchange(Value input1, Value input2) {
+            // TODO (cwimmer) implement XCHG operation for LIR
+            return null;
+        }
+    }
+
+    public AMD64LIRGenerator(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) {
+        super(graph, runtime, target, frameMap, method, lir);
+        lir.spillMoveFactory = new AMD64SpillMoveFactory();
+    }
+
+    @Override
+    protected void emitNode(ValueNode node) {
+        if (node instanceof LIRGenLowerable) {
+            ((LIRGenLowerable) node).generate(this);
+        } else {
+            super.emitNode(node);
+        }
+    }
+
+    @Override
+    public boolean canStoreConstant(Constant c) {
+        // there is no immediate move of 64-bit constants on Intel
+        switch (c.getKind()) {
+            case Long:   return Util.isInt(c.asLong());
+            case Double: return false;
+            case Object: return c.isNull();
+            default:     return true;
+        }
+    }
+
+    @Override
+    public boolean canInlineConstant(Constant c) {
+        switch (c.getKind()) {
+            case Long:   return NumUtil.isInt(c.asLong());
+            case Object: return c.isNull();
+            default:     return true;
+        }
+    }
+
+    @Override
+    public Address makeAddress(LocationNode location, ValueNode object) {
+        Value base = operand(object);
+        Value index = Value.IllegalValue;
+        int scale = 1;
+        int displacement = location.displacement();
+
+        if (isConstant(base)) {
+            if (asConstant(base).isNull()) {
+                base = Value.IllegalValue;
+            } else if (asConstant(base).getKind() != Kind.Object) {
+                long newDisplacement = displacement + asConstant(base).asLong();
+                if (NumUtil.isInt(newDisplacement)) {
+                    displacement = (int) newDisplacement;
+                    base = Value.IllegalValue;
+                }
+            }
+        }
+
+        if (location instanceof IndexedLocationNode) {
+            IndexedLocationNode indexedLoc = (IndexedLocationNode) location;
+
+            index = operand(indexedLoc.index());
+            if (indexedLoc.indexScalingEnabled()) {
+                scale = target().sizeInBytes(location.getValueKind());
+            }
+            if (isConstant(index)) {
+                long newDisplacement = displacement + asConstant(index).asLong() * scale;
+                // only use the constant index if the resulting displacement fits into a 32 bit offset
+                if (NumUtil.isInt(newDisplacement)) {
+                    displacement = (int) newDisplacement;
+                    index = Value.IllegalValue;
+                } else {
+                    // create a temporary variable for the index, the pointer load cannot handle a constant index
+                    Value newIndex = newVariable(Kind.Long);
+                    emitMove(index, newIndex);
+                    index = newIndex;
+                }
+            }
+        }
+
+        return new Address(location.getValueKind(), base, index, Address.Scale.fromInt(scale), displacement);
+    }
+
+    @Override
+    public Variable emitMove(Value input) {
+        Variable result = newVariable(input.getKind());
+        emitMove(input, result);
+        return result;
+    }
+
+    @Override
+    public void emitMove(Value src, Value dst) {
+        if (isRegister(src) || isStackSlot(dst)) {
+            append(new MoveFromRegOp(dst, src));
+        } else {
+            append(new MoveToRegOp(dst, src));
+        }
+    }
+
+    @Override
+    public Variable emitLoad(Value loadAddress, boolean canTrap) {
+        Variable result = newVariable(loadAddress.getKind());
+        append(new LoadOp(result, loadAddress, canTrap ? state() : null));
+        return result;
+    }
+
+    @Override
+    public void emitStore(Value storeAddress, Value inputVal, boolean canTrap) {
+        Value input = loadForStore(inputVal, storeAddress.getKind());
+        append(new StoreOp(storeAddress, input, canTrap ? state() : null));
+    }
+
+    @Override
+    public Variable emitLea(Value address) {
+        Variable result = newVariable(target().wordKind);
+        append(new LeaOp(result, address));
+        return result;
+    }
+
+    @Override
+    public void emitLabel(Label label, boolean align) {
+        append(new LabelOp(label, align));
+    }
+
+    @Override
+    public void emitJump(LabelRef label, LIRFrameState info) {
+        append(new JumpOp(label, info));
+    }
+
+    @Override
+    public void emitBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) {
+        boolean mirrored = emitCompare(left, right);
+        Condition finalCondition = mirrored ? cond.mirror() : cond;
+        switch (left.getKind().stackKind()) {
+            case Int:
+            case Long:
+            case Object: append(new BranchOp(finalCondition, label, info)); break;
+            case Float:
+            case Double: append(new FloatBranchOp(finalCondition, unorderedIsTrue, label, info)); break;
+            default: throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        }
+    }
+
+    @Override
+    public Variable emitCMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        boolean mirrored = emitCompare(left, right);
+        Condition finalCondition = mirrored ? cond.mirror() : cond;
+
+        Variable result = newVariable(trueValue.getKind());
+        switch (left.getKind().stackKind()) {
+            case Int:
+            case Long:
+            case Object: append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); break;
+            case Float:
+            case Double: append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); break;
+
+        }
+        return result;
+    }
+
+    /**
+     * This method emits the compare instruction, and may reorder the operands. It returns true if it did so.
+     *
+     * @param a the left operand of the comparison
+     * @param b the right operand of the comparison
+     * @return true if the left and right operands were switched, false otherwise
+     */
+    private boolean emitCompare(Value a, Value b) {
+        Variable left;
+        Value right;
+        boolean mirrored;
+        if (LIRValueUtil.isVariable(b)) {
+            left = load(b);
+            right = loadNonConst(a);
+            mirrored = true;
+        } else {
+            left = load(a);
+            right = loadNonConst(b);
+            mirrored = false;
+        }
+        switch (left.getKind().stackKind()) {
+            case Jsr:
+            case Int: append(new CompareOp(ICMP, left, right)); break;
+            case Long: append(new CompareOp(LCMP, left, right)); break;
+            case Object: append(new CompareOp(ACMP, left, right)); break;
+            case Float: append(new CompareOp(FCMP, left, right)); break;
+            case Double: append(new CompareOp(DCMP, left, right)); break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        return mirrored;
+    }
+
+    @Override
+    public Variable emitNegate(Value input) {
+        Variable result = newVariable(input.getKind());
+        switch (input.getKind()) {
+            case Int:    append(new Op1Stack(INEG, result, input)); break;
+            case Long:   append(new Op1Stack(LNEG, result, input)); break;
+            case Float:  append(new Op2Reg(FXOR, result, input, Constant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
+            case Double: append(new Op2Reg(DXOR, result, input, Constant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitAdd(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch(a.getKind()) {
+            case Int:    append(new Op2Stack(IADD, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LADD, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FADD, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DADD, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitSub(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch(a.getKind()) {
+            case Int:    append(new Op2Stack(ISUB, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LSUB, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FSUB, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DSUB, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitMul(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch(a.getKind()) {
+            case Int:    append(new Op2Reg(IMUL, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Reg(LMUL, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FMUL, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DMUL, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitDiv(Value a, Value b) {
+        switch(a.getKind()) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IDIV, RAX_I, RAX_I, load(b), state()));
+                return emitMove(RAX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LDIV, RAX_L, RAX_L, load(b), state()));
+                return emitMove(RAX_L);
+            case Float: {
+                Variable result = newVariable(a.getKind());
+                append(new Op2Stack(FDIV, result, a, loadNonConst(b)));
+                return result;
+            }
+            case Double: {
+                Variable result = newVariable(a.getKind());
+                append(new Op2Stack(DDIV, result, a, loadNonConst(b)));
+                return result;
+            }
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Value emitRem(Value a, Value b) {
+        switch(a.getKind()) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IREM, RDX_I, RAX_I, load(b), state()));
+                return emitMove(RDX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
+                return emitMove(RDX_L);
+            case Float:
+                return emitCall(RuntimeCall.ArithmeticFrem, false, a, b);
+            case Double:
+                return emitCall(RuntimeCall.ArithmeticDrem, false, a, b);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitUDiv(Value a, Value b) {
+        switch(a.getKind()) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IUDIV, RAX_I, RAX_I, load(b), state()));
+                return emitMove(RAX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LUDIV, RAX_L, RAX_L, load(b), state()));
+                return emitMove(RAX_L);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitURem(Value a, Value b) {
+        switch(a.getKind()) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IUREM, RDX_I, RAX_I, load(b), state()));
+                return emitMove(RDX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LUREM, RDX_L, RAX_L, load(b), state()));
+                return emitMove(RDX_L);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    @Override
+    public Variable emitAnd(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch(a.getKind()) {
+            case Int:    append(new Op2Stack(IAND, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LAND, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitOr(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch(a.getKind()) {
+            case Int:    append(new Op2Stack(IOR, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LOR, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitXor(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch(a.getKind()) {
+            case Int:    append(new Op2Stack(IXOR, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LXOR, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+
+    @Override
+    public Variable emitShl(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:    append(new ShiftOp(ISHL, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LSHL, result, a, loadShiftCount(b))); break;
+            default: GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitShr(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:    append(new ShiftOp(ISHR, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LSHR, result, a, loadShiftCount(b))); break;
+            default: GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitUShr(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:    append(new ShiftOp(IUSHR, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LUSHR, result, a, loadShiftCount(b))); break;
+            default: GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    private Value loadShiftCount(Value value) {
+        if (isConstant(value)) {
+            return value;
+        }
+        // Non-constant shift count must be in RCX
+        emitMove(value, RCX_I);
+        return RCX_I;
+    }
+
+
+    @Override
+    public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) {
+        Variable input = load(inputVal);
+        Variable result = newVariable(opcode.to);
+        switch (opcode) {
+            case I2L: append(new Op1Reg(I2L, result, input)); break;
+            case L2I: append(new Op1Stack(L2I, result, input)); break;
+            case I2B: append(new Op1Stack(I2B, result, input)); break;
+            case I2C: append(new Op1Stack(I2C, result, input)); break;
+            case I2S: append(new Op1Stack(I2S, result, input)); break;
+            case F2D: append(new Op1Reg(F2D, result, input)); break;
+            case D2F: append(new Op1Reg(D2F, result, input)); break;
+            case I2F: append(new Op1Reg(I2F, result, input)); break;
+            case I2D: append(new Op1Reg(I2D, result, input)); break;
+            case F2I: append(new Op1Reg(F2I, result, input)); break;
+            case D2I: append(new Op1Reg(D2I, result, input)); break;
+            case L2F: append(new Op1Reg(L2F, result, input)); break;
+            case L2D: append(new Op1Reg(L2D, result, input)); break;
+            case F2L: append(new Op1Reg(F2L, result, input)); break;
+            case D2L: append(new Op1Reg(D2L, result, input)); break;
+            case MOV_I2F: append(new Op1Reg(MOV_I2F, result, input)); break;
+            case MOV_L2D: append(new Op1Reg(MOV_L2D, result, input)); break;
+            case MOV_F2I: append(new Op1Reg(MOV_F2I, result, input)); break;
+            case MOV_D2L: append(new Op1Reg(MOV_D2L, result, input)); break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+
+    @Override
+    public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo) {
+        LIRFrameState info = state();
+        LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
+        append(new BranchOp(ConditionFlag.overflow, stubEntry, info));
+    }
+
+
+    @Override
+    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId) {
+        LIRFrameState info = state(leafGraphId);
+        LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
+        append(new JumpOp(stubEntry, info));
+    }
+
+    @Override
+    public void emitMembar(int barriers) {
+        int necessaryBarriers = target.arch.requiredBarriers(barriers);
+        if (target.isMP && necessaryBarriers != 0) {
+            append(new MembarOp(necessaryBarriers));
+        }
+    }
+
+    @Override
+    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        append(new DirectCallOp(callTarget.target(), result, parameters, temps, callState));
+    }
+
+    @Override
+    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        // The current register allocator cannot handle variables at call sites, need a fixed register.
+        Value targetAddress = AMD64.rax.asValue();
+        emitMove(operand(callTarget.computedAddress()), targetAddress);
+        append(new IndirectCallOp(callTarget.target(), result, parameters, temps, targetAddress, callState));
+    }
+
+    @Override
+    protected void emitCall(Object targetMethod, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info) {
+        if (isConstant(targetAddress)) {
+            append(new DirectCallOp(targetMethod, result, arguments, temps, info));
+        } else {
+            append(new IndirectCallOp(targetMethod, result, arguments, temps, targetAddress, info));
+        }
+    }
+
+    @Override
+    public void emitBitScanForward(Variable result, Value value) {
+        append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.BSF, result, value));
+    }
+
+    @Override
+    public void emitBitScanReverse(Variable result, Value value) {
+        if (value.getKind().isStackInt()) {
+            append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.IBSR, result, value));
+        } else {
+            append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.LBSR, result, value));
+        }
+    }
+
+    @Override
+    public void emitMathAbs(Variable result, Variable input) {
+        append(new Op2Reg(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL))));
+    }
+
+    @Override
+    public void emitMathSqrt(Variable result, Variable input) {
+        append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.SQRT, result, input));
+    }
+
+    @Override
+    public void emitMathLog(Variable result, Variable input, boolean base10) {
+        IntrinsicOpcode opcode = base10 ? AMD64MathIntrinsicOp.IntrinsicOpcode.LOG10 : AMD64MathIntrinsicOp.IntrinsicOpcode.LOG;
+        append(new AMD64MathIntrinsicOp(opcode, result, input));
+    }
+
+    @Override
+    public void emitMathCos(Variable result, Variable input) {
+        append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.COS, result, input));
+    }
+
+    @Override
+    public void emitMathSin(Variable result, Variable input) {
+        append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.SIN, result, input));
+    }
+
+    @Override
+    public void emitMathTan(Variable result, Variable input) {
+        append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.TAN, result, input));
+    }
+
+    @Override
+    public void emitByteSwap(Variable result, Value input) {
+        append(new AMD64ByteSwapOp(result, input));
+    }
+
+    @Override
+    protected void emitReturn(Value input) {
+        append(new ReturnOp(input));
+    }
+
+    @Override
+    protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
+        // Making a copy of the switch value is necessary because jump table destroys the input value
+        if (key.getKind() == Kind.Int) {
+            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.IllegalValue));
+        } else {
+            assert key.getKind() == Kind.Object;
+            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object)));
+        }
+    }
+
+    @Override
+    protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) {
+        append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key));
+    }
+
+    @Override
+    protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
+        // Making a copy of the switch value is necessary because jump table destroys the input value
+        Variable tmp = emitMove(key);
+        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
+    }
+
+    @Override
+    protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info, Object deoptInfo) {
+        assert info.topFrame.getBCI() >= 0 : "invalid bci for deopt framestate";
+        AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, reason, info, deoptInfo);
+        lir.stubs.add(stub);
+        return LabelRef.forLabel(stub.label);
+    }
+
+    @Override
+    protected void emitNullCheckGuard(ValueNode object, long leafGraphId) {
+        Variable value = load(operand(object));
+        LIRFrameState info = state(leafGraphId);
+        append(new NullCheckOp(value, info));
+    }
+
+    @Override
+    public void visitCompareAndSwap(CompareAndSwapNode node) {
+        Kind kind = node.newValue().kind();
+        assert kind == node.expected().kind();
+
+        Value expected = loadNonConst(operand(node.expected()));
+        Variable newValue = load(operand(node.newValue()));
+
+        Address address;
+        int displacement = node.displacement();
+        Value index = operand(node.offset());
+        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) {
+            displacement += (int) asConstant(index).asLong();
+            address = new Address(kind, load(operand(node.object())), displacement);
+        } else {
+            address = new Address(kind, load(operand(node.object())), load(index), Address.Scale.Times1, displacement);
+        }
+
+        RegisterValue rax = AMD64.rax.asValue(kind);
+        emitMove(expected, rax);
+        append(new CompareAndSwapOp(rax, address, rax, newValue));
+
+        Variable result = newVariable(node.kind());
+        append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE));
+        setResult(node, result);
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Oct 03 01:18:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Oct 03 16:49:51 2012 +0200
@@ -980,4 +980,15 @@
     public FrameMap frameMap() {
         return frameMap;
     }
+
+    public abstract void emitBitScanForward(Variable result, Value operand);
+    public abstract void emitBitScanReverse(Variable result, Value operand);
+
+    public abstract void emitMathAbs(Variable result, Variable input);
+    public abstract void emitMathSqrt(Variable result, Variable input);
+    public abstract void emitMathLog(Variable result, Variable input, boolean base10);
+    public abstract void emitMathCos(Variable result, Variable input);
+    public abstract void emitMathSin(Variable result, Variable input);
+    public abstract void emitMathTan(Variable result, Variable input);
+    public abstract void emitByteSwap(Variable result, Value operand);
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Oct 03 01:18:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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.graal.compiler.target.amd64;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.amd64.*;
-
-public class AMD64DeoptimizationStub extends AMD64Code {
-    public final Label label = new Label();
-    public final LIRFrameState info;
-    public final DeoptimizationAction action;
-    public final DeoptimizationReason reason;
-    public final Object deoptInfo;
-
-    public AMD64DeoptimizationStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info, Object deoptInfo) {
-        this.action = action;
-        this.reason = reason;
-        this.info = info;
-        this.deoptInfo = deoptInfo;
-    }
-
-    private static ArrayList<Object> keepAlive = new ArrayList<>();
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        // TODO (cwimmer): we want to get rid of a generally reserved scratch register.
-        Register scratch = tasm.frameMap.registerConfig.getScratchRegister();
-
-        masm.bind(label);
-        if (GraalOptions.CreateDeoptInfo && deoptInfo != null) {
-            masm.nop();
-            keepAlive.add(deoptInfo.toString());
-            AMD64Move.move(tasm, masm, scratch.asValue(), Constant.forObject(deoptInfo));
-            // TODO Make this an explicit calling convention instead of using a scratch register
-            AMD64Call.directCall(tasm, masm, RuntimeCall.SetDeoptInfo, info);
-        }
-
-        masm.movl(scratch, tasm.runtime.encodeDeoptActionAndReason(action, reason));
-        // TODO Make this an explicit calling convention instead of using a scratch register
-        AMD64Call.directCall(tasm, masm, RuntimeCall.Deoptimize, info);
-        AMD64Call.shouldNotReachHere(tasm, masm);
-    }
-
-    @Override
-    public String description() {
-        return "deopt stub[reason=" + reason + ", action=" + action + "]";
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Oct 03 01:18:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,636 +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.graal.compiler.target.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*;
-import static com.oracle.graal.lir.amd64.AMD64Compare.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.compiler.util.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.JumpOp;
-import com.oracle.graal.lir.StandardOp.LabelOp;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivOp;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Reg;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Stack;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op2Stack;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.ShiftOp;
-import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
-import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp;
-import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.SequentialSwitchOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.SwitchRangesOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
-import com.oracle.graal.lir.amd64.AMD64Move.NullCheckOp;
-import com.oracle.graal.lir.amd64.AMD64Move.SpillMoveOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.amd64.*;
-import com.oracle.max.asm.amd64.AMD64Assembler.*;
-
-/**
- * This class implements the X86-specific portion of the LIR generator.
- */
-public abstract class AMD64LIRGenerator extends LIRGenerator {
-
-    private static final RegisterValue RAX_I = AMD64.rax.asValue(Kind.Int);
-    private static final RegisterValue RAX_L = AMD64.rax.asValue(Kind.Long);
-    private static final RegisterValue RDX_I = AMD64.rdx.asValue(Kind.Int);
-    private static final RegisterValue RDX_L = AMD64.rdx.asValue(Kind.Long);
-    private static final RegisterValue RCX_I = AMD64.rcx.asValue(Kind.Int);
-
-    public static class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
-        @Override
-        public LIRInstruction createMove(Value result, Value input) {
-            return new SpillMoveOp(result, input);
-        }
-
-        @Override
-        public LIRInstruction createExchange(Value input1, Value input2) {
-            // TODO (cwimmer) implement XCHG operation for LIR
-            return null;
-        }
-    }
-
-    public AMD64LIRGenerator(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) {
-        super(graph, runtime, target, frameMap, method, lir);
-        lir.spillMoveFactory = new AMD64SpillMoveFactory();
-    }
-
-    @Override
-    protected void emitNode(ValueNode node) {
-        if (node instanceof LIRGenLowerable) {
-            ((LIRGenLowerable) node).generate(this);
-        } else {
-            super.emitNode(node);
-        }
-    }
-
-    @Override
-    public boolean canStoreConstant(Constant c) {
-        // there is no immediate move of 64-bit constants on Intel
-        switch (c.getKind()) {
-            case Long:   return Util.isInt(c.asLong());
-            case Double: return false;
-            case Object: return c.isNull();
-            default:     return true;
-        }
-    }
-
-    @Override
-    public boolean canInlineConstant(Constant c) {
-        switch (c.getKind()) {
-            case Long:   return NumUtil.isInt(c.asLong());
-            case Object: return c.isNull();
-            default:     return true;
-        }
-    }
-
-    @Override
-    public Address makeAddress(LocationNode location, ValueNode object) {
-        Value base = operand(object);
-        Value index = Value.IllegalValue;
-        int scale = 1;
-        int displacement = location.displacement();
-
-        if (isConstant(base)) {
-            if (asConstant(base).isNull()) {
-                base = Value.IllegalValue;
-            } else if (asConstant(base).getKind() != Kind.Object) {
-                long newDisplacement = displacement + asConstant(base).asLong();
-                if (NumUtil.isInt(newDisplacement)) {
-                    displacement = (int) newDisplacement;
-                    base = Value.IllegalValue;
-                }
-            }
-        }
-
-        if (location instanceof IndexedLocationNode) {
-            IndexedLocationNode indexedLoc = (IndexedLocationNode) location;
-
-            index = operand(indexedLoc.index());
-            if (indexedLoc.indexScalingEnabled()) {
-                scale = target().sizeInBytes(location.getValueKind());
-            }
-            if (isConstant(index)) {
-                long newDisplacement = displacement + asConstant(index).asLong() * scale;
-                // only use the constant index if the resulting displacement fits into a 32 bit offset
-                if (NumUtil.isInt(newDisplacement)) {
-                    displacement = (int) newDisplacement;
-                    index = Value.IllegalValue;
-                } else {
-                    // create a temporary variable for the index, the pointer load cannot handle a constant index
-                    Value newIndex = newVariable(Kind.Long);
-                    emitMove(index, newIndex);
-                    index = newIndex;
-                }
-            }
-        }
-
-        return new Address(location.getValueKind(), base, index, Address.Scale.fromInt(scale), displacement);
-    }
-
-    @Override
-    public Variable emitMove(Value input) {
-        Variable result = newVariable(input.getKind());
-        emitMove(input, result);
-        return result;
-    }
-
-    @Override
-    public void emitMove(Value src, Value dst) {
-        if (isRegister(src) || isStackSlot(dst)) {
-            append(new MoveFromRegOp(dst, src));
-        } else {
-            append(new MoveToRegOp(dst, src));
-        }
-    }
-
-    @Override
-    public Variable emitLoad(Value loadAddress, boolean canTrap) {
-        Variable result = newVariable(loadAddress.getKind());
-        append(new LoadOp(result, loadAddress, canTrap ? state() : null));
-        return result;
-    }
-
-    @Override
-    public void emitStore(Value storeAddress, Value inputVal, boolean canTrap) {
-        Value input = loadForStore(inputVal, storeAddress.getKind());
-        append(new StoreOp(storeAddress, input, canTrap ? state() : null));
-    }
-
-    @Override
-    public Variable emitLea(Value address) {
-        Variable result = newVariable(target().wordKind);
-        append(new LeaOp(result, address));
-        return result;
-    }
-
-    @Override
-    public void emitLabel(Label label, boolean align) {
-        append(new LabelOp(label, align));
-    }
-
-    @Override
-    public void emitJump(LabelRef label, LIRFrameState info) {
-        append(new JumpOp(label, info));
-    }
-
-    @Override
-    public void emitBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) {
-        boolean mirrored = emitCompare(left, right);
-        Condition finalCondition = mirrored ? cond.mirror() : cond;
-        switch (left.getKind().stackKind()) {
-            case Int:
-            case Long:
-            case Object: append(new BranchOp(finalCondition, label, info)); break;
-            case Float:
-            case Double: append(new FloatBranchOp(finalCondition, unorderedIsTrue, label, info)); break;
-            default: throw GraalInternalError.shouldNotReachHere("" + left.getKind());
-        }
-    }
-
-    @Override
-    public Variable emitCMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        boolean mirrored = emitCompare(left, right);
-        Condition finalCondition = mirrored ? cond.mirror() : cond;
-
-        Variable result = newVariable(trueValue.getKind());
-        switch (left.getKind().stackKind()) {
-            case Int:
-            case Long:
-            case Object: append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); break;
-            case Float:
-            case Double: append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); break;
-
-        }
-        return result;
-    }
-
-    /**
-     * This method emits the compare instruction, and may reorder the operands. It returns true if it did so.
-     *
-     * @param a the left operand of the comparison
-     * @param b the right operand of the comparison
-     * @return true if the left and right operands were switched, false otherwise
-     */
-    private boolean emitCompare(Value a, Value b) {
-        Variable left;
-        Value right;
-        boolean mirrored;
-        if (LIRValueUtil.isVariable(b)) {
-            left = load(b);
-            right = loadNonConst(a);
-            mirrored = true;
-        } else {
-            left = load(a);
-            right = loadNonConst(b);
-            mirrored = false;
-        }
-        switch (left.getKind().stackKind()) {
-            case Jsr:
-            case Int: append(new CompareOp(ICMP, left, right)); break;
-            case Long: append(new CompareOp(LCMP, left, right)); break;
-            case Object: append(new CompareOp(ACMP, left, right)); break;
-            case Float: append(new CompareOp(FCMP, left, right)); break;
-            case Double: append(new CompareOp(DCMP, left, right)); break;
-            default: throw GraalInternalError.shouldNotReachHere();
-        }
-        return mirrored;
-    }
-
-    @Override
-    public Variable emitNegate(Value input) {
-        Variable result = newVariable(input.getKind());
-        switch (input.getKind()) {
-            case Int:    append(new Op1Stack(INEG, result, input)); break;
-            case Long:   append(new Op1Stack(LNEG, result, input)); break;
-            case Float:  append(new Op2Reg(FXOR, result, input, Constant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
-            case Double: append(new Op2Reg(DXOR, result, input, Constant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
-            default: throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitAdd(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch(a.getKind()) {
-            case Int:    append(new Op2Stack(IADD, result, a, loadNonConst(b))); break;
-            case Long:   append(new Op2Stack(LADD, result, a, loadNonConst(b))); break;
-            case Float:  append(new Op2Stack(FADD, result, a, loadNonConst(b))); break;
-            case Double: append(new Op2Stack(DADD, result, a, loadNonConst(b))); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitSub(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch(a.getKind()) {
-            case Int:    append(new Op2Stack(ISUB, result, a, loadNonConst(b))); break;
-            case Long:   append(new Op2Stack(LSUB, result, a, loadNonConst(b))); break;
-            case Float:  append(new Op2Stack(FSUB, result, a, loadNonConst(b))); break;
-            case Double: append(new Op2Stack(DSUB, result, a, loadNonConst(b))); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitMul(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch(a.getKind()) {
-            case Int:    append(new Op2Reg(IMUL, result, a, loadNonConst(b))); break;
-            case Long:   append(new Op2Reg(LMUL, result, a, loadNonConst(b))); break;
-            case Float:  append(new Op2Stack(FMUL, result, a, loadNonConst(b))); break;
-            case Double: append(new Op2Stack(DMUL, result, a, loadNonConst(b))); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitDiv(Value a, Value b) {
-        switch(a.getKind()) {
-            case Int:
-                emitMove(a, RAX_I);
-                append(new DivOp(IDIV, RAX_I, RAX_I, load(b), state()));
-                return emitMove(RAX_I);
-            case Long:
-                emitMove(a, RAX_L);
-                append(new DivOp(LDIV, RAX_L, RAX_L, load(b), state()));
-                return emitMove(RAX_L);
-            case Float: {
-                Variable result = newVariable(a.getKind());
-                append(new Op2Stack(FDIV, result, a, loadNonConst(b)));
-                return result;
-            }
-            case Double: {
-                Variable result = newVariable(a.getKind());
-                append(new Op2Stack(DDIV, result, a, loadNonConst(b)));
-                return result;
-            }
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Value emitRem(Value a, Value b) {
-        switch(a.getKind()) {
-            case Int:
-                emitMove(a, RAX_I);
-                append(new DivOp(IREM, RDX_I, RAX_I, load(b), state()));
-                return emitMove(RDX_I);
-            case Long:
-                emitMove(a, RAX_L);
-                append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
-                return emitMove(RDX_L);
-            case Float:
-                return emitCall(RuntimeCall.ArithmeticFrem, false, a, b);
-            case Double:
-                return emitCall(RuntimeCall.ArithmeticDrem, false, a, b);
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitUDiv(Value a, Value b) {
-        switch(a.getKind()) {
-            case Int:
-                emitMove(a, RAX_I);
-                append(new DivOp(IUDIV, RAX_I, RAX_I, load(b), state()));
-                return emitMove(RAX_I);
-            case Long:
-                emitMove(a, RAX_L);
-                append(new DivOp(LUDIV, RAX_L, RAX_L, load(b), state()));
-                return emitMove(RAX_L);
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public Variable emitURem(Value a, Value b) {
-        switch(a.getKind()) {
-            case Int:
-                emitMove(a, RAX_I);
-                append(new DivOp(IUREM, RDX_I, RAX_I, load(b), state()));
-                return emitMove(RDX_I);
-            case Long:
-                emitMove(a, RAX_L);
-                append(new DivOp(LUREM, RDX_L, RAX_L, load(b), state()));
-                return emitMove(RDX_L);
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-
-    @Override
-    public Variable emitAnd(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch(a.getKind()) {
-            case Int:    append(new Op2Stack(IAND, result, a, loadNonConst(b))); break;
-            case Long:   append(new Op2Stack(LAND, result, a, loadNonConst(b))); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitOr(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch(a.getKind()) {
-            case Int:    append(new Op2Stack(IOR, result, a, loadNonConst(b))); break;
-            case Long:   append(new Op2Stack(LOR, result, a, loadNonConst(b))); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitXor(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch(a.getKind()) {
-            case Int:    append(new Op2Stack(IXOR, result, a, loadNonConst(b))); break;
-            case Long:   append(new Op2Stack(LXOR, result, a, loadNonConst(b))); break;
-            default:     throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-
-    @Override
-    public Variable emitShl(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch (a.getKind()) {
-            case Int:    append(new ShiftOp(ISHL, result, a, loadShiftCount(b))); break;
-            case Long:   append(new ShiftOp(LSHL, result, a, loadShiftCount(b))); break;
-            default: GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitShr(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch (a.getKind()) {
-            case Int:    append(new ShiftOp(ISHR, result, a, loadShiftCount(b))); break;
-            case Long:   append(new ShiftOp(LSHR, result, a, loadShiftCount(b))); break;
-            default: GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    @Override
-    public Variable emitUShr(Value a, Value b) {
-        Variable result = newVariable(a.getKind());
-        switch (a.getKind()) {
-            case Int:    append(new ShiftOp(IUSHR, result, a, loadShiftCount(b))); break;
-            case Long:   append(new ShiftOp(LUSHR, result, a, loadShiftCount(b))); break;
-            default: GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    private Value loadShiftCount(Value value) {
-        if (isConstant(value)) {
-            return value;
-        }
-        // Non-constant shift count must be in RCX
-        emitMove(value, RCX_I);
-        return RCX_I;
-    }
-
-
-    @Override
-    public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) {
-        Variable input = load(inputVal);
-        Variable result = newVariable(opcode.to);
-        switch (opcode) {
-            case I2L: append(new Op1Reg(I2L, result, input)); break;
-            case L2I: append(new Op1Stack(L2I, result, input)); break;
-            case I2B: append(new Op1Stack(I2B, result, input)); break;
-            case I2C: append(new Op1Stack(I2C, result, input)); break;
-            case I2S: append(new Op1Stack(I2S, result, input)); break;
-            case F2D: append(new Op1Reg(F2D, result, input)); break;
-            case D2F: append(new Op1Reg(D2F, result, input)); break;
-            case I2F: append(new Op1Reg(I2F, result, input)); break;
-            case I2D: append(new Op1Reg(I2D, result, input)); break;
-            case F2I: append(new Op1Reg(F2I, result, input)); break;
-            case D2I: append(new Op1Reg(D2I, result, input)); break;
-            case L2F: append(new Op1Reg(L2F, result, input)); break;
-            case L2D: append(new Op1Reg(L2D, result, input)); break;
-            case F2L: append(new Op1Reg(F2L, result, input)); break;
-            case D2L: append(new Op1Reg(D2L, result, input)); break;
-            case MOV_I2F: append(new Op1Reg(MOV_I2F, result, input)); break;
-            case MOV_L2D: append(new Op1Reg(MOV_L2D, result, input)); break;
-            case MOV_F2I: append(new Op1Reg(MOV_F2I, result, input)); break;
-            case MOV_D2L: append(new Op1Reg(MOV_D2L, result, input)); break;
-            default: throw GraalInternalError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-
-    @Override
-    public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo) {
-        LIRFrameState info = state();
-        LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
-        append(new BranchOp(ConditionFlag.overflow, stubEntry, info));
-    }
-
-
-    @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId) {
-        LIRFrameState info = state(leafGraphId);
-        LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
-        append(new JumpOp(stubEntry, info));
-    }
-
-    @Override
-    public void emitMembar(int barriers) {
-        int necessaryBarriers = target.arch.requiredBarriers(barriers);
-        if (target.isMP && necessaryBarriers != 0) {
-            append(new MembarOp(necessaryBarriers));
-        }
-    }
-
-    @Override
-    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        append(new DirectCallOp(callTarget.target(), result, parameters, temps, callState));
-    }
-
-    @Override
-    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        // The current register allocator cannot handle variables at call sites, need a fixed register.
-        Value targetAddress = AMD64.rax.asValue();
-        emitMove(operand(callTarget.computedAddress()), targetAddress);
-        append(new IndirectCallOp(callTarget.target(), result, parameters, temps, targetAddress, callState));
-    }
-
-    @Override
-    protected void emitCall(Object targetMethod, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info) {
-        if (isConstant(targetAddress)) {
-            append(new DirectCallOp(targetMethod, result, arguments, temps, info));
-        } else {
-            append(new IndirectCallOp(targetMethod, result, arguments, temps, targetAddress, info));
-        }
-    }
-
-    @Override
-    protected void emitReturn(Value input) {
-        append(new ReturnOp(input));
-    }
-
-    @Override
-    protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
-        // Making a copy of the switch value is necessary because jump table destroys the input value
-        if (key.getKind() == Kind.Int) {
-            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.IllegalValue));
-        } else {
-            assert key.getKind() == Kind.Object;
-            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object)));
-        }
-    }
-
-    @Override
-    protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) {
-        append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key));
-    }
-
-    @Override
-    protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
-        // Making a copy of the switch value is necessary because jump table destroys the input value
-        Variable tmp = emitMove(key);
-        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
-    }
-
-    @Override
-    protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info, Object deoptInfo) {
-        assert info.topFrame.getBCI() >= 0 : "invalid bci for deopt framestate";
-        AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, reason, info, deoptInfo);
-        lir.stubs.add(stub);
-        return LabelRef.forLabel(stub.label);
-    }
-
-    @Override
-    protected void emitNullCheckGuard(ValueNode object, long leafGraphId) {
-        Variable value = load(operand(object));
-        LIRFrameState info = state(leafGraphId);
-        append(new NullCheckOp(value, info));
-    }
-
-    @Override
-    public void visitCompareAndSwap(CompareAndSwapNode node) {
-        Kind kind = node.newValue().kind();
-        assert kind == node.expected().kind();
-
-        Value expected = loadNonConst(operand(node.expected()));
-        Variable newValue = load(operand(node.newValue()));
-
-        Address address;
-        int displacement = node.displacement();
-        Value index = operand(node.offset());
-        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) {
-            displacement += (int) asConstant(index).asLong();
-            address = new Address(kind, load(operand(node.object())), displacement);
-        } else {
-            address = new Address(kind, load(operand(node.object())), load(index), Address.Scale.Times1, displacement);
-        }
-
-        RegisterValue rax = AMD64.rax.asValue(kind);
-        emitMove(expected, rax);
-        append(new CompareAndSwapOp(rax, address, rax, newValue));
-
-        Variable result = newVariable(node.kind());
-        append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE));
-        setResult(node, result);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitScanOp.java	Wed Oct 03 16:49:51 2012 +0200
@@ -0,0 +1,79 @@
+/*
+ * 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.graal.lir.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.amd64.*;
+
+
+public class AMD64BitScanOp extends AMD64LIRInstruction {
+    public enum IntrinsicOpcode  {
+        IBSR, LBSR,
+        BSF;
+    }
+
+    @Opcode private final IntrinsicOpcode opcode;
+    @Def protected Value result;
+    @Use({OperandFlag.REG, OperandFlag.ADDR}) protected Value input;
+
+    public AMD64BitScanOp(IntrinsicOpcode opcode, Value result, Value input) {
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        Register dst = ValueUtil.asIntReg(result);
+        if (ValueUtil.isAddress(input)) {
+            Address src = ValueUtil.asAddress(input);
+            switch(opcode) {
+                case BSF:
+                    masm.bsfq(dst, src);
+                    break;
+                case IBSR:
+                    masm.bsrl(dst, src);
+                    break;
+                case LBSR:
+                    masm.bsrq(dst, src);
+                    break;
+            }
+        } else {
+            Register src = ValueUtil.asRegister(input);
+            switch(opcode) {
+                case BSF:
+                    masm.bsfq(dst, src);
+                    break;
+                case IBSR:
+                    masm.bsrl(dst, src);
+                    break;
+                case LBSR:
+                    masm.bsrq(dst, src);
+                    break;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java	Wed Oct 03 16:49:51 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.graal.lir.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.amd64.*;
+
+@Opcode("BSWAP")
+public class AMD64ByteSwapOp extends AMD64LIRInstruction {
+    @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result;
+    @Use protected Value input;
+
+    public AMD64ByteSwapOp(Value result, Value input) {
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        AMD64Move.move(tasm, masm, result, input);
+        switch(input.getKind()) {
+            case Int:
+                masm.bswapl(ValueUtil.asIntReg(result));
+                break;
+            case Long:
+                masm.bswapq(ValueUtil.asLongReg(result));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Wed Oct 03 16:49:51 2012 +0200
@@ -0,0 +1,61 @@
+/*
+ * 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.graal.lir.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.amd64.*;
+
+public class AMD64MathIntrinsicOp extends AMD64LIRInstruction {
+    public enum IntrinsicOpcode  {
+        SQRT,
+        SIN, COS, TAN,
+        LOG, LOG10;
+    }
+
+    @Opcode private final IntrinsicOpcode opcode;
+    @Def protected Value result;
+    @Use protected Value input;
+
+    public AMD64MathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) {
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        switch (opcode) {
+            case SQRT:  masm.sqrtsd(asDoubleReg(result), asDoubleReg(input)); break;
+            case LOG:   masm.flog(asDoubleReg(result), asDoubleReg(input), false); break;
+            case LOG10: masm.flog(asDoubleReg(result), asDoubleReg(input), true); break;
+            case SIN:   masm.fsin(asDoubleReg(result), asDoubleReg(input)); break;
+            case COS:   masm.fcos(asDoubleReg(result), asDoubleReg(input)); break;
+            case TAN:   masm.ftan(asDoubleReg(result), asDoubleReg(input)); break;
+            default:    throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Wed Oct 03 01:18:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Wed Oct 03 16:49:51 2012 +0200
@@ -330,7 +330,7 @@
         Node curStampNode = null;
         for (Node node : snippetCopy.getNodes()) {
             if (node instanceof ValueNode && ((ValueNode) node).stamp() == StampFactory.forNodeIntrinsic()) {
-                assert curStampNode == null : "Currently limited to stamp node (but this can be converted to a List if necessary)";
+                assert curStampNode == null : "Currently limited to one stamp node (but this can be converted to a List if necessary)";
                 curStampNode = node;
             }
             if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java	Wed Oct 03 01:18:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java	Wed Oct 03 16:49:51 2012 +0200
@@ -30,8 +30,6 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.target.amd64.*;
-import com.oracle.graal.snippets.target.amd64.AMD64BitScanOp.IntrinsicOpcode;
 
 
 public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -61,7 +59,7 @@
     @Override
     public void generate(LIRGenerator gen) {
         Variable result = gen.newVariable(Kind.Int);
-        gen.append(new AMD64BitScanOp(IntrinsicOpcode.BSF, result, gen.operand(value)));
+        gen.emitBitScanForward(result, gen.operand(value));
         gen.setResult(this, result);
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java	Wed Oct 03 01:18:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java	Wed Oct 03 16:49:51 2012 +0200
@@ -25,14 +25,11 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.target.amd64.*;
-import com.oracle.graal.snippets.target.amd64.AMD64BitScanOp.IntrinsicOpcode;
 
 
 public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -65,15 +62,7 @@
     @Override
     public void generate(LIRGenerator gen) {
         Variable result = gen.newVariable(Kind.Int);
-        IntrinsicOpcode opcode;
-        if (value.kind().isStackInt()) {
-            opcode = IntrinsicOpcode.IBSR;
-        } else if (value.kind().isLong()) {
-            opcode = IntrinsicOpcode.LBSR;
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-        gen.append(new AMD64BitScanOp(opcode, result, gen.operand(value)));
+        gen.emitBitScanReverse(result, gen.operand(value));
         gen.setResult(this, result);
     }
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java	Wed Oct 03 01:18:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java	Wed Oct 03 16:49:51 2012 +0200
@@ -22,19 +22,15 @@
  */
 package com.oracle.graal.snippets.nodes;
 
-import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.target.amd64.*;
 
 public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, LIRGenLowerable {
 
@@ -65,13 +61,13 @@
         Variable input = gen.load(gen.operand(x()));
         Variable result = gen.newVariable(kind());
         switch (operation()) {
-            case ABS:   gen.append(new Op2Reg(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); break;
-            case SQRT:  gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.SQRT, result, input)); break;
-            case LOG:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.LOG, result, input)); break;
-            case LOG10: gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.LOG10, result, input)); break;
-            case SIN:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.SIN, result, input)); break;
-            case COS:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.COS, result, input)); break;
-            case TAN:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.IntrinsicOpcode.TAN, result, input)); break;
+            case ABS:   gen.emitMathAbs(result, input); break;
+            case SQRT:  gen.emitMathSqrt(result, input); break;
+            case LOG:   gen.emitMathLog(result, input, false); break;
+            case LOG10: gen.emitMathLog(result, input, true); break;
+            case SIN:   gen.emitMathSin(result, input); break;
+            case COS:   gen.emitMathCos(result, input); break;
+            case TAN:   gen.emitMathTan(result, input); break;
             default:    throw GraalInternalError.shouldNotReachHere();
         }
         gen.setResult(this, result);
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java	Wed Oct 03 01:18:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java	Wed Oct 03 16:49:51 2012 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.target.amd64.*;
 
 
 public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -63,7 +62,7 @@
     @Override
     public void generate(LIRGenerator gen) {
         Variable result = gen.newVariable(value.kind());
-        gen.append(new AMD64ByteSwapOp(result, gen.operand(value)));
+        gen.emitByteSwap(result, gen.operand(value));
         gen.setResult(this, result);
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64BitScanOp.java	Wed Oct 03 01:18:03 2012 +0200
+++ /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.graal.snippets.target.amd64;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.max.asm.amd64.*;
-
-
-public class AMD64BitScanOp extends AMD64LIRInstruction {
-    public enum IntrinsicOpcode  {
-        IBSR, LBSR,
-        BSF;
-    }
-
-    @Opcode private final IntrinsicOpcode opcode;
-    @Def protected Value result;
-    @Use({OperandFlag.REG, OperandFlag.ADDR}) protected Value input;
-
-    public AMD64BitScanOp(IntrinsicOpcode opcode, Value result, Value input) {
-        this.opcode = opcode;
-        this.result = result;
-        this.input = input;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        Register dst = ValueUtil.asIntReg(result);
-        if (ValueUtil.isAddress(input)) {
-            Address src = ValueUtil.asAddress(input);
-            switch(opcode) {
-                case BSF:
-                    masm.bsfq(dst, src);
-                    break;
-                case IBSR:
-                    masm.bsrl(dst, src);
-                    break;
-                case LBSR:
-                    masm.bsrq(dst, src);
-                    break;
-            }
-        } else {
-            Register src = ValueUtil.asRegister(input);
-            switch(opcode) {
-                case BSF:
-                    masm.bsfq(dst, src);
-                    break;
-                case IBSR:
-                    masm.bsrl(dst, src);
-                    break;
-                case LBSR:
-                    masm.bsrq(dst, src);
-                    break;
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64ByteSwapOp.java	Wed Oct 03 01:18:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.graal.snippets.target.amd64;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.LIRInstruction.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.max.asm.amd64.*;
-
-@Opcode("BSWAP")
-public class AMD64ByteSwapOp extends AMD64LIRInstruction {
-    @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result;
-    @Use protected Value input;
-
-    public AMD64ByteSwapOp(Value result, Value input) {
-        this.result = result;
-        this.input = input;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        AMD64Move.move(tasm, masm, result, input);
-        switch(input.getKind()) {
-            case Int:
-                masm.bswapl(ValueUtil.asIntReg(result));
-                break;
-            case Long:
-                masm.bswapq(ValueUtil.asLongReg(result));
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Wed Oct 03 01:18:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.graal.snippets.target.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.max.asm.amd64.*;
-
-public class AMD64MathIntrinsicOp extends AMD64LIRInstruction {
-    public enum IntrinsicOpcode  {
-        SQRT,
-        SIN, COS, TAN,
-        LOG, LOG10;
-    }
-
-    @Opcode private final IntrinsicOpcode opcode;
-    @Def protected Value result;
-    @Use protected Value input;
-
-    public AMD64MathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) {
-        this.opcode = opcode;
-        this.result = result;
-        this.input = input;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        switch (opcode) {
-            case SQRT:  masm.sqrtsd(asDoubleReg(result), asDoubleReg(input)); break;
-            case LOG:   masm.flog(asDoubleReg(result), asDoubleReg(input), false); break;
-            case LOG10: masm.flog(asDoubleReg(result), asDoubleReg(input), true); break;
-            case SIN:   masm.fsin(asDoubleReg(result), asDoubleReg(input)); break;
-            case COS:   masm.fcos(asDoubleReg(result), asDoubleReg(input)); break;
-            case TAN:   masm.ftan(asDoubleReg(result), asDoubleReg(input)); break;
-            default:    throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-}
--- a/mx/projects	Wed Oct 03 01:18:03 2012 +0200
+++ b/mx/projects	Wed Oct 03 16:49:51 2012 +0200
@@ -65,7 +65,7 @@
 # graal.hotspot.amd64
 project@com.oracle.graal.hotspot.amd64@subDir=graal
 project@com.oracle.graal.hotspot.amd64@sourceDirs=src
-project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot
+project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64
 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7
 
@@ -168,10 +168,17 @@
 # graal.compiler
 project@com.oracle.graal.compiler@subDir=graal
 project@com.oracle.graal.compiler@sourceDirs=src
-project@com.oracle.graal.compiler@dependencies=com.oracle.graal.compiler.virtual,com.oracle.graal.compiler.loop,com.oracle.graal.alloc,com.oracle.graal.lir.amd64
+project@com.oracle.graal.compiler@dependencies=com.oracle.graal.compiler.virtual,com.oracle.graal.compiler.loop,com.oracle.graal.alloc
 project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler@javaCompliance=1.7
 
+# graal.compiler.amd64
+project@com.oracle.graal.compiler.amd64@subDir=graal
+project@com.oracle.graal.compiler.amd64@sourceDirs=src
+project@com.oracle.graal.compiler.amd64@dependencies=com.oracle.graal.compiler,com.oracle.graal.lir.amd64
+project@com.oracle.graal.compiler.amd64@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.compiler.amd64@javaCompliance=1.7
+
 # graal.boot
 project@com.oracle.graal.boot@subDir=graal
 project@com.oracle.graal.boot@sourceDirs=src
--- a/src/share/vm/runtime/arguments.cpp	Wed Oct 03 01:18:03 2012 +0200
+++ b/src/share/vm/runtime/arguments.cpp	Wed Oct 03 16:49:51 2012 +0200
@@ -2150,6 +2150,7 @@
 #ifdef AMD64
         "com.oracle.max.asm.amd64",
         "com.oracle.graal.lir.amd64",
+        "com.oracle.graal.compiler.amd64",
         "com.oracle.graal.hotspot.amd64",
 #endif
         "com.oracle.graal.api",