package com.oracle.truffle.llvm.runtime.nodes.vars;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.llvm.runtime.LLVMIVarBit;
import com.oracle.truffle.llvm.runtime.floating.LLVM80BitFloat;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode;
import com.oracle.truffle.llvm.runtime.pointer.LLVMNativePointer;
import com.oracle.truffle.llvm.runtime.vector.LLVMVector;
@NodeChild(value = "valueNode", type = LLVMExpressionNode.class)
public abstract class LLVMWriteNode extends LLVMStatementNode {
protected final FrameSlot slot;
protected LLVMWriteNode(FrameSlot slot) {
assert slot != null;
this.slot = slot;
}
public abstract void executeWithTarget(VirtualFrame frame, Object value);
@Override
public String toString() {
return getShortString("slot");
}
public abstract static class LLVMWriteI1Node extends LLVMWriteNode {
protected LLVMWriteI1Node(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeI1(VirtualFrame frame, boolean value) {
frame.setBoolean(slot, value);
}
}
public abstract static class LLVMWriteI8Node extends LLVMWriteNode {
protected LLVMWriteI8Node(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeI8(VirtualFrame frame, byte value) {
frame.setByte(slot, value);
}
}
public abstract static class LLVMWriteI16Node extends LLVMWriteNode {
protected LLVMWriteI16Node(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeI16(VirtualFrame frame, short value) {
frame.setInt(slot, value);
}
}
public abstract static class LLVMWriteI32Node extends LLVMWriteNode {
protected LLVMWriteI32Node(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeI32(VirtualFrame frame, int value) {
frame.setInt(slot, value);
}
}
public abstract static class LLVMWriteI64Node extends LLVMWriteNode {
protected LLVMWriteI64Node(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeI64(VirtualFrame frame, long value) {
if (frame.getFrameDescriptor().getFrameSlotKind(slot) == FrameSlotKind.Long) {
frame.setLong(slot, value);
} else {
frame.setObject(slot, value);
}
}
@Specialization(replaces = "writeI64")
protected void writePointer(VirtualFrame frame, Object value) {
if (frame.getFrameDescriptor().getFrameSlotKind(slot) == FrameSlotKind.Long) {
CompilerDirectives.transferToInterpreterAndInvalidate();
frame.getFrameDescriptor().setFrameSlotKind(slot, FrameSlotKind.Object);
}
frame.setObject(slot, value);
}
}
public abstract static class LLVMWriteIVarBitNode extends LLVMWriteNode {
protected LLVMWriteIVarBitNode(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeIVarBit(VirtualFrame frame, LLVMIVarBit value) {
frame.setObject(slot, value);
}
}
public abstract static class LLVMWriteFloatNode extends LLVMWriteNode {
protected LLVMWriteFloatNode(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeFloat(VirtualFrame frame, float value) {
frame.setFloat(slot, value);
}
}
public abstract static class LLVMWriteDoubleNode extends LLVMWriteNode {
protected LLVMWriteDoubleNode(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeDouble(VirtualFrame frame, double value) {
frame.setDouble(slot, value);
}
}
public abstract static class LLVMWrite80BitFloatingNode extends LLVMWriteNode {
protected LLVMWrite80BitFloatingNode(FrameSlot slot) {
super(slot);
}
@Specialization
protected void write80BitFloat(VirtualFrame frame, LLVM80BitFloat value) {
frame.setObject(slot, value);
}
}
public abstract static class LLVMWritePointerNode extends LLVMWriteNode {
protected LLVMWritePointerNode(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeLong(VirtualFrame frame, long value) {
frame.setObject(slot, LLVMNativePointer.create(value));
}
@Fallback
protected void writeObject(VirtualFrame frame, Object value) {
frame.setObject(slot, value);
}
}
public abstract static class LLVMWriteVectorNode extends LLVMWriteNode {
protected LLVMWriteVectorNode(FrameSlot slot) {
super(slot);
}
@Specialization
protected void writeVector(VirtualFrame frame, LLVMVector value) {
frame.setObject(slot, value);
}
}
}