static llvm::Value* HandleTypeCastsFromIntegers(llvm::Value* value, int src_type_bw, llvm::Type* dest_type, bool sign, llvm::IRBuilder<>& builder) {
  llvm::Type::TypeID dest_type_id = dest_type->getTypeID();

  switch (dest_type_id) {
    case llvm::Type::IntegerTyID:
      // We should never come here...
      return HandleIntegerTypeCast(value, dest_type, src_type_bw, dest_type->getIntegerBitWidth(), sign, builder);
      break;
    case llvm::Type::FloatTyID:
      // Not sure if this is required but if it does not fit in 32-bit,
      //   go to double first.
      if (src_type_bw != 32) {
        value = HandleTypeCastsFromIntegers(value, src_type_bw,
                                            llvm::Type::getDoubleTy(llvm::getGlobalContext()),
                                            sign, builder);
        return HandleTypeCastsFromDoubles(value, dest_type, sign, builder);
      }

      if (sign == true) {
        return builder.CreateSIToFP(value, dest_type, "sitofp");
      } else {
        return builder.CreateUIToFP(value, dest_type, "uitofp");
      }
    case llvm::Type::DoubleTyID:
      if (sign == true) {
        return builder.CreateSIToFP(value, dest_type, "sitofp");
      } else {
        return builder.CreateUIToFP(value, dest_type, "uitofp");
      }
    default:
      assert(0);
  }
  return nullptr;
}
static llvm::Value* HandleTypeCastsFromDoubles(llvm::Value* value, llvm::Type* dest_type, bool sign, llvm::IRBuilder<>& builder) {
  llvm::Type::TypeID dest_type_id = dest_type->getTypeID();

  switch (dest_type_id) {
    case llvm::Type::IntegerTyID: {
      // Let us check we have the right size though.
      int dest_type_bw = dest_type->getIntegerBitWidth();

      if (sign) {
        value = builder.CreateFPToSI(value, dest_type, "fptosi");
      } else {
        value = builder.CreateFPToUI(value, dest_type, "fptoui");
      }

      if (dest_type_bw != 64) {
        // Now go to the right size.
        value = HandleIntegerTypeCast(value, dest_type, 64, 32, sign, builder);
      }
      return value;
    }
    case llvm::Type::FloatTyID:
      return builder.CreateFPTrunc(value, dest_type, "fptrunc");
    default:
      assert(0);
  }
  return nullptr;
}
예제 #3
0
llvm::Value* MemoryExpression::GetPointer(WasmFunction*fct, llvm::IRBuilder<>& builder) const {
  llvm::Type* ptr_type= nullptr;

  if (type_ == INT_32 || type_ == INT_64) {
    switch (size_) {
      case 8:
        ptr_type= llvm::Type::getInt8PtrTy(llvm::getGlobalContext());
        break;
      case 16:
        ptr_type= llvm::Type::getInt16PtrTy(llvm::getGlobalContext());
        break;
      case 32:
        ptr_type= llvm::Type::getInt32PtrTy(llvm::getGlobalContext());
        break;
      case 64:
        ptr_type= llvm::Type::getInt64PtrTy(llvm::getGlobalContext());
        break;
      default:
        assert(0);
        break;
    }
  } else {
    switch (size_) {
      case 32:
        ptr_type= llvm::Type::getFloatPtrTy(llvm::getGlobalContext());
        break;
      case 64:
        ptr_type= llvm::Type::getDoublePtrTy(llvm::getGlobalContext());
        break;
      default:
        assert(0);
        break;
    }
  }

  assert(ptr_type != nullptr);

  // Create the base address in the same right type.
  llvm::Type* dest_type = ConvertType(type_);

  llvm::Value* address_i = address_->Codegen(fct, builder);
  llvm::Value* local_base = fct->GetLocalBase();
  llvm::Type* type_64 = llvm::Type::getInt64Ty(llvm::getGlobalContext());
  local_base = builder.CreatePtrToInt(local_base, type_64, "base");

  llvm::Type* address_type = address_i->getType();
  assert(address_type->isIntegerTy() == true);
  int bw = address_i->getType()->getIntegerBitWidth();

  // If not 64, transform it into 64.
  if (bw != 64) {
    address_i = HandleIntegerTypeCast(address_i, type_64, bw, 64, false, builder);
  }

  address_i = builder.CreateAdd(address_i, local_base, "add_with_offset");

  return builder.CreateIntToPtr(address_i, ptr_type, "ptr");
}
예제 #4
0
llvm::Value* Store::ResizeIntegerIfNeed(llvm::Value* value,
                                        llvm::Type* value_type,
                                        llvm::Type* address_type,
                                        bool sign,
                                        llvm::IRBuilder<>& builder) {
  // Get size differences.
  int value_type_bw = value_type->getIntegerBitWidth();

  if (value_type_bw != size_) {
    // Then it depends on sign.
    value = HandleIntegerTypeCast(value, GetAddressType(),
                                  value_type_bw, size_,
                                  sign, builder);
  }

  return value;
}
llvm::Value* HandleTypeCasts(llvm::Value* value, llvm::Type* src_type, llvm::Type* dest_type, bool sign, llvm::IRBuilder<>& builder) {
  if (dest_type != src_type) {
    llvm::Type::TypeID src_type_id = src_type->getTypeID();

    switch (src_type_id) {
      case llvm::Type::IntegerTyID: {
        int src_type_bw = src_type->getIntegerBitWidth();
        return HandleTypeCastsFromIntegers(value, src_type_bw, dest_type, sign, builder);
      }
      case llvm::Type::FloatTyID:
        return HandleTypeCastsFromFloats(value, dest_type, sign, builder);
      case llvm::Type::DoubleTyID:
        return HandleTypeCastsFromDoubles(value, dest_type, sign, builder);
      case llvm::Type::PointerTyID:
        // Probably not good to do this.
        return value;
      default: {
        llvm::Type::TypeID dest_type_id = dest_type->getTypeID();

        BISON_PRINT("HandleTypeCast failure: destination is %d and src is %d\n", dest_type_id, src_type_id);

        (void) dest_type_id;
        assert(0);
        break;
      }
    }
  } else {
    // A bit more code to handle integer case
    llvm::Type::TypeID dest_type_id = dest_type->getTypeID();
    if (dest_type_id == llvm::Type::IntegerTyID) {
      // Now check sizes.
      int dest_type_bw = dest_type->getIntegerBitWidth();
      int src_type_bw = src_type->getIntegerBitWidth();

      // We have a problem here.
      if (dest_type_bw != src_type_bw) {
        // Handle difference of sizes.
        value = HandleIntegerTypeCast(value, dest_type, src_type_bw, dest_type_bw, sign, builder);
      }
    }

    return value;
  }
}
예제 #6
0
llvm::Value* Load::ResizeIntegerIfNeed(llvm::Value* value,
                                        llvm::Type* value_type,
                                        ETYPE destination_type,
                                        bool sign,
                                        llvm::IRBuilder<>& builder) {
  // Get size differences.
  int value_type_bw = value_type->getIntegerBitWidth();
  size_t type_size = GetTypeSize(type_);

  if (value_type_bw != type_size) {
    // Then it depends on sign.
    value = HandleIntegerTypeCast(value, ConvertType(type_),
                                  value_type_bw,
                                  type_size,
                                  sign, builder);
  }

  return value;
}