github.com/matrixorigin/matrixone@v1.2.0/cgo/arith.c (about)

     1  /* 
     2   * Copyright 2021 Matrix Origin
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  #include "mo_impl.h"
    18  
    19  /* 
    20   * Signed int add with overflow check.
    21   *
    22   * The test checks if rt[i] and tmpx have different sign, and rt[i]
    23   * and tmpy have different sign, therefore, tmpx and tmpy have same 
    24   * sign but the result has different sign, therefore, it is an overflow.
    25   *
    26   * DO NOT use __builtin_add_overflow, which gcc cannot vectorize with SIMD
    27   * and is actually much much slower.
    28   */
    29  #define ADD_SIGNED_OVFLAG(TGT, A, B)                 \
    30      TGT = (A) + (B);                                 \
    31      opflag |= ((TGT) ^ (A)) & ((TGT) ^ (B))
    32  
    33  #define ADD_SIGNED_OVFLAG_CHECK                      \
    34      if (opflag < 0)    {                             \
    35          return RC_OUT_OF_RANGE;                      \
    36      } else return RC_SUCCESS
    37  
    38  
    39  /*
    40   * Unsigned int add with overflow check
    41   *
    42   * If result is less, we know it wrapped around.
    43   */
    44  #define ADD_UNSIGNED_OVFLAG(TGT, A, B)              \
    45      TGT = (A) + (B);                                \
    46      if ((TGT) < (A)) {                              \
    47          opflag = 1;                                 \
    48      } else (void) 0
    49  
    50  #define ADD_UNSIGNED_OVFLAG_CHECK                   \
    51      if (opflag != 0) {                              \
    52          return RC_OUT_OF_RANGE;                     \
    53      } else return RC_SUCCESS
    54  
    55  /*
    56   * Float/Double overflow check.
    57   *
    58   * At this moment we don't do anything.
    59   */
    60  #define ADD_FLOAT_OVFLAG(TGT, A, B)                 \
    61      TGT = (A) + (B)    
    62  
    63  #define ADD_FLOAT_OVFLAG_CHECK                      \
    64      (void) opflag;                                  \
    65      return RC_SUCCESS
    66  
    67  /*
    68   * Signed int sub with overflow check.
    69   */
    70  #define SUB_SIGNED_OVFLAG(TGT, A, B)                 \
    71      TGT = (A) - (B);                                 \
    72      opflag |= ((A) ^ (B)) & ((TGT) ^ (A))
    73  
    74  #define SUB_SIGNED_OVFLAG_CHECK                      \
    75      if (opflag < 0)    {                             \
    76          return RC_OUT_OF_RANGE;                      \
    77      }else return RC_SUCCESS
    78  
    79  
    80  /*
    81   * Unsigned int sub with overflow check
    82   *
    83   * If A is less than B,, we know it wrapped around.
    84   */
    85  #define SUB_UNSIGNED_OVFLAG(TGT, A, B)              \
    86      TGT = (A) - (B);                                \
    87      if ((A) < (B)) {                                \
    88          opflag = 1;                                 \
    89      } else (void) 0
    90  
    91  #define SUB_UNSIGNED_OVFLAG_CHECK                   \
    92      if (opflag != 0) {                              \
    93          return RC_OUT_OF_RANGE;                     \
    94      } else return RC_SUCCESS
    95  
    96  
    97  /*
    98   * Float/Double overflow check.
    99   *
   100   * At this moment we don't do anything.
   101   */
   102  #define SUB_FLOAT_OVFLAG(TGT, A, B)                 \
   103      TGT = (A) - (B)
   104  
   105  #define SUB_FLOAT_OVFLAG_CHECK                      \
   106      (void) opflag;                                  \
   107      return RC_SUCCESS
   108  
   109  /*
   110   * Signed int mul with overflow check.
   111   */
   112  #define MUL_SIGNED_OVFLAG(TGT, A, B, MAXVAL, MINVAL, ZT ,UPTYPE)               \
   113      temp = (UPTYPE)(A) * (UPTYPE)(B);                                          \
   114      TGT = (ZT)temp;                                                            \
   115      opflag = ((A ^ B) > 0 && temp > MAXVAL) || ((A ^ B) < 0 && temp < MINVAL)
   116  
   117  #define MUL_SIGNED_OVFLAG_CHECK                                                \
   118      if (opflag != 0)    {                                                      \
   119          return RC_OUT_OF_RANGE;                                                \
   120      }else return RC_SUCCESS
   121  
   122  
   123  /*
   124   * Unsigned int mul with overflow check
   125   */
   126  #define MUL_UNSIGNED_OVFLAG(TGT, A, B, MAXVAL, MINVAL, ZT, UPTYPE)             \
   127      temp = (UPTYPE)(A) * (UPTYPE)(B);                                          \
   128      TGT = (ZT)temp;                                                            \
   129      opflag = (temp > MAXVAL)
   130  
   131  #define MUL_UNSIGNED_OVFLAG_CHECK                                              \
   132      if (opflag != 0) {                                                         \
   133          return RC_OUT_OF_RANGE;                                                \
   134      } else return RC_SUCCESS
   135  
   136  
   137  /*
   138   * Float/Double mul overflow check.
   139   *
   140   * At this moment we don't do anything.
   141   */
   142  #define MUL_FLOAT_OVFLAG(TGT, A, B)                 \
   143      TGT = (A) * (B)
   144  
   145  #define MUL_FLOAT_OVFLAG_CHECK                      \
   146      (void) opflag;                                  \
   147      return RC_SUCCESS
   148  
   149  
   150  /*
   151   * Float/Double div overflow check.
   152   *
   153   * At this moment we don't do anything.
   154   */
   155  #define DIV_FLOAT_OVFLAG(TGT, A, B)                 \
   156      if ((B) == 0) {                                 \
   157          opflag = 1;                                 \
   158      } else TGT = (A) / (B)
   159  
   160  #define DIV_FLOAT_OVFLAG_CHECK                      \
   161      if (opflag == 1) {                              \
   162          return RC_DIVISION_BY_ZERO;                 \
   163      } else return RC_SUCCESS
   164  
   165  /*
   166   * Signed int mod with overflow check.
   167   */
   168  #define MOD_SIGNED_OVFLAG(TGT, A, B)                \
   169      if ((B) == 0) {                                 \
   170          opflag = 1;                                 \
   171      } else TGT = (A) % (B)
   172  
   173  
   174  #define MOD_SIGNED_OVFLAG_CHECK                     \
   175      if (opflag == 1) {                              \
   176          return RC_DIVISION_BY_ZERO;                 \
   177      } else return RC_SUCCESS
   178  
   179  
   180  /*
   181   * Unsigned int mod with overflow check
   182   */
   183  #define MOD_UNSIGNED_OVFLAG(TGT, A, B)              \
   184      if ((B) == 0) {                                 \
   185          opflag = 1;                                 \
   186      } else TGT = (A) % (B)
   187  
   188  #define MOD_UNSIGNED_OVFLAG_CHECK                   \
   189      if (opflag == 1) {                              \
   190          return RC_DIVISION_BY_ZERO;                 \
   191      } else return RC_SUCCESS
   192  
   193  
   194  /*
   195   * Float mod overflow check.
   196   */
   197  #define MOD_FLOAT_OVFLAG(TGT, A, B)                 \
   198      if ((B) == 0) {                                 \
   199          opflag = 1;                                 \
   200      } else TGT = fmodf((A), (B))
   201  
   202  #define MOD_FLOAT_OVFLAG_CHECK                      \
   203      if (opflag == 1) {                              \
   204          return RC_DIVISION_BY_ZERO;                 \
   205      } else return RC_SUCCESS
   206  
   207  
   208  /*
   209   * Double mod overflow check.
   210   */
   211  #define MOD_DOUBLE_OVFLAG(TGT, A, B)                \
   212      if ((B) == 0) {                                 \
   213          opflag = 1;                                 \
   214      } else TGT = fmod((A), (B))
   215  
   216  #define MOD_DOUBLE_OVFLAG_CHECK                     \
   217      if (opflag == 1) {                              \
   218          return RC_DIVISION_BY_ZERO;                 \
   219      } else return RC_SUCCESS
   220  
   221  // MO_ARITH_T: Handle general arithmetic operations
   222  #define MO_ARITH_T(OP, ZT)                                    \
   223      ZT *rt = (ZT *) r;                                        \
   224      ZT *at = (ZT *) a;                                        \
   225      ZT *bt = (ZT *) b;                                        \
   226      ZT opflag = 0;                                            \
   227      if ((flag & LEFT_IS_SCALAR) != 0) {                       \
   228          if (nulls != NULL) {                                  \
   229              for (uint64_t i = 0; i < n; i++) {                \
   230                  if (!bitmap_test(nulls, i)) {                 \
   231                      OP(rt[i], at[0], bt[i]);                  \
   232                  }                                             \
   233              }                                                 \
   234          } else {                                              \
   235              for (uint64_t i = 0; i < n; i++) {                \
   236                  OP(rt[i], at[0], bt[i]);                      \
   237              }                                                 \
   238          }                                                     \
   239      } else if ((flag & RIGHT_IS_SCALAR) != 0) {               \
   240          if (nulls != NULL) {                                  \
   241              for (uint64_t i = 0; i < n; i++) {                \
   242                  if (!bitmap_test(nulls, i)) {                 \
   243                      OP(rt[i], at[i], bt[0]);                  \
   244                  }                                             \
   245              }                                                 \
   246          } else {                                              \
   247              for (uint64_t i = 0; i < n; i++) {                \
   248                  OP(rt[i], at[i], bt[0]);                      \
   249              }                                                 \
   250          }                                                     \
   251      } else {                                                  \
   252          if (nulls != NULL) {                                  \
   253              for (uint64_t i = 0; i < n; i++) {                \
   254                  if (!bitmap_test(nulls, i)) {                 \
   255                      OP(rt[i], at[i], bt[i]);                  \
   256                  }                                             \
   257              }                                                 \
   258          } else {                                              \
   259              for (uint64_t i = 0; i < n; i++) {                \
   260                  OP(rt[i], at[i], bt[i]);                      \
   261              }                                                 \
   262          }                                                     \
   263      }                                                         \
   264      OP ## _CHECK 
   265  
   266  
   267  // MO_MUL_T: Handle signed and unsigned integer multiplication
   268  #define MO_MUL_T(OP, ZT, MAXVAL, MINVAL, UPTYPE)                               \
   269      ZT *rt = (ZT *) r;                                                         \
   270      ZT *at = (ZT *) a;                                                         \
   271      ZT *bt = (ZT *) b;                                                         \
   272      UPTYPE temp = 0;                                                           \
   273      ZT opflag = 0;                                                             \
   274      if ((flag & LEFT_IS_SCALAR) != 0) {                                        \
   275          if (nulls != NULL) {                                                   \
   276              for (uint64_t i = 0; i < n; i++) {                                 \
   277                  if (!bitmap_test(nulls, i)) {                                  \
   278                      OP(rt[i], at[0], bt[i], MAXVAL, MINVAL, ZT, UPTYPE);       \
   279                  }                                                              \
   280              }                                                                  \
   281          } else {                                                               \
   282              for (uint64_t i = 0; i < n; i++) {                                 \
   283                  OP(rt[i], at[0], bt[i], MAXVAL, MINVAL, ZT, UPTYPE);           \
   284              }                                                                  \
   285          }                                                                      \
   286      } else if ((flag & RIGHT_IS_SCALAR) != 0) {                                \
   287          if (nulls != NULL) {                                                   \
   288              for (uint64_t i = 0; i < n; i++) {                                 \
   289                  if (!bitmap_test(nulls, i)) {                                  \
   290                      OP(rt[i], at[i], bt[0], MAXVAL, MINVAL, ZT, UPTYPE);       \
   291                  }                                                              \
   292              }                                                                  \
   293          } else {                                                               \
   294              for (uint64_t i = 0; i < n; i++) {                                 \
   295                  OP(rt[i], at[i], bt[0], MAXVAL, MINVAL, ZT, UPTYPE);           \
   296              }                                                                  \
   297          }                                                                      \
   298      } else {                                                                   \
   299          if (nulls != NULL) {                                                   \
   300              for (uint64_t i = 0; i < n; i++) {                                 \
   301                  if (!bitmap_test(nulls, i)) {                                  \
   302                      OP(rt[i], at[i], bt[i], MAXVAL, MINVAL, ZT, UPTYPE);       \
   303                  }                                                              \
   304              }                                                                  \
   305          } else {                                                               \
   306              for (uint64_t i = 0; i < n; i++) {                                 \
   307                  OP(rt[i], at[i], bt[i], MAXVAL, MINVAL, ZT, UPTYPE);           \
   308              }                                                                  \
   309          }                                                                      \
   310      }                                                                          \
   311      OP ## _CHECK
   312  
   313  
   314  
   315  // Addition operation
   316  int32_t SignedInt_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   317  {
   318      if (szof == 1) {
   319          MO_ARITH_T(ADD_SIGNED_OVFLAG, int8_t);
   320      } else if (szof == 2) {
   321          MO_ARITH_T(ADD_SIGNED_OVFLAG, int16_t);
   322      } else if (szof == 4) {
   323          MO_ARITH_T(ADD_SIGNED_OVFLAG, int32_t);
   324      } else if (szof == 8) {
   325          MO_ARITH_T(ADD_SIGNED_OVFLAG, int64_t);
   326      } else {
   327          return RC_INVALID_ARGUMENT;
   328      }
   329      return RC_SUCCESS;
   330  }
   331  
   332  int32_t UnsignedInt_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   333  {
   334      if (szof == 1) {
   335          MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint8_t);
   336      } else if (szof == 2) {
   337          MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint16_t);
   338      } else if (szof == 4) {
   339          MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint32_t);
   340      } else if (szof == 8) {
   341          MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint64_t);
   342      } else {
   343          return RC_INVALID_ARGUMENT;
   344      }
   345      return RC_SUCCESS;
   346  }
   347  
   348  int32_t Float_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   349  {
   350      if (szof == 4) {
   351          MO_ARITH_T(ADD_FLOAT_OVFLAG, float);
   352      } else if (szof == 8) {
   353          MO_ARITH_T(ADD_FLOAT_OVFLAG, double);
   354      } else {
   355          return RC_INVALID_ARGUMENT;
   356      }
   357      return RC_SUCCESS;
   358  }
   359  
   360  // Subtraction operation
   361  int32_t SignedInt_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   362  {
   363      if (szof == 1) {
   364          MO_ARITH_T(SUB_SIGNED_OVFLAG, int8_t);
   365      } else if (szof == 2) {
   366          MO_ARITH_T(SUB_SIGNED_OVFLAG, int16_t);
   367      } else if (szof == 4) {
   368          MO_ARITH_T(SUB_SIGNED_OVFLAG, int32_t);
   369      } else if (szof == 8) {
   370          MO_ARITH_T(SUB_SIGNED_OVFLAG, int64_t);
   371      } else {
   372          return RC_INVALID_ARGUMENT;
   373      }
   374      return RC_SUCCESS;
   375  }
   376  
   377  int32_t UnsignedInt_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   378  {
   379      if (szof == 1) {
   380          MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint8_t);
   381      } else if (szof == 2) {
   382          MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint16_t);
   383      } else if (szof == 4) {
   384          MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint32_t);
   385      } else if (szof == 8) {
   386          MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint64_t);
   387      } else {
   388          return RC_INVALID_ARGUMENT;
   389      }
   390      return RC_SUCCESS;
   391  }
   392  
   393  int32_t Float_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   394  {
   395      if (szof == 4) {
   396          MO_ARITH_T(SUB_FLOAT_OVFLAG, float);
   397      } else if (szof == 8) {
   398          MO_ARITH_T(SUB_FLOAT_OVFLAG, double);
   399      } else {
   400          return RC_INVALID_ARGUMENT;
   401      }
   402      return RC_SUCCESS;
   403  }
   404  
   405  // Multiplication operation
   406  int32_t SignedInt_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   407  {
   408      if (szof == 1) {
   409          MO_MUL_T(MUL_SIGNED_OVFLAG, int8_t, INT8_MAX, INT8_MIN, int16_t);
   410      } else if (szof == 2) {
   411          MO_MUL_T(MUL_SIGNED_OVFLAG, int16_t, INT16_MAX, INT16_MIN, int16_t);
   412      } else if (szof == 4) {
   413          MO_MUL_T(MUL_SIGNED_OVFLAG, int32_t, INT32_MAX, INT32_MIN, int64_t);
   414      } else if (szof == 8) {
   415          MO_MUL_T(MUL_SIGNED_OVFLAG, int64_t, INT64_MAX, INT64_MIN, __int128);
   416      } else {
   417          return RC_INVALID_ARGUMENT;
   418      }
   419      return RC_SUCCESS;
   420  }
   421  
   422  
   423  int32_t UnsignedInt_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   424  {
   425      if (szof == 1) {
   426          MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint8_t, UINT8_MAX, 0, uint16_t);
   427      } else if (szof == 2) {
   428          MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint16_t, UINT16_MAX, 0, uint32_t);
   429      } else if (szof == 4) {
   430          MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint32_t, UINT32_MAX, 0, uint64_t);
   431      } else if (szof == 8) {
   432          MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint64_t, UINT64_MAX, 0, __int128);
   433      } else {
   434          return RC_INVALID_ARGUMENT;
   435      }
   436      return RC_SUCCESS;
   437  }
   438  
   439  
   440  int32_t Float_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   441  {
   442      if (szof == 4) {
   443          MO_ARITH_T(MUL_FLOAT_OVFLAG, float);
   444      } else if (szof == 8) {
   445          MO_ARITH_T(MUL_FLOAT_OVFLAG, double);
   446      } else {
   447          return RC_INVALID_ARGUMENT;
   448      }
   449      return RC_SUCCESS;
   450  }
   451  
   452  // Division operation
   453  int32_t Float_VecDiv(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) {
   454      if (szof == 4) {
   455          MO_ARITH_T(DIV_FLOAT_OVFLAG, float);
   456      } else if (szof == 8) {
   457          MO_ARITH_T(DIV_FLOAT_OVFLAG, double);
   458      } else {
   459          return RC_INVALID_ARGUMENT;
   460      }
   461      return RC_SUCCESS;
   462  }
   463  
   464  // Mod operation
   465  int32_t SignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   466  {
   467      if (szof == 1) {
   468          MO_ARITH_T(MOD_SIGNED_OVFLAG, int8_t);
   469      } else if (szof == 2) {
   470          MO_ARITH_T(MOD_SIGNED_OVFLAG, int16_t);
   471      } else if (szof == 4) {
   472          MO_ARITH_T(MOD_SIGNED_OVFLAG, int32_t);
   473      } else if (szof == 8) {
   474          MO_ARITH_T(MOD_SIGNED_OVFLAG, int64_t);
   475      } else {
   476          return RC_INVALID_ARGUMENT;
   477      }
   478      return RC_SUCCESS;
   479  }
   480  
   481  int32_t UnsignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   482  {
   483      if (szof == 1) {
   484          MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint8_t);
   485      } else if (szof == 2) {
   486          MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint16_t);
   487      } else if (szof == 4) {
   488          MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint32_t);
   489      } else if (szof == 8) {
   490          MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint64_t);
   491      } else {
   492          return RC_INVALID_ARGUMENT;
   493      }
   494      return RC_SUCCESS;
   495  }
   496  
   497  int32_t Float_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   498  {
   499      if (szof == 4) {
   500          MO_ARITH_T(MOD_FLOAT_OVFLAG, float);
   501      } else if (szof == 8) {
   502          MO_ARITH_T(MOD_DOUBLE_OVFLAG, double);
   503      } else {
   504          return RC_INVALID_ARGUMENT;
   505      }
   506      return RC_SUCCESS;
   507  }
   508  
   509  
   510  /*
   511   * Float/Double integer div overflow check.
   512   *
   513   * At this moment we don't do anything.
   514   */
   515  #define INTDIV_FLOAT_OVFLAG(TGT, A, B)              \
   516      if ((B) == 0) {                                 \
   517          opflag = 1;                                 \
   518      } else TGT = (int64_t)((A) / (B))
   519  
   520  #define INTDIV_FLOAT_OVFLAG_CHECK                   \
   521      if (opflag == 1) {                              \
   522          return RC_DIVISION_BY_ZERO;                 \
   523      } else return RC_SUCCESS
   524  
   525  // MO_INT_DIV : Handle floating-point integer division
   526  #define MO_INT_DIV(OP, ZT, RT)                                \
   527      RT *rt = (RT *) r;                                        \
   528      ZT *at = (ZT *) a;                                        \
   529      ZT *bt = (ZT *) b;                                        \
   530      ZT opflag = 0;                                            \
   531      if ((flag & LEFT_IS_SCALAR) != 0) {                       \
   532          if (nulls != NULL) {                                  \
   533              for (uint64_t i = 0; i < n; i++) {                \
   534                  if (!bitmap_test(nulls, i)) {                 \
   535                      OP(rt[i], at[0], bt[i]);                  \
   536                  }                                             \
   537              }                                                 \
   538          } else {                                              \
   539              for (uint64_t i = 0; i < n; i++) {                \
   540                  OP(rt[i], at[0], bt[i]);                      \
   541              }                                                 \
   542          }                                                     \
   543      } else if ((flag & RIGHT_IS_SCALAR) != 0) {               \
   544          if (nulls != NULL) {                                  \
   545              for (uint64_t i = 0; i < n; i++) {                \
   546                  if (!bitmap_test(nulls, i)) {                 \
   547                      OP(rt[i], at[i], bt[0]);                  \
   548                  }                                             \
   549              }                                                 \
   550          } else {                                              \
   551              for (uint64_t i = 0; i < n; i++) {                \
   552                  OP(rt[i], at[i], bt[0]);                      \
   553              }                                                 \
   554          }                                                     \
   555      } else {                                                  \
   556          if (nulls != NULL) {                                  \
   557              for (uint64_t i = 0; i < n; i++) {                \
   558                  if (!bitmap_test(nulls, i)) {                 \
   559                      OP(rt[i], at[i], bt[i]);                  \
   560                  }                                             \
   561              }                                                 \
   562          } else {                                              \
   563              for (uint64_t i = 0; i < n; i++) {                \
   564                  OP(rt[i], at[i], bt[i]);                      \
   565              }                                                 \
   566          }                                                     \
   567      }                                                         \
   568      OP ## _CHECK
   569  
   570  
   571  int32_t Float_VecIntegerDiv(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof)
   572  {
   573      if (szof == 4) {
   574          MO_INT_DIV(INTDIV_FLOAT_OVFLAG, float, int64_t);
   575      } else if (szof == 8) {
   576          MO_INT_DIV(INTDIV_FLOAT_OVFLAG, double, int64_t);
   577      } else {
   578          return RC_INVALID_ARGUMENT;
   579      }
   580      return RC_SUCCESS;
   581  }