290 const llvm::Type*
const targetType,
291 const std::string& twine =
"")
294#define BIND_ARITHMETIC_CAST_OP(Function, Twine) \
295 std::bind(&Function, \
296 std::placeholders::_1, \
297 std::placeholders::_2, \
298 std::placeholders::_3, \
301 if (targetType->isDoubleTy()) {
310 else if (targetType->isFloatTy()) {
319 else if (targetType->isHalfTy()) {
328 else if (targetType->isIntegerTy(64)) {
337 else if (targetType->isIntegerTy(32)) {
346 else if (targetType->isIntegerTy(16)) {
355 else if (targetType->isIntegerTy(8)) {
364 else if (targetType->isIntegerTy(1)) {
374#undef BIND_ARITHMETIC_CAST_OP
396 const std::string& twine =
"")
399#define BIND_BINARY_OP(Function) \
400 [twine](llvm::IRBuilder<>& B, llvm::Value* L, llvm::Value* R) \
401 -> llvm::Value* { return B.Function(L, R, twine); }
407 if (type->isFloatingPointTy()) {
408 OPENVDB_ASSERT(!(ast::tokens::operatorType(token) == ast::tokens::LOGICAL ||
409 ast::tokens::operatorType(token) == ast::tokens::BITWISE)
410 &&
"unable to perform logical or bitwise operation on floating point values");
412 if (token == ast::tokens::PLUS)
return BIND_BINARY_OP(CreateFAdd);
413 else if (token == ast::tokens::MINUS)
return BIND_BINARY_OP(CreateFSub);
414 else if (token == ast::tokens::MULTIPLY)
return BIND_BINARY_OP(CreateFMul);
415 else if (token == ast::tokens::DIVIDE)
return BIND_BINARY_OP(CreateFDiv);
416 else if (token == ast::tokens::MODULO)
return BIND_BINARY_OP(CreateFRem);
417 else if (token == ast::tokens::EQUALSEQUALS)
return BIND_BINARY_OP(CreateFCmpOEQ);
418 else if (token == ast::tokens::NOTEQUALS)
return BIND_BINARY_OP(CreateFCmpONE);
419 else if (token == ast::tokens::MORETHAN)
return BIND_BINARY_OP(CreateFCmpOGT);
420 else if (token == ast::tokens::LESSTHAN)
return BIND_BINARY_OP(CreateFCmpOLT);
421 else if (token == ast::tokens::MORETHANOREQUAL)
return BIND_BINARY_OP(CreateFCmpOGE);
422 else if (token == ast::tokens::LESSTHANOREQUAL)
return BIND_BINARY_OP(CreateFCmpOLE);
425 else if (type->isIntegerTy()) {
427 else if (token == ast::tokens::MINUS)
return BIND_BINARY_OP(CreateSub);
428 else if (token == ast::tokens::MULTIPLY)
return BIND_BINARY_OP(CreateMul);
429 else if (token == ast::tokens::DIVIDE)
return BIND_BINARY_OP(CreateSDiv);
430 else if (token == ast::tokens::MODULO)
return BIND_BINARY_OP(CreateSRem);
431 else if (token == ast::tokens::EQUALSEQUALS)
return BIND_BINARY_OP(CreateICmpEQ);
432 else if (token == ast::tokens::NOTEQUALS)
return BIND_BINARY_OP(CreateICmpNE);
433 else if (token == ast::tokens::MORETHAN)
return BIND_BINARY_OP(CreateICmpSGT);
434 else if (token == ast::tokens::LESSTHAN)
return BIND_BINARY_OP(CreateICmpSLT);
435 else if (token == ast::tokens::MORETHANOREQUAL)
return BIND_BINARY_OP(CreateICmpSGE);
436 else if (token == ast::tokens::LESSTHANOREQUAL)
return BIND_BINARY_OP(CreateICmpSLE);
437 else if (token == ast::tokens::AND)
return BIND_BINARY_OP(CreateAnd);
438 else if (token == ast::tokens::OR)
return BIND_BINARY_OP(CreateOr);
439 else if (token == ast::tokens::SHIFTLEFT)
return BIND_BINARY_OP(CreateShl);
440 else if (token == ast::tokens::SHIFTRIGHT)
return BIND_BINARY_OP(CreateAShr);
441 else if (token == ast::tokens::BITAND)
return BIND_BINARY_OP(CreateAnd);
442 else if (token == ast::tokens::BITOR)
return BIND_BINARY_OP(CreateOr);
443 else if (token == ast::tokens::BITXOR)
return BIND_BINARY_OP(CreateXor);
448 OPENVDB_ASSERT(
false &&
"invalid LLVM type for binary operation");
508 llvm::Type* targetElementType,
509 llvm::IRBuilder<>& builder)
511 OPENVDB_ASSERT(targetElementType && (targetElementType->isIntegerTy() ||
512 targetElementType->isFloatingPointTy()) &&
513 "Target element type is not a scalar type");
514 OPENVDB_ASSERT(ptrToArray && ptrToArray->getType()->isPointerTy() &&
515 "Input to arrayCast is not a pointer type.");
517 llvm::Type* arrayType = ptrToArray->getType()->getContainedType(0);
518 OPENVDB_ASSERT(arrayType && llvm::isa<llvm::ArrayType>(arrayType));
521 llvm::Type* sourceElementType = arrayType->getArrayElementType();
522 OPENVDB_ASSERT(sourceElementType && (sourceElementType->isIntegerTy() ||
523 sourceElementType->isFloatingPointTy()) &&
524 "Source element type is not a scalar type");
526 if (sourceElementType == targetElementType)
return ptrToArray;
530 const size_t elementSize = arrayType->getArrayNumElements();
531 llvm::Value* targetArray =
533 llvm::ArrayType::get(targetElementType, elementSize));
535 for (
size_t i = 0; i < elementSize; ++i) {
538 source =
ir_load(builder, source);
539 source = llvmCastFunction(builder, source, targetElementType);
540 builder.CreateStore(source, target);