changeset 10665:dcee58529a1c

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Tue, 09 Jul 2013 11:21:06 +0200
parents a9b76e1e5ab3 (current diff) 4ef92b67aeae (diff)
children 9808158cfeab e7d07c9bb779
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodSubstitutions.java
diffstat 75 files changed, 6481 insertions(+), 421 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 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.asm.hsail;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.*;
+
+/**
+ * The platform-dependent base class for the HSAIL assembler.
+ */
+public abstract class AbstractHSAILAssembler extends AbstractAssembler {
+
+    public AbstractHSAILAssembler(TargetDescription target) {
+        super(target);
+    }
+
+    @Override
+    public final void bind(Label l) {
+        super.bind(l);
+        emitString0(nameOf(l) + ":\n");
+    }
+
+    @Override
+    public void align(int modulus) {
+        // Nothing to do
+    }
+
+    @Override
+    public void jmp(Label l) {
+        emitString("brn " + nameOf(l) + ";");
+    }
+
+    @Override
+    protected void patchJumpTarget(int branch, int jumpTarget) {
+        // Nothing to do
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAddress.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, 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.asm.hsail;
+
+import com.oracle.graal.api.code.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents an address in target machine memory, specified via some combination of a base register
+ * and a displacement.
+ */
+public final class HSAILAddress extends AbstractAddress {
+
+    private final Register base;
+    private final long displacement;
+
+    /**
+     * Creates an {@link HSAILAddress} with given base register and no displacement.
+     * 
+     * 
+     * @param base the base register
+     */
+    public HSAILAddress(Register base) {
+        this(base, 0);
+    }
+
+    /**
+     * Creates an {@link HSAILAddress} with given base register and a displacement. This is the most
+     * general constructor.
+     * 
+     * @param base the base register
+     * @param displacement the displacement
+     */
+    public HSAILAddress(Register base, long displacement) {
+        this.base = base;
+        this.displacement = displacement;
+    }
+
+    /**
+     * @return Base register that defines the start of the address computation. If not present, is
+     *         denoted by {@link Value#ILLEGAL}.
+     */
+    public Register getBase() {
+        return base;
+    }
+
+    /**
+     * @return Optional additive displacement.
+     */
+    public long getDisplacement() {
+        return displacement;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,236 @@
+/*
+ * 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.asm.hsail;
+
+import com.oracle.graal.api.code.*;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hsail.*;
+import com.oracle.graal.graph.GraalInternalError;
+import com.amd.okra.OkraUtil;
+
+/**
+ * This class contains routines to emit HSAIL assembly code.
+ */
+public class HSAILAssembler extends AbstractHSAILAssembler {
+
+    /**
+     * Stack size in bytes (used to keep track of spilling).
+     */
+    private int maxDataTypeSize;
+
+    /**
+     * Maximum stack offset used by a store operation.
+     */
+    private long maxStackOffset = 0;
+
+    public long upperBoundStackSize() {
+        return maxStackOffset + maxDataTypeSize;
+    }
+
+    public HSAILAssembler(TargetDescription target) {
+        super(target);
+    }
+
+    @Override
+    public HSAILAddress makeAddress(Register base, int displacement) {
+        return new HSAILAddress(base, displacement);
+    }
+
+    @Override
+    public HSAILAddress getPlaceholder() {
+        return null;
+    }
+
+    public final void undefined(String str) {
+        emitString("undefined operation " + str);
+    }
+
+    public final void exit() {
+        emitString("ret;" + "");
+    }
+
+    /**
+     * An Object is only moved into a register when it is a class constant (which is not really a
+     * constant because it can be moved by GC). Because we can't patch the HSAIL once it is
+     * finalized, we handle changes due to GC movement by dereferencing a global reference that is
+     * created by JNI since these JNI global references do not move.
+     */
+    public final void mov(Register a, Object obj) {
+        if (obj instanceof Class) {
+            Class<?> clazz = (Class<?>) obj;
+            long refHandle = OkraUtil.getRefHandle(clazz);
+            String className = clazz.getName();
+            String regName = "$d" + a.encoding();
+            emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + ";  // handle for " + className);
+            emitString("ld_global_u64 " + regName + ", [" + regName + "];");
+        } else {
+            throw GraalInternalError.shouldNotReachHere("mov from object not a class");
+        }
+
+    }
+
+    public final void emitMov(Value dst, Value src) {
+        if (isRegister(dst) && isConstant(src) && src.getKind().getStackKind() == Kind.Object) {
+            mov(asRegister(dst), (asConstant(src)).asObject());
+        } else {
+            String argtype = getArgType(dst).substring(1);
+            emitString("mov_b" + argtype + " " + mapRegOrConstToString(dst) + ", " + mapRegOrConstToString(src) + ";");
+        }
+    }
+
+    public final void emitLoad(Value dest, HSAILAddress addr) {
+        emitString("ld_global_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + mapAddress(addr) + ";");
+    }
+
+    public final void emitSpillLoad(Value dest, Value src) {
+        emitString("ld_spill_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + HSAIL.mapStackSlot(src) + ";");
+    }
+
+    public final void emitStore(Value src, HSAILAddress addr) {
+        emitString("st_global_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + mapAddress(addr) + ";");
+    }
+
+    public final void emitSpillStore(Value src, Value dest) {
+        int sizestored = getArgSize(src);
+        if (maxDataTypeSize < sizestored) {
+            maxDataTypeSize = sizestored;
+        }
+        int stackoffset = HSAIL.getStackOffset(dest);
+        if (maxStackOffset < stackoffset) {
+            maxStackOffset = stackoffset;
+        }
+        emitString("st_spill_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + HSAIL.mapStackSlot(dest) + ";");
+    }
+
+    public void cbr(String target1) {
+        emitString("cbr " + "$c0" + ", " + target1 + ";");
+    }
+
+    public int getArgSize(Value src) {
+        switch (src.getKind()) {
+            case Int:
+            case Float:
+                return 32;
+            case Double:
+            case Long:
+            case Object:
+                return 64;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static final String getArgType(Value src) {
+        String prefix = "";
+        switch (src.getKind()) {
+            case Float:
+                prefix = "f32";
+                break;
+            case Double:
+                prefix = "f64";
+                break;
+            case Int:
+                prefix = "s32";
+                break;
+            case Long:
+                prefix = "s64";
+                break;
+            case Object:
+                prefix = "u64";
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return prefix;
+    }
+
+    public static final String getArgTypeForceUnsigned(Value src) {
+        switch (src.getKind()) {
+            case Int:
+                return "u32";
+            case Long:
+            case Object:
+                return "u64";
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public void emitCompare(Value src0, Value src1, String condition, boolean unordered, boolean isUnsignedCompare) {
+        String prefix = "cmp_" + condition + (unordered ? "u" : "") + "_b1_" + (isUnsignedCompare ? getArgTypeForceUnsigned(src1) : getArgType(src1));
+        emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";");
+    }
+
+    public void emitConvert(Value dest, Value src) {
+        String prefix = (getArgType(dest).equals("f32") && getArgType(src).equals("f64")) ? "cvt_near_" : "cvt_";
+        emitString(prefix + getArgType(dest) + "_" + getArgType(src) + " " + HSAIL.mapRegister(dest) + ", " + HSAIL.mapRegister(src) + ";");
+    }
+
+    public void emitArg1(String mnemonic, Value dest, Value src) {
+        emitString(mnemonic + "_" + getArgType(src) + " " + HSAIL.mapRegister(dest) + ", " + mapRegOrConstToString(src) + ";" + "");
+    }
+
+    public static String mapAddress(HSAILAddress addr) {
+        return "[$d" + addr.getBase().encoding() + " + " + addr.getDisplacement() + "]";
+    }
+
+    private static String mapRegOrConstToString(Value src) {
+        if (!isConstant(src)) {
+            return HSAIL.mapRegister(src);
+        } else {
+            Constant consrc = asConstant(src);
+            switch (src.getKind()) {
+                case Int:
+                    return Integer.toString(consrc.asInt());
+                case Float:
+                    return Float.toString(consrc.asFloat()) + "f";
+                case Double:
+                    return Double.toString(consrc.asDouble());
+                case Long:
+                    return Long.toString(consrc.asLong());
+                default:
+                    throw GraalInternalError.shouldNotReachHere("unknown type: " + src);
+            }
+        }
+
+    }
+
+    public final void emit(String mnemonic, Value dest, Value src0, Value src1) {
+        String prefix = getArgType(dest);
+        emit(mnemonic + "_" + prefix, dest, "", src0, src1);
+    }
+
+    private void emit(String instr, Value dest, String controlRegString, Value src0, Value src1) {
+        assert (!isConstant(dest));
+        emitString(String.format("%s %s, %s%s, %s;", instr, HSAIL.mapRegister(dest), controlRegString, mapRegOrConstToString(src0), mapRegOrConstToString(src1)));
+    }
+
+    public final void cmovCommon(Value dest, Value trueReg, Value falseReg, int width) {
+        String instr = (width == 32 ? "cmov_b32" : "cmov_b64");
+        emit(instr, dest, "$c0, ", trueReg, falseReg);
+    }
+
+}
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/AbstractPTXAssembler.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/AbstractPTXAssembler.java	Tue Jul 09 11:21:06 2013 +0200
@@ -34,30 +34,25 @@
         super(target);
     }
 
-    public static final String UNBOUND_TARGET = "L" + Integer.MAX_VALUE;
-
     @Override
     public final void bind(Label l) {
         super.bind(l);
-        emitString0("L" + l.toString() + ":\n");
+        emitString0(nameOf(l) + ":\n");
     }
 
     @Override
     public void align(int modulus) {
-        // TODO Auto-generated method stub
+        // Nothing to do
     }
 
     @Override
     public void jmp(Label l) {
-        // TODO Auto-generated method stub
+        // Nothing to do
     }
 
     @Override
     protected void patchJumpTarget(int branch, int jumpTarget) {
-        final int spaces = UNBOUND_TARGET.length();
-        String targetString = String.format("L%-" + spaces + "s", jumpTarget + ";");
-        int offset = "\tbra ".length();  // XXX we need a better way to figure this out
-        codeBuffer.emitString(targetString, branch + offset);
+        // Nothing to do. All branches already point to the right label.
     }
 
 }
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java	Tue Jul 09 11:21:06 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.asm;
 
 import java.nio.*;
+import java.util.*;
 
 import com.oracle.graal.api.code.*;
 
@@ -56,6 +57,34 @@
 
     protected abstract void patchJumpTarget(int branch, int jumpTarget);
 
+    private Map<Label, String> nameMap;
+
+    /**
+     * Creates a name for a label.
+     * 
+     * @param l the label for which a name is being created
+     * @param id a label identifier that is unique with the scope of this assembler
+     */
+    protected String createLabelName(Label l, int id) {
+        return "@L" + id;
+    }
+
+    /**
+     * Gets a name for a label, creating it if it does not yet exist. By default, the returned name
+     * is only unique with the scope of this assembler.
+     */
+    public String nameOf(Label l) {
+        if (nameMap == null) {
+            nameMap = new HashMap<>();
+        }
+        String name = nameMap.get(l);
+        if (name == null) {
+            name = createLabelName(l, nameMap.size());
+            nameMap.put(l, name);
+        }
+        return name;
+    }
+
     protected final void emitByte(int x) {
         codeBuffer.emitByte(x);
     }
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java	Tue Jul 09 11:21:06 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.asm;
 
-import java.util.ArrayList;
+import java.util.*;
 
 /**
  * This class represents a label within assembly code.
@@ -66,7 +66,7 @@
     }
 
     public void addPatchAt(int branchLocation) {
-        assert !isBound() : "Label is already bound";
+        assert !isBound() : "Label is already bound " + this + " " + branchLocation + " at position " + position;
         patchPositions.add(branchLocation);
     }
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Jul 09 11:21:06 2013 +0200
@@ -241,6 +241,13 @@
     }
 
     @Override
+    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        AllocatableValue targetAddress = AMD64.rax.asValue();
+        emitMove(targetAddress, operand(callTarget.computedAddress()));
+        append(new AMD64Call.IndirectCallOp(callTarget.target(), result, parameters, temps, targetAddress, callState));
+    }
+
+    @Override
     public void emitOverflowCheckBranch(LabelRef destination, boolean negated) {
         append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, destination));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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.hsail.test.infra;
+
+/**
+ * This class extends KernelTester and provides a base class
+ * for which the HSAIL code comes from the Graal compiler.
+ */
+import com.oracle.graal.compiler.hsail.HSAILCompilationResult;
+import java.lang.reflect.Method;
+import java.io.*;
+
+public abstract class GraalKernelTester extends KernelTester {
+
+    HSAILCompilationResult hsailCompResult;
+    private boolean showHsailSource = false;
+    private boolean saveInFile = false;
+
+    @Override
+    public String getCompiledHSAILSource(Method testMethod) {
+        if (hsailCompResult == null) {
+            hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(testMethod);
+        }
+        String hsailSource = hsailCompResult.getHSAILCode();
+        if (showHsailSource) {
+            logger.severe(hsailSource);
+        }
+        if (saveInFile) {
+            try {
+                File fout = File.createTempFile("tmp", ".hsail");
+                logger.fine("creating " + fout.getCanonicalPath());
+                FileWriter fw = new FileWriter(fout);
+                BufferedWriter bw = new BufferedWriter(fw);
+                bw.write(hsailSource);
+                bw.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return hsailSource;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,829 @@
+/*
+ * 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.hsail.test.infra;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.nio.file.*;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+import java.util.logging.*;
+
+import com.amd.okra.*;
+
+/**
+ * Abstract class on which the HSAIL unit tests are built. Executes a method or lambda on both the
+ * Java side and the Okra side and compares the results for fields that are annotated with
+ * {@link KernelTester.Result}.
+ */
+public abstract class KernelTester {
+
+    /**
+     * Denotes a field whose value is to be compared as part of computing the result of a test.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    public @interface Result {
+    }
+
+    // Using these in case we want to compile with Java 7.
+    public interface MyIntConsumer {
+
+        void accept(int value);
+    }
+
+    public interface MyObjConsumer {
+
+        void accept(Object obj);
+    }
+
+    public enum DispatchMode {
+        SEQ, JTP, OKRA
+    }
+
+    public enum HsailMode {
+        COMPILED, INJECT_HSAIL, INJECT_OCL
+    }
+
+    private DispatchMode dispatchMode;
+    // Where the hsail comes from.
+    private HsailMode hsailMode;
+    private Method testMethod;
+    // What type of okra dispatch to use when client calls.
+    private boolean useLambdaMethod;
+    private Class<?>[] testMethodParams = null;
+    private int id = nextId.incrementAndGet();
+    static AtomicInteger nextId = new AtomicInteger(0);
+    public static Logger logger;
+    private OkraContext okraContext;
+    private OkraKernel okraKernel;
+    private static final String propPkgName = KernelTester.class.getPackage().getName();
+    private static Level logLevel;
+    private static ConsoleHandler consoleHandler;
+
+    static {
+        logger = Logger.getLogger(propPkgName);
+        logLevel = Level.parse(System.getProperty("kerneltester.logLevel", "SEVERE"));
+
+        // This block configure the logger with handler and formatter.
+        consoleHandler = new ConsoleHandler();
+        logger.addHandler(consoleHandler);
+        logger.setUseParentHandlers(false);
+        SimpleFormatter formatter = new SimpleFormatter() {
+
+            @SuppressWarnings("sync-override")
+            @Override
+            public String format(LogRecord record) {
+                return (record.getMessage() + "\n");
+            }
+        };
+        consoleHandler.setFormatter(formatter);
+        setLogLevel(logLevel);
+    }
+
+    private static boolean gaveNoOkraWarning = false;
+    private boolean onSimulator;
+    private boolean okraLibExists;
+
+    public boolean runningOnSimulator() {
+        return onSimulator;
+    }
+
+    public KernelTester() {
+        okraLibExists = OkraUtil.okraLibExists();
+        dispatchMode = DispatchMode.SEQ;
+        hsailMode = HsailMode.COMPILED;
+        useLambdaMethod = false;
+    }
+
+    public abstract void runTest();
+
+    // Default comparison is to compare all things marked @Result.
+    public boolean compareResults(KernelTester base) {
+        Class<?> clazz = this.getClass();
+        while (clazz != null && clazz != KernelTester.class) {
+            for (Field f : clazz.getDeclaredFields()) {
+                if (!Modifier.isStatic(f.getModifiers())) {
+                    Result annos = f.getAnnotation(Result.class);
+                    if (annos != null) {
+                        logger.fine("@Result field = " + f);
+                        Object myResult = getFieldFromObject(f, this);
+                        Object otherResult = getFieldFromObject(f, base);
+                        boolean same = compareObjects(myResult, otherResult);
+                        logger.fine("comparing " + myResult + ", " + otherResult + ", match=" + same);
+                        if (!same) {
+                            logger.severe("mismatch comparing " + f + ", " + myResult + " vs. " + otherResult);
+                            logSevere("FAILED!!! " + this.getClass());
+                            return false;
+                        }
+                    }
+                }
+            }
+            clazz = clazz.getSuperclass();
+        }
+        logInfo("PASSED: " + this.getClass());
+        return true;
+    }
+
+    private boolean compareObjects(Object first, Object second) {
+        Class<?> clazz = first.getClass();
+        if (clazz != second.getClass()) {
+            return false;
+        }
+        if (!clazz.isArray()) {
+            // Non arrays.
+            if (clazz.equals(float.class) || clazz.equals(double.class)) {
+                return isEqualsFP((double) first, (double) second);
+            } else {
+                return first.equals(second);
+            }
+        } else {
+            // Handle the case where Objects are arrays.
+            ArrayComparer comparer;
+            if (clazz.equals(float[].class) || clazz.equals(double[].class)) {
+                comparer = new FPArrayComparer();
+            } else if (clazz.equals(long[].class) || clazz.equals(int[].class) || clazz.equals(byte[].class)) {
+                comparer = new IntArrayComparer();
+            } else if (clazz.equals(boolean[].class)) {
+                comparer = new BooleanArrayComparer();
+            } else {
+                comparer = new ObjArrayComparer();
+            }
+            return comparer.compareArrays(first, second);
+        }
+    }
+
+    static final int MISMATCHLIMIT = 10;
+    static final int ELEMENTDISPLAYLIMIT = 20;
+
+    public int getMisMatchLimit() {
+        return MISMATCHLIMIT;
+    }
+
+    public int getElementDisplayLimit() {
+        return ELEMENTDISPLAYLIMIT;
+    }
+
+    abstract class ArrayComparer {
+
+        abstract Object getElement(Object ary, int index);
+
+        // Equality test, can be overridden
+        boolean isEquals(Object firstElement, Object secondElement) {
+            return firstElement.equals(secondElement);
+        }
+
+        boolean compareArrays(Object first, Object second) {
+            int len = Array.getLength(first);
+            if (len != Array.getLength(second)) {
+                return false;
+            }
+            // If info logLevel, build string of first few elements from first array.
+            if (logLevel.intValue() <= Level.INFO.intValue()) {
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < Math.min(len, getElementDisplayLimit()); i++) {
+                    sb.append(getElement(first, i));
+                    sb.append(", ");
+                }
+                logger.info(sb.toString());
+            }
+            boolean success = true;
+            int mismatches = 0;
+            for (int i = 0; i < len; i++) {
+                Object firstElement = getElement(first, i);
+                Object secondElement = getElement(second, i);
+                if (!isEquals(firstElement, secondElement)) {
+                    logSevere("mismatch at index " + i + ", expected " + secondElement + ", saw " + firstElement);
+                    success = false;
+                    mismatches++;
+                    if (mismatches >= getMisMatchLimit()) {
+                        logSevere("...Truncated");
+                        break;
+                    }
+                }
+            }
+            return success;
+        }
+    }
+
+    class FPArrayComparer extends ArrayComparer {
+
+        @Override
+        Object getElement(Object ary, int index) {
+            return Array.getDouble(ary, index);
+        }
+
+        @Override
+        boolean isEquals(Object firstElement, Object secondElement) {
+            return isEqualsFP((double) firstElement, (double) secondElement);
+        }
+    }
+
+    class IntArrayComparer extends ArrayComparer {
+
+        @Override
+        Object getElement(Object ary, int index) {
+            return Array.getLong(ary, index);
+        }
+    }
+
+    class BooleanArrayComparer extends ArrayComparer {
+
+        @Override
+        Object getElement(Object ary, int index) {
+            return Array.getBoolean(ary, index);
+        }
+    }
+
+    class ObjArrayComparer extends ArrayComparer {
+
+        @Override
+        Object getElement(Object ary, int index) {
+            return Array.get(ary, index);
+        }
+    }
+
+    /**
+     * This isEqualsFP method allows subclass to override what FP equality means for this particular
+     * unit test.
+     */
+    public boolean isEqualsFP(double first, double second) {
+        return first == second;
+    }
+
+    public void setDispatchMode(DispatchMode dispatchMode) {
+        this.dispatchMode = dispatchMode;
+    }
+
+    public void setHsailMode(HsailMode hsailMode) {
+        this.hsailMode = hsailMode;
+    }
+
+    /**
+     * Return a clone of this instance unless overridden, we just call the null constructor.
+     */
+    public KernelTester newInstance() {
+        try {
+            return this.getClass().getConstructor((Class<?>[]) null).newInstance();
+        } catch (Throwable t) {
+            fail("Unexpected exception " + t);
+            return null;
+        }
+    }
+
+    public Method getMethodFromMethodName(String methName, Class<?> clazz) {
+        Class<?> clazz2 = clazz;
+        while (clazz2 != null) {
+            for (Method m : clazz2.getDeclaredMethods()) {
+                logger.fine(" in " + clazz2 + ", trying to match " + m);
+                if (m.getName().equals(methName)) {
+                    testMethodParams = m.getParameterTypes();
+                    if (logLevel.intValue() <= Level.FINE.intValue()) {
+                        logger.fine(" in " + clazz2 + ", matched " + m);
+                        logger.fine("parameter types are...");
+                        int paramNum = 0;
+                        for (Class<?> pclazz : testMethodParams) {
+                            logger.fine(paramNum++ + ") " + pclazz.toString());
+                        }
+                    }
+                    return m;
+                }
+            }
+            // Didn't find it in current clazz, try superclass.
+            clazz2 = clazz2.getSuperclass();
+        }
+        // If we got this far, no match.
+        return null;
+    }
+
+    private void setTestMethod(String methName, Class<?> inClazz) {
+        testMethod = getMethodFromMethodName(methName, inClazz);
+        if (testMethod == null) {
+            fail("cannot find method " + methName + " in class " + inClazz);
+        } else {
+            // Print info but only for first such class.
+            if (id == 1) {
+                logger.fine("testMethod to be compiled is \n   " + testMethod);
+            }
+        }
+    }
+
+    // Default is method name "run", but could be overridden.
+    private final String defaultMethodName = "run";
+
+    public String getTestMethodName() {
+        return defaultMethodName;
+    }
+
+    /**
+     * The dispatchMethodKernel dispatches a non-lambda method. All the parameters of the compiled
+     * method are supplied as parameters to this call.
+     */
+    public void dispatchMethodKernel(int range, Object... args) {
+        if (testMethod == null) {
+            setTestMethod(getTestMethodName(), this.getClass());
+        }
+        if (dispatchMode == DispatchMode.SEQ) {
+            dispatchMethodKernelSeq(range, args);
+        } else if (dispatchMode == DispatchMode.OKRA) {
+            dispatchMethodKernelOkra(range, args);
+        }
+    }
+
+    /**
+     * This dispatchLambdaMethodKernel dispatches the lambda version of a kernel where the "kernel"
+     * is for the lambda method itself (like lambda$0).
+     */
+    public void dispatchLambdaMethodKernel(int range, MyIntConsumer consumer) {
+        if (testMethod == null) {
+            setTestMethod(findLambdaMethodName(), this.getClass());
+        }
+        if (dispatchMode == DispatchMode.SEQ) {
+            dispatchLambdaKernelSeq(range, consumer);
+        } else if (dispatchMode == DispatchMode.OKRA) {
+            dispatchLambdaMethodKernelOkra(range, consumer);
+        }
+    }
+
+    public void dispatchLambdaMethodKernel(Object[] ary, MyObjConsumer consumer) {
+        if (testMethod == null) {
+            setTestMethod(findLambdaMethodName(), this.getClass());
+        }
+        if (dispatchMode == DispatchMode.SEQ) {
+            dispatchLambdaKernelSeq(ary, consumer);
+        } else if (dispatchMode == DispatchMode.OKRA) {
+            dispatchLambdaMethodKernelOkra(ary, consumer);
+        }
+    }
+
+    /**
+     * The dispatchLambdaKernel dispatches the lambda version of a kernel where the "kernel" is for
+     * the xxx$$Lambda.accept method in the wrapper for the lambda. Note that the useLambdaMethod
+     * boolean provides a way of actually invoking dispatchLambdaMethodKernel from this API.
+     */
+    public void dispatchLambdaKernel(int range, MyIntConsumer consumer) {
+        if (useLambdaMethod) {
+            dispatchLambdaMethodKernel(range, consumer);
+            return;
+        }
+        if (testMethod == null) {
+            setTestMethod("accept", consumer.getClass());
+        }
+        if (dispatchMode == DispatchMode.SEQ) {
+            dispatchLambdaKernelSeq(range, consumer);
+        } else if (dispatchMode == DispatchMode.OKRA) {
+            dispatchLambdaKernelOkra(range, consumer);
+        }
+    }
+
+    public void dispatchLambdaKernel(Object[] ary, MyObjConsumer consumer) {
+        if (useLambdaMethod) {
+            dispatchLambdaMethodKernel(ary, consumer);
+            return;
+        }
+        if (testMethod == null) {
+            setTestMethod("accept", consumer.getClass());
+        }
+        if (dispatchMode == DispatchMode.SEQ) {
+            dispatchLambdaKernelSeq(ary, consumer);
+        } else if (dispatchMode == DispatchMode.OKRA) {
+            dispatchLambdaKernelOkra(ary, consumer);
+        }
+    }
+
+    private ArrayList<String> getLambdaMethodNames() {
+        Class<?> clazz = this.getClass();
+        ArrayList<String> lambdaNames = new ArrayList<>();
+        while (clazz != null && (lambdaNames.size() == 0)) {
+            for (Method m : clazz.getDeclaredMethods()) {
+                logger.fine(" in " + clazz + ", trying to match " + m);
+                if (m.getName().startsWith("lambda$")) {
+                    lambdaNames.add(m.getName());
+                }
+            }
+            // Didn't find it in current clazz, try superclass.
+            clazz = clazz.getSuperclass();
+        }
+        return lambdaNames;
+    }
+
+    /**
+     * findLambdaMethodName finds a name in the class starting with lambda$. If we find more than
+     * one, throw an error, and tell user to override explicitly
+     */
+    private String findLambdaMethodName() {
+        // If user overrode getTestMethodName, use that name.
+        if (!getTestMethodName().equals(defaultMethodName)) {
+            return getTestMethodName();
+        } else {
+            ArrayList<String> lambdaNames = getLambdaMethodNames();
+            switch (lambdaNames.size()) {
+                case 1:
+                    return lambdaNames.get(0);
+                case 0:
+                    fail("No lambda method found in " + this.getClass());
+                    return null;
+                default:
+                    // More than one lambda.
+                    String msg = "Multiple lambda methods found in " + this.getClass() + "\nYou should override getTestMethodName with one of the following\n";
+                    for (String name : lambdaNames) {
+                        msg = msg + name + "\n";
+                    }
+                    fail(msg);
+                    return null;
+            }
+        }
+    }
+
+    /**
+     * The getCompiledHSAILSource returns the string of HSAIL code for the compiled method. By
+     * default, throws an error. In graal for instance, this would be overridden in
+     * GraalKernelTester.
+     */
+    public String getCompiledHSAILSource(Method testMethod1) {
+        fail("no compiler connected so unable to compile " + testMethod1 + "\nYou could try injecting HSAIL or OpenCL");
+        return null;
+    }
+
+    public String getHSAILSource(Method testMethod1) {
+        switch (hsailMode) {
+            case COMPILED:
+                return getCompiledHSAILSource(testMethod1);
+            case INJECT_HSAIL:
+                return getHsailFromClassnameHsailFile();
+            case INJECT_OCL:
+                return getHsailFromClassnameOclFile();
+            default:
+                fail("unknown hsailMode = " + hsailMode);
+                return null;
+        }
+    }
+
+    /**
+     * The getHSAILKernelName returns the name of the hsail kernel. By default we use 'run'. unless
+     * coming from opencl injection. Could be overridden by the junit test.
+     */
+    public String getHSAILKernelName() {
+        return (hsailMode != HsailMode.INJECT_OCL ? "&run" : "&__OpenCL_run_kernel");
+    }
+
+    private void createOkraKernel() {
+        // Call routines in the derived class to get the hsail code and kernel name.
+        String hsailSource = getHSAILSource(testMethod);
+        if (!okraLibExists) {
+            if (!gaveNoOkraWarning) {
+                logger.fine("No Okra library detected, skipping all KernelTester tests in " + this.getClass().getPackage().getName());
+                gaveNoOkraWarning = true;
+            }
+        }
+        // Ignore any kerneltester test if okra does not exist.
+        assumeTrue(okraLibExists);
+        // Control which okra instances can run the tests.
+        onSimulator = OkraContext.isSimulator();
+        okraContext = new OkraContext();
+        if (!okraContext.isValid()) {
+            fail("...unable to create context");
+        }
+        // Control verbosity in okra from our logLevel.
+        if (logLevel.intValue() <= Level.INFO.intValue()) {
+            okraContext.setVerbose(true);
+        }
+        okraKernel = new OkraKernel(okraContext, hsailSource, getHSAILKernelName());
+        if (!okraKernel.isValid()) {
+            fail("...unable to create kernel");
+        }
+    }
+
+    private void dispatchKernelOkra(int range, Object... args) {
+        if (okraKernel == null) {
+            createOkraKernel();
+        }
+        if (logLevel.intValue() <= Level.FINE.intValue()) {
+            logger.fine("Arguments passed to okra...");
+            for (Object arg : args) {
+                logger.fine("  " + arg);
+            }
+        }
+        okraKernel.setLaunchAttributes(range);
+        okraKernel.dispatchWithArgs(args);
+    }
+
+    private void dispatchMethodKernelSeq(int range, Object... args) {
+        Object[] invokeArgs = new Object[args.length + 1];
+        // Need space on the end for the gid parameter.
+        System.arraycopy(args, 0, invokeArgs, 0, args.length);
+        int gidArgIndex = invokeArgs.length - 1;
+        if (logLevel.intValue() <= Level.FINE.intValue()) {
+            for (Object arg : args) {
+                logger.fine(arg.toString());
+            }
+        }
+        for (int rangeIndex = 0; rangeIndex < range; rangeIndex++) {
+            invokeArgs[gidArgIndex] = rangeIndex;
+            try {
+                testMethod.invoke(this, invokeArgs);
+            } catch (IllegalAccessException e) {
+                fail("could not invoke " + testMethod + ", make sure it is public");
+            } catch (IllegalArgumentException e) {
+                fail("wrong arguments invoking " + testMethod + ", check number and type of args passed to dispatchMethodKernel");
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                /**
+                 * We will ignore ArrayIndexOutOfBoundsException because the graal okra target
+                 * doesn't really handle it yet (basically returns early if it sees one).
+                 */
+                if (cause instanceof ArrayIndexOutOfBoundsException) {
+                    logger.severe("ignoring ArrayIndexOutOfBoundsException for index " + rangeIndex);
+                } else {
+                    // Other exceptions.
+                    String errstr = testMethod + " threw an exception on gid=" + rangeIndex + ", exception was " + cause;
+                    fail(errstr);
+                }
+            } catch (Exception e) {
+                fail("Unknown exception " + e + " invoking " + testMethod);
+            }
+        }
+    }
+
+    private void dispatchMethodKernelOkra(int range, Object... args) {
+        Object[] fixedArgs = fixArgTypes(args);
+        if (Modifier.isStatic(testMethod.getModifiers())) {
+            dispatchKernelOkra(range, fixedArgs);
+        } else {
+            // If it is a non-static method we have to push "this" as the first argument.
+            Object[] newFixedArgs = new Object[fixedArgs.length + 1];
+            System.arraycopy(fixedArgs, 0, newFixedArgs, 1, fixedArgs.length);
+            newFixedArgs[0] = this;
+            dispatchKernelOkra(range, newFixedArgs);
+        }
+    }
+
+    /**
+     * For primitive arg parameters, make sure arg types are cast to whatever the testMethod
+     * signature says they should be.
+     */
+    private Object[] fixArgTypes(Object[] args) {
+        Object[] fixedArgs = new Object[args.length];
+        for (int i = 0; i < args.length; i++) {
+            Class<?> paramClass = testMethodParams[i];
+            if (paramClass.equals(Float.class) || paramClass.equals(float.class)) {
+                fixedArgs[i] = ((Number) args[i]).floatValue();
+            } else if (paramClass.equals(Integer.class) || paramClass.equals(int.class)) {
+                fixedArgs[i] = ((Number) args[i]).intValue();
+            } else if (paramClass.equals(Long.class) || paramClass.equals(long.class)) {
+                fixedArgs[i] = ((Number) args[i]).longValue();
+            } else if (paramClass.equals(Double.class) || paramClass.equals(double.class)) {
+                fixedArgs[i] = ((Number) args[i]).doubleValue();
+            } else if (paramClass.equals(Byte.class) || paramClass.equals(byte.class)) {
+                fixedArgs[i] = ((Number) args[i]).byteValue();
+            } else if (paramClass.equals(Boolean.class) || paramClass.equals(boolean.class)) {
+                fixedArgs[i] = (boolean) args[i];
+            } else {
+                // All others just move unchanged.
+                fixedArgs[i] = args[i];
+            }
+        }
+        return fixedArgs;
+    }
+
+    /**
+     * Dispatching a lambda on the java side is simple.
+     */
+    @SuppressWarnings("static-method")
+    private void dispatchLambdaKernelSeq(int range, MyIntConsumer consumer) {
+        for (int i = 0; i < range; i++) {
+            consumer.accept(i);
+        }
+    }
+
+    @SuppressWarnings("static-method")
+    private void dispatchLambdaKernelSeq(Object[] ary, MyObjConsumer consumer) {
+        for (Object obj : ary) {
+            consumer.accept(obj);
+        }
+    }
+
+    /**
+     * The dispatchLambdaMethodKernelOkra dispatches in the case where the hsail kernel implements
+     * the lambda method itself as opposed to the wrapper that calls the lambda method. From the
+     * consumer object, we need to find the fields and pass them to the kernel.
+     */
+    private void dispatchLambdaMethodKernelOkra(int range, MyIntConsumer consumer) {
+        logger.info("To determine parameters to pass to hsail kernel, we will examine   " + consumer.getClass());
+        Field[] fields = consumer.getClass().getDeclaredFields();
+        Object[] args = new Object[fields.length];
+        int argIndex = 0;
+        for (Field f : fields) {
+            logger.info("... " + f);
+            args[argIndex++] = getFieldFromObject(f, consumer);
+        }
+        dispatchKernelOkra(range, args);
+    }
+
+    private void dispatchLambdaMethodKernelOkra(Object[] ary, MyObjConsumer consumer) {
+        logger.info("To determine parameters to pass to hsail kernel, we will examine   " + consumer.getClass());
+        Field[] fields = consumer.getClass().getDeclaredFields();
+        Object[] args = new Object[fields.length];
+        int argIndex = 0;
+        for (Field f : fields) {
+            logger.info("... " + f);
+            args[argIndex++] = getFieldFromObject(f, consumer);
+        }
+        dispatchKernelOkra(ary.length, args);
+    }
+
+    /**
+     * The dispatchLambdaKernelOkra dispatches in the case where the hsail kernel where the hsail
+     * kernel implements the accept method of the wrapper that calls the lambda method as opposed to
+     * the actual lambda method itself.
+     */
+    private void dispatchLambdaKernelOkra(int range, MyIntConsumer consumer) {
+        // The "wrapper" method always has only one arg consisting of the consumer.
+        Object[] args = new Object[1];
+        args[0] = consumer;
+        dispatchKernelOkra(range, args);
+    }
+
+    private void dispatchLambdaKernelOkra(Object[] ary, MyObjConsumer consumer) {
+        // The "wrapper" method always has only one arg consisting of the consumer.
+        Object[] args = new Object[1];
+        args[0] = consumer;
+        dispatchKernelOkra(ary.length, args);
+    }
+
+    private void disposeKernelOkra() {
+        if (okraContext != null) {
+            okraContext.dispose();
+        }
+    }
+
+    private void compareOkraToSeq(HsailMode hsailMode1) {
+        compareOkraToSeq(hsailMode1, false);
+    }
+
+    /**
+     * Runs this instance on OKRA, and as SEQ and compares the output of the two executions.
+     */
+    private void compareOkraToSeq(HsailMode hsailMode1, boolean useLambda) {
+        // Create and run sequential instance.
+        KernelTester testerSeq = newInstance();
+        testerSeq.setDispatchMode(DispatchMode.SEQ);
+        testerSeq.runTest();
+        // Now do this object.
+        this.setHsailMode(hsailMode1);
+        this.setDispatchMode(DispatchMode.OKRA);
+        this.useLambdaMethod = useLambda;
+        this.runTest();
+        this.disposeKernelOkra();
+        assertTrue("failed comparison to SEQ", compareResults(testerSeq));
+    }
+
+    public void testGeneratedHsail() {
+        compareOkraToSeq(HsailMode.COMPILED);
+    }
+
+    public void testGeneratedHsailUsingLambdaMethod() {
+        compareOkraToSeq(HsailMode.COMPILED, true);
+    }
+
+    public void testInjectedHsail() {
+        newInstance().compareOkraToSeq(HsailMode.INJECT_HSAIL);
+    }
+
+    public void testInjectedOpencl() {
+        newInstance().compareOkraToSeq(HsailMode.INJECT_OCL);
+    }
+
+    private static Object getFieldFromObject(Field f, Object fromObj) {
+        try {
+            f.setAccessible(true);
+            Type type = f.getType();
+            logger.info("type = " + type);
+            if (type == double.class) {
+                return f.getDouble(fromObj);
+            } else if (type == float.class) {
+                return f.getFloat(fromObj);
+            } else if (type == long.class) {
+                return f.getLong(fromObj);
+            } else if (type == int.class) {
+                return f.getInt(fromObj);
+            } else if (type == byte.class) {
+                return f.getByte(fromObj);
+            } else if (type == boolean.class) {
+                return f.getBoolean(fromObj);
+            } else {
+                return f.get(fromObj);
+            }
+        } catch (Exception e) {
+            fail("unable to get field " + f + " from " + fromObj);
+            return null;
+        }
+    }
+
+    public static void checkFileExists(String fileName) {
+        assertTrue(fileName + " does not exist", fileExists(fileName));
+    }
+
+    public static boolean fileExists(String fileName) {
+        return new File(fileName).exists();
+    }
+
+    public static String getFileAsString(String sourceFileName) {
+        String source = null;
+        try {
+            checkFileExists(sourceFileName);
+            source = new String(Files.readAllBytes(FileSystems.getDefault().getPath(sourceFileName)));
+        } catch (IOException e) {
+            fail("could not open file " + sourceFileName);
+            return null;
+        }
+        return source;
+    }
+
+    public static String getHsailFromFile(String sourceFileName) {
+        logger.severe("... getting hsail from file " + sourceFileName);
+        return getFileAsString(sourceFileName);
+    }
+
+    private static void executeCmd(String... cmd) {
+        logger.info("spawning" + Arrays.toString(cmd));
+        try {
+            ProcessBuilder pb = new ProcessBuilder(cmd);
+            Process p = pb.start();
+            if (logLevel.intValue() <= Level.INFO.intValue()) {
+                InputStream in = p.getInputStream();
+                BufferedInputStream buf = new BufferedInputStream(in);
+                InputStreamReader inread = new InputStreamReader(buf);
+                BufferedReader bufferedreader = new BufferedReader(inread);
+                String line;
+                while ((line = bufferedreader.readLine()) != null) {
+                    logger.info(line);
+                }
+            }
+            p.waitFor();
+        } catch (Exception e) {
+            fail("could not execute <" + Arrays.toString(cmd) + ">");
+        }
+    }
+
+    public static String getHsailFromOpenCLFile(String openclFileName) {
+        String openclHsailFile = "opencl_out.hsail";
+        String tmpTahitiFile = "_temp_0_Tahiti.txt";
+        checkFileExists(openclFileName);
+        logger.severe("...converting " + openclFileName + " to HSAIL...");
+        executeCmd("aoc2", "-m64", "-I./", "-march=hsail", openclFileName);
+        if (fileExists(tmpTahitiFile)) {
+            return getFileAsString(tmpTahitiFile);
+        } else {
+            executeCmd("HSAILasm", "-disassemble", "-o", openclHsailFile, openclFileName.replace(".cl", ".bin"));
+            checkFileExists(openclHsailFile);
+            return getFileAsString(openclHsailFile);
+        }
+    }
+
+    public String getHsailFromClassnameHsailFile() {
+        return (getHsailFromFile(this.getClass().getSimpleName() + ".hsail"));
+    }
+
+    public String getHsailFromClassnameOclFile() {
+        return (getHsailFromOpenCLFile(this.getClass().getSimpleName() + ".cl"));
+    }
+
+    public static void logInfo(String msg) {
+        logger.info(msg);
+    }
+
+    public static void logSevere(String msg) {
+        logger.severe(msg);
+    }
+
+    public static void setLogLevel(Level level) {
+        logLevel = level;
+        logger.setLevel(level);
+        consoleHandler.setLevel(level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.hsail.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.GraalCompilerTest;
+import com.oracle.graal.compiler.hsail.HSAILCompilationResult;
+import com.oracle.graal.nodes.StructuredGraph;
+
+/**
+ * Test class for small Java methods compiled to HSAIL kernels.
+ */
+public class BasicHSAILTest extends GraalCompilerTest {
+
+    public void testAdd() {
+        test("testAddSnippet");
+    }
+
+    public static int testAddSnippet(int a) {
+        return a * a;
+    }
+
+    public void testArrayConstantIndex() {
+        test("testArrayReturnFirstElement");
+    }
+
+    public void testArrayVariableIndex() {
+        test("testArrayReturnIthElement");
+    }
+
+    public void testArrayMultiplyConstant() {
+        test("testArrayMultiplyZero");
+    }
+
+    public void testArrayMultiplyVar() {
+        test("testArrayMultiplyGid");
+    }
+
+    public void testArrayMisc() {
+        test("testArrayLocalVariable");
+    }
+
+    public void testArrayLoopVar() {
+        test("testArrayMultiplyGidLoop");
+    }
+
+    void setupPalette(int[] in) {
+        for (int i = 0; i < in.length; i++) {
+            in[i] = i;
+        }
+    }
+
+    public void testNBody() {
+        test("nBodySpill");
+    }
+
+    public void testArrayMandel() {
+        final int width = 768;
+        final int height = width;
+        int loopiterations = 1;
+        int counter = 0;
+        final int range = width * height;
+        int[] rgb = new int[range];
+        int[] palette = new int[range];
+        setupPalette(palette);
+        while (counter < loopiterations) {
+            for (int gid = 0; gid < range; gid++) {
+                testMandelSimple(rgb, palette, -1.0f, 0.0f, 3f, gid);
+            }
+            counter++;
+        }
+        test("testMandelSimple");
+    }
+
+    public void testDanglingElse() {
+        test("danglingElse");
+    }
+
+    public void testIntSquaresTernary() {
+        test("intSquaresTernary");
+    }
+
+    public void testDanglingElse2() {
+        test("danglingElse2");
+    }
+
+    public void testDanglingElse3() {
+        test("danglingElse3");
+    }
+
+    public void testSimpleIf() {
+        test("simpleIf");
+    }
+
+    public void testParams11() {
+        test("testParams1");
+    }
+
+    public void testParams21() {
+        test("testParams2");
+    }
+
+    public void testParams31() {
+        test("testParams3");
+    }
+
+    public void testAssignment1() {
+        test("testAssignment");
+    }
+
+    public void testArithmetic1() {
+        test("testArithmetic");
+    }
+
+    public void testSimpleWhile1() {
+        test("testSimpleWhile");
+    }
+
+    public void testComplexWhile1() {
+        test("testComplexWhile");
+    }
+
+    public void testSquaresThree() {
+        test("testMulThreeArrays");
+    }
+
+    @Test
+    public void testCondMoves() {
+        test("testMinI");
+        test("testMinF");
+    }
+
+    public int testMinI(int a, int b) {
+        return (a < b ? 1 : 2);
+    }
+
+    public float testMinF(int a, int b) {
+        return (a < b ? 1.0f : 2.0f);
+    }
+
+    public static void testMulThreeArrays(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = ina[gid] * inb[gid];
+    }
+
+    public static int testArrayMultiplyZero(int[] array1, int[] array2) {
+        return array1[0] = array2[0] * array2[0];
+    }
+
+    public static int testArrayMultiplyGid(int[] array1, int[] array2, int gid) {
+        return array1[gid] = array2[gid] * array2[gid];
+    }
+
+    public static float testParams3(float c, float d, float e) {
+        return c + d + e;
+    }
+
+    public static int testAssignment() {
+        final int width = 768;
+        final int height = 768;
+        final int maxIterations = 64;
+        return width * height * maxIterations;
+    }
+
+    public static int testSimpleWhile(int i) {
+        int count = 0;
+        int j = 0;
+        final int maxIterations = 64;
+        while (count < maxIterations) {
+            j += count * i;
+            count++;
+        }
+        return j;
+    }
+
+    public static void testComplexWhile() {
+        float lx = 1;
+        float ly = 2;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+        final int maxIterations = 64;
+        int count = 0;
+        while (count < maxIterations && zx * zx + zy * zy < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+    }
+
+    public static void testMandel(int[] rgb, int[] pallette, float xoffset, float yoffset, float scale, int gid) {
+        final int width = 768;
+        final int height = 768;
+        final int maxIterations = 64;
+        float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
+        float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
+        int count = 0;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+        /**
+         * Iterate until the algorithm converges or until maxIterations are reached.
+         */
+        while (count < maxIterations && zx * zx + zy * zy < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+        rgb[gid] = pallette[count];
+    }
+
+    public static void testMandelSimple(int[] rgb, int[] pallette, float xoffset, float yoffset, float scale, int gid) {
+        final int width = 768;
+        final int height = width;
+        final int maxIterations = 64;
+        float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
+        float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
+        int count = 0;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+        /**
+         * Iterate until the algorithm converges or until maxIterations are reached.
+         */
+        while (count < maxIterations && zx * zx + zy * zy < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+        rgb[gid] = pallette[count];
+    }
+
+    public static void testMandel2(int[] rgb, int[] pallette, int xoffseti, int yoffseti, int scalei, int gid) {
+        final int width = 768;
+        final int height = 768;
+        final int maxIterations = 64;
+        float xoffset = xoffseti;
+        float yoffset = yoffseti;
+        float scale = scalei;
+        float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
+        float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
+        int count = 0;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+        /**
+         * Iterate until the algorithm converges or until maxIterations are reached.
+         */
+        while (count < maxIterations && zx * zx + zy * zy < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+        rgb[gid] = pallette[count];
+    }
+
+    public static int testArrayLocalVariable(int gid, int[] array) {
+        int foo = 198;
+        return array[gid + foo];
+    }
+
+    public static int testArrayReturnFirstElement(int[] array) {
+        return array[0];
+    }
+
+    public static int testArrayReturnIthElement(int i, int[] array) {
+        return array[i];
+    }
+
+    public static void simpleIf(int[] out, int[] in, int gid) {
+        if (gid > 9) {
+            out[gid] = in[gid] * in[gid];
+        }
+    }
+
+    public static int danglingElse(int a) {
+        return (a > 5) ? (a + 7) : (a - 3);
+    }
+
+    public static int danglingElse2(int a, int b) {
+        if (a > 5) {
+            return (a + 7 * (b - 4 + a));
+        } else {
+            return (a - 3 + b * 3 * a + 5);
+        }
+    }
+
+    public static int danglingElse3(int a, int b) {
+        int val;
+        if (a > 5) {
+            val = (a + 7 * (b - 4 + a));
+        } else {
+            val = (a - 3 + b * 3 * a + 5);
+        }
+        return val + a;
+    }
+
+    public static void intSquaresTernary(int[] out, int[] in, int gid) {
+        int val = in[gid] * in[gid];
+        val = (val % 2 == 1 ? val + 1 : val);
+        out[gid] = val;
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph);
+        compResult.dumpCompilationResult();
+    }
+
+    public static void nBodySpill(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) {
+        final int bodies = 8;
+        final float delT = .005f;
+        final float espSqr = 1.0f;
+        final float mass = 5f;
+        final int count = bodies * 3;
+        final int globalId = gid * 3;
+        float accx = 0.f;
+        float accy = 0.f;
+        float accz = 0.f;
+        for (int i = 0; i < count; i += 3) {
+            final float dx = inxyz[i + 0] - inxyz[globalId + 0];
+            final float dy = inxyz[i + 1] - inxyz[globalId + 1];
+            final float dz = inxyz[i + 2] - inxyz[globalId + 2];
+            final float invDist = (float) (1.0 / (Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr)));
+            accx += mass * invDist * invDist * invDist * dx;
+            accy += mass * invDist * invDist * invDist * dy;
+            accz += mass * invDist * invDist * invDist * dz;
+        }
+        accx *= delT;
+        accy *= delT;
+        accz *= delT;
+        outxyz[globalId + 0] = inxyz[globalId + 0] + (invxyz[globalId + 0] * delT) + (accx * .5f * delT);
+        outxyz[globalId + 1] = inxyz[globalId + 1] + (invxyz[globalId + 1] * delT) + (accy * .5f * delT);
+        outxyz[globalId + 2] = inxyz[globalId + 2] + (invxyz[globalId + 2] * delT) + (accz * .5f * delT);
+        outvxyz[globalId + 0] = invxyz[globalId + 0] + accx;
+        outvxyz[globalId + 1] = invxyz[globalId + 1] + accy;
+        outvxyz[globalId + 2] = invxyz[globalId + 2] + accz;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/CallTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Tests direct method calls.
+ */
+public class CallTest extends GraalKernelTester {
+
+    static final int width = 768;
+    static final int height = width;
+    private int iterations = 100;
+    static final int range = width * height;
+    @Result public float[] inArray = new float[range];
+
+    public static int foo(int gid, int i) {
+        if (gid < 25) {
+            return gid * i;
+        } else {
+            return gid - i;
+        }
+    }
+
+    public void run(float[] inArray1, int gid) {
+        for (int i = 0; i < iterations; i++) {
+            inArray1[gid] = foo(gid, i);
+        }
+    }
+
+    @Override
+    public void runTest() {
+        dispatchMethodKernel(range, inArray);
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FcompUnorderedTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,90 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+/**
+ * This was a version of Mandel Test that happened to generate a Nan and so was useful for testing
+ * ordered and unordered comparison. However, we should probably replace this with a test (or set of
+ * tests) that is more focussed on Nan and comparisons.
+ */
+public class FcompUnorderedTest extends GraalKernelTester {
+
+    static final int initialWidth = 5;
+    static final int initialHeight = initialWidth;
+    static final int range = 25;
+    @Result private int[] rgb = new int[range];
+    private float[] lxresult = new float[range];
+
+    public static void run(int[] rgb, float xoffset, float yoffset, float scale, int gid) {
+        final int width = initialWidth;
+        final int height = initialHeight;
+        final int maxIterations = 64;
+        float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
+        float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
+        int count = 0;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+        /**
+         * Iterate until the algorithm converges or until maxIterations are reached.
+         */
+        while (count < maxIterations && zx < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+        rgb[gid] = count;
+    }
+
+    void setupPalette(int[] in) {
+        for (int i = 0; i < in.length; i++) {
+            in[i] = i;
+        }
+    }
+
+    @Override
+    public void runTest() {
+        int[] palette = new int[256];
+        setupPalette(palette);
+        for (int i = 0; i < range; i++) {
+            lxresult[i] = -1;
+        }
+        /*
+         * Call it for a range, specifying testmethod args (but not the fields it uses or the gid
+         * argument).
+         */
+        dispatchMethodKernel(range, rgb, 1.0f, 1.0f, 1.0f);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatConvertTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+import org.junit.*;
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Tests floating point comparison.
+ */
+public class FloatConvertTest extends GraalKernelTester {
+
+    static final int size = 128;
+    static final float[] inputFloat = new float[size];
+    static final double[] inputDouble = new double[size];
+    @Result static final float[] outputFloat = new float[size];
+    @Result static final double[] outputDouble = new double[size];
+    static float[] seedFloat = new float[size];
+    {
+        for (int i = 0; i < seedFloat.length; i++) {
+            seedFloat[i] = (float) Math.random();
+        }
+    }
+    static double[] seedDouble = new double[size];
+    {
+        for (int i = 0; i < seedDouble.length; i++) {
+            seedDouble[i] = Math.random();
+        }
+    }
+
+    public static void run(float[] inFloat, double[] inDouble, float[] outFloat, double[] outDouble, int gid) {
+        outFloat[gid] = (float) inDouble[gid];
+        outDouble[gid] = inFloat[gid];
+    }
+
+    @Override
+    public void runTest() {
+        System.arraycopy(seedDouble, 0, inputDouble, 0, seedDouble.length);
+        Arrays.fill(outputDouble, 0f);
+        System.arraycopy(seedFloat, 0, inputFloat, 0, seedFloat.length);
+        Arrays.fill(outputFloat, 0f);
+        dispatchMethodKernel(64, inputFloat, inputDouble, outputFloat, outputDouble);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatDivPrecisionTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.hsail.test;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+import org.junit.Test;
+
+/**
+ * This test (originally derived from a discrepancy seen in Mandel) showed a difference in the
+ * division answers when run on Bonaire hardware (compared to Java).
+ */
+public class FloatDivPrecisionTest extends GraalKernelTester {
+
+    static final int width = 768;
+    static final int height = width;
+    static final int range = width * height;
+    @Result private float[] floatResult = new float[range];
+
+    public static void run(float[] floatOut, int gid) {
+        floatOut[gid] = gid / (float) width;
+    }
+
+    @Override
+    public void runTest() {
+        dispatchMethodKernel(range, floatResult);
+
+    }
+
+    /**
+     * Allows subclass to override what FP equality means for this particular unit test.
+     * 
+     */
+    @Override
+    public boolean isEqualsFP(double first, double second) {
+        return Math.abs(first - second) == 0;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+import org.junit.*;
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Tests floating point square root.
+ */
+public class FloatSqrtTest extends GraalKernelTester {
+
+    static final int size = 128;
+    static final float[] input = new float[size];
+    @Result static final float[] output = new float[size];
+    static float[] seed = new float[size];
+    {
+        for (int i = 0; i < seed.length; i++) {
+            seed[i] = (float) Math.random();
+        }
+
+    }
+
+    public static void run(float[] input1, float[] output1, int gid) {
+        output1[gid] = (float) Math.sqrt(input1[gid]);
+    }
+
+    @Override
+    public void runTest() {
+        System.arraycopy(seed, 0, input, 0, seed.length);
+        Arrays.fill(output, 0f);
+        dispatchMethodKernel(64, input, output);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntAddIndexTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests array element addition.
+ */
+public class IntAddIndexTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        int outIdx = gid + ina[0] - 1;
+        out[outIdx] = ina[gid] + inb[gid];
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntAddTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests integer addition.
+ */
+public class IntAddTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = ina[gid] + inb[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntDivTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests integer division.
+ */
+public class IntDivTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param ina
+     * @param inb
+     * @param gid
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = inb[gid] / ina[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntDoubledTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,48 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests doubling an integer value.
+ */
+public class IntDoubledTest extends StaticMethodTwoIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param in
+     * @param gid
+     */
+    public static void run(int[] out, int[] in, int gid) {
+        out[gid] = in[gid] + in[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntFloatConvertTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+/**
+ * Tests integer to float conversion.
+ */
+public class IntFloatConvertTest extends GraalKernelTester {
+
+    static final int size = 128;
+    static final int[] inputInt = new int[size];
+    static final double[] inputDouble = new double[size];
+    @Result static final int[] outputInt = new int[size];
+    @Result static final double[] outputDouble = new double[size];
+    static int[] seedInt = new int[size];
+    {
+        for (int i = 0; i < seedInt.length; i++) {
+            seedInt[i] = (int) Math.random();
+        }
+    }
+    static double[] seedDouble = new double[size];
+    {
+        for (int i = 0; i < seedDouble.length; i++) {
+            seedDouble[i] = Math.random();
+        }
+    }
+
+    public static void run(int[] inInt, double[] inDouble, int[] outInt, double[] outDouble, int gid) {
+        outInt[gid] = (int) inDouble[gid];
+        outDouble[gid] = inInt[gid];
+    }
+
+    @Override
+    public void runTest() {
+        System.arraycopy(seedDouble, 0, inputDouble, 0, seedDouble.length);
+        Arrays.fill(outputDouble, 0);
+        System.arraycopy(seedInt, 0, inputInt, 0, seedInt.length);
+        Arrays.fill(outputInt, 0);
+        dispatchMethodKernel(64, inputInt, inputDouble, outputInt, outputDouble);
+    }
+
+    public void test() {
+        super.testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntLongConvertTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+import org.junit.*;
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Tests integer to long conversion.
+ */
+public class IntLongConvertTest extends GraalKernelTester {
+
+    static final int size = 128;
+    static final int[] inputInt = new int[size];
+    static final long[] inputLong = new long[size];
+    @Result static final int[] outputInt = new int[size];
+    @Result static final long[] outputLong = new long[size];
+    static int[] seedInt = new int[size];
+    {
+        for (int i = 0; i < seedInt.length; i++) {
+            seedInt[i] = (int) Math.random();
+        }
+    }
+    static long[] seedLong = new long[size];
+    {
+        for (int i = 0; i < seedLong.length; i++) {
+            seedLong[i] = (long) Math.random();
+        }
+    }
+
+    public static void run(int[] inInt, long[] inLong, int[] outInt, long[] outLong, int gid) {
+        outInt[gid] = (int) inLong[gid];
+        outLong[gid] = inInt[gid];
+    }
+
+    @Override
+    public void runTest() {
+        System.arraycopy(seedLong, 0, inputLong, 0, seedLong.length);
+        Arrays.fill(outputLong, 0);
+        System.arraycopy(seedInt, 0, inputInt, 0, seedInt.length);
+        Arrays.fill(outputInt, 0);
+        dispatchMethodKernel(64, inputInt, inputLong, outputInt, outputLong);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntModTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests modulo operation.
+ */
+public class IntModTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param ina
+     * @param inb
+     * @param gid
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = inb[gid] % ina[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntMulTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests array multiplication.
+ */
+public class IntMulTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param ina
+     * @param inb
+     * @param gid
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = ina[gid] * inb[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSqrAddTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests array addition and multiplication.
+ */
+public class IntSqrAddTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param ina
+     * @param inb
+     * @param gid
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = (ina[gid] * ina[gid]) + inb[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSquaredGidCmpTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests comparison operation and array multiplication.
+ */
+public class IntSquaredGidCmpTest extends StaticMethodTwoIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter
+     * 
+     * @param out
+     * @param in
+     * @param gid
+     */
+    public static void run(int[] out, int[] in, int gid) {
+        if (gid > 9) {
+            out[gid] = in[gid] * in[gid];
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSquaredTernaryTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests conditionals, modulo arithmetic, and addition and multiplications.
+ */
+public class IntSquaredTernaryTest extends StaticMethodTwoIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param in
+     * @param gid
+     */
+    public static void run(int[] out, int[] in, int gid) {
+        int val = in[gid] * in[gid];
+        val = (val % 2 == 1 ? val + 1 : val);
+        out[gid] = val;
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSquaredTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,48 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests squaring an array element.
+ */
+public class IntSquaredTest extends StaticMethodTwoIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param in
+     * @param gid
+     */
+    public static void run(int[] out, int[] in, int gid) {
+        out[gid] = in[gid] * in[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSubTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests subtracting one array element from another.
+ */
+public class IntSubTest extends StaticMethodThreeIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param ina
+     * @param inb
+     * @param gid
+     */
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = ina[gid] - inb[gid];
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSumArrayTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests iteratively summing the elements of an array.
+ */
+public class IntSumArrayTest extends StaticMethodTwoIntArrays {
+
+    /**
+     * The static "kernel" method we will be testing. By convention the gid is the last parameter.
+     * 
+     * @param out
+     * @param in
+     * @param gid
+     */
+    public static void run(int[] out, int[] in, int gid) {
+        int sum = 0;
+        for (int n : in) {
+            sum += n;
+        }
+        out[gid] = sum;
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticDoubleSpillTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,126 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+import org.junit.Test;
+
+/**
+ * Tests the spilling of double variables into memory.
+ */
+public class StaticDoubleSpillTest extends GraalKernelTester {
+
+    static final int size = 100;
+    private double[] in = new double[size * 400];
+    @Result private double[] out = new double[size * 400];
+
+    public static void run(double[] out, double[] in, int gid) {
+        int id = gid;
+        int step = 20;
+        double sum0;
+        double sum1;
+        double sum2;
+        double sum3;
+        double sum4;
+        double sum5;
+        double sum6;
+        double sum7;
+        double sum8;
+        double sum9;
+        double sum10;
+        double sum11;
+        double sum12;
+        double sum13;
+        double sum14;
+        double sum15;
+        double sum16;
+        double sum17;
+        double sum18;
+        double sum19;
+        sum0 = sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = sum7 = sum8 = sum9 = 0;
+        sum10 = sum11 = sum12 = sum13 = sum14 = sum15 = sum16 = sum17 = sum18 = sum19 = 0;
+        for (int i = 0; i < size; i += step) {
+            sum0 += in[i + 0];
+            sum1 += in[i + 1];
+            sum2 += in[i + 2];
+            sum3 += in[i + 3];
+            sum4 += in[i + 4];
+            sum5 += in[i + 5];
+            sum6 += in[i + 6];
+            sum7 += in[i + 7];
+            sum8 += in[i + 8];
+            sum9 += in[i + 9];
+            sum10 += in[i + 0];
+            sum11 += in[i + 1];
+            sum12 += in[i + 2];
+            sum13 += in[i + 3];
+            sum14 += in[i + 4];
+            sum15 += in[i + 5];
+            sum16 += in[i + 6];
+            sum17 += in[i + 7];
+            sum18 += in[i + 8];
+            sum19 += in[i + 9];
+        }
+        out[id * step + 0] = sum0;
+        out[id * step + 1] = sum1;
+        out[id * step + 2] = sum2;
+        out[id * step + 3] = sum3;
+        out[id * step + 4] = sum4;
+        out[id * step + 5] = sum5;
+        out[id * step + 6] = sum6;
+        out[id * step + 7] = sum7;
+        out[id * step + 8] = sum8;
+        out[id * step + 9] = sum9;
+        out[id * step + 10] = sum10;
+        out[id * step + 11] = sum11;
+        out[id * step + 12] = sum12;
+        out[id * step + 13] = sum13;
+        out[id * step + 14] = sum14;
+        out[id * step + 15] = sum15;
+        out[id * step + 16] = sum16;
+        out[id * step + 17] = sum17;
+        out[id * step + 18] = sum18;
+        out[id * step + 19] = sum19;
+    }
+
+    @Override
+    public void runTest() {
+        /**
+         * Call it for a range, specifying testmethod args (but not the fields it uses or the gid
+         * argument).
+         * 
+         */
+        Arrays.fill(out, 0f);
+        Arrays.fill(in, 0f);
+        dispatchMethodKernel(size, out, in);
+    }
+
+    // Marked to only run on hardware until simulator spill bug is fixed.
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticIntSpillTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,95 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+import org.junit.Test;
+
+/**
+ * Tests the spilling of integers into memory.
+ */
+public class StaticIntSpillTest extends GraalKernelTester {
+
+    static final int size = 100;
+    private int[] in = new int[size * 400];
+    @Result private int[] out = new int[size * 400];
+
+    public static void run(int[] out, int[] in, int gid) {
+        int id = gid;
+        int step = 20;
+        int sum0;
+        int sum1;
+        int sum2;
+        int sum3;
+        int sum4;
+        int sum5;
+        int sum6;
+        int sum7;
+        int sum8;
+        int sum9;
+        sum0 = sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = sum7 = sum8 = sum9 = 0;
+        for (int i = 0; i < size; i += step) {
+            sum0 += in[i + 0];
+            sum1 += in[i + 1];
+            sum2 += in[i + 2];
+            sum3 += in[i + 3];
+            sum4 += in[i + 4];
+            sum5 += in[i + 5];
+            sum6 += in[i + 6];
+            sum7 += in[i + 7];
+            sum8 += in[i + 8];
+            sum9 += in[i + 9];
+        }
+        out[id * step + 0] = sum0;
+        out[id * step + 1] = sum1;
+        out[id * step + 2] = sum2;
+        out[id * step + 3] = sum3;
+        out[id * step + 4] = sum4;
+        out[id * step + 5] = sum5;
+        out[id * step + 6] = sum6;
+        out[id * step + 7] = sum7;
+        out[id * step + 8] = sum8;
+        out[id * step + 9] = sum9;
+    }
+
+    @Override
+    public void runTest() {
+        /**
+         * Call it for a range, specifying testmethod args (but not the fields it uses or the gid
+         * argument).
+         * 
+         */
+        Arrays.fill(out, 0);
+        Arrays.fill(in, 0);
+        dispatchMethodKernel(size, out, in);
+    }
+
+    // Marked to only run on hardware until simulator spill bug is fixed.
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,84 @@
+/*
+ * 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.hsail.test;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+import org.junit.Test;
+
+/**
+ * Unit test that simulates the Mandelbrot application. The run method here is a static method
+ * version of the original mandel kernel and the invoke parameters are for the starting point of the
+ * mandel demo. Note: this will likely not pass the junit test on real hardware, but should pass on
+ * the simulator.
+ */
+public class StaticMandelTest extends GraalKernelTester {
+
+    static final int initWidth = 768;
+    static final int initHeight = initWidth;
+    static final int maxIterations = 64;
+    static final int range = initWidth * initHeight;
+    @Result private int[] rgb = new int[range];
+
+    public static void run(int[] rgb, int[] pallette, float xoffset, float yoffset, float scale, int gid) {
+        final int width = initWidth;
+        final int height = initHeight;
+        float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
+        float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
+        int count = 0;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+
+        // Iterate until the algorithm converges or until maxIterations are reached.
+        while (count < maxIterations && zx * zx + zy * zy < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+        rgb[gid] = pallette[count];
+    }
+
+    void setupPalette(int[] in) {
+        for (int i = 0; i < in.length; i++) {
+            in[i] = i;
+        }
+    }
+
+    @Override
+    public void runTest() {
+        int[] palette = new int[256];
+        setupPalette(palette);
+        /**
+         * Call it for a range, specifying testmethod args (but not the fields it uses or the gid
+         * argument).
+         */
+        dispatchMethodKernel(range, rgb, palette, -1f, 0f, 3f);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests the addition of elements from sixteen input arrays.
+ */
+public class StaticMethod16InArraysTest extends StaticMethodTwoIntArrays {
+
+    @Override
+    void setupArrays(int[] in) {
+        for (int i = 0; i < num; i++) {
+            in[i] = i;
+            outArray[i] = -i;
+        }
+    }
+
+    public static void run(int[] out, int[] ina, int[] inb, int[] inc, int[] ind, int[] ine, int[] inf, int[] ing, int[] inh, int[] ini, int[] inj, int[] ink, int[] inl, int[] inm, int[] inn,
+                    int[] ino, int[] inp, int gid) {
+        out[gid] = ina[gid] + inb[gid] + inc[gid] + ind[gid] + ine[gid] + inf[gid] + ing[gid] + inh[gid] + ini[gid] + inj[gid] + ink[gid] + inl[gid] + inm[gid] + inn[gid] + ino[gid] + inp[gid];
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray = new int[num];
+        setupArrays(inArray);
+        /**
+         * DumpArrayParameters(inArray); Call it for a range, specifying testmethod args (but not
+         * the fields it uses or the gid argument). Will put output in outArray.
+         */
+        dispatchMethodKernel(num, outArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray, inArray);
+    }
+
+    /**
+     * This test fails because we don't have correct logic to handle more input parameters than
+     * there are registers.
+     */
+    @Test(expected = java.lang.ClassCastException.class)
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethodThreeIntArrays.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.hsail.test;
+
+/**
+ * Superclass that initializes two input arrays and one output array. Derived by some of the other
+ * test cases that take two arrays as input parameters.
+ */
+public abstract class StaticMethodThreeIntArrays extends StaticMethodTwoIntArrays {
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i + 1;
+            in2[i] = in1[i] + 10;
+            outArray[i] = -i;
+        }
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        /**
+         * DumpArrayParameters(inArray); Call it for a range, specifying testmethod args (but not
+         * the fields it uses or the gid argument). Will put output in outArray.
+         */
+        dispatchMethodKernel(num, outArray, inArray1, inArray2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethodTwoIntArrays.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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.hsail.test;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Superclass that initializes one input array and one output array. Derived by some of the other
+ * test cases that take one array as input and write to an output array.
+ */
+public abstract class StaticMethodTwoIntArrays extends GraalKernelTester {
+
+    static final int num = 20;
+    @Result protected int[] outArray = new int[num];
+
+    void setupArrays(int[] in) {
+        for (int i = 0; i < num; i++) {
+            in[i] = i;
+            outArray[i] = -i;
+        }
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray = new int[num];
+        setupArrays(inArray);
+        /**
+         * DumpArrayParameters(inArray); Call it for a range, specifying testmethod args (but not
+         * the fields it uses or the gid argument). Will put output in outArray.
+         */
+        dispatchMethodKernel(num, outArray, inArray);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,104 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * This version of NBody causes Graal to generate register spilling code.
+ */
+public class StaticNBodySpillTest extends GraalKernelTester {
+
+    static final int bodies = 5;
+    static final float delT = .005f;
+    static final float espSqr = 1.0f;
+    static final float mass = 5f;
+    static final int width = 768;
+    static final int height = 768;
+    // Positions xy and z of bodies.
+    @Result private float[] inxyz = new float[bodies * 3];
+    // Positions xy and z of bodies.
+    @Result private float[] outxyz = new float[bodies * 3]; // positions xy and z of bodies
+    // Velocity component of x,y and z of bodies.
+    @Result private float[] invxyz = new float[bodies * 3];
+    @Result private float[] outvxyz = new float[bodies * 3];
+    static float[] seedxyz = new float[bodies * 3];
+    {
+        final float maxDist = width / 4;
+        for (int body = 0; body < (bodies * 3); body += 3) {
+            final float theta = (float) (Math.random() * Math.PI * 2);
+            final float phi = (float) (Math.random() * Math.PI * 2);
+            final float radius = (float) (Math.random() * maxDist);
+            seedxyz[body + 0] = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2;
+            seedxyz[body + 1] = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2;
+            seedxyz[body + 2] = (float) (radius * Math.cos(phi));
+        }
+    }
+
+    public static void run(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) {
+        final int count = bodies * 3;
+        final int globalId = gid * 3;
+        float accx = 0.f;
+        float accy = 0.f;
+        float accz = 0.f;
+        for (int i = 0; i < count; i += 3) {
+            final float dx = inxyz[i + 0] - inxyz[globalId + 0];
+            final float dy = inxyz[i + 1] - inxyz[globalId + 1];
+            final float dz = inxyz[i + 2] - inxyz[globalId + 2];
+            final float invDist = (float) (1.0 / (Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr)));
+            accx += mass * invDist * invDist * invDist * dx;
+            accy += mass * invDist * invDist * invDist * dy;
+            accz += mass * invDist * invDist * invDist * dz;
+        }
+        accx *= delT;
+        accy *= delT;
+        accz *= delT;
+        outxyz[globalId + 0] = inxyz[globalId + 0] + (invxyz[globalId + 0] * delT) + (accx * .5f * delT);
+        outxyz[globalId + 1] = inxyz[globalId + 1] + (invxyz[globalId + 1] * delT) + (accy * .5f * delT);
+        outxyz[globalId + 2] = inxyz[globalId + 2] + (invxyz[globalId + 2] * delT) + (accz * .5f * delT);
+        outvxyz[globalId + 0] = invxyz[globalId + 0] + accx;
+        outvxyz[globalId + 1] = invxyz[globalId + 1] + accy;
+        outvxyz[globalId + 2] = invxyz[globalId + 2] + accz;
+    }
+
+    @Override
+    public void runTest() {
+        System.arraycopy(seedxyz, 0, inxyz, 0, seedxyz.length);
+        Arrays.fill(outxyz, 0f);
+        Arrays.fill(outvxyz, 0f);
+        Arrays.fill(invxyz, 0f);
+        dispatchMethodKernel(bodies, inxyz, outxyz, invxyz, outvxyz);
+    }
+
+    // Marked to only run on hardware until simulator spill bug is fixed.
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,101 @@
+/*
+ * 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.hsail.test;
+
+import java.util.*;
+
+import org.junit.*;
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Unit test of NBody demo app.
+ */
+public class StaticNBodyTest extends GraalKernelTester {
+
+    static final int bodies = 1024;
+    static final float delT = .005f;
+    static final float espSqr = 1.0f;
+    static final float mass = 5f;
+    static final int width = 768;
+    static final int height = 768;
+    // Positions xy and z of bodies.
+    @Result private float[] inxyz = new float[bodies * 3];
+    // Positions xy and z of bodies.
+    @Result private float[] outxyz = new float[bodies * 3];
+    // Velocity component of x,y and z of bodies.
+    @Result private float[] invxyz = new float[bodies * 3];
+    @Result private float[] outvxyz = new float[bodies * 3];
+    static float[] seedxyz = new float[bodies * 3];
+    {
+        final float maxDist = width / 4;
+        for (int body = 0; body < (bodies * 3); body += 3) {
+            final float theta = (float) (Math.random() * Math.PI * 2);
+            final float phi = (float) (Math.random() * Math.PI * 2);
+            final float radius = (float) (Math.random() * maxDist);
+            seedxyz[body + 0] = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2;
+            seedxyz[body + 1] = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2;
+            seedxyz[body + 2] = (float) (radius * Math.cos(phi));
+        }
+    }
+
+    public static void run(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) {
+        final int count = bodies * 3;
+        final int globalId = gid * 3;
+        float accx = 0.f;
+        float accy = 0.f;
+        float accz = 0.f;
+        for (int i = 0; i < count; i += 3) {
+            final float dx = inxyz[i + 0] - inxyz[globalId + 0];
+            final float dy = inxyz[i + 1] - inxyz[globalId + 1];
+            final float dz = inxyz[i + 2] - inxyz[globalId + 2];
+            final float invDist = (float) (1.0 / (Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr)));
+            accx += mass * invDist * invDist * invDist * dx;
+            accy += mass * invDist * invDist * invDist * dy;
+            accz += mass * invDist * invDist * invDist * dz;
+        }
+        accx *= delT;
+        accy *= delT;
+        accz *= delT;
+        outxyz[globalId + 0] = inxyz[globalId + 0] + (invxyz[globalId + 0] * delT) + (accx * .5f * delT);
+        outxyz[globalId + 1] = inxyz[globalId + 1] + (invxyz[globalId + 1] * delT) + (accy * .5f * delT);
+        outxyz[globalId + 2] = inxyz[globalId + 2] + (invxyz[globalId + 2] * delT) + (accz * .5f * delT);
+        outvxyz[globalId + 0] = invxyz[globalId + 0] + accx;
+        outvxyz[globalId + 1] = invxyz[globalId + 1] + accy;
+        outvxyz[globalId + 2] = invxyz[globalId + 2] + accz;
+    }
+
+    @Override
+    public void runTest() {
+        System.arraycopy(seedxyz, 0, inxyz, 0, seedxyz.length);
+        Arrays.fill(outxyz, 0f);
+        Arrays.fill(outvxyz, 0f);
+        Arrays.fill(invxyz, 0f);
+        dispatchMethodKernel(bodies, inxyz, outxyz, invxyz, outvxyz);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/CompileAndDispatch.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,35 @@
+/*
+ * 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.graal.compiler.hsail;
+
+/**
+ * Interface for compiling a Java program to HSAIL and dispatching execution to the GPU or an HSAIL
+ * simulator.
+ */
+public interface CompileAndDispatch {
+
+    Object createKernel(Class<?> consumerClass);
+
+    boolean dispatchKernel(Object kernel, int jobSize, Object[] args);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,137 @@
+/*
+ * 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.graal.compiler.hsail;
+
+import com.oracle.graal.api.code.CompilationResult;
+import java.lang.reflect.Method;
+
+import com.amd.okra.OkraContext;
+import com.amd.okra.OkraKernel;
+import com.oracle.graal.hotspot.HotSpotGraalRuntime;
+import com.oracle.graal.hotspot.HotSpotVMConfig;
+import com.oracle.graal.hotspot.amd64.AMD64HotSpotRuntime;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.Graal;
+import com.oracle.graal.java.GraphBuilderConfiguration;
+import com.oracle.graal.java.GraphBuilderPhase;
+import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.nodes.java.MethodCallTargetNode;
+import com.oracle.graal.nodes.spi.Replacements;
+import com.oracle.graal.phases.OptimisticOptimizations;
+import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.compiler.target.Backend;
+import com.oracle.graal.nodes.spi.GraalCodeCacheProvider;
+import com.oracle.graal.debug.*;
+
+/**
+ * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
+ * JDK interception code that offloads to the GPU.
+ */
+public class ForEachToGraal implements CompileAndDispatch {
+
+    protected final GraalCodeCacheProvider runtime;
+    protected final Replacements replacements;
+    protected final Backend backend;
+
+    public ForEachToGraal() {
+        this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        this.replacements = Graal.getRequiredCapability(Replacements.class);
+        this.backend = Graal.getRequiredCapability(Backend.class);
+    }
+
+    private static CompilationResult getCompiledLambda(Class consumerClass) {
+        /**
+         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
+         * that accept will call.
+         */
+        Method[] icMethods = consumerClass.getMethods();
+        Method acceptMethod = null;
+        for (Method m : icMethods) {
+            if (m.getName().equals("accept") && acceptMethod == null) {
+                acceptMethod = m;
+            }
+        }
+        HotSpotVMConfig config = HotSpotGraalRuntime.graalRuntime().getConfig();
+        AMD64HotSpotRuntime hsruntime = new AMD64HotSpotRuntime(config, HotSpotGraalRuntime.graalRuntime());
+        ResolvedJavaMethod rm = hsruntime.lookupJavaMethod(acceptMethod);
+        StructuredGraph graph = new StructuredGraph(rm);
+        new GraphBuilderPhase(hsruntime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        NodeIterable<Node> nin = graph.getNodes();
+        ResolvedJavaMethod lambdaMethod = null;
+        for (Node n : nin) {
+            if (n instanceof MethodCallTargetNode) {
+                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
+                Debug.log("target ... " + lambdaMethod);
+                break;
+            }
+        }
+        if (lambdaMethod == null) {
+            // Did not find call in Consumer.accept.
+            Debug.log("Should not Reach here, did not find call in accept()");
+            return null;
+        }
+        // Now that we have the target lambda, compile it.
+        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
+        if (hsailCompResult != null) {
+            hsailCompResult.dumpCompilationResult();
+        }
+        return hsailCompResult.getCompilationResult();
+    }
+
+    // Implementations of the CompileAndDispatch interface.
+    @Override
+    public Object createKernel(Class<?> consumerClass) {
+        try {
+            CompilationResult result = getCompiledLambda(consumerClass);
+            if (result != null) {
+                String code = new String(new String(result.getTargetCode(), 0, result.getTargetCodeSize()));
+                OkraContext okraContext = new OkraContext();
+                OkraKernel okraKernel = new OkraKernel(okraContext, code, "&run");
+                if (okraKernel.isValid()) {
+                    return okraKernel;
+                }
+            }
+        } catch (Throwable e) {
+            // Note: Graal throws Errors. We want to revert to regular Java in these cases.
+            Debug.log("WARNING:Graal compilation failed.");
+            e.printStackTrace();
+            return null;
+        }
+        // If we got this far, return null.
+        return null;
+    }
+
+    @Override
+    public boolean dispatchKernel(Object kernel, int jobSize, Object[] args) {
+        if (!(kernel instanceof OkraKernel)) {
+            Debug.log("unknown kernel for dispatchKernel");
+            return false;
+        }
+        OkraKernel okraKernel = (OkraKernel) kernel;
+        okraKernel.setLaunchAttributes(jobSize);
+        int status = okraKernel.dispatchWithArgs(args);
+        return (status == 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.hsail.*;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+
+/**
+ * HSAIL specific backend.
+ */
+public class HSAILBackend extends Backend {
+
+    private Map<String, String> paramTypeMap = new HashMap<>();
+    private Buffer codeBuffer;
+
+    public HSAILBackend(CodeCacheProvider runtime, TargetDescription target) {
+        super(runtime, target);
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<int>", "s32");
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<float>", "f32");
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<double>", "f64");
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<long>", "s64");
+    }
+
+    @Override
+    public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        return new HSAILLIRGenerator(graph, runtime(), target, frameMap, cc, lir);
+    }
+
+    public String getPartialCodeString() {
+        return (codeBuffer == null ? "" : new String(codeBuffer.copyData(0, codeBuffer.position())));
+    }
+
+    class HotSpotFrameContext implements FrameContext {
+
+        @Override
+        public void enter(TargetMethodAssembler tasm) {
+            Debug.log("Nothing to do here");
+        }
+
+        @Override
+        public void leave(TargetMethodAssembler tasm) {
+            Debug.log("Nothing to do here");
+        }
+    }
+
+    @Override
+    protected AbstractAssembler createAssembler(FrameMap frameMap) {
+        return new HSAILAssembler(target);
+    }
+
+    @Override
+    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
+        FrameMap frameMap = lirGen.frameMap;
+        AbstractAssembler masm = new HSAILAssembler(target);
+        HotSpotFrameContext frameContext = new HotSpotFrameContext();
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        tasm.setFrameSize(frameMap.frameSize());
+        return tasm;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod method) {
+        assert method != null : lirGen.getGraph() + " is not associated with a method";
+        // Emit the prologue.
+        codeBuffer = tasm.asm.codeBuffer;
+        codeBuffer.emitString0("version 0:95: $full : $large;");
+        codeBuffer.emitString("");
+        Signature signature = method.getSignature();
+        int sigParamCount = signature.getParameterCount(false);
+        // We're subtracting 1 because we're not making the final gid as a parameter.
+        int nonConstantParamCount = sigParamCount - 1;
+        boolean isStatic = (Modifier.isStatic(method.getModifiers()));
+        // Determine if this is an object lambda.
+        boolean isObjectLambda = true;
+        if (signature.getParameterType(nonConstantParamCount, null).getKind() == Kind.Int) {
+            isObjectLambda = false;
+        } else {
+            // Add space for gid int reg.
+            nonConstantParamCount++;
+        }
+
+        // If this is an instance method, include mappings for the "this" parameter
+        // as the first parameter.
+        if (!isStatic) {
+            nonConstantParamCount++;
+        }
+        // Add in any "constant" parameters (currently none).
+        int totalParamCount = nonConstantParamCount;
+        JavaType[] paramtypes = new JavaType[totalParamCount];
+        String[] paramNames = new String[totalParamCount];
+        int pidx = 0;
+        for (int i = 0; i < totalParamCount; i++) {
+            if (i == 0 && !isStatic) {
+                paramtypes[i] = runtime().lookupJavaType(Object.class);
+                paramNames[i] = "%_this";
+            } else if (i < nonConstantParamCount) {
+                if (isObjectLambda && (i == (nonConstantParamCount))) {
+                    // Set up the gid register mapping.
+                    paramtypes[i] = runtime().lookupJavaType(int.class);
+                    paramNames[i] = "%_gid";
+                } else {
+                    paramtypes[i] = signature.getParameterType(pidx++, null);
+                    paramNames[i] = "%_arg" + i;
+                }
+            }
+        }
+        codeBuffer.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method);
+        codeBuffer.emitString("");
+        codeBuffer.emitString0("kernel &run (");
+        codeBuffer.emitString("");
+        FrameMap frameMap = tasm.frameMap;
+        RegisterConfig regConfig = frameMap.registerConfig;
+        // Build list of param types which does include the gid (for cc register mapping query).
+        JavaType[] ccParamTypes = new JavaType[nonConstantParamCount + 1];
+        // Include the gid.
+        System.arraycopy(paramtypes, 0, ccParamTypes, 0, nonConstantParamCount);
+        // Last entry comes from the signature.
+        ccParamTypes[ccParamTypes.length - 1] = signature.getParameterType(sigParamCount - 1, null);
+        CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, ccParamTypes, target, false);
+        /**
+         * Compute the hsail size mappings up to but not including the last non-constant parameter
+         * (which is the gid).
+         * 
+         */
+        String[] paramHsailSizes = new String[totalParamCount];
+        for (int i = 0; i < totalParamCount; i++) {
+            String paramtypeStr = paramtypes[i].toString();
+            String sizeStr = paramTypeMap.get(paramtypeStr);
+            // Catch all for any unmapped paramtype that is u64 (address of an object).
+            paramHsailSizes[i] = (sizeStr != null ? sizeStr : "u64");
+        }
+        // Emit the kernel function parameters.
+        for (int i = 0; i < totalParamCount; i++) {
+            String str = "kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
+            if (i != totalParamCount - 1) {
+                str += ",";
+            }
+            codeBuffer.emitString(str);
+        }
+        codeBuffer.emitString(") {");
+
+        /*
+         * End of parameters start of prolog code. Emit the load instructions for loading of the
+         * kernel non-constant parameters into registers. The constant class parameters will not be
+         * loaded up front but will be loaded as needed.
+         */
+        for (int i = 0; i < nonConstantParamCount; i++) {
+            codeBuffer.emitString("ld_kernarg_" + paramHsailSizes[i] + "  " + HSAIL.mapRegister(cc.getArgument(i)) + ", [" + paramNames[i] + "];");
+        }
+
+        /*
+         * Emit the workitemaid instruction for loading the hidden gid parameter. This is assigned
+         * the register as if it were the last of the nonConstant parameters.
+         */
+        String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding());
+        codeBuffer.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
+
+        /*
+         * Note the logic used for this spillseg size is to leave space and then go back and patch
+         * in the correct size once we have generated all the instructions. This should probably be
+         * done in a more robust way by implementing something like codeBuffer.insertString.
+         */
+        int spillsegDeclarationPosition = codeBuffer.position() + 1;
+        String spillsegTemplate = "align 4 spill_u8 %spillseg[123456];";
+        codeBuffer.emitString(spillsegTemplate);
+        // Emit object array load prologue here.
+        if (isObjectLambda) {
+            final int arrayElementsOffset = 24;
+            String iterationObjArgReg = HSAIL.mapRegister(cc.getArgument(nonConstantParamCount - 1));
+            String tmpReg = workItemReg.replace("s", "d"); // "$d1";
+            // Convert gid to long.
+            codeBuffer.emitString("cvt_u64_s32 " + tmpReg + ", " + workItemReg + "; // Convert gid to long");
+            // Adjust index for sizeof ref.
+            codeBuffer.emitString("mul_u64 " + tmpReg + ", " + tmpReg + ", " + 8 + "; // Adjust index for sizeof ref");
+            // Adjust for actual data start.
+            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + arrayElementsOffset + "; // Adjust for actual elements data start");
+            // Add to array ref ptr.
+            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + iterationObjArgReg + "; // Add to array ref ptr");
+            // Load the object into the parameter reg.
+            codeBuffer.emitString("ld_global_u64 " + iterationObjArgReg + ", " + "[" + tmpReg + "]" + "; // Load from array element into parameter reg");
+        }
+        // Prologue done, Emit code for the LIR.
+        lirGen.lir.emitCode(tasm);
+        // Now that code is emitted go back and figure out what the upper Bound stack size was.
+        long maxStackSize = ((HSAILAssembler) tasm.asm).upperBoundStackSize();
+        String spillsegStringFinal;
+        if (maxStackSize == 0) {
+            // If no spilling, get rid of spillseg declaration.
+            char[] array = new char[spillsegTemplate.length()];
+            Arrays.fill(array, ' ');
+            spillsegStringFinal = new String(array);
+        } else {
+            spillsegStringFinal = spillsegTemplate.replace("123456", String.format("%6d", maxStackSize));
+        }
+        codeBuffer.emitString(spillsegStringFinal, spillsegDeclarationPosition);
+        // Emit the epilogue.
+        codeBuffer.emitString0("};");
+        codeBuffer.emitString("");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,153 @@
+/*
+ * 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.hsail;
+
+import static com.oracle.graal.api.code.CodeUtil.*;
+
+import java.util.logging.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.*;
+import com.oracle.graal.api.runtime.Graal;
+import com.oracle.graal.compiler.GraalCompiler;
+import com.oracle.graal.java.GraphBuilderConfiguration;
+import com.oracle.graal.java.GraphBuilderPhase;
+import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.nodes.spi.GraalCodeCacheProvider;
+import com.oracle.graal.phases.OptimisticOptimizations;
+import com.oracle.graal.phases.PhasePlan;
+import com.oracle.graal.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.nodes.spi.Replacements;
+import com.oracle.graal.compiler.target.Backend;
+import com.oracle.graal.hsail.*;
+
+import java.lang.reflect.Method;
+
+/**
+ * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code.
+ */
+public class HSAILCompilationResult {
+
+    private CompilationResult compResult;
+    protected static GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+    protected static Replacements replacements = Graal.getRequiredCapability(Replacements.class);
+    protected static Backend backend = Graal.getRequiredCapability(Backend.class);
+    protected static SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class);
+    private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName();
+    private static Level logLevel;
+    private static ConsoleHandler consoleHandler;
+    public static Logger logger;
+    static {
+        logger = Logger.getLogger(propPkgName);
+        logLevel = Level.FINE;
+        // This block configures the logger with handler and formatter.
+        consoleHandler = new ConsoleHandler();
+        logger.addHandler(consoleHandler);
+        logger.setUseParentHandlers(false);
+        SimpleFormatter formatter = new SimpleFormatter() {
+
+            @SuppressWarnings("sync-override")
+            @Override
+            public String format(LogRecord record) {
+                return (record.getMessage() + "\n");
+            }
+        };
+        consoleHandler.setFormatter(formatter);
+        logger.setLevel(logLevel);
+        consoleHandler.setLevel(logLevel);
+    }
+
+    public static HSAILCompilationResult getHSAILCompilationResult(Method meth) {
+        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(meth);
+        return getHSAILCompilationResult(javaMethod);
+    }
+
+    public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) {
+        StructuredGraph graph = new StructuredGraph(javaMethod);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        return getHSAILCompilationResult(graph);
+    }
+
+    public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
+        Debug.dump(graph, "Graph");
+        TargetDescription target = new TargetDescription(new HSAIL(), true, 1, 0, true);
+        HSAILBackend hsailBackend = new HSAILBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target);
+        PhasePlan phasePlan = new PhasePlan();
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
+        phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
+        phasePlan.addPhase(PhasePosition.AFTER_PARSING, new HSAILPhase());
+        new HSAILPhase().apply(graph);
+        CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
+        try {
+            CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE,
+                            new SpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
+            return new HSAILCompilationResult(compResult);
+        } catch (GraalInternalError e) {
+            String partialCode = hsailBackend.getPartialCodeString();
+            if (partialCode != null && !partialCode.equals("")) {
+                logger.fine("-------------------\nPartial Code Generation:\n--------------------");
+                logger.fine(partialCode);
+                logger.fine("-------------------\nEnd of Partial Code Generation\n--------------------");
+            }
+            throw e;
+        }
+    }
+
+    private static class HSAILPhase extends Phase {
+
+        @Override
+        protected void run(StructuredGraph graph) {
+            for (LocalNode local : graph.getNodes(LocalNode.class)) {
+                if (local.kind() == Kind.Object) {
+                    local.setStamp(StampFactory.declaredNonNull(local.objectStamp().type()));
+                }
+            }
+        }
+    }
+
+    protected HSAILCompilationResult(CompilationResult compResultInput) {
+        compResult = compResultInput;
+    }
+
+    public CompilationResult getCompilationResult() {
+        return compResult;
+    }
+
+    public String getHSAILCode() {
+        return new String(compResult.getTargetCode(), 0, compResult.getTargetCodeSize());
+    }
+
+    public void dumpCompilationResult() {
+        logger.fine("targetCodeSize=" + compResult.getTargetCodeSize());
+        logger.fine(getHSAILCode());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,673 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.hsail.HSAILArithmetic.*;
+import static com.oracle.graal.lir.hsail.HSAILBitManipulationOp.IntrinsicOpcode.*;
+import static com.oracle.graal.lir.hsail.HSAILCompare.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.JumpOp;
+import com.oracle.graal.lir.hsail.*;
+import com.oracle.graal.lir.hsail.HSAILArithmetic.Op1Stack;
+import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Reg;
+import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Stack;
+import com.oracle.graal.lir.hsail.HSAILArithmetic.ShiftOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.CompareBranchOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;
+import com.oracle.graal.lir.hsail.HSAILMove.LeaOp;
+import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
+import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp;
+import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp;
+import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * This class implements the HSAIL specific portion of the LIR generator.
+ */
+public class HSAILLIRGenerator extends LIRGenerator {
+
+    public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory {
+
+        @Override
+        public LIRInstruction createMove(AllocatableValue dst, Value src) {
+            if (src instanceof HSAILAddressValue) {
+                return new LeaOp(dst, (HSAILAddressValue) src);
+            } else if (isRegister(src) || isStackSlot(dst)) {
+                return new MoveFromRegOp(dst, src);
+            } else {
+                return new MoveToRegOp(dst, src);
+            }
+        }
+    }
+
+    public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, runtime, target, frameMap, cc, lir);
+        lir.spillMoveFactory = new HSAILSpillMoveFactory();
+    }
+
+    @Override
+    protected void emitNode(ValueNode node) {
+        if (node instanceof LIRGenLowerable) {
+            ((LIRGenLowerable) node).generate(this);
+        } else {
+            super.emitNode(node);
+        }
+    }
+
+    @Override
+    public boolean canStoreConstant(Constant c) {
+        // Operand b must be in the .reg state space.
+        return false;
+    }
+
+    @Override
+    public boolean canInlineConstant(Constant c) {
+        switch (c.getKind()) {
+            case Long:
+                return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c);
+            case Object:
+                return c.isNull();
+            default:
+                return true;
+        }
+    }
+
+    @Override
+    public Variable emitMove(Value input) {
+        Variable result = newVariable(input.getKind());
+        emitMove(result, input);
+        return result;
+    }
+
+    @Override
+    public void emitMove(AllocatableValue dst, Value src) {
+        if (isRegister(src) || isStackSlot(dst)) {
+            append(new MoveFromRegOp(dst, src));
+        } else {
+            append(new MoveToRegOp(dst, src));
+        }
+    }
+
+    public HSAILAddressValue emitAddress(Value base, long displacement, Value index, int scale) {
+        AllocatableValue baseRegister;
+        long finalDisp = displacement;
+
+        if (isConstant(base)) {
+            if (asConstant(base).isNull()) {
+                baseRegister = Value.ILLEGAL;
+            } else if (asConstant(base).getKind() != Kind.Object) {
+                finalDisp += asConstant(base).asLong();
+                baseRegister = Value.ILLEGAL;
+            } else {
+                baseRegister = load(base);
+            }
+        } else if (base == Value.ILLEGAL) {
+            baseRegister = Value.ILLEGAL;
+        } else {
+            baseRegister = asAllocatable(base);
+        }
+        if (index != Value.ILLEGAL) {
+            if (isConstant(index)) {
+                finalDisp += asConstant(index).asLong() * scale;
+            } else {
+                Value indexRegister;
+                Value convertedIndex;
+                convertedIndex = this.emitConvert(ConvertNode.Op.I2L, index);
+                if (scale != 1) {
+                    indexRegister = emitUMul(convertedIndex, Constant.forInt(scale));
+                } else {
+                    indexRegister = convertedIndex;
+                }
+                if (baseRegister == Value.ILLEGAL) {
+                    baseRegister = asAllocatable(indexRegister);
+                } else {
+                    baseRegister = emitAdd(baseRegister, indexRegister);
+                }
+            }
+        }
+        return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp);
+    }
+
+    private HSAILAddressValue asAddress(Value address) {
+        if (address instanceof HSAILAddressValue) {
+            return (HSAILAddressValue) address;
+        } else {
+            return emitAddress(address, 0, Value.ILLEGAL, 0);
+        }
+    }
+
+    @Override
+    public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) {
+        HSAILAddressValue loadAddress = asAddress(address);
+        Variable result = newVariable(kind);
+        append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null));
+        return result;
+    }
+
+    @Override
+    public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) {
+        HSAILAddressValue storeAddress = asAddress(address);
+        Variable input = load(inputVal);
+        append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null));
+    }
+
+    @Override
+    public Variable emitAddress(StackSlot address) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitJump(LabelRef label) {
+        append(new JumpOp(label));
+    }
+
+    private static HSAILCompare mapKindToCompareOp(Kind kind) {
+        switch (kind) {
+            case Int:
+                return ICMP;
+            case Long:
+                return LCMP;
+            case Float:
+                return FCMP;
+            case Double:
+                return DCMP;
+            case Object:
+                return ACMP;
+            default:
+                throw GraalInternalError.shouldNotReachHere("" + kind);
+        }
+    }
+
+    @Override
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
+        // We don't have top worry about mirroring the condition on HSAIL.
+        Condition finalCondition = cond;
+        Variable result = newVariable(left.getKind());
+        Kind kind = left.getKind().getStackKind();
+        switch (kind) {
+            case Int:
+            case Long:
+            case Object:
+                append(new CompareBranchOp(mapKindToCompareOp(kind), finalCondition, left, right, result, result, label));
+                break;
+            case Float:
+            case Double:
+                append(new FloatCompareBranchOp(mapKindToCompareOp(kind), finalCondition, left, right, result, result, label, unorderedIsTrue));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        }
+    }
+
+    @Override
+    public void emitOverflowCheckBranch(LabelRef label, boolean negated) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        Condition finalCondition = cond;
+        Variable result = newVariable(trueValue.getKind());
+        Kind kind = left.getKind().getStackKind();
+        switch (kind) {
+            case Int:
+            case Long:
+            case Object:
+                append(new CondMoveOp(mapKindToCompareOp(kind), load(left), load(right), result, finalCondition, load(trueValue), load(falseValue)));
+                break;
+            case Float:
+            case Double:
+                append(new FloatCondMoveOp(mapKindToCompareOp(kind), load(left), load(right), result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: " + left.getKind());
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public Variable emitNegate(Value input) {
+        Variable result = newVariable(input.getKind());
+        switch (input.getKind()) {
+            case Int:
+                append(new Op1Stack(INEG, result, input));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+
+    }
+
+    public Variable emitTestAddressAdd(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;
+            case Object:
+                throw GraalInternalError.shouldNotReachHere();
+            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;
+            case Object:
+                append(new Op2Stack(OADD, 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 Float:
+                append(new Op2Stack(FSUB, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Stack(LSUB, 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 Op2Reg(FMUL, result, a, loadNonConst(b)));
+                break;
+            case Double:
+                append(new Op2Reg(DMUL, result, a, loadNonConst(b)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    public Variable emitUMul(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new Op2Reg(LUMUL, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Reg(LUMUL, result, a, loadNonConst(b)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    protected boolean peephole(ValueNode valueNode) {
+        // No peephole optimizations for now.
+        return false;
+    }
+
+    @Override
+    public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new Op2Stack(IDIV, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Stack(LDIV, result, a, loadNonConst(b)));
+                break;
+            case Float:
+                append(new Op2Stack(FDIV, result, a, loadNonConst(b)));
+                break;
+            case Double:
+                append(new Op2Stack(DDIV, result, a, loadNonConst(b)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+
+    }
+
+    @Override
+    public Value emitRem(Value a, Value b, DeoptimizingNode deopting) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new Op2Stack(IREM, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Stack(LREM, result, a, loadNonConst(b)));
+                break;
+            case Float:
+                append(new Op2Stack(FREM, result, a, loadNonConst(b)));
+                break;
+            case Double:
+                append(new Op2Stack(DREM, result, a, loadNonConst(b)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) {
+        throw new InternalError("NYI");
+    }
+
+    @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;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitOr(Value a, Value b) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public Variable emitXor(Value a, Value b) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public Variable emitShl(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new ShiftOp(ISHL, result, a, b));
+                break;
+            default:
+                GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitShr(Value a, Value b) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public Variable emitUShr(Value a, Value b) {
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new ShiftOp(IUSHR, result, a, b));
+                break;
+            default:
+                GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) {
+        Variable input = load(inputVal);
+        Variable result = newVariable(opcode.to);
+        switch (opcode) {
+            case I2F:
+                append(new Op1Stack(I2F, result, input));
+                break;
+            case I2L:
+                append(new Op1Stack(I2L, result, input));
+                break;
+            case I2D:
+                append(new Op1Stack(I2D, result, input));
+                break;
+            case D2I:
+                append(new Op1Stack(D2I, result, input));
+                break;
+            case L2I:
+                append(new Op1Stack(L2I, result, input));
+                break;
+            case F2D:
+                append(new Op1Stack(F2D, result, input));
+                break;
+            case D2F:
+                append(new Op1Stack(D2F, result, input));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
+        append(new ReturnOp(Value.ILLEGAL));
+    }
+
+    @Override
+    public void emitMembar(int barriers) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
+        throw new InternalError("NYI emitForeignCall");
+    }
+
+    @Override
+    public void emitBitCount(Variable result, Value value) {
+        if (value.getKind().getStackKind() == Kind.Int) {
+            append(new HSAILBitManipulationOp(IPOPCNT, result, value));
+        } else {
+            append(new HSAILBitManipulationOp(LPOPCNT, result, value));
+        }
+    }
+
+    @Override
+    public void emitBitScanForward(Variable result, Value value) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitBitScanReverse(Variable result, Value value) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitMathAbs(Variable result, Variable input) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitMathSqrt(Variable result, Variable input) {
+        append(new Op1Stack(SQRT, result, input));
+    }
+
+    @Override
+    public void emitMathLog(Variable result, Variable input, boolean base10) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitMathCos(Variable result, Variable input) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitMathSin(Variable result, Variable input) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitMathTan(Variable result, Variable input) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitByteSwap(Variable result, Value input) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    protected void emitReturn(Value input) {
+        append(new ReturnOp(input));
+    }
+
+    @Override
+    protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void visitCompareAndSwap(CompareAndSwapNode node) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void visitBreakpointNode(BreakpointNode node) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void visitSafepointNode(SafepointNode i) {
+        Debug.log("visitSafePointNode unimplemented");
+    }
+
+    @Override
+    public void emitUnwind(Value operand) {
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) {
+        assert v.kind() == Kind.Object;
+        Variable obj = newVariable(Kind.Object);
+        emitMove(obj, operand(v));
+        append(new HSAILMove.NullCheckOp(obj, state(deopting)));
+    }
+
+    @Override
+    public void visitInfopointNode(InfopointNode i) {
+        throw new InternalError("NYI");
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Jul 09 11:21:06 2013 +0200
@@ -341,11 +341,15 @@
 
     @Override
     protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        AllocatableValue metaspaceMethod = AMD64.rbx.asValue();
-        emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()));
-        AllocatableValue targetAddress = AMD64.rax.asValue();
-        emitMove(targetAddress, operand(callTarget.computedAddress()));
-        append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
+        if (callTarget instanceof HotSpotIndirectCallTargetNode) {
+            AllocatableValue metaspaceMethod = AMD64.rbx.asValue();
+            emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()));
+            AllocatableValue targetAddress = AMD64.rax.asValue();
+            emitMove(targetAddress, operand(callTarget.computedAddress()));
+            append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
+        } else {
+            super.emitIndirectCall(callTarget, result, parameters, temps, callState);
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Jul 09 11:21:06 2013 +0200
@@ -184,5 +184,5 @@
      * stub that does the necessary argument shuffling and a tail call via an indirect jump to the
      * verified entry point of the given native method.
      */
-    private static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode);
+    public static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Tue Jul 09 11:21:06 2013 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.bridge.*;
 
 /**
  * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
@@ -96,11 +97,16 @@
 
     @Override
     public Object execute(Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException {
+        assert checkThreeObjectArgs();
+        return CompilerToVMImpl.executeCompiledMethodIntrinsic(arg1, arg2, arg3, this);
+    }
+
+    protected boolean checkThreeObjectArgs() {
         assert method.getSignature().getParameterCount(!Modifier.isStatic(method.getModifiers())) == 3;
         assert method.getSignature().getParameterKind(0) == Kind.Object;
         assert method.getSignature().getParameterKind(1) == Kind.Object;
         assert !Modifier.isStatic(method.getModifiers()) || method.getSignature().getParameterKind(2) == Kind.Object;
-        return graalRuntime().getCompilerToVM().executeCompiledMethod(arg1, arg2, arg3, this);
+        return true;
     }
 
     private boolean checkArgs(Object... args) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jul 09 11:21:06 2013 +0200
@@ -680,15 +680,15 @@
 
                     ValueNode newObject = allocations[objIndex];
                     if (virtual instanceof VirtualInstanceNode) {
-                        VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
+                        VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
                         for (int i = 0; i < entryCount; i++) {
                             ValueNode value = commit.getValues().get(valuePos++);
                             if (value instanceof VirtualObjectNode) {
                                 value = allocations[commit.getVirtualObjects().indexOf(value)];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE,
-                                                instance.field(i).getKind() == Kind.Object);
+                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)), WriteBarrierType.NONE,
+                                                virtualInstance.field(i).getKind() == Kind.Object);
 
                                 graph.addBeforeFixed(commit, graph.add(write));
                             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.nodes;
-
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.common.*;
-
-public class HotSpotNmethodExecuteNode extends AbstractCallNode implements Lowerable, MemoryCheckpoint.Single {
-
-    @Input private ValueNode code;
-    private final Class[] signature;
-
-    public HotSpotNmethodExecuteNode(Kind kind, Class[] signature, ValueNode code, ValueNode arg1, ValueNode arg2, ValueNode arg3) {
-        super(StampFactory.forKind(kind), new ValueNode[]{arg1, arg2, arg3});
-        this.code = code;
-        this.signature = signature;
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.ANY_LOCATION;
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (code.isConstant() && code.asConstant().asObject() instanceof HotSpotNmethod) {
-            HotSpotNmethod nmethod = (HotSpotNmethod) code.asConstant().asObject();
-            InvokeNode invoke = replaceWithInvoke(tool.getRuntime());
-            StructuredGraph graph = (StructuredGraph) nmethod.getGraph();
-            if (graph != null) {
-                InliningUtil.inline(invoke, graph, false);
-            }
-        } else {
-            replaceWithInvoke(tool.getRuntime());
-        }
-    }
-
-    protected InvokeNode replaceWithInvoke(MetaAccessProvider tool) {
-        ResolvedJavaMethod method = null;
-        ResolvedJavaField methodField = null;
-        ResolvedJavaField metaspaceMethodField = null;
-        ResolvedJavaField codeBlobField = null;
-        try {
-            method = tool.lookupJavaMethod(HotSpotNmethodExecuteNode.class.getMethod("placeholder", Object.class, Object.class, Object.class));
-            methodField = tool.lookupJavaField(HotSpotNmethod.class.getDeclaredField("method"));
-            codeBlobField = tool.lookupJavaField(HotSpotInstalledCode.class.getDeclaredField("codeBlob"));
-            metaspaceMethodField = tool.lookupJavaField(HotSpotResolvedJavaMethod.class.getDeclaredField("metaspaceMethod"));
-        } catch (NoSuchMethodException | SecurityException | NoSuchFieldException e) {
-            throw new IllegalStateException(e);
-        }
-        ResolvedJavaType[] signatureTypes = new ResolvedJavaType[signature.length];
-        for (int i = 0; i < signature.length; i++) {
-            signatureTypes[i] = tool.lookupJavaType(signature[i]);
-        }
-        final int verifiedEntryPointOffset = HotSpotReplacementsUtil.verifiedEntryPointOffset();
-
-        LoadFieldNode loadCodeBlob = graph().add(new LoadFieldNode(code, codeBlobField));
-        UnsafeLoadNode load = graph().add(new UnsafeLoadNode(loadCodeBlob, verifiedEntryPointOffset, ConstantNode.forLong(0, graph()), graalRuntime().getTarget().wordKind));
-
-        LoadFieldNode loadMethod = graph().add(new LoadFieldNode(code, methodField));
-        LoadFieldNode loadmetaspaceMethod = graph().add(new LoadFieldNode(loadMethod, metaspaceMethodField));
-
-        HotSpotIndirectCallTargetNode callTarget = graph().add(
-                        new HotSpotIndirectCallTargetNode(loadmetaspaceMethod, load, arguments(), stamp(), signatureTypes, method, CallingConvention.Type.JavaCall));
-
-        InvokeNode invoke = graph().add(new InvokeNode(callTarget, 0));
-
-        invoke.setStateAfter(stateAfter());
-        graph().replaceFixedWithFixed(this, invoke);
-
-        graph().addBeforeFixed(invoke, loadmetaspaceMethod);
-        graph().addBeforeFixed(loadmetaspaceMethod, loadMethod);
-        graph().addBeforeFixed(invoke, load);
-        graph().addBeforeFixed(load, loadCodeBlob);
-
-        return invoke;
-    }
-
-    public static Object placeholder(@SuppressWarnings("unused") Object a1, @SuppressWarnings("unused") Object a2, @SuppressWarnings("unused") Object a3) {
-        return 1;
-    }
-
-    @NodeIntrinsic
-    public static native <T> T call(@ConstantNodeParameter Kind kind, @ConstantNodeParameter Class[] signature, Object code, Object arg1, Object arg2, Object arg3);
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java	Tue Jul 09 11:19:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.replacements;
-
-import static com.oracle.graal.phases.GraalOptions.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.nodes.spi.*;
-
-@ServiceProvider(ReplacementsProvider.class)
-public class HotSpotNmethodIntrinsics implements ReplacementsProvider {
-
-    @Override
-    public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-        if (IntrinsifyInstalledCodeMethods.getValue()) {
-            replacements.registerSubstitutions(HotSpotNmethodSubstitutions.class);
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodSubstitutions.java	Tue Jul 09 11:19:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.replacements;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.replacements.Snippet.Fold;
-
-@ClassSubstitution(HotSpotNmethod.class)
-public class HotSpotNmethodSubstitutions {
-
-    @MethodSubstitution(isStatic = false)
-    public static Object execute(HotSpotInstalledCode code, final Object arg1, final Object arg2, final Object arg3) {
-        return HotSpotNmethodExecuteNode.call(Kind.Object, getSignature(), code, arg1, arg2, arg3);
-    }
-
-    @Fold
-    private static Class[] getSignature() {
-        return new Class[]{Object.class, Object.class, Object.class};
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,440 @@
+/*
+ * 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.graal.hsail;
+
+import static com.oracle.graal.api.code.MemoryBarriers.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Register.RegisterCategory;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+
+/**
+ * Represents the HSAIL architecture.
+ */
+public class HSAIL extends Architecture {
+
+    // @formatter:off
+    public static final RegisterCategory CPU = new RegisterCategory("CPU");
+    public static final RegisterCategory FPU = new RegisterCategory("FPU");
+
+    // Control registers.
+    public static final Register c0 = new Register(0, 0, "c0", CPU);
+    public static final Register c1 = new Register(1, 1, "c1", CPU);
+    public static final Register c2 = new Register(2, 2, "c2", CPU);
+    public static final Register c3 = new Register(3, 3, "c3", CPU);
+    public static final Register c4 = new Register(4, 4, "c4", CPU);
+    public static final Register c5 = new Register(5, 5, "c5", CPU);
+    public static final Register c6 = new Register(6, 6, "c6", CPU);
+    public static final Register c7 = new Register(7, 7, "c7", CPU);
+
+    //32 bit registers.
+    public static final Register s0  = new Register(8,  0,  "s0", CPU);
+    public static final Register s1  = new Register(9,  1,  "s1", CPU);
+    public static final Register s2 = new Register(10, 2, "s2", CPU);
+    public static final Register s3 = new Register(11, 3, "s3", CPU);
+    public static final Register s4 = new Register(12, 4, "s4", CPU);
+    public static final Register s5 = new Register(13, 5, "s5", CPU);
+    public static final Register s6 = new Register(14, 6, "s6", CPU);
+    public static final Register s7 = new Register(15, 7, "s7", CPU);
+    public static final Register s8  = new Register(16,  8,  "s8", CPU);
+    public static final Register s9  = new Register(17,  9,  "s9", CPU);
+    public static final Register s10 = new Register(18, 10, "s10", CPU);
+    public static final Register s11 = new Register(19, 11, "s11", CPU);
+    public static final Register s12 = new Register(20, 12, "s12", CPU);
+    public static final Register s13 = new Register(21, 13, "s13", CPU);
+    public static final Register s14 = new Register(22, 14, "s14", CPU);
+    public static final Register s15 = new Register(23, 15, "s15", CPU);
+    public static final Register s16  = new Register(24, 16,  "s16", CPU);
+    public static final Register s17  = new Register(25,  17,  "s17", CPU);
+    public static final Register s18 = new Register(26, 18, "s18", CPU);
+    public static final Register s19 = new Register(27, 19, "s19", CPU);
+    public static final Register s20 = new Register(28, 20, "s20", CPU);
+    public static final Register s21 = new Register(29, 21, "s21", CPU);
+    public static final Register s22 = new Register(30, 22, "s22", CPU);
+    public static final Register s23 = new Register(31, 23, "s23", CPU);
+    public static final Register s24  = new Register(32, 24,  "s24", CPU);
+    public static final Register s25  = new Register(33, 25,  "s25", CPU);
+    public static final Register s26 = new Register(34, 26, "s26", CPU);
+    public static final Register s27 = new Register(35, 27, "s27", CPU);
+    public static final Register s28 = new Register(36, 28, "s28", CPU);
+    public static final Register s29 = new Register(37, 29, "s29", CPU);
+    public static final Register s30 = new Register(38, 30, "s30", CPU);
+    public static final Register s31 = new Register(39, 31, "s31", CPU);
+    public static final Register s32  = new Register(40, 32,  "s32", CPU);
+    public static final Register s33  = new Register(41,  33,  "s33", CPU);
+    public static final Register s34 = new Register(42, 34, "s34", CPU);
+    public static final Register s35 = new Register(43, 35, "s35", CPU);
+    public static final Register s36 = new Register(44, 36, "s36", CPU);
+    public static final Register s37 = new Register(45, 37, "s37", CPU);
+    public static final Register s38 = new Register(45, 38, "s38", CPU);
+    public static final Register s39 = new Register(46, 39, "s39", CPU);
+    public static final Register s40  = new Register(47, 40,  "s40", CPU);
+    public static final Register s41  = new Register(48,  41,  "s41", CPU);
+    public static final Register s42 = new Register(49, 42, "s42", CPU);
+    public static final Register s43 = new Register(50, 43, "s43", CPU);
+    public static final Register s44 = new Register(51, 44, "s44", CPU);
+    public static final Register s45 = new Register(52, 45, "s45", CPU);
+    public static final Register s46 = new Register(53, 46, "s46", CPU);
+    public static final Register s47 = new Register(54, 47, "s47", CPU);
+    public static final Register s48  = new Register(55, 48,  "s48", CPU);
+    public static final Register s49  = new Register(56,  49,  "s49", CPU);
+    public static final Register s50 = new Register(57, 50, "s50", CPU);
+    public static final Register s51 = new Register(58, 51, "s51", CPU);
+    public static final Register s52 = new Register(59, 52, "s52", CPU);
+    public static final Register s53 = new Register(60, 53, "s53", CPU);
+    public static final Register s54 = new Register(61, 54, "s54", CPU);
+    public static final Register s55 = new Register(62, 55, "s55", CPU);
+    public static final Register s56  = new Register(64, 56,  "s56", CPU);
+    public static final Register s57  = new Register(64, 57,  "s57", CPU);
+    public static final Register s58 = new Register(65, 58, "s58", CPU);
+    public static final Register s59 = new Register(66, 59, "s59", CPU);
+    public static final Register s60 = new Register(67, 60, "s60", CPU);
+    public static final Register s61 = new Register(68, 61, "s61", CPU);
+    public static final Register s62 = new Register(69, 62, "s62", CPU);
+    public static final Register s63 = new Register(70, 63, "s63", CPU);
+    public static final Register s64  = new Register(71, 64,  "s64", CPU);
+    public static final Register s65  = new Register(72, 65,  "s65", CPU);
+    public static final Register s66 = new Register(73, 66, "s66", CPU);
+    public static final Register s67 = new Register(74, 67, "s67", CPU);
+    public static final Register s68 = new Register(75, 68, "s68", CPU);
+    public static final Register s69 = new Register(76, 69, "s69", CPU);
+    public static final Register s70 = new Register(77, 70, "s70", CPU);
+    public static final Register s71 = new Register(78, 71, "s71", CPU);
+    public static final Register s72  = new Register(79, 72,  "s72", CPU);
+    public static final Register s73  = new Register(80, 73,  "s73", CPU);
+    public static final Register s74 = new Register(81, 74, "s74", CPU);
+    public static final Register s75 = new Register(82, 75, "s75", CPU);
+    public static final Register s76 = new Register(83, 76, "s76", CPU);
+    public static final Register s77 = new Register(84, 77, "s77", CPU);
+    public static final Register s78 = new Register(85, 78, "s78", CPU);
+    public static final Register s79 = new Register(86, 79, "s79", CPU);
+    public static final Register s80  = new Register(87, 80,  "s80", CPU);
+    public static final Register s81  = new Register(88, 81,  "s81", CPU);
+    public static final Register s82 = new Register(89, 82, "s82", CPU);
+    public static final Register s83 = new Register(90, 83, "s83", CPU);
+    public static final Register s84 = new Register(91, 84, "s84", CPU);
+    public static final Register s85 = new Register(92, 85, "s85", CPU);
+    public static final Register s86 = new Register(93, 86, "s86", CPU);
+    public static final Register s87 = new Register(94, 87, "s87", CPU);
+    public static final Register s88  = new Register(95,  88,  "s88", CPU);
+    public static final Register s89  = new Register(96,  89,  "s89", CPU);
+    public static final Register s90 = new Register(97, 90, "s90", CPU);
+    public static final Register s91 = new Register(98, 91, "s91", CPU);
+    public static final Register s92 = new Register(99, 92, "s92", CPU);
+    public static final Register s93 = new Register(100, 93, "s93", CPU);
+    public static final Register s94 = new Register(101, 94, "s94", CPU);
+    public static final Register s95 = new Register(102, 95, "s95", CPU);
+    public static final Register s96  = new Register(103, 96,  "s96", CPU);
+    public static final Register s97  = new Register(104, 97,  "s97", CPU);
+    public static final Register s98 = new Register(105, 98, "s98", CPU);
+    public static final Register s99 = new Register(106, 99, "s99", CPU);
+    public static final Register s100 = new Register(107, 100, "s100", CPU);
+    public static final Register s101 = new Register(108, 101, "s101", CPU);
+    public static final Register s102 = new Register(109, 102, "s102", CPU);
+    public static final Register s103 = new Register(110, 103, "s103", CPU);
+    public static final Register s104  = new Register(111, 104,  "s104", CPU);
+    public static final Register s105  = new Register(112,  105,  "s105", CPU);
+    public static final Register s106 = new Register(113, 106, "s106", CPU);
+    public static final Register s107 = new Register(114, 107, "s107", CPU);
+    public static final Register s108 = new Register(115, 108, "s108", CPU);
+    public static final Register s109 = new Register(116, 109, "s109", CPU);
+    public static final Register s110 = new Register(117, 110, "s110", CPU);
+    public static final Register s111 = new Register(118, 111, "s111", CPU);
+    public static final Register s112  = new Register(119, 112,  "s112", CPU);
+    public static final Register s113  = new Register(120, 113,  "s113", CPU);
+    public static final Register s114 = new Register(121, 114, "s114", CPU);
+    public static final Register s115 = new Register(122, 115, "s115", CPU);
+    public static final Register s116 = new Register(123, 116, "s116", CPU);
+    public static final Register s117 = new Register(124, 117, "s117", CPU);
+    public static final Register s118 = new Register(125, 118, "s118", CPU);
+    public static final Register s119 = new Register(126, 119, "s119", CPU);
+    public static final Register s120  = new Register(127, 120,  "s120", CPU);
+    public static final Register s121  = new Register(128, 121,  "s121", CPU);
+    public static final Register s122 = new Register(129, 122, "s122", CPU);
+    public static final Register s123 = new Register(130, 123, "s123", CPU);
+    public static final Register s124 = new Register(131, 124, "s124", CPU);
+    public static final Register s125 = new Register(132, 125, "s125", CPU);
+    public static final Register s126 = new Register(133, 126, "s126", CPU);
+    public static final Register s127 = new Register(134, 127, "s127", CPU);
+
+    //64 bit registers.
+    public static final Register d0  = new Register(135,  0,  "d0", CPU);
+    public static final Register d1  = new Register(136,  1,  "d1", CPU);
+    public static final Register d2 = new Register(137, 2, "d2", CPU);
+    public static final Register d3 = new Register(138, 3, "d3", CPU);
+    public static final Register d4 = new Register(139, 4, "d4", CPU);
+    public static final Register d5 = new Register(140, 5, "d5", CPU);
+    public static final Register d6 = new Register(141, 6, "d6", CPU);
+    public static final Register d7 = new Register(142, 7, "d7", CPU);
+    public static final Register d8  = new Register(143,  8,  "d8", CPU);
+    public static final Register d9  = new Register(144,  9,  "d9", CPU);
+    public static final Register d10 = new Register(145, 10, "d10", CPU);
+    public static final Register d11 = new Register(146, 11, "d11", CPU);
+    public static final Register d12 = new Register(147, 12, "d12", CPU);
+    public static final Register d13 = new Register(148, 13, "d13", CPU);
+    public static final Register d14 = new Register(149, 14, "d14", CPU);
+    public static final Register d15 = new Register(150, 15, "d15", CPU);
+    public static final Register d16  = new Register(151, 16,  "d16", CPU);
+    public static final Register d17  = new Register(152,  17,  "d17", CPU);
+    public static final Register d18 = new Register(153, 18, "d18", CPU);
+    public static final Register d19 = new Register(154, 19, "d19", CPU);
+    public static final Register d20 = new Register(155, 20, "d20", CPU);
+    public static final Register d21 = new Register(156, 21, "d21", CPU);
+    public static final Register d22 = new Register(157, 22, "d22", CPU);
+    public static final Register d23 = new Register(158, 23, "d23", CPU);
+    public static final Register d24  = new Register(159, 24,  "d24", CPU);
+    public static final Register d25  = new Register(160, 25,  "d25", CPU);
+    public static final Register d26 = new Register(161, 26, "d26", CPU);
+    public static final Register d27 = new Register(162, 27, "d27", CPU);
+    public static final Register d28 = new Register(163, 28, "d28", CPU);
+    public static final Register d29 = new Register(164, 29, "d29", CPU);
+    public static final Register d30 = new Register(165, 30, "d30", CPU);
+    public static final Register d31 = new Register(166, 31, "d31", CPU);
+    public static final Register d32  = new Register(167, 32,  "d32", CPU);
+    public static final Register d33  = new Register(168,  33,  "d33", CPU);
+    public static final Register d34 = new Register(169, 34, "d34", CPU);
+    public static final Register d35 = new Register(170, 35, "d35", CPU);
+    public static final Register d36 = new Register(171, 36, "d36", CPU);
+    public static final Register d37 = new Register(172, 37, "d37", CPU);
+    public static final Register d38 = new Register(173, 38, "d38", CPU);
+    public static final Register d39 = new Register(174, 39, "d39", CPU);
+    public static final Register d40  = new Register(175, 40,  "d40", CPU);
+    public static final Register d41  = new Register(176,  41,  "d41", CPU);
+    public static final Register d42 = new Register(177, 42, "d42", CPU);
+    public static final Register d43 = new Register(178, 43, "d43", CPU);
+    public static final Register d44 = new Register(179, 44, "d44", CPU);
+    public static final Register d45 = new Register(180, 45, "d45", CPU);
+    public static final Register d46 = new Register(181, 46, "d46", CPU);
+    public static final Register d47 = new Register(182, 47, "d47", CPU);
+    public static final Register d48  = new Register(183, 48,  "d48", CPU);
+    public static final Register d49  = new Register(184,  49,  "d49", CPU);
+    public static final Register d50 = new Register(185, 50, "d50", CPU);
+    public static final Register d51 = new Register(186, 51, "d51", CPU);
+    public static final Register d52 = new Register(187, 52, "d52", CPU);
+    public static final Register d53 = new Register(188, 53, "d53", CPU);
+    public static final Register d54 = new Register(189, 54, "d54", CPU);
+    public static final Register d55 = new Register(190, 55, "d55", CPU);
+    public static final Register d56  = new Register(191, 56,  "d56", CPU);
+    public static final Register d57  = new Register(192, 57,  "d57", CPU);
+    public static final Register d58 = new Register(193, 58, "d58", CPU);
+    public static final Register d59 = new Register(194, 59, "d59", CPU);
+    public static final Register d60 = new Register(195, 60, "d60", CPU);
+    public static final Register d61 = new Register(196, 61, "d61", CPU);
+    public static final Register d62 = new Register(197, 62, "d62", CPU);
+    public static final Register d63 = new Register(198, 63, "d63", CPU);
+
+    //128 bit registers.
+    public static final Register q0 = new Register(199, 0, "q0", CPU);
+    public static final Register q1 = new Register(200, 1, "q1", CPU);
+    public static final Register q2 = new Register(201, 2, "q2", CPU);
+    public static final Register q3 = new Register(202, 3, "q3", CPU);
+    public static final Register q4 = new Register(203, 4, "q4", CPU);
+    public static final Register q5 = new Register(204, 5, "q5", CPU);
+    public static final Register q6 = new Register(205, 6, "q6", CPU);
+    public static final Register q7 = new Register(206, 7, "q7", CPU);
+    public static final Register q8 = new Register(207, 8, "q8", CPU);
+    public static final Register q9 = new Register(208, 9, "q9", CPU);
+    public static final Register q10 = new Register(209, 10, "q10", CPU);
+    public static final Register q11 = new Register(210, 11, "q11", CPU);
+    public static final Register q12 = new Register(211, 12, "q12", CPU);
+    public static final Register q13 = new Register(212, 13, "q13", CPU);
+    public static final Register q14 = new Register(213, 14, "q14", CPU);
+    public static final Register q15 = new Register(214, 15, "q15", CPU);
+    public static final Register q16 = new Register(215, 16, "q16", CPU);
+    public static final Register q17 = new Register(216, 17, "q17", CPU);
+    public static final Register q18 = new Register(217, 18, "q18", CPU);
+    public static final Register q19 = new Register(218, 19, "q19", CPU);
+    public static final Register q20 = new Register(219, 20, "q20", CPU);
+    public static final Register q21 = new Register(220, 21, "q21", CPU);
+    public static final Register q22 = new Register(221, 22, "q22", CPU);
+    public static final Register q23 = new Register(222, 23, "q23", CPU);
+    public static final Register q24 = new Register(223, 24, "q24", CPU);
+    public static final Register q25 = new Register(224, 25, "q25", CPU);
+    public static final Register q26 = new Register(225, 26, "q26", CPU);
+    public static final Register q27 = new Register(226, 27, "q27", CPU);
+    public static final Register q28 = new Register(227, 28, "q28", CPU);
+    public static final Register q29 = new Register(228, 29, "q29", CPU);
+    public static final Register q30 = new Register(229, 30, "q30", CPU);
+    public static final Register q31 = new Register(230, 31, "q31", CPU);
+
+    public static final Register[] cRegisters = {
+        c0, c1, c2, c3, c4, c5, c6, c7
+    };
+
+    public static final Register[] sRegisters = {
+        s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10,
+        s11, s12, s13, s14, s15, s16, s17, s18, s19,
+        s20, s21, s22, s23, s24, s25, s26, s27, s28,
+        s29, s30, s31, s32, s33, s34, s35, s36, s37,
+        s38, s39, s40, s41, s42, s43, s44, s45, s46,
+        s47, s48, s49, s50, s51, s52, s53, s54, s55,
+        s56, s57, s58, s59, s60, s61, s62, s63, s64,
+        s65, s66, s67, s68, s69, s70, s71, s72, s73,
+        s74, s75, s76, s77, s78, s79, s80, s81, s82,
+        s83, s84, s85, s86, s87, s88, s89, s90, s91,
+        s92, s93, s94, s95, s96, s97, s98, s99, s100,
+        s101, s102, s103, s104, s105, s106, s107, s108,
+        s109, s110, s111, s112, s113, s114, s115, s116,
+        s117, s118, s119, s120, s121, s122, s123, s124,
+        s125, s126, s127
+    };
+
+    public static final Register[] dRegisters = {
+        d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28,
+        d29, d30, d31, d32, d33, d34, d35, d36, d37, d38, d39, d40, d41, d42, d43, d44, d45, d46, d47, d48, d49, d50, d51, d52, d53, d54, d55,
+        d56, d57, d58, d59, d60, d61, d62, d63
+    };
+
+    public static final Register[] qRegisters = {
+        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21, q22, q23, q24, q25, q26, q27, q28, q29, q30, q31
+    };
+
+    public static final Register[] allRegisters = {
+        c0, c1, c2, c3, c4, c5, c6, c7, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19,
+        s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, s32, s33, s34, s35,
+        s36, s37, s38, s39, s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s50, s51, s52,
+        s53, s54, s55, s56, s57, s58, s59, s60, s61,
+        s62, s63, s64, s65, s66, s67, s68, s69, s70,
+        s71, s72, s73, s74, s75, s76, s77, s78, s79,
+        s80, s81, s82, s83, s84, s85, s86, s87, s88,
+        s89, s90, s91, s92, s93, s94, s95, s96, s97,
+        s98, s99, s100, s101, s102, s103, s104, s105,
+        s106, s107, s108, s109, s110, s111, s112, s113,
+        s114, s115, s116, s117, s118, s119, s120, s121,
+        s122, s123, s124, s125, s126, s127,  d0, d1, d2,
+        d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13,
+        d14, d15, d16, d17, d18, d19, d20, d21, d22, d23,
+        d24, d25, d26, d27, d28, d29, d30, d31, d32, d33,
+        d34, d35, d36, d37, d38, d39, d40, d41, d42, d43,
+        d44, d45, d46, d47, d48, d49, d50, d51, d52, d53,
+        d54, d55, d56, d57, d58, d59, d60, d61, d62, d63,
+        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11,
+        q12, q13, q14, q15, q16, q17, q18, q19, q20, q21,
+        q22, q23, q24, q25, q26, q27, q28, q29, q30, q31
+    };
+
+    public HSAIL() {
+        super("HSAIL",
+                        8,
+                        ByteOrder.LITTLE_ENDIAN,
+                        allRegisters,
+                        LOAD_STORE | STORE_STORE,
+                        1,
+                        q31.encoding + 1,
+                        8);
+    }
+
+
+    public static int getStackOffset(Value reg) {
+        return -(((StackSlot) reg).getRawOffset());
+    }
+
+    public static String mapStackSlot(Value reg) {
+        StackSlot s = (StackSlot) reg;
+        long offset = -s.getRawOffset();
+        return "[%spillseg]" + "[" + offset + "]";
+    }
+
+    // @formatter:on
+    public static String mapRegister(Value arg) {
+        Register reg;
+        int encoding = 0;
+        String regPrefix = null;
+        String argType = arg.getKind().getJavaName();
+        if (argType.equals("double") || argType.equals("long")) {
+            regPrefix = "$d";
+        } else if (argType.equals("int") || argType.equals("float")) {
+            regPrefix = "$s";
+        } else {
+            regPrefix = "$d";
+        }
+        switch (argType) {
+            case "float":
+                reg = asFloatReg(arg);
+                encoding = reg.encoding() + 16;
+                break;
+            case "int":
+                reg = asIntReg(arg);
+                encoding = reg.encoding();
+                break;
+            case "long":
+                reg = asLongReg(arg);
+                encoding = reg.encoding();
+                break;
+            case "double":
+                reg = asDoubleReg(arg);
+                encoding = reg.encoding() + 16;
+                break;
+            case "Object":
+                reg = asObjectReg(arg);
+                encoding = reg.encoding();
+                break;
+            default:
+                GraalInternalError.shouldNotReachHere();
+                break;
+        }
+        return new String(regPrefix + encoding);
+    }
+
+    @Override
+    public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
+        if (!(platformKind instanceof Kind)) {
+            return false;
+        }
+        Kind kind = (Kind) platformKind;
+        if (category == CPU) {
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                case Char:
+                case Short:
+                case Int:
+                case Long:
+                case Object:
+                    return true;
+            }
+        } else if (category == FPU) {
+            switch (kind) {
+                case Float:
+                case Double:
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public PlatformKind getLargestStorableKind(RegisterCategory category) {
+        if (category == CPU) {
+            return Kind.Long;
+        } else if (category == FPU) {
+            return Kind.Double;
+        } else {
+            return Kind.Illegal;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILAddressValue.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,104 @@
+/*
+ * 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.lir.hsail;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.lir.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+
+/**
+ * Represents an address value used in HSAIL code.
+ */
+public final class HSAILAddressValue extends CompositeValue {
+
+    private static final long serialVersionUID = 1802222435353022623L;
+    @Component({REG, LIRInstruction.OperandFlag.ILLEGAL}) private AllocatableValue base;
+    private final long displacement;
+
+    /**
+     * Creates an {@link HSAILAddressValue} with given base register and no displacement.
+     * 
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     */
+    public HSAILAddressValue(Kind kind, AllocatableValue base) {
+        this(kind, base, 0);
+    }
+
+    /**
+     * Creates an {@link HSAILAddressValue} with given base register and a displacement. This is the
+     * most general constructor.
+     * 
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     * @param displacement the displacement
+     */
+    public HSAILAddressValue(Kind kind, AllocatableValue base, long displacement) {
+        super(kind);
+        this.base = base;
+        this.displacement = displacement;
+        assert !isStackSlot(base);
+    }
+
+    public HSAILAddress toAddress() {
+        Register baseReg = base == Value.ILLEGAL ? Register.None : asRegister(base);
+        return new HSAILAddress(baseReg, displacement);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append(getKind().getJavaName()).append("[");
+        String sep = "";
+        if (isLegal(base)) {
+            s.append(base);
+            sep = " + ";
+        }
+        if (displacement < 0) {
+            s.append(" - ").append(-displacement);
+        } else if (displacement > 0) {
+            s.append(sep).append(displacement);
+        }
+        s.append("]");
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof HSAILAddressValue) {
+            HSAILAddressValue addr = (HSAILAddressValue) obj;
+            return getKind() == addr.getKind() && displacement == addr.displacement && base.equals(addr.base);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return base.hashCode() ^ ((int) displacement << 4) ^ (getKind().ordinal() << 12);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+
+// @formatter:off
+/**
+ * Defines arithmetic instruction nodes.
+ */
+public enum HSAILArithmetic {
+    IADD, OADD, ISUB, FSUB, DSUB, IMUL, FMUL,
+    DMUL, IDIV, FDIV, DDIV, IUADD, IUSUB,
+    IUMUL, IUDIV, LADD, DADD, FADD, LSUB,
+    LMUL, LDIV, LUADD, LUSUB, LUMUL,
+    LUDIV, IMAX, LMAX, IUMAX, LUMAX,
+    IMIN, LMIN, IUMIN, LUMIN, IREM,
+    LREM, FREM, DREM, IUREM, LUREM,
+    ICARRY, LCARRY, IUCARRY, LUCARRY,
+    IAND, INEG, IUSHR, I2B, I2S, I2L,
+    F2D, F2I, F2L, D2F, I2F, I2D, D2I,
+    L2F, D2L, MOV_F2I, MOV_D2L, L2D, MOV_I2F,
+    MOV_L2D, ISHL, SQRT, UNDEF, CALL, L2I;
+
+    public static class Op1Stack extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG, STACK, CONST}) protected Value x;
+
+        public Op1Stack(HSAILArithmetic opcode, Value result, Value x) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, opcode, result, x, null);
+        }
+    }
+
+    public static class Op2Stack extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG, CONST}) protected Value x;
+        @Alive({REG, CONST}) protected Value y;
+
+        public Op2Stack(HSAILArithmetic opcode, Value result, Value x, Value y) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, opcode, result, x, y, null);
+        }
+
+        @Override
+        public void verify() {
+            super.verify();
+            verifyKind(opcode, result, x, y);
+        }
+    }
+
+    public static class Op1Reg extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG}) protected Value x;
+
+        public Op1Reg(HSAILArithmetic opcode, Value result, Value x) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, opcode, result, x, null);
+        }
+    }
+
+    public static class Op2Reg extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG, STACK, CONST}) protected Value x;
+        @Alive({REG, CONST}) protected Value y;
+
+        public Op2Reg(HSAILArithmetic opcode, Value result, Value x, Value y) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, opcode, result, x, y, null);
+        }
+
+        @Override
+        public void verify() {
+            super.verify();
+            verifyKind(opcode, result, x, y);
+        }
+    }
+
+    public static class Op2RegCommutative extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG, STACK, CONST}) protected Value x;
+        @Use({REG, CONST}) protected Value y;
+
+        public Op2RegCommutative(HSAILArithmetic opcode, Value result, Value x, Value y) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            verifyKind(opcode, result, x, y);
+        }
+    }
+
+    public static class ShiftOp extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG, STACK, CONST}) protected Value x;
+        @Alive({REG, CONST}) protected Value y;
+
+        public ShiftOp(HSAILArithmetic opcode, Value result, Value x, Value y) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, opcode, result, x, y, null);
+        }
+
+        @Override
+        public void verify() {
+            super.verify();
+            verifyKind(opcode, result, x, x);
+            assert y.getKind().getStackKind() == Kind.Int;
+        }
+    }
+
+    public static class DivOp extends HSAILLIRInstruction {
+        @Opcode private final HSAILArithmetic opcode;
+        @Def protected Value result;
+        @Use protected Value x;
+        @Alive protected Value y;
+        @State protected LIRFrameState state;
+
+        public DivOp(HSAILArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+            this.y = y;
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, opcode, result, y, state);
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            verifyKind(opcode, result, x, y);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    protected static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value result) {
+        switch (opcode) {
+            default:   throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src, LIRFrameState info) {
+        int exceptionOffset = -1;
+        if (isRegister(src)) {
+            switch (opcode) {
+                case I2F:
+                case I2D:
+                case D2I:
+                case I2L:
+                case L2I:
+                case F2D:
+                case D2F: masm.emitConvert(dst, src); break;
+                case SQRT: masm.emitArg1("sqrt", dst, src); break;
+                case UNDEF: masm.undefined("undefined node"); break;
+                case CALL: masm.undefined("undefined node CALL"); break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }  else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        if (info != null) {
+            assert exceptionOffset != -1;
+            tasm.recordImplicitException(exceptionOffset, info);
+        }
+    }
+
+    public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
+        int exceptionOffset = -1;
+        switch (opcode) {
+            case IADD:
+            case LADD:
+            case DADD:
+            case FADD:
+            case OADD:
+                masm.emit("add", dst, src1, src2); break;
+            case ISUB:
+            case LSUB:
+            case DSUB:
+            case FSUB:
+                masm.emit("sub", dst, src1, src2); break;
+            case IMUL:
+            case LMUL:
+            case FMUL:
+            case DMUL:
+            case LUMUL:
+                masm.emit("mul", dst, src1, src2); break;
+            case IDIV:
+            case LDIV:
+            case FDIV:
+            case DDIV:
+                masm.emit("div", dst, src1, src2); break;
+            case IMAX:
+            case LMAX:
+                masm.emit("max", dst, src1, src2); break;
+            case IMIN:
+            case LMIN:
+                masm.emit("min", dst, src1, src2); break;
+            case ISHL:
+                masm.emit("shl", dst, src1, src2); break;
+            case IREM:
+                masm.emit("rem", dst, src1, src2); break;
+            default:    throw GraalInternalError.shouldNotReachHere();
+        }
+        if (info != null) {
+            assert exceptionOffset != -1;
+            tasm.recordImplicitException(exceptionOffset, info);
+        }
+    }
+
+    private static void verifyKind(HSAILArithmetic opcode, Value result, Value x, Value y) {
+        assert (opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int)
+        || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long)
+        || (opcode.name().startsWith("LU") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Int)
+        || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float)
+        || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double)
+        || (opcode.name().startsWith("O") && result.getKind() == Kind.Object && x.getKind() == Kind.Object && (y.getKind() == Kind.Int || y.getKind() == Kind.Long)
+                        );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import com.oracle.graal.lir.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Defines bit manipulation operations.
+ */
+public class HSAILBitManipulationOp extends HSAILLIRInstruction {
+
+    public enum IntrinsicOpcode {
+        IPOPCNT, LPOPCNT, IBSR, LBSR, BSF;
+    }
+
+    @Opcode private final IntrinsicOpcode opcode;
+    @Def protected Value result;
+    @Use({OperandFlag.REG}) protected Value input;
+
+    public HSAILBitManipulationOp(IntrinsicOpcode opcode, Value result, Value input) {
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        switch (opcode) {
+            case IPOPCNT:
+                throw GraalInternalError.shouldNotReachHere();
+            case LPOPCNT:
+                throw GraalInternalError.shouldNotReachHere();
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,113 @@
+/*
+ * 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.hsail;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.lir.*;
+
+/**
+ * Implementation of compare operations.
+ */
+public enum HSAILCompare {
+    ICMP, LCMP, ACMP, FCMP, DCMP;
+
+    public static class CompareOp extends HSAILLIRInstruction {
+
+        @Opcode private final HSAILCompare opcode;
+        @Use({REG, STACK, CONST}) protected Value x;
+        @Use({REG, STACK, CONST}) protected Value y;
+        @Def({REG}) protected Value z;
+        private final Condition condition;
+        public boolean unordered = false;
+
+        public CompareOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z) {
+            this.opcode = opcode;
+            this.condition = condition;
+            this.x = x;
+            this.y = y;
+            this.z = z;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            emit(tasm, masm, condition, x, y, z, unordered);
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            assert (x.getKind() == y.getKind() && ((name().startsWith("I") && x.getKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long) ||
+                            (name().startsWith("A") && x.getKind() == Kind.Object) || (name().startsWith("F") && x.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double)));
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) {
+        emitCompare(masm, condition, x, y, unorderedIsTrue);
+    }
+
+    private static String conditionToString(Condition condition) {
+        switch (condition) {
+            case EQ:
+                return "eq";
+            case NE:
+                return "ne";
+            case LT:
+            case BT:
+                return "lt";
+            case LE:
+            case BE:
+                return "le";
+            case GT:
+            case AT:
+                return "gt";
+            case GE:
+            case AE:
+                return "ge";
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static boolean isUnsignedCompare(Condition condition) {
+        switch (condition) {
+            case BT:
+            case BE:
+            case AT:
+            case AE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static void emitCompare(HSAILAssembler masm, Condition condition, Value src0, Value src1, boolean unordered) {
+        masm.emitCompare(src0, src1, conditionToString(condition), unordered, isUnsignedCompare(condition));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.*;
+
+/**
+ * Implementation of control flow instructions.
+ */
+public class HSAILControlFlow {
+
+    public static class ReturnOp extends HSAILLIRInstruction {
+
+        @Use({REG, ILLEGAL}) protected Value x;
+
+        public ReturnOp(Value x) {
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            if (tasm.frameContext != null) {
+                tasm.frameContext.leave(tasm);
+            }
+            masm.exit();
+        }
+    }
+
+    public static class CompareBranchOp extends HSAILLIRInstruction implements StandardOp.BranchOp {
+
+        @Opcode protected final HSAILCompare opcode;
+        @Use({REG, CONST}) protected Value x;
+        @Use({REG, CONST}) protected Value y;
+        @Def({REG}) protected Value z;
+        protected Condition condition;
+        protected LabelRef destination;
+        protected boolean unordered = false;
+        @Def({REG}) protected Value result;
+
+        public CompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef destination) {
+            this.condition = condition;
+            this.opcode = opcode;
+            this.x = x;
+            this.y = y;
+            this.z = z;
+            this.result = result;
+            this.destination = destination;
+        }
+
+        @Override
+        public LabelRef destination() {
+            return destination;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            HSAILCompare.emit(tasm, masm, condition, x, y, z, unordered);
+            masm.cbr(masm.nameOf(destination.label()));
+        }
+    }
+
+    public static class FloatCompareBranchOp extends CompareBranchOp {
+
+        public FloatCompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef destination, boolean unordered) {
+            super(opcode, condition, x, y, z, result, destination);
+            this.unordered = unordered;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+            unordered = !unordered;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            HSAILCompare.emit(tasm, masm, condition, x, y, z, unordered);
+            masm.cbr(masm.nameOf(destination.label()));
+        }
+    }
+
+    public static class DoubleCompareBranchOp extends CompareBranchOp {
+
+        public DoubleCompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef destination, boolean unordered) {
+            super(opcode, condition, x, y, z, result, destination);
+            this.unordered = unordered;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+            unordered = !unordered;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            HSAILCompare.emit(tasm, masm, condition, x, y, z, unordered);
+            masm.cbr(masm.nameOf(destination.label()));
+        }
+    }
+
+    public static class BranchOp extends HSAILLIRInstruction implements StandardOp.BranchOp {
+
+        protected Condition condition;
+        protected LabelRef destination;
+        @Def({REG}) protected Value result;
+
+        public BranchOp(Condition condition, Value result, LabelRef destination) {
+            this.condition = condition;
+            this.destination = destination;
+            this.result = result;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            masm.cbr(masm.nameOf(destination.label()));
+        }
+
+        @Override
+        public LabelRef destination() {
+            return destination;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+        }
+    }
+
+    public static class FloatBranchOp extends BranchOp {
+
+        public FloatBranchOp(Condition condition, Value result, LabelRef destination) {
+            super(condition, result, destination);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            masm.cbr(masm.nameOf(destination.label()));
+        }
+    }
+
+    public static class CondMoveOp extends HSAILLIRInstruction {
+
+        @Opcode protected final HSAILCompare opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Alive({REG}) protected Value trueValue;
+        @Use({REG, STACK, CONST}) protected Value falseValue;
+        @Use({REG, STACK, CONST}) protected Value left;
+        @Use({REG, STACK, CONST}) protected Value right;
+        protected final Condition condition;
+
+        public CondMoveOp(HSAILCompare opcode, Variable left, Variable right, Variable result, Condition condition, Variable trueValue, Value falseValue) {
+            this.opcode = opcode;
+            this.result = result;
+            this.left = left;
+            this.right = right;
+            this.condition = condition;
+            this.trueValue = trueValue;
+            this.falseValue = falseValue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            HSAILCompare.emit(tasm, masm, condition, left, right, right, false);
+            cmove(tasm, masm, result, false, trueValue, falseValue);
+        }
+    }
+
+    public static class FloatCondMoveOp extends CondMoveOp {
+
+        private final boolean unorderedIsTrue;
+
+        public FloatCondMoveOp(HSAILCompare opcode, Variable left, Variable right, Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Value falseValue) {
+            super(opcode, left, right, result, condition, trueValue, falseValue);
+            this.unorderedIsTrue = unorderedIsTrue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            HSAILCompare.emit(tasm, masm, condition, left, right, right, unorderedIsTrue);
+            cmove(tasm, masm, result, false, trueValue, falseValue);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void cmove(TargetMethodAssembler tasm, HSAILAssembler masm, Value result, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        // Check that we don't overwrite an input operand before it is used.
+        assert (result.getKind() == trueValue.getKind() && result.getKind() == falseValue.getKind());
+        int width;
+        switch (result.getKind()) {
+        /**
+         * We don't need to pass the cond to the assembler. We will always use $c0 as the control
+         * register.
+         */
+            case Float:
+            case Int:
+                width = 32;
+                break;
+            case Double:
+            case Long:
+                width = 64;
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        masm.cmovCommon(result, trueValue, falseValue, width);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILLIRInstruction.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Convenience class to provide HSAILAssembler for the {@link #emitCode} method.
+ */
+public abstract class HSAILLIRInstruction extends LIRInstruction {
+
+    @Override
+    public final void emitCode(TargetMethodAssembler tasm) {
+        emitCode(tasm, (HSAILAssembler) tasm.asm);
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Tue Jul 09 11:21:06 2013 +0200
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013, 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.hsail;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.MoveOp;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Implementation of move instructions.
+ */
+public class HSAILMove {
+
+    // Stack size in bytes (used to keep track of spilling).
+    static int maxDatatypeSize;
+    // Maximum stack offset used by a store operation.
+    static long maxStackOffset = 0;
+
+    public static long upperBoundStackSize() {
+        return maxStackOffset + maxDatatypeSize;
+    }
+
+    @Opcode("MOVE")
+    public static class SpillMoveOp extends HSAILLIRInstruction implements MoveOp {
+
+        @Def({REG, STACK}) protected AllocatableValue result;
+        @Use({REG, STACK, CONST}) protected Value input;
+
+        public SpillMoveOp(AllocatableValue result, Value input) {
+            this.result = result;
+            this.input = input;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public Value getInput() {
+            return input;
+        }
+
+        @Override
+        public AllocatableValue getResult() {
+            return result;
+        }
+    }
+
+    @Opcode("MOVE")
+    public static class MoveToRegOp extends HSAILLIRInstruction implements MoveOp {
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK, CONST}) protected Value input;
+
+        public MoveToRegOp(AllocatableValue result, Value input) {
+            this.result = result;
+            this.input = input;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public Value getInput() {
+            return input;
+        }
+
+        @Override
+        public AllocatableValue getResult() {
+            return result;
+        }
+    }
+
+    @Opcode("MOVE")
+    public static class MoveFromRegOp extends HSAILLIRInstruction implements MoveOp {
+
+        @Def({REG, STACK}) protected AllocatableValue result;
+        @Use({REG, CONST, HINT}) protected Value input;
+
+        public MoveFromRegOp(AllocatableValue result, Value input) {
+            this.result = result;
+            this.input = input;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public Value getInput() {
+            return input;
+        }
+
+        @Override
+        public AllocatableValue getResult() {
+            return result;
+        }
+    }
+
+    public static class LoadOp extends HSAILLIRInstruction {
+
+        @SuppressWarnings("unused") private final Kind kind;
+        @Def({REG}) protected AllocatableValue result;
+        @Use({COMPOSITE}) protected HSAILAddressValue address;
+        @State protected LIRFrameState state;
+
+        public LoadOp(Kind kind, AllocatableValue result, HSAILAddressValue address, LIRFrameState state) {
+            this.kind = kind;
+            this.result = result;
+            this.address = address;
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            HSAILAddress addr = address.toAddress();
+            masm.emitLoad(result, addr);
+        }
+    }
+
+    public static class StoreOp extends HSAILLIRInstruction {
+
+        @SuppressWarnings("unused") private final Kind kind;
+        @Use({COMPOSITE}) protected HSAILAddressValue address;
+        @Use({REG}) protected AllocatableValue input;
+        @State protected LIRFrameState state;
+
+        public StoreOp(Kind kind, HSAILAddressValue address, AllocatableValue input, LIRFrameState state) {
+            this.kind = kind;
+            this.address = address;
+            this.input = input;
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            assert isRegister(input);
+            HSAILAddress addr = address.toAddress();
+            masm.emitStore(input, addr);
+        }
+    }
+
+    public static class LeaOp extends HSAILLIRInstruction {
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({COMPOSITE, UNINITIALIZED}) protected HSAILAddressValue address;
+
+        public LeaOp(AllocatableValue result, HSAILAddressValue address) {
+            this.result = result;
+            this.address = address;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            throw new InternalError("NYI");
+        }
+    }
+
+    public static class StackLeaOp extends HSAILLIRInstruction {
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
+
+        public StackLeaOp(AllocatableValue result, StackSlot slot) {
+            this.result = result;
+            this.slot = slot;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            throw new InternalError("NYI");
+        }
+    }
+
+    @Opcode("CAS")
+    public static class CompareAndSwapOp extends HSAILLIRInstruction {
+
+        @Def protected AllocatableValue result;
+        @Use({COMPOSITE}) protected HSAILAddressValue address;
+        @Use protected AllocatableValue cmpValue;
+        @Use protected AllocatableValue newValue;
+
+        public CompareAndSwapOp(AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
+            this.result = result;
+            this.address = address;
+            this.cmpValue = cmpValue;
+            this.newValue = newValue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            compareAndSwap(tasm, masm, result, address, cmpValue, newValue);
+        }
+    }
+
+    public static class NullCheckOp extends HSAILLIRInstruction {
+
+        @Use protected Value input;
+        @State protected LIRFrameState state;
+
+        public NullCheckOp(Variable input, LIRFrameState state) {
+            this.input = input;
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+            Debug.log("NullCheckOp unimplemented");
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static void move(TargetMethodAssembler tasm, HSAILAssembler masm, Value result, Value input) {
+        if (isRegister(input)) {
+            if (isRegister(result)) {
+                masm.emitMov(result, input);
+            } else if (isStackSlot(result)) {
+                masm.emitSpillStore(input, result);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isStackSlot(input)) {
+            if (isRegister(result)) {
+                masm.emitSpillLoad(result, input);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(input)) {
+            if (isRegister(result)) {
+                masm.emitMov(result, input);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    protected static void compareAndSwap(TargetMethodAssembler tasm, HSAILAssembler masm, AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
+        throw new InternalError("NYI");
+    }
+}
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Tue Jul 09 11:21:06 2013 +0200
@@ -22,28 +22,19 @@
  */
 package com.oracle.graal.lir.ptx;
 
-import static com.oracle.graal.api.code.ValueUtil.asIntReg;
-import static com.oracle.graal.api.code.ValueUtil.asLongReg;
-import static com.oracle.graal.api.code.ValueUtil.asObjectReg;
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
-import com.oracle.graal.api.code.Register;
 import com.oracle.graal.api.code.CompilationResult.JumpTable;
-import com.oracle.graal.api.meta.Constant;
-import com.oracle.graal.api.meta.Kind;
-import com.oracle.graal.api.meta.Value;
-import com.oracle.graal.asm.Buffer;
-import com.oracle.graal.asm.Label;
-import com.oracle.graal.asm.NumUtil;
-import com.oracle.graal.asm.ptx.AbstractPTXAssembler;
-import com.oracle.graal.asm.ptx.PTXAssembler;
-import com.oracle.graal.graph.GraalInternalError;
-import com.oracle.graal.lir.LabelRef;
-import com.oracle.graal.lir.StandardOp;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.ptx.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.FallThroughOp;
-import com.oracle.graal.lir.Variable;
-import com.oracle.graal.lir.asm.TargetMethodAssembler;
-import com.oracle.graal.nodes.calc.Condition;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.*;
 
 public class PTXControlFlow {
 
@@ -77,10 +68,7 @@
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
             masm.at();
-            Label l = destination.label();
-            // l.addPatchAt(tasm.asm.codeBuffer.position());
-            String target = l.isBound() ? "L" + l.toString() : AbstractPTXAssembler.UNBOUND_TARGET;
-            masm.bra(target);
+            masm.bra(masm.nameOf(destination.label()));
         }
 
         @Override
@@ -172,20 +160,14 @@
                     assert NumUtil.isInt(lc);
                     masm.setp_eq_s32((int) lc, intKey);
                     masm.at();
-                    Label l = keyTargets[i].label();
-                    l.addPatchAt(tasm.asm.codeBuffer.position());
-                    String target = l.isBound() ? "L" + l.toString() : AbstractPTXAssembler.UNBOUND_TARGET;
-                    masm.bra(target);
+                    masm.bra(masm.nameOf(keyTargets[i].label()));
                 }
             } else if (key.getKind() == Kind.Long) {
                 Register longKey = asLongReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
                     masm.setp_eq_s64(tasm.asLongConst(keyConstants[i]), longKey);
                     masm.at();
-                    Label l = keyTargets[i].label();
-                    l.addPatchAt(tasm.asm.codeBuffer.position());
-                    String target = l.isBound() ? "L" + l.toString() : AbstractPTXAssembler.UNBOUND_TARGET;
-                    masm.bra(target);
+                    masm.bra(masm.nameOf(keyTargets[i].label()));
                 }
             } else if (key.getKind() == Kind.Object) {
                 Register intKey = asObjectReg(key);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Tue Jul 09 11:21:06 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -45,6 +46,10 @@
         return object;
     }
 
+    public GuardingPiNode(ValueNode object) {
+        this(object, object.graph().unique(new IsNullNode(object)), true, DeoptimizationReason.NullCheckException, DeoptimizationAction.None, object.stamp().join(StampFactory.objectNonNull()));
+    }
+
     public GuardingPiNode(ValueNode object, ValueNode condition, boolean negateCondition, DeoptimizationReason reason, DeoptimizationAction action, Stamp stamp) {
         super(object.stamp().join(stamp));
         assert stamp() != null;
@@ -83,6 +88,9 @@
     }
 
     @NodeIntrinsic
+    public static native <T> T guardingNonNull(T object);
+
+    @NodeIntrinsic
     public static native Object guardingPi(Object object, LogicNode condition, @ConstantNodeParameter boolean negateCondition, @ConstantNodeParameter DeoptimizationReason reason,
                     @ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter Stamp stamp);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Jul 09 11:21:06 2013 +0200
@@ -42,7 +42,7 @@
         super(object, location, stamp, guard, barrierType, compress);
     }
 
-    private ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) {
+    public ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) {
         super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Tue Jul 09 11:21:06 2013 +0200
@@ -24,9 +24,10 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-public abstract class UnsafeAccessNode extends FixedWithNextNode {
+public abstract class UnsafeAccessNode extends FixedWithNextNode implements Canonicalizable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -57,4 +58,39 @@
     public Kind accessKind() {
         return accessKind;
     }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (offset().isConstant()) {
+            long constantOffset = offset().asConstant().asLong();
+
+            // Try to canonicalize to a field access.
+            if (object().stamp() instanceof ObjectStamp) {
+                // TODO (gd) remove that once UnsafeAccess only have an object base
+                ObjectStamp receiverStamp = object().objectStamp();
+                ResolvedJavaType receiverType = receiverStamp.type();
+                if (receiverType != null) {
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement() + constantOffset);
+                    // No need for checking that the receiver is non-null. The field access includes
+                    // the null check and if a field is found, the offset is so small that this is
+                    // never a valid access of an arbitrary address.
+                    if (field != null && field.getKind() == this.accessKind()) {
+                        return cloneAsFieldAccess(field);
+                    }
+                }
+            }
+
+            if (constantOffset != 0 && Integer.MAX_VALUE - displacement() >= constantOffset) {
+                int intDisplacement = (int) (constantOffset + displacement());
+                if (constantOffset == intDisplacement) {
+                    return cloneWithZeroOffset(intDisplacement);
+                }
+            }
+        }
+        return this;
+    }
+
+    protected abstract ValueNode cloneAsFieldAccess(ResolvedJavaField field);
+
+    protected abstract ValueNode cloneWithZeroOffset(int intDisplacement);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Tue Jul 09 11:21:06 2013 +0200
@@ -25,7 +25,6 @@
 import static com.oracle.graal.graph.UnsafeAccess.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
@@ -35,7 +34,7 @@
  * Load of a value from a location specified as an offset relative to an object. No null check is
  * performed before the load.
  */
-public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable, Canonicalizable {
+public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable {
 
     public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) {
         this(nonNull ? StampFactory.objectNonNull() : StampFactory.object(), object, displacement, offset, Kind.Object);
@@ -70,29 +69,13 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (offset().isConstant()) {
-            long constantOffset = offset().asConstant().asLong();
-            if (constantOffset != 0) {
-                int intDisplacement = (int) (constantOffset + displacement());
-                if (constantOffset == intDisplacement) {
-                    Graph graph = this.graph();
-                    return graph.add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph.unique(ConstantNode.forInt(0, graph)), accessKind()));
-                }
-            } else if (object().stamp() instanceof ObjectStamp) { // TODO (gd) remove that once
-                                                                  // UnsafeAccess only have an
-                                                                  // object base
-                ObjectStamp receiverStamp = object().objectStamp();
-                ResolvedJavaType receiverType = receiverStamp.type();
-                if (receiverStamp.nonNull() && receiverType != null) {
-                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
-                    if (field != null) {
-                        return this.graph().add(new LoadFieldNode(object(), field));
-                    }
-                }
-            }
-        }
-        return this;
+    protected ValueNode cloneAsFieldAccess(ResolvedJavaField field) {
+        return this.graph().add(new LoadFieldNode(object(), field));
+    }
+
+    @Override
+    protected ValueNode cloneWithZeroOffset(int intDisplacement) {
+        return graph().add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph().unique(ConstantNode.forInt(0, graph())), accessKind()));
     }
 
     @SuppressWarnings("unchecked")
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Tue Jul 09 11:21:06 2013 +0200
@@ -34,7 +34,7 @@
  * Store of a value at a location specified as an offset relative to an object. No null check is
  * performed before the store.
  */
-public class UnsafeStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, Canonicalizable, MemoryCheckpoint.Single {
+public class UnsafeStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, MemoryCheckpoint.Single {
 
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
@@ -94,32 +94,17 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (offset().isConstant()) {
-            long constantOffset = offset().asConstant().asLong();
-            if (constantOffset != 0) {
-                int intDisplacement = (int) (constantOffset + displacement());
-                if (constantOffset == intDisplacement) {
-                    UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(stamp(), object(), intDisplacement, ConstantNode.forInt(0, graph()), value(), accessKind()));
-                    unsafeStoreNode.setStateAfter(stateAfter());
-                    return unsafeStoreNode;
-                }
-            } else if (object().stamp() instanceof ObjectStamp) { // TODO (gd) remove that once
-                                                                  // UnsafeAccess only have an
-                                                                  // object base
-                ObjectStamp receiverStamp = object().objectStamp();
-                if (receiverStamp.nonNull()) {
-                    ResolvedJavaType receiverType = receiverStamp.type();
-                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
-                    if (field != null) {
-                        StoreFieldNode storeFieldNode = graph().add(new StoreFieldNode(object(), field, value()));
-                        storeFieldNode.setStateAfter(stateAfter());
-                        return storeFieldNode;
-                    }
-                }
-            }
-        }
-        return this;
+    protected ValueNode cloneAsFieldAccess(ResolvedJavaField field) {
+        StoreFieldNode storeFieldNode = graph().add(new StoreFieldNode(object(), field, value()));
+        storeFieldNode.setStateAfter(stateAfter());
+        return storeFieldNode;
+    }
+
+    @Override
+    protected ValueNode cloneWithZeroOffset(int intDisplacement) {
+        UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(stamp(), object(), intDisplacement, ConstantNode.forInt(0, graph()), value(), accessKind()));
+        unsafeStoreNode.setStateAfter(stateAfter());
+        return unsafeStoreNode;
     }
 
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jul 09 11:21:06 2013 +0200
@@ -331,27 +331,7 @@
                 assert inlineable instanceof InlineableMacroNode;
 
                 Class<? extends FixedWithNextNode> macroNodeClass = ((InlineableMacroNode) inlineable).getMacroNodeClass();
-                if (((MethodCallTargetNode) invoke.callTarget()).targetMethod() != concrete) {
-                    assert ((MethodCallTargetNode) invoke.callTarget()).invokeKind() != InvokeKind.Static;
-                    InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
-                }
-
-                FixedWithNextNode macroNode;
-                try {
-                    macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke);
-                } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
-                    throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass);
-                }
-
-                CallTargetNode callTarget = invoke.callTarget();
-                if (invoke instanceof InvokeNode) {
-                    graph.replaceFixedWithFixed((InvokeNode) invoke, graph.add(macroNode));
-                } else {
-                    InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
-                    invokeWithException.killExceptionEdge();
-                    graph.replaceSplitWithFixed(invokeWithException, graph.add(macroNode), invokeWithException.next());
-                }
-                GraphUtil.killWithUnusedFloatingInputs(callTarget);
+                inlineMacroNode(invoke, concrete, graph, macroNodeClass);
             }
 
             InlinedBytecodes.add(concrete.getCodeSize());
@@ -1480,4 +1460,29 @@
     public static Class<? extends FixedWithNextNode> getMacroNodeClass(Replacements replacements, ResolvedJavaMethod target) {
         return replacements.getMacroSubstitution(target);
     }
+
+    public static FixedWithNextNode inlineMacroNode(Invoke invoke, ResolvedJavaMethod concrete, StructuredGraph graph, Class<? extends FixedWithNextNode> macroNodeClass) throws GraalInternalError {
+        if (((MethodCallTargetNode) invoke.callTarget()).targetMethod() != concrete) {
+            assert ((MethodCallTargetNode) invoke.callTarget()).invokeKind() != InvokeKind.Static;
+            InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
+        }
+
+        FixedWithNextNode macroNode;
+        try {
+            macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke);
+        } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
+            throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass);
+        }
+
+        CallTargetNode callTarget = invoke.callTarget();
+        if (invoke instanceof InvokeNode) {
+            graph.replaceFixedWithFixed((InvokeNode) invoke, graph.add(macroNode));
+        } else {
+            InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
+            invokeWithException.killExceptionEdge();
+            graph.replaceSplitWithFixed(invokeWithException, graph.add(macroNode), invokeWithException.next());
+        }
+        GraphUtil.killWithUnusedFloatingInputs(callTarget);
+        return macroNode;
+    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Jul 09 11:21:06 2013 +0200
@@ -231,14 +231,12 @@
                     if (node == beginNode) {
                         loweringTool.setLastFixedNode(beginNode);
                     } else if (node instanceof Lowerable) {
-                        // Handles cases where there is a lowerable nodes scheduled before the begin
+                        // Handles cases where there are lowerable nodes scheduled before the begin
                         // node.
                         BeginNode newBegin = node.graph().add(new BeginNode());
                         beginNode.replaceAtPredecessor(newBegin);
                         newBegin.setNext(beginNode);
                         loweringTool.setLastFixedNode(newBegin);
-                    } else if (node == beginNode) {
-                        loweringTool.setLastFixedNode(beginNode);
                     } else {
                         continue;
                     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java	Tue Jul 09 11:21:06 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.replacements;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -36,9 +34,6 @@
 
     @MethodSubstitution
     public static Object newInstance(Class<?> componentType, int length) throws NegativeArraySizeException {
-        if (componentType == null) {
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.NullCheckException);
-        }
-        return DynamicNewArrayNode.newArray(componentType, length);
+        return DynamicNewArrayNode.newArray(GuardingPiNode.guardingNonNull(componentType), length);
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Jul 09 11:21:06 2013 +0200
@@ -71,37 +71,43 @@
 
     @Override
     public Object call(PackedFrame caller, Arguments args) {
-        for (;;) {
-            if (compiledMethod != null) {
-                try {
-                    return compiledMethod.execute(this, caller, args);
-                } catch (InvalidInstalledCodeException ex) {
-                    compiledMethod = null;
-                    invokeCounter = invalidationReprofileCount;
-                    if (TruffleFunctionInlining.getValue()) {
-                        originalInvokeCounter += invalidationReprofileCount;
-                    }
-                    if (TraceTruffleCompilation.getValue()) {
-                        OUT.printf("[truffle] invalidated %-48s |Alive %5.0fms\n", rootNode, (System.nanoTime() - timeCompilationFinished) / 1e6);
-                    }
-                }
+        if (CompilerDirectives.injectBranchProbability(CompilerDirectives.FASTPATH_PROBABILITY, compiledMethod != null)) {
+            try {
+                return compiledMethod.execute(this, caller, args);
+            } catch (InvalidInstalledCodeException ex) {
+                return compiledCodeInvalidated(caller, args);
+            }
+        } else {
+            return interpreterCall(caller, args);
+        }
+    }
+
+    protected Object compiledCodeInvalidated(PackedFrame caller, Arguments args) {
+        compiledMethod = null;
+        invokeCounter = invalidationReprofileCount;
+        if (TruffleFunctionInlining.getValue()) {
+            originalInvokeCounter += invalidationReprofileCount;
+        }
+        if (TraceTruffleCompilation.getValue()) {
+            OUT.printf("[truffle] invalidated %-48s |Alive %5.0fms\n", rootNode, (System.nanoTime() - timeCompilationFinished) / 1e6);
+        }
+        return call(caller, args);
+    }
+
+    private Object interpreterCall(PackedFrame caller, Arguments args) {
+        invokeCounter--;
+        loopAndInvokeCounter--;
+        if (disableCompilation || loopAndInvokeCounter > 0 || invokeCounter > 0) {
+            return executeHelper(caller, args);
+        } else {
+            if (TruffleFunctionInlining.getValue() && inline()) {
+                invokeCounter = 2;
+                loopAndInvokeCounter = inliningReprofileCount;
+                originalInvokeCounter = inliningReprofileCount;
             } else {
-                invokeCounter--;
-                loopAndInvokeCounter--;
-                if (disableCompilation || loopAndInvokeCounter > 0 || invokeCounter > 0) {
-                    return executeHelper(caller, args);
-                } else {
-                    if (TruffleFunctionInlining.getValue()) {
-                        if (inline()) {
-                            invokeCounter = 2;
-                            loopAndInvokeCounter = inliningReprofileCount;
-                            originalInvokeCounter = inliningReprofileCount;
-                            continue;
-                        }
-                    }
-                    compile();
-                }
+                compile();
             }
+            return call(caller, args);
         }
     }
 
@@ -260,7 +266,7 @@
 
                 @Override
                 public boolean visit(Node node) {
-                    if (node instanceof RootNode && node != root) {
+                    if (node instanceof RootNode && visitedCount > 0) {
                         return false;
                     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Tue Jul 09 11:21:06 2013 +0200
@@ -26,7 +26,6 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.common.*;
@@ -68,41 +67,8 @@
                     return ConstantNode.forObject(value, metaAccessProvider, node.graph());
                 }
             }
-        } else if (node instanceof UnsafeLoadNode) {
-            UnsafeLoadNode unsafeLoadNode = (UnsafeLoadNode) node;
-            if (unsafeLoadNode.offset().isConstant()) {
-                long offset = unsafeLoadNode.offset().asConstant().asLong() + unsafeLoadNode.displacement();
-                ResolvedJavaType type = unsafeLoadNode.object().objectStamp().type();
-                ResolvedJavaField field = recursiveFindFieldWithOffset(type, offset);
-                if (field != null) {
-                    return node.graph().add(new LoadFieldNode(unsafeLoadNode.object(), field));
-                }
-            }
-        } else if (node instanceof UnsafeStoreNode) {
-            UnsafeStoreNode unsafeStoreNode = (UnsafeStoreNode) node;
-            if (unsafeStoreNode.offset().isConstant()) {
-                long offset = unsafeStoreNode.offset().asConstant().asLong() + unsafeStoreNode.displacement();
-                ResolvedJavaType type = unsafeStoreNode.object().objectStamp().type();
-                ResolvedJavaField field = recursiveFindFieldWithOffset(type, offset);
-                if (field != null) {
-                    StoreFieldNode storeFieldNode = node.graph().add(new StoreFieldNode(unsafeStoreNode.object(), field, unsafeStoreNode.value()));
-                    storeFieldNode.setStateAfter(unsafeStoreNode.stateAfter());
-                    return storeFieldNode;
-                }
-            }
         }
 
         return node;
     }
-
-    private ResolvedJavaField recursiveFindFieldWithOffset(ResolvedJavaType type, long offset) {
-        if (type != null) {
-            ResolvedJavaField field = type.findInstanceFieldWithOffset(offset);
-            if (field != null) {
-                return field;
-            }
-            return recursiveFindFieldWithOffset(type.getSuperclass(), offset);
-        }
-        return null;
-    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Tue Jul 09 11:21:06 2013 +0200
@@ -216,25 +216,25 @@
         if (invoke.callTarget() instanceof MethodCallTargetNode) {
             final MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) invoke.callTarget();
             if ((methodCallTargetNode.invokeKind() == InvokeKind.Special || methodCallTargetNode.invokeKind() == InvokeKind.Static) &&
-                            !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers())) {
-                if (methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) != null) {
-                    // Do not inline explode loop methods, they need canonicalization and forced
-                    // unrolling.
-                    return invoke.asNode();
-                }
-                StructuredGraph inlinedGraph = Debug.scope("ExpandInvoke", methodCallTargetNode.targetMethod(), new Callable<StructuredGraph>() {
+                            !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers()) && methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null) {
+                Class<? extends FixedWithNextNode> macroSubstitution = replacements.getMacroSubstitution(methodCallTargetNode.targetMethod());
+                if (macroSubstitution != null) {
+                    return InliningUtil.inlineMacroNode(invoke, methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution);
+                } else {
+                    StructuredGraph inlinedGraph = Debug.scope("ExpandInvoke", methodCallTargetNode.targetMethod(), new Callable<StructuredGraph>() {
 
-                    public StructuredGraph call() {
-                        StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
-                        if (inlineGraph == null) {
-                            inlineGraph = parseGraph(methodCallTargetNode.targetMethod());
+                        public StructuredGraph call() {
+                            StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
+                            if (inlineGraph == null) {
+                                inlineGraph = parseGraph(methodCallTargetNode.targetMethod());
+                            }
+                            return inlineGraph;
                         }
-                        return inlineGraph;
-                    }
-                });
-                FixedNode fixedNode = (FixedNode) invoke.predecessor();
-                InliningUtil.inline(invoke, inlinedGraph, true);
-                return fixedNode;
+                    });
+                    FixedNode fixedNode = (FixedNode) invoke.predecessor();
+                    InliningUtil.inline(invoke, inlinedGraph, true);
+                    return fixedNode;
+                }
             }
         }
         return invoke.asNode();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/UnsafeCastMacroNode.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/UnsafeCastMacroNode.java	Tue Jul 09 11:21:06 2013 +0200
@@ -41,7 +41,10 @@
             Class c = (Class) arguments.get(1).asConstant().asObject();
             ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c);
             Stamp s = StampFactory.declaredNonNull(lookupJavaType);
-            return graph().unique(new UnsafeCastNode(arguments.get(0), s));
+            ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode());
+            UnsafeCastNode unsafeCast = graph().unique(new UnsafeCastNode(arguments.get(0), s, (GuardingNode) valueAnchorNode));
+            this.replaceAtUsages(unsafeCast);
+            return valueAnchorNode;
         }
         return this;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Tue Jul 09 11:21:06 2013 +0200
@@ -57,4 +57,7 @@
 
     @MacroSubstitution(macro = BailoutNode.class, isStatic = true)
     public static native void bailout(String reason);
+
+    @MacroSubstitution(macro = UnsafeCastMacroNode.class, isStatic = true)
+    public static native Object unsafeCast(Object value, Class clazz);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Tue Jul 09 11:21:06 2013 +0200
@@ -33,7 +33,7 @@
 public class OptimizedCallTargetSubstitutions {
 
     @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
-    public static native Object call(OptimizedCallTarget target, PackedFrame caller, Arguments args);
+    public static native Object interpreterCall(OptimizedCallTarget target, PackedFrame caller, Arguments args);
 
     @MethodSubstitution
     private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Tue Jul 09 11:19:53 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Tue Jul 09 11:21:06 2013 +0200
@@ -126,4 +126,17 @@
     @Target({ElementType.METHOD})
     public @interface Unsafe {
     }
+
+    /**
+     * Treats the given value as a value of the given class. The class must evaluate to a constant.
+     * 
+     * @param value the value that is known to have the specified type
+     * @param clazz the specified type of the value
+     * @return the value
+     */
+    @SuppressWarnings("unchecked")
+    @Unsafe
+    public static <T> T unsafeCast(Object value, Class<T> clazz) {
+        return (T) value;
+    }
 }
--- a/mx/projects	Tue Jul 09 11:19:53 2013 +0200
+++ b/mx/projects	Tue Jul 09 11:21:06 2013 +0200
@@ -24,8 +24,11 @@
 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar
 library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar
 
+library@OKRA@path=lib/okra-1.jar
+library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.jar
+
 distribution@GRAAL@path=graal.jar
-distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.truffle,com.oracle.graal.truffle.printer,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot
+distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.truffle,com.oracle.graal.truffle.printer,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail
 
 # graal.api.runtime
 project@com.oracle.graal.api.runtime@subDir=graal
@@ -466,6 +469,49 @@
 project@com.oracle.graal.asm.amd64.test@javaCompliance=1.7
 project@com.oracle.graal.asm.amd64.test@workingSets=Graal,Assembler,AMD64,Test
 
+# graal.hsail
+project@com.oracle.graal.hsail@subDir=graal
+project@com.oracle.graal.hsail@sourceDirs=src
+project@com.oracle.graal.hsail@dependencies=com.oracle.graal.api.code,com.oracle.graal.graph
+project@com.oracle.graal.hsail@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.hsail@javaCompliance=1.7
+
+# graal.lir.hsail
+project@com.oracle.graal.lir.hsail@subDir=graal
+project@com.oracle.graal.lir.hsail@sourceDirs=src
+project@com.oracle.graal.lir.hsail@dependencies=com.oracle.graal.lir,com.oracle.graal.asm.hsail
+project@com.oracle.graal.lir.hsail@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.lir.hsail@javaCompliance=1.7
+
+# graal.compiler.hsail
+project@com.oracle.graal.compiler.hsail@subDir=graal
+project@com.oracle.graal.compiler.hsail@sourceDirs=src
+project@com.oracle.graal.compiler.hsail@dependencies=com.oracle.graal.lir.hsail,com.oracle.graal.hotspot.amd64
+project@com.oracle.graal.compiler.hsail@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.compiler.hsail@javaCompliance=1.7
+
+# graal.compiler.hsail.test.infra - HSAIL compiler test infrastructure
+project@com.oracle.graal.compiler.hsail.test.infra@subDir=graal
+project@com.oracle.graal.compiler.hsail.test.infra@sourceDirs=src
+project@com.oracle.graal.compiler.hsail.test.infra@dependencies=com.oracle.graal.compiler.hsail,JUNIT
+project@com.oracle.graal.compiler.hsail.test.infra@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.compiler.hsail.test.infra@javaCompliance=1.7
+
+# graal.compiler.hsail.test
+project@com.oracle.graal.compiler.hsail.test@subDir=graal
+project@com.oracle.graal.compiler.hsail.test@sourceDirs=src
+project@com.oracle.graal.compiler.hsail.test@dependencies=com.oracle.graal.compiler.hsail.test.infra,com.oracle.graal.compiler.test
+project@com.oracle.graal.compiler.hsail.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.compiler.hsail.test@javaCompliance=1.7
+
+
+# graal.asm.hsail
+project@com.oracle.graal.asm.hsail@subDir=graal
+project@com.oracle.graal.asm.hsail@sourceDirs=src
+project@com.oracle.graal.asm.hsail@dependencies=com.oracle.graal.hsail,OKRA,com.oracle.graal.asm
+project@com.oracle.graal.asm.hsail@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.asm.hsail@javaCompliance=1.7
+
 # graal.asm.ptx
 project@com.oracle.graal.asm.ptx@subDir=graal
 project@com.oracle.graal.asm.ptx@sourceDirs=src
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Tue Jul 09 11:19:53 2013 +0200
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Tue Jul 09 11:21:06 2013 +0200
@@ -179,7 +179,6 @@
       break;
     }
     default:
-      fatal("invalid _next_call_type value");
       break;
   }
 }