mkql_builtins_rotright.cpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. #include "mkql_builtins_impl.h" // Y_IGNORE
  2. namespace NKikimr {
  3. namespace NMiniKQL {
  4. namespace {
  5. template<typename TInput, typename TOutput>
  6. struct TRotRight : public TShiftArithmeticBinary<TInput, TOutput, TRotRight<TInput, TOutput>> {
  7. static TOutput Do(TInput arg, ui8 bits)
  8. {
  9. bits %= (sizeof(arg) * CHAR_BIT);
  10. return bits ? ((arg >> bits) | (arg << (sizeof(arg) * CHAR_BIT - bits))) : arg;
  11. }
  12. #ifndef MKQL_DISABLE_CODEGEN
  13. static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
  14. {
  15. const auto maxb = ConstantInt::get(arg->getType(), sizeof(TInput) * CHAR_BIT);
  16. const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
  17. const auto rem = BinaryOperator::CreateURem(zext, maxb, "rem", block);
  18. const auto lshr = BinaryOperator::CreateLShr(arg, rem, "lshr", block);
  19. const auto sub = BinaryOperator::CreateSub(maxb, rem, "sub", block);
  20. const auto shl = BinaryOperator::CreateShl(arg, sub, "shl", block);
  21. const auto res = BinaryOperator::CreateOr(shl, lshr, "res", block);
  22. return res;
  23. }
  24. #endif
  25. };
  26. }
  27. void RegisterRotRight(IBuiltinFunctionRegistry& registry) {
  28. RegisterUnsignedShiftFunctionOpt<TRotRight, TBinaryShiftArgsOpt>(registry, "RotRight");
  29. }
  30. } // namespace NMiniKQL
  31. } // namespace NKikimr