use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class BasicNodeFactory method createAlloca.
protected static LLVMExpressionNode createAlloca(LLVMParserRuntime runtime, Type type, int byteSize, int alignment) {
if (type instanceof StructureType) {
StructureType struct = (StructureType) type;
final int[] offsets = new int[struct.getNumberOfElements()];
final Type[] types = new Type[struct.getNumberOfElements()];
int currentOffset = 0;
for (int i = 0; i < struct.getNumberOfElements(); i++) {
final Type elemType = struct.getElementType(i);
if (!struct.isPacked()) {
currentOffset += runtime.getContext().getBytePadding(currentOffset, elemType);
}
offsets[i] = currentOffset;
types[i] = elemType;
currentOffset += runtime.getContext().getByteSize(elemType);
}
assert currentOffset <= byteSize : "currentOffset " + currentOffset + " vs. byteSize " + byteSize;
LLVMAllocaConstInstruction alloc = LLVMAllocaConstInstructionNodeGen.create(byteSize, alignment, type);
alloc.setTypes(types);
alloc.setOffsets(offsets);
return alloc;
}
return LLVMAllocaConstInstructionNodeGen.create(byteSize, alignment, type);
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class Types method record.
@Override
public void record(long id, long[] args) {
TypesRecord record = TypesRecord.decode(id);
Type type;
switch(record) {
case NUMBER_OF_ENTRIES:
table = new Type[(int) args[0]];
return;
case VOID:
type = VoidType.INSTANCE;
break;
case FLOAT:
type = PrimitiveType.FLOAT;
break;
case DOUBLE:
type = PrimitiveType.DOUBLE;
break;
case LABEL:
type = MetaType.LABEL;
break;
case OPAQUE:
if (structName != null) {
type = new OpaqueType(LLVMIdentifier.toLocalIdentifier(structName));
structName = null;
module.addGlobalType(type);
} else {
type = new OpaqueType();
}
break;
case INTEGER:
type = Type.getIntegerType((int) args[0]);
break;
case POINTER:
{
final PointerType pointerType = new PointerType(null);
setType((int) args[0], pointerType::setPointeeType);
type = pointerType;
break;
}
case FUNCTION_OLD:
{
final FunctionType functionType = new FunctionType(null, toTypes(args, 3, args.length), args[0] != 0);
setType((int) args[2], functionType::setReturnType);
type = functionType;
break;
}
case HALF:
type = PrimitiveType.HALF;
break;
case ARRAY:
{
final ArrayType arrayType = new ArrayType(null, (int) args[0]);
setType((int) args[1], arrayType::setElementType);
type = arrayType;
break;
}
case VECTOR:
{
final VectorType vectorType = new VectorType(null, (int) args[0]);
setType((int) args[1], vectorType::setElementType);
type = vectorType;
break;
}
case X86_FP80:
type = PrimitiveType.X86_FP80;
break;
case FP128:
type = PrimitiveType.F128;
break;
case PPC_FP128:
type = PrimitiveType.PPC_FP128;
break;
case METADATA:
type = MetaType.METADATA;
break;
case X86_MMX:
type = MetaType.X86MMX;
break;
case STRUCT_NAME:
{
structName = Records.toString(args);
return;
}
case STRUCT_ANON:
case STRUCT_NAMED:
{
final boolean isPacked = args[0] != 0;
final Type[] members = toTypes(args, 1, args.length);
if (structName != null) {
type = new StructureType(LLVMIdentifier.toTypeIdentifier(structName), isPacked, members);
structName = null;
module.addGlobalType(type);
} else {
type = new StructureType(isPacked, members);
}
break;
}
case FUNCTION:
{
final FunctionType functionType = new FunctionType(null, toTypes(args, 2, args.length), args[0] != 0);
setType((int) args[1], functionType::setReturnType);
type = functionType;
break;
}
case TOKEN:
type = MetaType.TOKEN;
break;
default:
type = MetaType.UNKNOWN;
break;
}
if (table[size] != null) {
((UnresolvedType) table[size]).dependent.accept(type);
}
table[size++] = type;
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class AsmFactory method getArguments.
private void getArguments() {
LLVMStoreNode[] writeNodes = null;
LLVMExpressionNode[] valueNodes = null;
if (retType instanceof StructureType) {
writeNodes = new LLVMStoreNode[retTypes.length];
valueNodes = new LLVMExpressionNode[retTypes.length];
}
Set<String> todoRegisters = new HashSet<>(registers);
for (Argument arg : argInfo) {
// output register
if (arg.isOutput()) {
FrameSlot slot = null;
if (arg.isRegister()) {
slot = getRegisterSlot(arg.getRegister());
LLVMExpressionNode register = LLVMAMD64ReadRegisterNodeGen.create(slot);
if (retType instanceof StructureType) {
assert retTypes[arg.getOutIndex()] == arg.getType();
if (arg.getType() instanceof PointerType) {
valueNodes[arg.getOutIndex()] = LLVMToAddressNodeGen.create(register);
writeNodes[arg.getOutIndex()] = LLVMAddressStoreNodeGen.create(null, null);
} else {
PrimitiveKind primitiveKind = getPrimitiveKind(arg);
switch(primitiveKind) {
case I8:
valueNodes[arg.getOutIndex()] = LLVMToI8NoZeroExtNodeGen.create(register);
writeNodes[arg.getOutIndex()] = LLVMI8StoreNodeGen.create(null, null);
break;
case I16:
valueNodes[arg.getOutIndex()] = LLVMToI16NoZeroExtNodeGen.create(register);
writeNodes[arg.getOutIndex()] = LLVMI16StoreNodeGen.create(null, null);
break;
case I32:
valueNodes[arg.getOutIndex()] = LLVMToI32NoZeroExtNodeGen.create(register);
writeNodes[arg.getOutIndex()] = LLVMI32StoreNodeGen.create(null, null);
break;
case I64:
valueNodes[arg.getOutIndex()] = register;
writeNodes[arg.getOutIndex()] = LLVMI64StoreNodeGen.create(null, null);
break;
default:
throw new AsmParseException("invalid operand size: " + arg.getType());
}
}
} else {
result = castResult(register);
}
} else {
assert arg.isMemory();
slot = getArgumentSlot(arg.getIndex(), argTypes[arg.getOutIndex()]);
LLVMExpressionNode argnode = LLVMArgNodeGen.create(arg.getOutIndex());
arguments.add(LLVMWriteAddressNodeGen.create(argnode, slot, sourceLocation));
}
}
// input register
if (arg.isInput()) {
FrameSlot slot = null;
if (arg.isRegister()) {
String reg = arg.isAnonymous() ? arg.getRegister() : AsmRegisterOperand.getBaseRegister(arg.getRegister());
slot = getRegisterSlot(reg);
todoRegisters.remove(reg);
LLVMExpressionNode argnode = LLVMArgNodeGen.create(arg.getInIndex());
if (argTypes[arg.getInIndex()] instanceof PointerType) {
arguments.add(LLVMWriteAddressNodeGen.create(argnode, slot, null));
} else {
LLVMExpressionNode node = LLVMToI64NoZeroExtNodeGen.create(argnode);
arguments.add(LLVMWriteI64NodeGen.create(node, slot, null));
}
}
slot = getArgumentSlot(arg.getIndex(), argTypes[arg.getInIndex()]);
LLVMExpressionNode argnode = LLVMArgNodeGen.create(arg.getInIndex());
if (arg.getType() instanceof PrimitiveType) {
LLVMExpressionNode node = LLVMToI64NoZeroExtNodeGen.create(argnode);
arguments.add(LLVMWriteI64NodeGen.create(node, slot, null));
} else if (arg.getType() instanceof PointerType) {
arguments.add(LLVMWriteAddressNodeGen.create(argnode, slot, null));
} else {
throw new AsmParseException("invalid operand size: " + arg.getType());
}
}
}
if (retType instanceof StructureType) {
LLVMExpressionNode addrArg = LLVMArgNodeGen.create(1);
FrameSlot slot = frameDescriptor.addFrameSlot("returnValue", null, FrameSlotKind.Object);
LLVMWriteAddressNode writeAddr = LLVMWriteAddressNodeGen.create(addrArg, slot, null);
statements.add(writeAddr);
LLVMExpressionNode addr = LLVMAddressReadNodeGen.create(slot);
this.result = StructLiteralNodeGen.create(retOffsets, writeNodes, valueNodes, addr);
}
// rsp is initialized to stack pointer; ignore it here
todoRegisters.remove("rsp");
// initialize registers
for (String register : todoRegisters) {
if (register.startsWith("$")) {
continue;
}
LLVMExpressionNode node = LLVMAMD64I64NodeGen.create(0);
FrameSlot slot = getRegisterSlot(register);
arguments.add(LLVMWriteI64NodeGen.create(node, slot, null));
}
// initialize flags
LLVMExpressionNode zero = LLVMAMD64I1NodeGen.create(false);
arguments.add(LLVMWriteI1NodeGen.create(zero, getFlagSlot(LLVMAMD64Flags.CF), sourceLocation));
arguments.add(LLVMWriteI1NodeGen.create(zero, getFlagSlot(LLVMAMD64Flags.PF), sourceLocation));
arguments.add(LLVMWriteI1NodeGen.create(zero, getFlagSlot(LLVMAMD64Flags.AF), sourceLocation));
arguments.add(LLVMWriteI1NodeGen.create(zero, getFlagSlot(LLVMAMD64Flags.ZF), sourceLocation));
arguments.add(LLVMWriteI1NodeGen.create(zero, getFlagSlot(LLVMAMD64Flags.SF), sourceLocation));
arguments.add(LLVMWriteI1NodeGen.create(zero, getFlagSlot(LLVMAMD64Flags.OF), sourceLocation));
// copy stack pointer
LLVMExpressionNode stackPointer = LLVMArgNodeGen.create(0);
FrameSlot stackSlot = frameDescriptor.addFrameSlot(LLVMStack.FRAME_ID);
stackSlot.setKind(FrameSlotKind.Object);
arguments.add(LLVMWriteAddressNodeGen.create(stackPointer, frameDescriptor.findFrameSlot(LLVMStack.FRAME_ID), sourceLocation));
arguments.add(LLVMWriteAddressNodeGen.create(stackPointer, getRegisterSlot("rsp"), null));
assert retType instanceof VoidType || retType != null;
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class BasicNodeFactory method createArrayLiteral.
@Override
public LLVMExpressionNode createArrayLiteral(LLVMParserRuntime runtime, List<LLVMExpressionNode> arrayValues, ArrayType arrayType) {
assert arrayType.getNumberOfElements() == arrayValues.size();
LLVMExpressionNode arrayAlloc = createAlloca(runtime, arrayType);
int nrElements = arrayValues.size();
Type elementType = arrayType.getElementType();
int elementSize = runtime.getContext().getByteSize(elementType);
if (elementSize == 0) {
throw new AssertionError(elementType + " has size of 0!");
}
if (elementType instanceof PrimitiveType) {
switch(((PrimitiveType) elementType).getPrimitiveKind()) {
case I8:
return LLVMI8ArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
case I16:
return LLVMI16ArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
case I32:
return LLVMI32ArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
case I64:
return LLVMI64ArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
case FLOAT:
return LLVMFloatArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
case DOUBLE:
return LLVMDoubleArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
case X86_FP80:
return LLVM80BitFloatArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
default:
throw new AssertionError(elementType);
}
} else if (Type.isFunctionOrFunctionPointer(elementType)) {
return LLVMFunctionArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
} else if (elementType instanceof PointerType) {
return LLVMAddressArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), elementSize, arrayAlloc);
} else if (elementType instanceof ArrayType || elementType instanceof StructureType) {
return LLVMStructArrayLiteralNodeGen.create(arrayValues.toArray(new LLVMExpressionNode[nrElements]), createMemMove(), elementSize, arrayAlloc);
}
throw new AssertionError(elementType);
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class BasicNodeFactory method createInlineAssemblerExpression.
@Override
public LLVMExpressionNode createInlineAssemblerExpression(LLVMParserRuntime runtime, String asmExpression, String asmFlags, LLVMExpressionNode[] args, Type[] argTypes, Type retType, LLVMSourceLocation sourceSection) {
Type[] retTypes = null;
int[] retOffsets = null;
if (retType instanceof StructureType) {
// multiple out values
assert args[1] instanceof LLVMAllocaConstInstruction;
LLVMAllocaConstInstruction alloca = (LLVMAllocaConstInstruction) args[1];
retTypes = alloca.getTypes();
retOffsets = alloca.getOffsets();
}
Parser asmParser = new Parser(runtime.getLanguage(), sourceSection, asmExpression, asmFlags, argTypes, retType, retTypes, retOffsets);
LLVMInlineAssemblyRootNode assemblyRoot = asmParser.Parse();
LLVMFunctionDescriptor asm = LLVMFunctionDescriptor.createDescriptor(runtime.getContext(), runtime.getLibrary(), "<asm>", new FunctionType(MetaType.UNKNOWN, new Type[0], false), -1);
asm.declareInSulong(Truffle.getRuntime().createCallTarget(assemblyRoot), false);
LLVMFunctionLiteralNode asmFunction = LLVMFunctionLiteralNodeGen.create(asm);
return new LLVMCallNode(new FunctionType(MetaType.UNKNOWN, argTypes, false), asmFunction, args, sourceSection);
}
Aggregations