use of com.oracle.truffle.llvm.runtime.types.PointerType in project sulong by graalvm.
the class AsmFactory method parseArguments.
private void parseArguments() {
argInfo = new ArrayList<>();
String[] tokens = asmFlags.substring(1, asmFlags.length() - 1).split(",");
int index = REG_START_INDEX + (retType instanceof StructureType ? 1 : 0);
int outIndex = 0;
for (String token : tokens) {
if (token.isEmpty()) {
continue;
}
boolean isTilde = false;
boolean isInput = true;
boolean isOutput = false;
boolean isMemory = false;
boolean isAnonymous = false;
String source = null;
String registerName = null;
int i;
for (i = 0; i < token.length() && source == null; i++) {
switch(token.charAt(i)) {
case '~':
isTilde = true;
isInput = false;
break;
case '+':
isInput = true;
isOutput = true;
break;
case '=':
isInput = false;
isOutput = true;
break;
case '*':
isMemory = true;
break;
case '&':
break;
default:
source = token.substring(i);
break;
}
}
if (isTilde) {
continue;
}
int start = source.indexOf('{');
int end = source.lastIndexOf('}');
if (start != -1 && end != -1) {
registerName = source.substring(start + 1, end);
} else if (source.equals(CONSTRAINT_REG) || source.equals(CONSTRAINT_REG_L)) {
registerName = TEMP_REGISTER_PREFIX + argInfo.size();
isAnonymous = true;
} else if (source.length() == 1 && Character.isDigit(source.charAt(0))) {
int id = Character.digit(source.charAt(0), 10);
Argument arg = argInfo.get(id);
assert isInput && !isOutput;
isInput = true;
isOutput = false;
if (arg.isRegister()) {
registerName = arg.getRegister();
}
isAnonymous = arg.isAnonymous();
}
assert registerName == null || AsmRegisterOperand.isRegister(registerName) || registerName.startsWith(TEMP_REGISTER_PREFIX);
int idIn = index;
int idOut = outIndex;
Type type;
if (isInput) {
type = argTypes[index++];
} else if (retType instanceof StructureType) {
if (isMemory) {
type = argTypes[index];
idOut = index++;
} else {
type = retTypes[outIndex++];
}
} else if (isOutput) {
type = retType;
if (isMemory) {
idOut = index++;
}
} else {
throw new AssertionError("neither input nor output");
}
if (isAnonymous && type instanceof PointerType) {
assert registerName != null;
addFrameSlot(registerName, type);
}
argInfo.add(new Argument(isInput, isOutput, isMemory, isAnonymous, type, argInfo.size(), idIn, idOut, source, registerName));
}
assert index == argTypes.length;
assert retType instanceof StructureType ? outIndex == retOffsets.length : outIndex == 0;
}
use of com.oracle.truffle.llvm.runtime.types.PointerType 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.types.PointerType 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.types.PointerType in project sulong by graalvm.
the class LLVMBitcodeInstructionVisitor method visit.
@Override
public void visit(InvokeInstruction call) {
final Type targetType = call.getType();
int argumentCount = getArgumentCount(call.getArgumentCount(), targetType);
final LLVMExpressionNode[] argNodes = new LLVMExpressionNode[argumentCount];
final Type[] argTypes = new Type[argumentCount];
int argIndex = 0;
argNodes[argIndex] = nodeFactory.createFrameRead(runtime, PointerType.VOID, getStackSlot());
argTypes[argIndex] = new PointerType(null);
argIndex++;
if (targetType instanceof StructureType) {
argTypes[argIndex] = new PointerType(targetType);
argNodes[argIndex] = nodeFactory.createAlloca(runtime, targetType);
argIndex++;
}
for (int i = 0; argIndex < argumentCount; i++, argIndex++) {
argNodes[argIndex] = symbols.resolve(call.getArgument(i));
argTypes[argIndex] = call.getArgument(i).getType();
final AttributesGroup paramAttr = call.getParameterAttributesGroup(i);
if (isByValue(paramAttr)) {
argNodes[argIndex] = capsuleAddressByValue(argNodes[argIndex], argTypes[argIndex], paramAttr);
}
}
final SymbolImpl target = call.getCallTarget();
int regularIndex = call.normalSuccessor().getBlockIndex();
int unwindIndex = call.unwindSuccessor().getBlockIndex();
List<FrameSlot> normalTo = new ArrayList<>();
List<FrameSlot> unwindTo = new ArrayList<>();
List<Type> normalType = new ArrayList<>();
List<Type> unwindType = new ArrayList<>();
List<LLVMExpressionNode> normalValue = new ArrayList<>();
List<LLVMExpressionNode> unwindValue = new ArrayList<>();
if (blockPhis != null) {
for (Phi phi : blockPhis) {
FrameSlot slot = getSlot(phi.getPhiValue().getName());
LLVMExpressionNode value = symbols.resolve(phi.getValue());
if (call.normalSuccessor() == phi.getBlock()) {
normalTo.add(slot);
normalType.add(phi.getValue().getType());
normalValue.add(value);
} else {
unwindTo.add(slot);
unwindType.add(phi.getValue().getType());
unwindValue.add(value);
}
}
}
LLVMExpressionNode normalPhi = nodeFactory.createPhi(runtime, normalValue.toArray(new LLVMExpressionNode[normalValue.size()]), normalTo.toArray(new FrameSlot[normalTo.size()]), normalType.toArray(Type.EMPTY_ARRAY));
LLVMExpressionNode unwindPhi = nodeFactory.createPhi(runtime, unwindValue.toArray(new LLVMExpressionNode[unwindValue.size()]), unwindTo.toArray(new FrameSlot[unwindTo.size()]), unwindType.toArray(Type.EMPTY_ARRAY));
final LLVMSourceLocation source = sourceFunction.getSourceLocation(call);
LLVMExpressionNode function = nodeFactory.createLLVMBuiltin(runtime, target, argNodes, argCount, null);
if (function == null) {
function = symbols.resolve(target);
}
LLVMControlFlowNode result = nodeFactory.createFunctionInvoke(runtime, getSlot(call.getName()), function, argNodes, new FunctionType(targetType, argTypes, false), regularIndex, unwindIndex, normalPhi, unwindPhi, source);
setControlFlowNode(result);
}
use of com.oracle.truffle.llvm.runtime.types.PointerType in project sulong by graalvm.
the class LLVMBitcodeInstructionVisitor method capsuleAddressByValue.
private LLVMExpressionNode capsuleAddressByValue(LLVMExpressionNode child, Type type, AttributesGroup paramAttr) {
final Type pointee = ((PointerType) type).getPointeeType();
final int size = runtime.getContext().getByteSize(pointee);
int alignment = runtime.getContext().getByteAlignment(pointee);
for (Attribute attr : paramAttr.getAttributes()) {
if (attr instanceof Attribute.KnownIntegerValueAttribute && ((Attribute.KnownIntegerValueAttribute) attr).getAttr() == Attribute.Kind.ALIGN) {
alignment = ((Attribute.KnownIntegerValueAttribute) attr).getValue();
}
}
return nodeFactory.createVarArgCompoundValue(runtime, size, alignment, child);
}
Aggregations