--- /dev/null 2013-07-08 15:00:07.000000000 -0700 +++ new/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java 2013-07-08 15:00:07.000000000 -0700 @@ -0,0 +1,70 @@ +/* + * 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 java.util.*; + +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 { + + private final Map nameMap = new HashMap<>(); + + public AbstractHSAILAssembler(TargetDescription target) { + super(target); + } + + public String nameOf(Label l) { + String name = nameMap.get(l); + if (name == null) { + name = "@L" + nameMap.size(); + nameMap.put(l, name); + } + return name; + } + + @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 2013-07-08 15:00:08.000000000 -0700 +++ new/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAddress.java 2013-07-08 15:00:08.000000000 -0700 @@ -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 2013-07-08 15:00:10.000000000 -0700 +++ new/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java 2013-07-08 15:00:10.000000000 -0700 @@ -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); + } + +} --- old/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java 2013-07-08 15:00:12.000000000 -0700 +++ new/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java 2013-07-08 15:00:12.000000000 -0700 @@ -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); } --- /dev/null 2013-07-08 15:00:18.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java 2013-07-08 15:00:18.000000000 -0700 @@ -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 2013-07-08 15:00:19.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java 2013-07-08 15:00:19.000000000 -0700 @@ -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 getLambdaMethodNames() { + Class clazz = this.getClass(); + ArrayList 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 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 2013-07-08 15:00:21.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java 2013-07-08 15:00:21.000000000 -0700 @@ -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 2013-07-08 15:00:22.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/CallTest.java 2013-07-08 15:00:22.000000000 -0700 @@ -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 2013-07-08 15:00:24.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FcompUnorderedTest.java 2013-07-08 15:00:23.000000000 -0700 @@ -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 2013-07-08 15:00:25.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatConvertTest.java 2013-07-08 15:00:25.000000000 -0700 @@ -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 2013-07-08 15:00:27.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatDivPrecisionTest.java 2013-07-08 15:00:26.000000000 -0700 @@ -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 2013-07-08 15:00:28.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java 2013-07-08 15:00:28.000000000 -0700 @@ -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 2013-07-08 15:00:29.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntAddIndexTest.java 2013-07-08 15:00:28.000000000 -0700 @@ -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 2013-07-08 15:00:30.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntAddTest.java 2013-07-08 15:00:30.000000000 -0700 @@ -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 2013-07-08 15:00:31.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntDivTest.java 2013-07-08 15:00:31.000000000 -0700 @@ -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 2013-07-08 15:00:32.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntDoubledTest.java 2013-07-08 15:00:32.000000000 -0700 @@ -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 2013-07-08 15:00:33.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntFloatConvertTest.java 2013-07-08 15:00:33.000000000 -0700 @@ -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 2013-07-08 15:00:34.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntLongConvertTest.java 2013-07-08 15:00:34.000000000 -0700 @@ -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 2013-07-08 15:00:35.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntModTest.java 2013-07-08 15:00:35.000000000 -0700 @@ -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 2013-07-08 15:00:36.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntMulTest.java 2013-07-08 15:00:36.000000000 -0700 @@ -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 2013-07-08 15:00:37.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSqrAddTest.java 2013-07-08 15:00:37.000000000 -0700 @@ -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 2013-07-08 15:00:39.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSquaredGidCmpTest.java 2013-07-08 15:00:38.000000000 -0700 @@ -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 2013-07-08 15:00:40.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSquaredTernaryTest.java 2013-07-08 15:00:40.000000000 -0700 @@ -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 2013-07-08 15:00:42.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSquaredTest.java 2013-07-08 15:00:41.000000000 -0700 @@ -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 2013-07-08 15:00:43.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSubTest.java 2013-07-08 15:00:42.000000000 -0700 @@ -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 2013-07-08 15:00:44.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntSumArrayTest.java 2013-07-08 15:00:43.000000000 -0700 @@ -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 2013-07-08 15:00:45.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticDoubleSpillTest.java 2013-07-08 15:00:45.000000000 -0700 @@ -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 2013-07-08 15:00:46.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticIntSpillTest.java 2013-07-08 15:00:46.000000000 -0700 @@ -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 2013-07-08 15:00:47.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java 2013-07-08 15:00:47.000000000 -0700 @@ -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 2013-07-08 15:00:48.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java 2013-07-08 15:00:48.000000000 -0700 @@ -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 2013-07-08 15:00:49.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethodThreeIntArrays.java 2013-07-08 15:00:49.000000000 -0700 @@ -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 2013-07-08 15:00:50.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethodTwoIntArrays.java 2013-07-08 15:00:50.000000000 -0700 @@ -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 2013-07-08 15:00:51.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java 2013-07-08 15:00:51.000000000 -0700 @@ -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 2013-07-08 15:00:52.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java 2013-07-08 15:00:52.000000000 -0700 @@ -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 2013-07-08 15:00:56.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/CompileAndDispatch.java 2013-07-08 15:00:55.000000000 -0700 @@ -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 2013-07-08 15:00:57.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java 2013-07-08 15:00:56.000000000 -0700 @@ -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 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 2013-07-08 15:00:58.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java 2013-07-08 15:00:58.000000000 -0700 @@ -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 paramTypeMap = new HashMap<>(); + private Buffer codeBuffer; + + public HSAILBackend(CodeCacheProvider runtime, TargetDescription target) { + super(runtime, target); + paramTypeMap.put("HotSpotResolvedPrimitiveType", "s32"); + paramTypeMap.put("HotSpotResolvedPrimitiveType", "f32"); + paramTypeMap.put("HotSpotResolvedPrimitiveType", "f64"); + paramTypeMap.put("HotSpotResolvedPrimitiveType", "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 2013-07-08 15:00:59.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java 2013-07-08 15:00:59.000000000 -0700 @@ -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 2013-07-08 15:01:00.000000000 -0700 +++ new/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java 2013-07-08 15:01:00.000000000 -0700 @@ -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"); + } +} --- old/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java 2013-07-08 15:01:02.000000000 -0700 +++ new/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java 2013-07-08 15:01:01.000000000 -0700 @@ -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)); } --- /dev/null 2013-07-08 15:01:07.000000000 -0700 +++ new/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java 2013-07-08 15:01:07.000000000 -0700 @@ -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 2013-07-08 15:01:11.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILAddressValue.java 2013-07-08 15:01:11.000000000 -0700 @@ -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 2013-07-08 15:01:12.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java 2013-07-08 15:01:12.000000000 -0700 @@ -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 2013-07-08 15:01:13.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java 2013-07-08 15:01:13.000000000 -0700 @@ -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 2013-07-08 15:01:14.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java 2013-07-08 15:01:14.000000000 -0700 @@ -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 2013-07-08 15:01:15.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java 2013-07-08 15:01:15.000000000 -0700 @@ -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 2013-07-08 15:01:16.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILLIRInstruction.java 2013-07-08 15:01:16.000000000 -0700 @@ -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 2013-07-08 15:01:17.000000000 -0700 +++ new/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java 2013-07-08 15:01:17.000000000 -0700 @@ -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"); + } +} --- old/mx/projects 2013-07-08 15:01:18.000000000 -0700 +++ new/mx/projects 2013-07-08 15:01:18.000000000 -0700 @@ -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