use of com.oracle.truffle.llvm.runtime.types.Type in project sulong by graalvm.
the class AsmFactory method createBinaryOperationImplicitSize.
void createBinaryOperationImplicitSize(String operation, AsmOperand a, AsmOperand b) {
AsmOperand dst = b;
AsmOperand src = a;
assert a != null && b != null;
Type dstType = getType(b, a);
PrimitiveType.PrimitiveKind dstPrimitiveType = (dstType instanceof PrimitiveType) ? ((PrimitiveType) dstType).getPrimitiveKind() : null;
LLVMExpressionNode out;
switch(operation) {
case "lea":
out = getOperandAddress(dstType, src);
if (isLeaPointer(src)) {
dstType = new PointerType(dstType);
}
break;
case "xor":
if (dstType instanceof PrimitiveType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
LLVMExpressionNode srcB = getOperandLoad(dstType, b);
switch(dstPrimitiveType) {
case I8:
out = LLVMAMD64XorbNodeGen.create(srcA, srcB);
break;
case I16:
out = LLVMAMD64XorwNodeGen.create(srcA, srcB);
break;
case I32:
out = LLVMAMD64XorlNodeGen.create(srcA, srcB);
break;
case I64:
out = LLVMAMD64XorqNodeGen.create(srcA, srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
break;
case "mov":
if (dstType instanceof PrimitiveType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
out = srcA;
} else if (dstType instanceof PointerType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
out = srcA;
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
break;
case "bsr":
if (dstType instanceof PrimitiveType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
LLVMExpressionNode srcB = getOperandLoad(dstType, b);
switch(dstPrimitiveType) {
case I16:
out = LLVMAMD64BsrwNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I32:
out = LLVMAMD64BsrlNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I64:
out = LLVMAMD64BsrqNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
break;
case "bsf":
if (dstType instanceof PrimitiveType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
LLVMExpressionNode srcB = getOperandLoad(dstType, b);
switch(dstPrimitiveType) {
case I16:
out = LLVMAMD64BsfwNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I32:
out = LLVMAMD64BsflNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I64:
out = LLVMAMD64BsfqNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
break;
case "xchg":
{
if (dstType instanceof PrimitiveType) {
XchgOperands operands = new XchgOperands(a, b, dstType);
switch(dstPrimitiveType) {
case I8:
out = LLVMAMD64XchgbNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
case I16:
out = LLVMAMD64XchgwNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
case I32:
out = LLVMAMD64XchglNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
case I64:
out = LLVMAMD64XchgqNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
statements.add(out);
return;
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
}
case "cmpxchg":
{
if (dstType instanceof PointerType) {
// treat pointers as I64
dstPrimitiveType = PrimitiveKind.I64;
}
if (dstType instanceof PrimitiveType || dstType instanceof PointerType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
LLVMExpressionNode srcB = getOperandLoad(dstType, b);
LLVMAMD64WriteValueNode dst1 = getStore(dstType, b);
LLVMAMD64WriteValueNode dst2;
LLVMExpressionNode accumulator;
if (dstType instanceof PointerType) {
dst2 = getRegisterStore("rax");
accumulator = getOperandLoad(new PointerType(PrimitiveType.I8), new AsmRegisterOperand("rax"));
out = LLVMAMD64CmpXchgqNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
} else {
switch(dstPrimitiveType) {
case I8:
dst2 = getRegisterStore("al");
accumulator = getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al"));
out = LLVMAMD64CmpXchgbNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
case I16:
dst2 = getRegisterStore("ax");
accumulator = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax"));
out = LLVMAMD64CmpXchgwNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
case I32:
dst2 = getRegisterStore("eax");
accumulator = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax"));
out = LLVMAMD64CmpXchglNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
case I64:
dst2 = getRegisterStore("rax");
accumulator = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax"));
out = LLVMAMD64CmpXchgqNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
}
statements.add(out);
return;
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
}
case "and":
if (dstType instanceof PrimitiveType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
LLVMExpressionNode srcB = getOperandLoad(dstType, b);
switch(dstPrimitiveType) {
case I8:
out = LLVMAMD64AndbNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case I16:
out = LLVMAMD64AndwNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case I32:
out = LLVMAMD64AndlNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case I64:
out = LLVMAMD64AndqNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
break;
case "or":
if (dstType instanceof PrimitiveType) {
LLVMExpressionNode srcA = getOperandLoad(dstType, a);
LLVMExpressionNode srcB = getOperandLoad(dstType, b);
switch(dstPrimitiveType) {
case I8:
out = LLVMAMD64OrbNodeGen.create(srcA, srcB);
break;
case I16:
out = LLVMAMD64OrwNodeGen.create(srcA, srcB);
break;
case I32:
out = LLVMAMD64OrlNodeGen.create(srcA, srcB);
break;
case I64:
out = LLVMAMD64OrqNodeGen.create(srcA, srcB);
break;
default:
throw new AsmParseException("invalid operand type: " + dstType);
}
} else {
throw new AsmParseException("invalid operand type: " + dstType);
}
break;
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.types.Type in project sulong by graalvm.
the class AsmFactory method createTernaryOperation.
void createTernaryOperation(String operation, AsmOperand a, AsmOperand b, AsmOperand c) {
AsmOperand dst = c;
LLVMExpressionNode srcA;
LLVMExpressionNode srcB;
LLVMExpressionNode out;
Type dstType;
assert a != null && b != null && c != null;
char suffix = operation.charAt(operation.length() - 1);
dstType = getPrimitiveTypeFromSuffix(suffix);
srcB = getOperandLoad(dstType, b);
srcA = getOperandLoad(dstType, a);
@SuppressWarnings("unused") PrimitiveType.PrimitiveKind dstPrimitiveType = (dstType instanceof PrimitiveType) ? ((PrimitiveType) dstType).getPrimitiveKind() : null;
switch(operation) {
case "imulw":
out = LLVMAMD64Imulw3NodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), srcA, srcB);
break;
case "imull":
out = LLVMAMD64Imull3NodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), srcA, srcB);
break;
case "imulq":
out = LLVMAMD64Imulq3NodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), srcA, srcB);
break;
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.types.Type in project sulong by graalvm.
the class Function method createLandingpadOld.
private void createLandingpadOld(long[] args) {
int i = 0;
final Type type = types.get(args[i++]);
long persFn = getIndex(args[i++]);
if (scope.isValueForwardRef((int) persFn)) {
i++;
}
final boolean isCleanup = args[i++] != 0;
final int numClauses = (int) args[i++];
// catch = 0, filter = 1
long[] clauseKinds = new long[numClauses];
long[] clauseTypes = new long[numClauses];
for (int j = 0; j < numClauses; j++) {
clauseKinds[j] = args[i++];
clauseTypes[j] = getIndex(args[i++]);
if (scope.isValueForwardRef(clauseTypes[j])) {
i++;
}
}
emit(LandingpadInstruction.generate(scope.getSymbols(), type, isCleanup, clauseKinds, clauseTypes));
}
use of com.oracle.truffle.llvm.runtime.types.Type in project sulong by graalvm.
the class Function method createFunctionCall.
private void createFunctionCall(long[] args) {
int i = 0;
final AttributesCodeEntry paramAttr = paramAttributes.getCodeEntry(args[i++]);
final long ccinfo = args[i++];
if (((ccinfo >> CALL_HAS_FMF_SHIFT) & 1) != 0) {
// fast math flags
i++;
}
FunctionType functionType = null;
if (((ccinfo >> CALL_HAS_EXPLICITTYPE_SHIFT) & 1) != 0) {
functionType = (FunctionType) types.get(args[i++]);
}
int callee = getIndex(args[i++]);
Type calleeType;
if (scope.isValueForwardRef(callee)) {
calleeType = types.get(args[i++]);
} else {
calleeType = scope.getValueType(callee);
}
if (functionType == null) {
if (calleeType instanceof FunctionType) {
functionType = (FunctionType) calleeType;
} else {
functionType = (FunctionType) ((PointerType) calleeType).getPointeeType();
}
}
int[] arguments = new int[args.length - i];
int skipped = 0;
int j = 0;
while (j < functionType.getArgumentTypes().length && i < args.length) {
arguments[j++] = getIndex(args[i++]);
}
while (i < args.length) {
int index = getIndex(args[i++]);
arguments[j++] = index;
if (scope.isValueForwardRef(index)) {
i++;
skipped++;
}
}
if (skipped > 0) {
arguments = Arrays.copyOf(arguments, arguments.length - skipped);
}
final Type returnType = functionType.getReturnType();
if (returnType == VoidType.INSTANCE) {
emit(VoidCallInstruction.fromSymbols(scope, callee, arguments, paramAttr));
} else {
emit(CallInstruction.fromSymbols(scope, returnType, callee, arguments, paramAttr));
}
}
use of com.oracle.truffle.llvm.runtime.types.Type in project sulong by graalvm.
the class Function method createPhi.
private void createPhi(long[] args) {
Type type = types.get(args[0]);
int count = (args.length) - 1 >> 1;
int[] values = new int[count];
InstructionBlock[] blocks = new InstructionBlock[count];
for (int i = 0, j = 1; i < count; i++) {
values[i] = getIndex(Records.toSignedValue(args[j++]));
blocks[i] = function.getBlock(args[j++]);
}
emit(PhiInstruction.generate(scope.getSymbols(), type, values, blocks));
}
Aggregations