use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode in project sulong by graalvm.
the class AsmFactory method createRep.
private void createRep(LLVMExpressionNode body) {
if ("rep".equals(currentPrefix)) {
LLVMExpressionNode rcx = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rcx"));
LLVMAMD64WriteValueNode writeRCX = getStore(PrimitiveType.I64, new AsmRegisterOperand("rcx"));
LLVMExpressionNode rep = new LLVMAMD64RepNode(writeRCX, rcx, body);
statements.add(rep);
} else {
statements.add(body);
}
}
use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode in project sulong by graalvm.
the class AsmFactory method getOperandStore.
private LLVMExpressionNode getOperandStore(Type type, AsmOperand operand, LLVMExpressionNode from) {
if (operand instanceof AsmRegisterOperand) {
AsmRegisterOperand op = (AsmRegisterOperand) operand;
FrameSlot frame = getRegisterSlot(op.getBaseRegister());
LLVMExpressionNode register = LLVMAMD64ReadRegisterNodeGen.create(frame);
int shift = op.getShift();
LLVMExpressionNode out = null;
assert (type instanceof PointerType && op.getType() == PrimitiveType.I64) || (op.getType() instanceof PointerType && type == PrimitiveType.I64) || (type == op.getType());
switch(((PrimitiveType) op.getType()).getPrimitiveKind()) {
case I8:
out = LLVMI8ToR64NodeGen.create(shift, register, from);
break;
case I16:
out = LLVMI16ToR64NodeGen.create(register, from);
break;
case I32:
out = LLVMI32ToR64NodeGen.create(from);
break;
case I64:
out = from;
break;
default:
throw new AsmParseException("unsupported operand type: " + op.getType());
}
return LLVMWriteI64NodeGen.create(out, frame, null);
} else if (operand instanceof AsmArgumentOperand) {
AsmArgumentOperand op = (AsmArgumentOperand) operand;
Argument info = argInfo.get(op.getIndex());
if (info.isMemory()) {
LLVMExpressionNode address = info.getAddress();
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMI8StoreNodeGen.create(address, from);
case I16:
return LLVMI16StoreNodeGen.create(address, from);
case I32:
return LLVMI32StoreNodeGen.create(address, from);
case I64:
return LLVMI64StoreNodeGen.create(address, from);
default:
throw new AsmParseException("unsupported operand type: " + type);
}
} else if (info.isRegister()) {
FrameSlot frame = getRegisterSlot(info.getRegister());
LLVMExpressionNode register = LLVMAMD64ReadRegisterNodeGen.create(frame);
LLVMExpressionNode out = null;
if (type instanceof PointerType || info.getType() instanceof PointerType) {
return LLVMAMD64WriteAddressRegisterNodeGen.create(sourceLocation, from, frame);
}
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
out = LLVMI8ToR64NodeGen.create(0, register, from);
break;
case I16:
out = LLVMI16ToR64NodeGen.create(register, from);
break;
case I32:
out = LLVMI32ToR64NodeGen.create(from);
break;
case I64:
out = from;
break;
default:
throw new AsmParseException("unsupported operand type: " + type);
}
return LLVMWriteI64NodeGen.create(out, frame, null);
} else {
throw new AssertionError("this should not happen; " + info);
}
} else if (operand instanceof AsmMemoryOperand) {
LLVMExpressionNode address = getOperandAddress(operand);
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMI8StoreNodeGen.create(null, address, from);
case I16:
return LLVMI16StoreNodeGen.create(null, address, from);
case I32:
return LLVMI32StoreNodeGen.create(null, address, from);
case I64:
return LLVMI64StoreNodeGen.create(null, address, from);
default:
throw new AsmParseException("unsupported operand type: " + type);
}
}
throw new AsmParseException("unsupported operand type: " + operand);
}
use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode in project sulong by graalvm.
the class AsmFactory method getOperandLoad.
private LLVMExpressionNode getOperandLoad(Type typeHint, AsmOperand operand) {
Type type = typeHint == null ? operand.getType() : typeHint;
if (operand instanceof AsmRegisterOperand) {
AsmRegisterOperand op = (AsmRegisterOperand) operand;
FrameSlot frame = getRegisterSlot(op.getBaseRegister());
LLVMExpressionNode register = LLVMAMD64ReadRegisterNodeGen.create(frame);
int shift = op.getShift();
assert type instanceof PointerType || type == op.getType();
if (type instanceof PointerType) {
switch(((PrimitiveType) op.getType()).getPrimitiveKind()) {
case I8:
return LLVMToI8NoZeroExtNodeGen.create(register);
case I16:
return LLVMToI16NoZeroExtNodeGen.create(register);
case I32:
return LLVMToI32NoZeroExtNodeGen.create(register);
case I64:
return LLVMAMD64ReadAddressNodeGen.create(frame);
default:
throw new AsmParseException("unsupported operand type: " + type);
}
}
switch(((PrimitiveType) op.getType()).getPrimitiveKind()) {
case I8:
return LLVMAMD64I64ToI8NodeGen.create(shift, register);
case I16:
return LLVMToI16NoZeroExtNodeGen.create(register);
case I32:
return LLVMToI32NoZeroExtNodeGen.create(register);
case I64:
return register;
default:
throw new AsmParseException("unsupported operand type: " + type);
}
} else if (operand instanceof AsmImmediateOperand) {
AsmImmediateOperand op = (AsmImmediateOperand) operand;
if (op.isLabel()) {
throw new AsmParseException("labels not supported");
} else {
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMAMD64I8NodeGen.create((byte) op.getValue());
case I16:
return LLVMAMD64I16NodeGen.create((short) op.getValue());
case I32:
return LLVMAMD64I32NodeGen.create((int) op.getValue());
case I64:
return LLVMAMD64I64NodeGen.create(op.getValue());
default:
throw new AsmParseException("unsupported operand type: " + type);
}
}
} else if (operand instanceof AsmArgumentOperand) {
AsmArgumentOperand op = (AsmArgumentOperand) operand;
Argument info = argInfo.get(op.getIndex());
FrameSlot frame = getArgumentSlot(op.getIndex(), type);
if (info.isMemory()) {
if (type instanceof PointerType) {
return LLVMAddressDirectLoadNodeGen.create(LLVMAddressReadNodeGen.create(frame));
}
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMI8LoadNodeGen.create(LLVMAddressReadNodeGen.create(frame));
case I16:
return LLVMI16LoadNodeGen.create(LLVMAddressReadNodeGen.create(frame));
case I32:
return LLVMI32LoadNodeGen.create(LLVMAddressReadNodeGen.create(frame));
case I64:
return LLVMI64LoadNodeGen.create(LLVMAddressReadNodeGen.create(frame));
default:
throw new AsmParseException("unsupported operand type: " + type);
}
} else if (info.isRegister()) {
frame = getRegisterSlot(info.getRegister());
if (type instanceof PointerType) {
return LLVMAMD64ReadAddressNodeGen.create(frame);
}
LLVMExpressionNode register = LLVMAMD64ReadRegisterNodeGen.create(frame);
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMToI8NoZeroExtNodeGen.create(register);
case I16:
return LLVMToI16NoZeroExtNodeGen.create(register);
case I32:
return LLVMToI32NoZeroExtNodeGen.create(register);
case I64:
return LLVMToI64NoZeroExtNodeGen.create(register);
default:
throw new AsmParseException("unsupported operand type: " + type);
}
} else {
// constraint "0"-"9"
if (type instanceof PointerType) {
return LLVMAMD64ReadAddressNodeGen.create(frame);
}
LLVMExpressionNode register = LLVMAMD64ReadRegisterNodeGen.create(frame);
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMToI8NoZeroExtNodeGen.create(register);
case I16:
return LLVMToI16NoZeroExtNodeGen.create(register);
case I32:
return LLVMToI32NoZeroExtNodeGen.create(register);
case I64:
return LLVMToI64NoZeroExtNodeGen.create(register);
default:
throw new AsmParseException("unsupported operand type: " + type);
}
}
} else if (operand instanceof AsmMemoryOperand) {
LLVMExpressionNode address = getOperandAddress(operand);
LLVMExpressionNode addr = LLVMToAddressNodeGen.create(address);
if (type instanceof PrimitiveType) {
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return LLVMI8LoadNodeGen.create(addr);
case I16:
return LLVMI16LoadNodeGen.create(addr);
case I32:
return LLVMI32LoadNodeGen.create(addr);
case I64:
return LLVMI64LoadNodeGen.create(addr);
default:
throw new AsmParseException("unsupported operand type: " + type);
}
} else if (type instanceof PointerType) {
return LLVMAddressDirectLoadNodeGen.create(addr);
} else {
throw new AsmParseException("unsupported operand type: " + type);
}
}
throw new AsmParseException("unsupported operand: " + operand);
}
use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode in project sulong by graalvm.
the class AsmFactory method createUnaryOperation.
void createUnaryOperation(String operation, AsmOperand operand) {
LLVMExpressionNode src;
LLVMExpressionNode out;
AsmOperand dst = operand;
Type dstType;
assert operation.length() > 0;
char suffix = operation.charAt(operation.length() - 1);
dstType = getPrimitiveTypeFromSuffix(suffix);
src = getOperandLoad(dstType, operand);
switch(operation) {
case "incb":
out = LLVMAMD64IncbNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "incw":
out = LLVMAMD64IncwNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "incl":
out = LLVMAMD64InclNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "incq":
out = LLVMAMD64IncqNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decb":
out = LLVMAMD64DecbNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decw":
out = LLVMAMD64DecwNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decl":
out = LLVMAMD64DeclNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decq":
out = LLVMAMD64DecqNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "negb":
out = LLVMAMD64NegbNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "negw":
out = LLVMAMD64NegwNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "negl":
out = LLVMAMD64NeglNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "negq":
out = LLVMAMD64NegqNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "notb":
out = LLVMAMD64NotbNodeGen.create(src);
break;
case "notw":
out = LLVMAMD64NotwNodeGen.create(src);
break;
case "notl":
out = LLVMAMD64NotlNodeGen.create(src);
break;
case "notq":
out = LLVMAMD64NotqNodeGen.create(src);
break;
case "idivb":
out = LLVMAMD64IdivbNodeGen.create(getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
dst = new AsmRegisterOperand("ax");
dstType = PrimitiveType.I16;
break;
case "idivw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("dx"));
out = LLVMAMD64IdivwNodeGen.create(res, high, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
statements.add(out);
return;
}
case "idivl":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("edx"));
out = LLVMAMD64IdivlNodeGen.create(res, high, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src);
statements.add(out);
return;
}
case "idivq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rdx"));
out = LLVMAMD64IdivqNodeGen.create(res, high, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src);
statements.add(out);
return;
}
case "imulb":
out = LLVMAMD64ImulbNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al")), src);
dst = new AsmRegisterOperand("ax");
dstType = PrimitiveType.I16;
break;
case "imulw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
out = LLVMAMD64ImulwNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
statements.add(out);
return;
}
case "imull":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
out = LLVMAMD64ImullNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src);
statements.add(out);
return;
}
case "imulq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
out = LLVMAMD64ImulqNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src);
statements.add(out);
return;
}
case "divb":
out = LLVMAMD64DivbNodeGen.create(getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
dst = new AsmRegisterOperand("ax");
dstType = PrimitiveType.I16;
break;
case "divw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("dx"));
out = LLVMAMD64DivwNodeGen.create(res, high, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
statements.add(out);
return;
}
case "divl":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("edx"));
out = LLVMAMD64DivlNodeGen.create(res, high, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src);
statements.add(out);
return;
}
case "divq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rdx"));
out = LLVMAMD64DivqNodeGen.create(res, high, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src);
statements.add(out);
return;
}
case "mulb":
out = LLVMAMD64MulbNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al")), src);
dst = new AsmRegisterOperand("ax");
dstType = PrimitiveType.I16;
break;
case "mulw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
out = LLVMAMD64MulwNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
statements.add(out);
return;
}
case "mull":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
out = LLVMAMD64MullNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src);
statements.add(out);
return;
}
case "mulq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
out = LLVMAMD64MulqNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src);
statements.add(out);
return;
}
case "bswapl":
out = LLVMAMD64BswaplNodeGen.create(src);
break;
case "bswapq":
out = LLVMAMD64BswapqNodeGen.create(src);
break;
case "popw":
out = LLVMAMD64PopwNodeGen.create();
break;
case "popl":
out = LLVMAMD64PoplNodeGen.create();
break;
case "popq":
out = LLVMAMD64PopqNodeGen.create();
break;
case "pushw":
statements.add(LLVMAMD64PushwNodeGen.create(src));
return;
case "pushl":
statements.add(LLVMAMD64PushlNodeGen.create(src));
return;
case "pushq":
statements.add(LLVMAMD64PushqNodeGen.create(src));
return;
default:
statements.add(new LLVMUnsupportedInlineAssemblerNode(sourceLocation, "Unsupported operation: " + operation));
return;
}
LLVMExpressionNode write = getOperandStore(dstType, dst, out);
statements.add(write);
}
use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode in project sulong by graalvm.
the class LLVMSymbolReadResolver method resolveElementPointer.
public LLVMExpressionNode resolveElementPointer(SymbolImpl base, List<SymbolImpl> indices) {
LLVMExpressionNode currentAddress = resolve(base);
Type currentType = base.getType();
for (int i = 0, indicesSize = indices.size(); i < indicesSize; i++) {
final SymbolImpl indexSymbol = indices.get(i);
final Type indexType = indexSymbol.getType();
final Long indexInteger = evaluateLongIntegerConstant(indexSymbol);
if (indexInteger == null) {
// the index is determined at runtime
if (currentType instanceof StructureType) {
// according to http://llvm.org/docs/LangRef.html#getelementptr-instruction
throw new IllegalStateException("Indices on structs must be constant integers!");
}
AggregateType aggregate = (AggregateType) currentType;
final long indexedTypeLength = runtime.getContext().getIndexOffset(1, aggregate);
currentType = aggregate.getElementType(1);
final LLVMExpressionNode indexNode = resolve(indexSymbol);
currentAddress = runtime.getNodeFactory().createTypedElementPointer(runtime, currentAddress, indexNode, indexedTypeLength, currentType);
} else {
// the index is a constant integer
AggregateType aggregate = (AggregateType) currentType;
final long addressOffset = runtime.getContext().getIndexOffset(indexInteger, aggregate);
currentType = aggregate.getElementType(indexInteger);
// computed by getelementptr even if it is the same as the basepointer
if (addressOffset != 0 || i == indicesSize - 1) {
final LLVMExpressionNode indexNode;
if (indexType == PrimitiveType.I32) {
indexNode = runtime.getNodeFactory().createLiteral(runtime, 1, PrimitiveType.I32);
} else if (indexType == PrimitiveType.I64) {
indexNode = runtime.getNodeFactory().createLiteral(runtime, 1L, PrimitiveType.I64);
} else {
throw new AssertionError(indexType);
}
currentAddress = runtime.getNodeFactory().createTypedElementPointer(runtime, currentAddress, indexNode, addressOffset, currentType);
}
}
}
return currentAddress;
}
Aggregations