graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java
Print this page
*** 77,93 ****
* 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");
}
}
--- 77,95 ----
* 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) {
+ String regName = "$d" + a.encoding();
if (obj instanceof Class) {
Class<?> clazz = (Class<?>) obj;
long refHandle = OkraUtil.getRefHandle(clazz);
String className = clazz.getName();
emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + "; // handle for " + className);
emitString("ld_global_u64 " + regName + ", [" + regName + "];");
+ } else if (obj == null) {
+ emitString("mov_b64 " + regName + ", 0x0; // null object");
} else {
throw GraalInternalError.shouldNotReachHere("mov from object not a class");
}
}
*** 99,118 ****
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) {
--- 101,136 ----
String argtype = getArgType(dst).substring(1);
emitString("mov_b" + argtype + " " + mapRegOrConstToString(dst) + ", " + mapRegOrConstToString(src) + ";");
}
}
+ private void emitAddrOp(String instr, Value reg, HSAILAddress addr) {
+ emitString(instr + " " + HSAIL.mapRegister(reg) + ", " + mapAddress(addr) + ";");
+ }
+
public final void emitLoad(Value dest, HSAILAddress addr) {
! emitLoad(dest, addr, getArgType(dest));
}
! public final void emitLoad(Value dest, HSAILAddress addr, String argTypeStr) {
! emitAddrOp("ld_global_" + argTypeStr, dest, addr);
! }
!
! public final void emitLda(Value dest, HSAILAddress addr) {
! emitAddrOp("lda_global_u64", dest, addr);
}
public final void emitStore(Value src, HSAILAddress addr) {
! emitStore(src, addr, getArgType(src));
! }
!
! public final void emitStore(Value dest, HSAILAddress addr, String argTypeStr) {
! emitAddrOp("st_global_" + argTypeStr, dest, addr);
! }
!
! public final void emitSpillLoad(Value dest, Value src) {
! emitString("ld_spill_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + mapStackSlot(src, getArgSize(dest)) + ";");
}
public final void emitSpillStore(Value src, Value dest) {
int sizestored = getArgSize(src);
if (maxDataTypeSize < sizestored) {
*** 120,130 ****
}
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 + ";");
}
--- 138,162 ----
}
int stackoffset = HSAIL.getStackOffset(dest);
if (maxStackOffset < stackoffset) {
maxStackOffset = stackoffset;
}
! emitString("st_spill_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + mapStackSlot(dest, getArgSize(src)) + ";");
! }
!
! /**
! * The mapping to stack slots is always relative to the beginning
! * of the spillseg. HSAIL.getStackOffset returns the positive
! * version of the originally negative offset. Then we back up
! * from that by the argSize in bytes. This ensures that slots of
! * different size do not overlap, even though we have converted
! * from negative to positive offsets.
! */
! public static String mapStackSlot(Value reg, int argSize) {
! long offset = HSAIL.getStackOffset(reg);
! int argSizeBytes = argSize / 8;
! return "[%spillseg]" + "[" + (offset - argSizeBytes) + "]";
}
public void cbr(String target1) {
emitString("cbr " + "$c0" + ", " + target1 + ";");
}
*** 179,189 ****
}
}
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) + ";");
--- 211,223 ----
}
}
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));
! String comment = (isConstant(src1) && (src1.getKind() == Kind.Object)
! && (asConstant(src1).asObject() == null) ? " // null test " : "");
! emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";" + comment);
}
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) + ";");
*** 208,218 ****
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);
}
}
--- 242,259 ----
case Float:
return Float.toString(consrc.asFloat()) + "f";
case Double:
return Double.toString(consrc.asDouble());
case Long:
! return "0x" + Long.toHexString(consrc.asLong());
! case Object:
! Object obj = consrc.asObject();
! if (obj == null) {
! return "0";
! } else {
! throw GraalInternalError.shouldNotReachHere("unknown type: " + src);
! }
default:
throw GraalInternalError.shouldNotReachHere("unknown type: " + src);
}
}
*** 221,236 ****
--- 262,331 ----
public final void emit(String mnemonic, Value dest, Value src0, Value src1) {
String prefix = getArgType(dest);
emit(mnemonic + "_" + prefix, dest, "", src0, src1);
}
+ public final void emitForceUnsigned(String mnemonic, Value dest, Value src0, Value src1) {
+ String prefix = getArgTypeForceUnsigned(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)));
}
+ private void emit(String instr, Value dest, Value src0, Value src1, Value src2) {
+ assert (!isConstant(dest));
+ emitString(String.format("%s %s, %s, %s, %s;", instr, HSAIL.mapRegister(dest), mapRegOrConstToString(src0),
+ mapRegOrConstToString(src1), mapRegOrConstToString(src2)));
+ }
+
+
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);
}
+
+ /**
+ * Emit code to build a 64-bit pointer from a compressed-oop and the associated base and shift.
+ * We only emit this if base and shift are not both zero.
+ */
+ public void emitCompressedOopDecode(Value result, long narrowOopBase, int narrowOopShift) {
+ if (narrowOopBase == 0) {
+ emit("shl", result, result, Constant.forInt(narrowOopShift));
+ } else if (narrowOopShift == 0) {
+ // only use add if result is not starting as null (unsigned compare)
+ emitCompare(result, Constant.forLong(0), "eq", false, true);
+ emit("add", result, result, Constant.forLong(narrowOopBase));
+ cmovCommon(result, Constant.forLong(0), result, 64);
+ } else {
+ // only use mad if result is not starting as null (unsigned compare)
+ emitCompare(result, Constant.forLong(0), "eq", false, true);
+ emit("mad_u64 ", result, result, Constant.forInt(1 << narrowOopShift), Constant.forLong(narrowOopBase));
+ cmovCommon(result, Constant.forLong(0), result, 64);
+ }
+ }
+
+ /**
+ * Emit code to build a 32-bit compressed pointer from a full
+ * 64-bit pointer using the associated base and shift. We only
+ * emit this if base and shift are not both zero.
+ */
+ public void emitCompressedOopEncode(Value result, long narrowOopBase, int narrowOopShift) {
+ if (narrowOopBase != 0) {
+ // only use sub if result is not starting as null (unsigned compare)
+ emitCompare(result, Constant.forLong(0), "eq", false, true);
+ emit("sub", result, result, Constant.forLong(narrowOopBase));
+ cmovCommon(result, Constant.forLong(0), result, 64);
+ }
+ if (narrowOopShift != 0) {
+ emit("shr", result, result, Constant.forInt(narrowOopShift));
+ }
+ }
+
+ public void emitComment(String comment) {
+ emitString(comment);
+ }
}