289 const llvm::Type*
const targetType,
290 const std::string& twine =
"")
293#define BIND_ARITHMETIC_CAST_OP(Function, Twine) \
294 std::bind(&Function, \
295 std::placeholders::_1, \
296 std::placeholders::_2, \
297 std::placeholders::_3, \
300 if (targetType->isDoubleTy()) {
309 else if (targetType->isFloatTy()) {
318 else if (targetType->isHalfTy()) {
327 else if (targetType->isIntegerTy(64)) {
336 else if (targetType->isIntegerTy(32)) {
345 else if (targetType->isIntegerTy(16)) {
354 else if (targetType->isIntegerTy(8)) {
363 else if (targetType->isIntegerTy(1)) {
373#undef BIND_ARITHMETIC_CAST_OP
374 assert(
false &&
"invalid LLVM type conversion");
395 const std::string& twine =
"")
398#define BIND_BINARY_OP(Function) \
399 [twine](llvm::IRBuilder<>& B, llvm::Value* L, llvm::Value* R) \
400 -> llvm::Value* { return B.Function(L, R, twine); }
406 if (type->isFloatingPointTy()) {
407 assert(!(ast::tokens::operatorType(token) == ast::tokens::LOGICAL ||
408 ast::tokens::operatorType(token) == ast::tokens::BITWISE)
409 &&
"unable to perform logical or bitwise operation on floating point values");
411 if (token == ast::tokens::PLUS)
return BIND_BINARY_OP(CreateFAdd);
412 else if (token == ast::tokens::MINUS)
return BIND_BINARY_OP(CreateFSub);
413 else if (token == ast::tokens::MULTIPLY)
return BIND_BINARY_OP(CreateFMul);
414 else if (token == ast::tokens::DIVIDE)
return BIND_BINARY_OP(CreateFDiv);
415 else if (token == ast::tokens::MODULO)
return BIND_BINARY_OP(CreateFRem);
416 else if (token == ast::tokens::EQUALSEQUALS)
return BIND_BINARY_OP(CreateFCmpOEQ);
417 else if (token == ast::tokens::NOTEQUALS)
return BIND_BINARY_OP(CreateFCmpONE);
418 else if (token == ast::tokens::MORETHAN)
return BIND_BINARY_OP(CreateFCmpOGT);
419 else if (token == ast::tokens::LESSTHAN)
return BIND_BINARY_OP(CreateFCmpOLT);
420 else if (token == ast::tokens::MORETHANOREQUAL)
return BIND_BINARY_OP(CreateFCmpOGE);
421 else if (token == ast::tokens::LESSTHANOREQUAL)
return BIND_BINARY_OP(CreateFCmpOLE);
422 assert(
false &&
"unrecognised binary operator");
424 else if (type->isIntegerTy()) {
426 else if (token == ast::tokens::MINUS)
return BIND_BINARY_OP(CreateSub);
427 else if (token == ast::tokens::MULTIPLY)
return BIND_BINARY_OP(CreateMul);
428 else if (token == ast::tokens::DIVIDE)
return BIND_BINARY_OP(CreateSDiv);
429 else if (token == ast::tokens::MODULO)
return BIND_BINARY_OP(CreateSRem);
430 else if (token == ast::tokens::EQUALSEQUALS)
return BIND_BINARY_OP(CreateICmpEQ);
431 else if (token == ast::tokens::NOTEQUALS)
return BIND_BINARY_OP(CreateICmpNE);
432 else if (token == ast::tokens::MORETHAN)
return BIND_BINARY_OP(CreateICmpSGT);
433 else if (token == ast::tokens::LESSTHAN)
return BIND_BINARY_OP(CreateICmpSLT);
434 else if (token == ast::tokens::MORETHANOREQUAL)
return BIND_BINARY_OP(CreateICmpSGE);
435 else if (token == ast::tokens::LESSTHANOREQUAL)
return BIND_BINARY_OP(CreateICmpSLE);
436 else if (token == ast::tokens::AND)
return BIND_BINARY_OP(CreateAnd);
437 else if (token == ast::tokens::OR)
return BIND_BINARY_OP(CreateOr);
438 else if (token == ast::tokens::SHIFTLEFT)
return BIND_BINARY_OP(CreateShl);
439 else if (token == ast::tokens::SHIFTRIGHT)
return BIND_BINARY_OP(CreateAShr);
440 else if (token == ast::tokens::BITAND)
return BIND_BINARY_OP(CreateAnd);
441 else if (token == ast::tokens::BITOR)
return BIND_BINARY_OP(CreateOr);
442 else if (token == ast::tokens::BITXOR)
return BIND_BINARY_OP(CreateXor);
443 assert(
false &&
"unrecognised binary operator");
447 assert(
false &&
"invalid LLVM type for binary operation");
507 llvm::Type* targetElementType,
508 llvm::IRBuilder<>& builder)
510 assert(targetElementType && (targetElementType->isIntegerTy() ||
511 targetElementType->isFloatingPointTy()) &&
512 "Target element type is not a scalar type");
513 assert(ptrToArray && ptrToArray->getType()->isPointerTy() &&
514 "Input to arrayCast is not a pointer type.");
516 llvm::Type* arrayType = ptrToArray->getType()->getContainedType(0);
517 assert(arrayType && llvm::isa<llvm::ArrayType>(arrayType));
520 llvm::Type* sourceElementType = arrayType->getArrayElementType();
521 assert(sourceElementType && (sourceElementType->isIntegerTy() ||
522 sourceElementType->isFloatingPointTy()) &&
523 "Source element type is not a scalar type");
525 if (sourceElementType == targetElementType)
return ptrToArray;
529 const size_t elementSize = arrayType->getArrayNumElements();
530 llvm::Value* targetArray =
532 llvm::ArrayType::get(targetElementType, elementSize));
534 for (
size_t i = 0; i < elementSize; ++i) {
537 source =
ir_load(builder, source);
538 source = llvmCastFunction(builder, source, targetElementType);
539 builder.CreateStore(source, target);