use of com.oracle.truffle.api.frame.FrameSlot in project sulong by graalvm.
the class AsmFactory method getRegisterTarget.
private LLVMAMD64Target getRegisterTarget(Type type, String name) {
AsmRegisterOperand op = new AsmRegisterOperand(name);
FrameSlot frame = getRegisterSlot(name);
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I8:
return new LLVMAMD64Target(frame, op.getShift());
case I16:
case I32:
case I64:
return new LLVMAMD64Target(frame);
default:
throw new AsmParseException("unsupported operand type");
}
}
use of com.oracle.truffle.api.frame.FrameSlot in project sulong by graalvm.
the class AsmFactory method getOperandAddress.
private LLVMExpressionNode getOperandAddress(Type type, AsmOperand operand) {
if (operand instanceof AsmRegisterOperand) {
AsmRegisterOperand op = (AsmRegisterOperand) operand;
FrameSlot frame = getRegisterSlot(op.getBaseRegister());
if (type instanceof PointerType) {
return LLVMAddressReadNodeGen.create(frame);
} else {
throw new AsmParseException("not a pointer");
}
} else if (operand instanceof AsmArgumentOperand) {
AsmArgumentOperand op = (AsmArgumentOperand) operand;
Argument info = argInfo.get(op.getIndex());
FrameSlot frame = getArgumentSlot(op.getIndex(), type);
if (info.isMemory()) {
return LLVMAddressReadNodeGen.create(frame);
} else {
throw new AsmParseException("not a pointer");
}
} else if (operand instanceof AsmMemoryOperand) {
AsmMemoryOperand op = (AsmMemoryOperand) operand;
int displacement = op.getDisplacement();
AsmOperand base = op.getBase();
AsmOperand offset = op.getOffset();
int shift = op.getShift();
LLVMExpressionNode baseAddress;
assert op.getSegment() == null || op.getSegment().equals("%fs");
LLVMExpressionNode segment = null;
if (op.getSegment() != null) {
segment = new LLVMAMD64GetTlsNode();
}
if (base != null) {
baseAddress = getOperandLoad(new PointerType(type), base);
} else if (offset != null) {
LLVMExpressionNode offsetNode = getOperandLoad(null, offset);
if (op.getSegment() != null) {
return LLVMAMD64AddressOffsetComputationNodeGen.create(displacement, shift, segment, offsetNode);
} else {
return LLVMAMD64AddressNoBaseOffsetComputationNodeGen.create(displacement, shift, offsetNode);
}
} else if (op.getSegment() != null) {
return LLVMAMD64AddressDisplacementComputationNodeGen.create(displacement, segment);
} else {
if (type instanceof PrimitiveType) {
switch(((PrimitiveType) type).getPrimitiveKind()) {
case I16:
return LLVMAMD64I16NodeGen.create((short) displacement);
case I32:
return LLVMAMD64I32NodeGen.create(displacement);
case I64:
return LLVMAMD64I64NodeGen.create(displacement);
default:
throw new AsmParseException("unknown type: " + type);
}
} else if (type instanceof PointerType) {
return LLVMAMD64I64NodeGen.create(displacement);
} else {
throw new AsmParseException("invalid type: " + type);
}
}
LLVMExpressionNode address;
if (offset == null) {
address = LLVMAMD64AddressDisplacementComputationNodeGen.create(displacement, baseAddress);
} else {
LLVMExpressionNode offsetNode = getOperandLoad(null, offset);
address = LLVMAMD64AddressOffsetComputationNodeGen.create(displacement, shift, baseAddress, offsetNode);
}
if (op.getSegment() != null) {
address = LLVMAMD64AddressSegmentComputationNodeGen.create(address, segment);
}
return address;
} else {
throw new AsmParseException("unsupported operand: " + operand);
}
}
use of com.oracle.truffle.api.frame.FrameSlot 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.api.frame.FrameSlot in project sulong by graalvm.
the class LLVMBitcodeInstructionVisitor method convertToPhiWriteNodes.
private LLVMExpressionNode[] convertToPhiWriteNodes(ArrayList<Phi>[] phisPerSuccessor) {
if (phisPerSuccessor.length == 0) {
return LLVMExpressionNode.NO_EXPRESSIONS;
}
LLVMExpressionNode[] result = new LLVMExpressionNode[phisPerSuccessor.length];
for (int i = 0; i < result.length; i++) {
LLVMExpressionNode[] from = new LLVMExpressionNode[phisPerSuccessor[i].size()];
FrameSlot[] to = new FrameSlot[phisPerSuccessor[i].size()];
Type[] types = new Type[phisPerSuccessor[i].size()];
for (int j = 0; j < phisPerSuccessor[i].size(); j++) {
Phi phi = phisPerSuccessor[i].get(j);
to[j] = getSlot(phi.getPhiValue().getName());
from[j] = symbols.resolve(phi.getValue());
types[j] = phi.getValue().getType();
}
result[i] = nodeFactory.createPhi(runtime, from, to, types);
}
return result;
}
use of com.oracle.truffle.api.frame.FrameSlot in project sulong by graalvm.
the class LLVMBitcodeInstructionVisitor method visit.
@Override
public void visit(VoidInvokeInstruction call) {
final SymbolImpl target = call.getCallTarget();
// stackpointer
final int argumentCount = call.getArgumentCount() + 1;
final LLVMExpressionNode[] args = new LLVMExpressionNode[argumentCount];
final Type[] argsType = new Type[argumentCount];
int argIndex = 0;
args[argIndex] = nodeFactory.createFrameRead(runtime, PointerType.VOID, getStackSlot());
argsType[argIndex] = new PointerType(null);
argIndex++;
for (int i = 0; i < call.getArgumentCount(); i++) {
args[argIndex] = symbols.resolve(call.getArgument(i));
argsType[argIndex] = call.getArgument(i).getType();
final AttributesGroup paramAttr = call.getParameterAttributesGroup(i);
if (isByValue(paramAttr)) {
args[argIndex] = capsuleAddressByValue(args[argIndex], argsType[argIndex], paramAttr);
}
argIndex++;
}
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, args, argCount, null);
if (function == null) {
function = symbols.resolve(target);
}
LLVMControlFlowNode result = nodeFactory.createFunctionInvoke(runtime, null, function, args, new FunctionType(call.getType(), argsType, false), regularIndex, unwindIndex, normalPhi, unwindPhi, source);
setControlFlowNode(result);
}
Aggregations