LCOV - code coverage report
Current view: top level - src - runtime_intrinsics.c (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 349 479 72.9 %
Date: 2022-07-16 23:42:53 Functions: 139 301 46.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 202 456 44.3 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : // This is in implementation of the Julia intrinsic functions against boxed types
       4                 :            : // excluding the native function call interface (ccall, llvmcall)
       5                 :            : //
       6                 :            : // this file assumes a little-endian processor, although that isn't too hard to fix
       7                 :            : // it also assumes two's complement negative numbers, which might be a bit harder to fix
       8                 :            : //
       9                 :            : // TODO: add half-float support
      10                 :            : 
      11                 :            : #include "APInt-C.h"
      12                 :            : #include "julia.h"
      13                 :            : #include "julia_internal.h"
      14                 :            : 
      15                 :            : const unsigned int host_char_bit = 8;
      16                 :            : 
      17                 :            : // float16 intrinsics
      18                 :            : // TODO: use LLVM's compiler-rt on all platforms (Xcode already links compiler-rt)
      19                 :            : 
      20                 :            : #if !defined(_OS_DARWIN_)
      21                 :            : 
      22                 :         66 : static inline float half_to_float(uint16_t ival) JL_NOTSAFEPOINT
      23                 :            : {
      24                 :         66 :     uint32_t sign = (ival & 0x8000) >> 15;
      25                 :         66 :     uint32_t exp = (ival & 0x7c00) >> 10;
      26                 :         66 :     uint32_t sig = (ival & 0x3ff) >> 0;
      27                 :            :     uint32_t ret;
      28                 :            : 
      29         [ -  + ]:         66 :     if (exp == 0) {
      30         [ #  # ]:          0 :         if (sig == 0) {
      31                 :          0 :             sign = sign << 31;
      32                 :          0 :             ret = sign | exp | sig;
      33                 :            :         }
      34                 :            :         else {
      35                 :          0 :             int n_bit = 1;
      36                 :          0 :             uint16_t bit = 0x0200;
      37         [ #  # ]:          0 :             while ((bit & sig) == 0) {
      38                 :          0 :                 n_bit = n_bit + 1;
      39                 :          0 :                 bit = bit >> 1;
      40                 :            :             }
      41                 :          0 :             sign = sign << 31;
      42                 :          0 :             exp = ((-14 - n_bit + 127) << 23);
      43                 :          0 :             sig = ((sig & (~bit)) << n_bit) << (23 - 10);
      44                 :          0 :             ret = sign | exp | sig;
      45                 :            :         }
      46                 :            :     }
      47         [ -  + ]:         66 :     else if (exp == 0x1f) {
      48         [ #  # ]:          0 :         if (sig == 0) { // Inf
      49         [ #  # ]:          0 :             if (sign == 0)
      50                 :          0 :                 ret = 0x7f800000;
      51                 :            :             else
      52                 :          0 :                 ret = 0xff800000;
      53                 :            :         }
      54                 :            :         else // NaN
      55                 :          0 :             ret = 0x7fc00000 | (sign << 31) | (sig << (23 - 10));
      56                 :            :     }
      57                 :            :     else {
      58                 :         66 :         sign = sign << 31;
      59                 :         66 :         exp = ((exp - 15 + 127) << 23);
      60                 :         66 :         sig = sig << (23 - 10);
      61                 :         66 :         ret = sign | exp | sig;
      62                 :            :     }
      63                 :            : 
      64                 :            :     float fret;
      65                 :         66 :     memcpy(&fret, &ret, sizeof(float));
      66                 :         66 :     return fret;
      67                 :            : }
      68                 :            : 
      69                 :            : // float to half algorithm from:
      70                 :            : //   "Fast Half Float Conversion" by Jeroen van der Zijp
      71                 :            : //   ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf
      72                 :            : //
      73                 :            : // With adjustments for round-to-nearest, ties to even.
      74                 :            : 
      75                 :            : static uint16_t basetable[512] = {
      76                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      77                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      78                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      79                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      80                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      81                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      82                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      83                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      84                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      85                 :            :     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      86                 :            :     0x0000, 0x0000, 0x0000, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, 0x2000,
      87                 :            :     0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400, 0x4800, 0x4c00,
      88                 :            :     0x5000, 0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00, 0x7000, 0x7400, 0x7800,
      89                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      90                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      91                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      92                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      93                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      94                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      95                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      96                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      97                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      98                 :            :     0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
      99                 :            :     0x7c00, 0x7c00, 0x7c00, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     100                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     101                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     102                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     103                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     104                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     105                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     106                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     107                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     108                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
     109                 :            :     0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8400, 0x8800, 0x8c00, 0x9000, 0x9400,
     110                 :            :     0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00, 0xb000, 0xb400, 0xb800, 0xbc00, 0xc000,
     111                 :            :     0xc400, 0xc800, 0xcc00, 0xd000, 0xd400, 0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00,
     112                 :            :     0xf000, 0xf400, 0xf800, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     113                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     114                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     115                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     116                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     117                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     118                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     119                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     120                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     121                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
     122                 :            :     0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00};
     123                 :            : 
     124                 :            : static uint8_t shifttable[512] = {
     125                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     126                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     127                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     128                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     129                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     130                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     131                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     132                 :            :     0x19, 0x19, 0x19, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
     133                 :            :     0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
     134                 :            :     0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
     135                 :            :     0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     136                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     137                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     138                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     139                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     140                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     141                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     142                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     143                 :            :     0x18, 0x18, 0x18, 0x0d, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     144                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     145                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     146                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     147                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     148                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     149                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
     150                 :            :     0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13,
     151                 :            :     0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
     152                 :            :     0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
     153                 :            :     0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     154                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     155                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     156                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     157                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     158                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     159                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     160                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
     161                 :            :     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0d};
     162                 :            : 
     163                 :     282134 : static inline uint16_t float_to_half(float param) JL_NOTSAFEPOINT
     164                 :            : {
     165                 :            :     uint32_t f;
     166                 :     282134 :     memcpy(&f, &param, sizeof(float));
     167         [ +  + ]:     282134 :     if (isnan(param)) {
     168                 :        452 :         uint32_t t = 0x8000 ^ (0x8000 & ((uint16_t)(f >> 0x10)));
     169                 :        452 :         return t ^ ((uint16_t)(f >> 0xd));
     170                 :            :     }
     171                 :     281682 :     int i = ((f & ~0x007fffff) >> 23);
     172                 :     281682 :     uint8_t sh = shifttable[i];
     173                 :     281682 :     f &= 0x007fffff;
     174                 :            :     // If `val` is subnormal, the tables are set up to force the
     175                 :            :     // result to 0, so the significand has an implicit `1` in the
     176                 :            :     // cases we care about.
     177                 :     281682 :     f |= 0x007fffff + 0x1;
     178                 :     281682 :     uint16_t h = (uint16_t)(basetable[i] + ((f >> sh) & 0x03ff));
     179                 :            :     // round
     180                 :            :     // NOTE: we maybe should ignore NaNs here, but the payload is
     181                 :            :     // getting truncated anyway so "rounding" it might not matter
     182                 :     281682 :     int nextbit = (f >> (sh - 1)) & 1;
     183   [ +  +  +  - ]:     281682 :     if (nextbit != 0 && (h & 0x7C00) != 0x7C00) {
     184                 :            :         // Round halfway to even or check lower bits
     185   [ +  +  +  + ]:     146662 :         if ((h & 1) == 1 || (f & ((1 << (sh - 1)) - 1)) != 0)
     186                 :     146638 :             h += UINT16_C(1);
     187                 :            :     }
     188                 :     281682 :     return h;
     189                 :            : }
     190                 :            : 
     191                 :         66 : JL_DLLEXPORT float __gnu_h2f_ieee(uint16_t param)
     192                 :            : {
     193                 :         66 :     return half_to_float(param);
     194                 :            : }
     195                 :            : 
     196                 :          0 : JL_DLLEXPORT float __extendhfsf2(uint16_t param)
     197                 :            : {
     198                 :          0 :     return half_to_float(param);
     199                 :            : }
     200                 :            : 
     201                 :         30 : JL_DLLEXPORT uint16_t __gnu_f2h_ieee(float param)
     202                 :            : {
     203                 :         30 :     return float_to_half(param);
     204                 :            : }
     205                 :            : 
     206                 :     282104 : JL_DLLEXPORT uint16_t __truncdfhf2(double param)
     207                 :            : {
     208                 :     282104 :     float res = (float)param;
     209                 :            :     uint32_t resi;
     210                 :     282104 :     memcpy(&resi, &res, sizeof(res));
     211         [ +  + ]:     282104 :     if ((resi&0x7fffffffu) < 0x38800000u){ // if Float16(res) is subnormal
     212                 :            :         // shift so that the mantissa lines up where it would for normal Float16
     213                 :       8548 :         uint32_t shift = 113u-((resi & 0x7f800000u)>>23u);
     214         [ +  + ]:       8548 :         if (shift<23u) {
     215                 :       8224 :             resi |= 0x00800000; // set implicit bit
     216                 :       8224 :             resi >>= shift;
     217                 :            :         }
     218                 :            :     }
     219         [ +  + ]:     282104 :     if ((resi & 0x1fffu) == 0x1000u) { // if we are halfway between 2 Float16 values
     220                 :     253992 :         memcpy(&resi, &res, sizeof(res));
     221                 :            :         // adjust the value by 1 ULP in the direction that will make Float16(res) give the right answer
     222                 :     253992 :         resi += (fabs(res) < fabs(param)) - (fabs(param) < fabs(res));
     223                 :     253992 :         memcpy(&res, &resi, sizeof(res));
     224                 :            :     }
     225                 :     282104 :     return float_to_half(res);
     226                 :            : }
     227                 :            : 
     228                 :            : #endif
     229                 :            : 
     230                 :            : // run time version of bitcast intrinsic
     231                 :     499370 : JL_DLLEXPORT jl_value_t *jl_bitcast(jl_value_t *ty, jl_value_t *v)
     232                 :            : {
     233         [ +  + ]:     499370 :     JL_TYPECHK(bitcast, datatype, ty);
     234   [ +  -  +  + ]:     499368 :     if (!jl_is_concrete_type(ty) || !jl_is_primitivetype(ty))
     235                 :          5 :         jl_error("bitcast: target type not a leaf primitive type");
     236         [ +  + ]:     499363 :     if (!jl_is_primitivetype(jl_typeof(v)))
     237                 :          1 :         jl_error("bitcast: value not a primitive type");
     238         [ -  + ]:     499362 :     if (jl_datatype_size(jl_typeof(v)) != jl_datatype_size(ty))
     239                 :          0 :         jl_error("bitcast: argument size does not match size of target type");
     240         [ -  + ]:     499362 :     if (ty == jl_typeof(v))
     241                 :          0 :         return v;
     242         [ -  + ]:     499362 :     if (ty == (jl_value_t*)jl_bool_type)
     243         [ #  # ]:          0 :         return *(uint8_t*)jl_data_ptr(v) & 1 ? jl_true : jl_false;
     244                 :     499362 :     return jl_new_bits(ty, jl_data_ptr(v));
     245                 :            : }
     246                 :            : 
     247                 :            : // run time version of pointerref intrinsic (warning: i is not rooted)
     248                 :      59382 : JL_DLLEXPORT jl_value_t *jl_pointerref(jl_value_t *p, jl_value_t *i, jl_value_t *align)
     249                 :            : {
     250         [ -  + ]:      59382 :     JL_TYPECHK(pointerref, pointer, p);
     251         [ -  + ]:      59382 :     JL_TYPECHK(pointerref, long, i)
     252         [ -  + ]:      59382 :     JL_TYPECHK(pointerref, long, align);
     253                 :      59382 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     254         [ -  + ]:      59382 :     if (ety == (jl_value_t*)jl_any_type) {
     255                 :          0 :         jl_value_t **pp = (jl_value_t**)(jl_unbox_long(p) + (jl_unbox_long(i)-1)*sizeof(void*));
     256                 :          0 :         return *pp;
     257                 :            :     }
     258                 :            :     else {
     259         [ -  + ]:      59382 :         if (!is_valid_intrinsic_elptr(ety))
     260                 :          0 :             jl_error("pointerref: invalid pointer");
     261                 :      59382 :         size_t nb = LLT_ALIGN(jl_datatype_size(ety), jl_datatype_align(ety));
     262                 :      59382 :         char *pp = (char*)jl_unbox_long(p) + (jl_unbox_long(i)-1)*nb;
     263                 :      59382 :         return jl_new_bits(ety, pp);
     264                 :            :     }
     265                 :            : }
     266                 :            : 
     267                 :            : // run time version of pointerset intrinsic (warning: x is not gc-rooted)
     268                 :          0 : JL_DLLEXPORT jl_value_t *jl_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t *i, jl_value_t *align)
     269                 :            : {
     270         [ #  # ]:          0 :     JL_TYPECHK(pointerset, pointer, p);
     271         [ #  # ]:          0 :     JL_TYPECHK(pointerset, long, i);
     272         [ #  # ]:          0 :     JL_TYPECHK(pointerset, long, align);
     273                 :          0 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     274         [ #  # ]:          0 :     if (ety == (jl_value_t*)jl_any_type) {
     275                 :          0 :         jl_value_t **pp = (jl_value_t**)(jl_unbox_long(p) + (jl_unbox_long(i)-1)*sizeof(void*));
     276                 :          0 :         *pp = x;
     277                 :            :     }
     278                 :            :     else {
     279         [ #  # ]:          0 :         if (!is_valid_intrinsic_elptr(ety))
     280                 :          0 :             jl_error("pointerset: invalid pointer");
     281         [ #  # ]:          0 :         if (jl_typeof(x) != ety)
     282                 :          0 :             jl_type_error("pointerset", ety, x);
     283                 :          0 :         size_t elsz = jl_datatype_size(ety);
     284                 :          0 :         size_t nb = LLT_ALIGN(elsz, jl_datatype_align(ety));
     285                 :          0 :         char *pp = (char*)jl_unbox_long(p) + (jl_unbox_long(i)-1)*nb;
     286                 :          0 :         memcpy(pp, x, elsz);
     287                 :            :     }
     288                 :          0 :     return p;
     289                 :            : }
     290                 :            : 
     291                 :          3 : JL_DLLEXPORT jl_value_t *jl_atomic_pointerref(jl_value_t *p, jl_value_t *order)
     292                 :            : {
     293         [ -  + ]:          3 :     JL_TYPECHK(atomic_pointerref, pointer, p);
     294         [ -  + ]:          3 :     JL_TYPECHK(atomic_pointerref, symbol, order)
     295                 :          3 :     (void)jl_get_atomic_order_checked((jl_sym_t*)order, 1, 0);
     296                 :          3 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     297                 :          3 :     char *pp = (char*)jl_unbox_long(p);
     298         [ -  + ]:          3 :     if (ety == (jl_value_t*)jl_any_type) {
     299                 :          0 :         return jl_atomic_load((_Atomic(jl_value_t*)*)pp);
     300                 :            :     }
     301                 :            :     else {
     302         [ -  + ]:          3 :         if (!is_valid_intrinsic_elptr(ety))
     303                 :          0 :             jl_error("atomic_pointerref: invalid pointer");
     304                 :          3 :         size_t nb = jl_datatype_size(ety);
     305   [ +  -  -  + ]:          3 :         if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
     306                 :          0 :             jl_error("atomic_pointerref: invalid pointer for atomic operation");
     307                 :          3 :         return jl_atomic_new_bits(ety, pp);
     308                 :            :     }
     309                 :            : }
     310                 :            : 
     311                 :          2 : JL_DLLEXPORT jl_value_t *jl_atomic_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t *order)
     312                 :            : {
     313         [ -  + ]:          2 :     JL_TYPECHK(atomic_pointerset, pointer, p);
     314         [ -  + ]:          2 :     JL_TYPECHK(atomic_pointerset, symbol, order);
     315                 :          2 :     (void)jl_get_atomic_order_checked((jl_sym_t*)order, 0, 1);
     316                 :          2 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     317                 :          2 :     char *pp = (char*)jl_unbox_long(p);
     318         [ -  + ]:          2 :     if (ety == (jl_value_t*)jl_any_type) {
     319                 :          0 :         jl_atomic_store((_Atomic(jl_value_t*)*)pp, x);
     320                 :            :     }
     321                 :            :     else {
     322         [ -  + ]:          2 :         if (!is_valid_intrinsic_elptr(ety))
     323                 :          0 :             jl_error("atomic_pointerset: invalid pointer");
     324         [ -  + ]:          2 :         if (jl_typeof(x) != ety)
     325                 :          0 :             jl_type_error("atomic_pointerset", ety, x);
     326                 :          2 :         size_t nb = jl_datatype_size(ety);
     327   [ +  -  -  + ]:          2 :         if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
     328                 :          0 :             jl_error("atomic_pointerset: invalid pointer for atomic operation");
     329                 :          2 :         jl_atomic_store_bits(pp, x, nb);
     330                 :            :     }
     331                 :          2 :     return p;
     332                 :            : }
     333                 :            : 
     334                 :          2 : JL_DLLEXPORT jl_value_t *jl_atomic_pointerswap(jl_value_t *p, jl_value_t *x, jl_value_t *order)
     335                 :            : {
     336         [ -  + ]:          2 :     JL_TYPECHK(atomic_pointerswap, pointer, p);
     337         [ -  + ]:          2 :     JL_TYPECHK(atomic_pointerswap, symbol, order);
     338                 :          2 :     (void)jl_get_atomic_order_checked((jl_sym_t*)order, 1, 1);
     339                 :          2 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     340                 :            :     jl_value_t *y;
     341                 :          2 :     char *pp = (char*)jl_unbox_long(p);
     342         [ -  + ]:          2 :     if (ety == (jl_value_t*)jl_any_type) {
     343                 :          0 :         y = jl_atomic_exchange((_Atomic(jl_value_t*)*)pp, x);
     344                 :            :     }
     345                 :            :     else {
     346         [ -  + ]:          2 :         if (!is_valid_intrinsic_elptr(ety))
     347                 :          0 :             jl_error("atomic_pointerswap: invalid pointer");
     348         [ -  + ]:          2 :         if (jl_typeof(x) != ety)
     349                 :          0 :             jl_type_error("atomic_pointerswap", ety, x);
     350                 :          2 :         size_t nb = jl_datatype_size(ety);
     351   [ +  -  -  + ]:          2 :         if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
     352                 :          0 :             jl_error("atomic_pointerswap: invalid pointer for atomic operation");
     353                 :          2 :         y = jl_atomic_swap_bits(ety, pp, x, nb);
     354                 :            :     }
     355                 :          2 :     return y;
     356                 :            : }
     357                 :            : 
     358                 :          4 : JL_DLLEXPORT jl_value_t *jl_atomic_pointermodify(jl_value_t *p, jl_value_t *f, jl_value_t *x, jl_value_t *order)
     359                 :            : {
     360         [ -  + ]:          4 :     JL_TYPECHK(atomic_pointermodify, pointer, p);
     361         [ -  + ]:          4 :     JL_TYPECHK(atomic_pointermodify, symbol, order)
     362                 :          4 :     (void)jl_get_atomic_order_checked((jl_sym_t*)order, 1, 1);
     363                 :          4 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     364                 :          4 :     char *pp = (char*)jl_unbox_long(p);
     365                 :            :     jl_value_t *expected;
     366         [ -  + ]:          4 :     if (ety == (jl_value_t*)jl_any_type) {
     367                 :          0 :         expected = jl_atomic_load((_Atomic(jl_value_t*)*)pp);
     368                 :            :     }
     369                 :            :     else {
     370         [ -  + ]:          4 :         if (!is_valid_intrinsic_elptr(ety))
     371                 :          0 :             jl_error("atomic_pointermodify: invalid pointer");
     372                 :          4 :         size_t nb = jl_datatype_size(ety);
     373   [ +  -  -  + ]:          4 :         if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
     374                 :          0 :             jl_error("atomic_pointermodify: invalid pointer for atomic operation");
     375                 :          4 :         expected = jl_atomic_new_bits(ety, pp);
     376                 :            :     }
     377                 :            :     jl_value_t **args;
     378                 :          4 :     JL_GC_PUSHARGS(args, 2);
     379                 :          4 :     args[0] = expected;
     380                 :          0 :     while (1) {
     381                 :          4 :         args[1] = x;
     382                 :          4 :         jl_value_t *y = jl_apply_generic(f, args, 2);
     383                 :          4 :         args[1] = y;
     384         [ -  + ]:          4 :         if (ety == (jl_value_t*)jl_any_type) {
     385         [ #  # ]:          0 :             if (jl_atomic_cmpswap((_Atomic(jl_value_t*)*)pp, &expected, y))
     386                 :          0 :                 break;
     387                 :            :         }
     388                 :            :         else {
     389                 :            :             //if (!is_valid_intrinsic_elptr(ety)) // handled by jl_atomic_pointerref earlier
     390                 :            :             //    jl_error("atomic_pointermodify: invalid pointer");
     391         [ +  + ]:          4 :             if (jl_typeof(y) != ety)
     392                 :          1 :                 jl_type_error("atomic_pointermodify", ety, y);
     393                 :          3 :             size_t nb = jl_datatype_size(ety);
     394         [ +  - ]:          3 :             if (jl_atomic_bool_cmpswap_bits(pp, expected, y, nb))
     395                 :          3 :                 break;
     396                 :          0 :             expected = jl_atomic_new_bits(ety, pp);
     397                 :            :         }
     398                 :          0 :         args[0] = expected;
     399                 :          0 :         jl_gc_safepoint();
     400                 :            :     }
     401                 :            :     // args[0] == expected (old)
     402                 :            :     // args[1] == y (new)
     403                 :          3 :     jl_datatype_t *rettyp = jl_apply_modify_type(ety);
     404                 :            :     JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE)
     405                 :          3 :     args[0] = jl_new_struct(rettyp, args[0], args[1]);
     406                 :          3 :     JL_GC_POP();
     407                 :          3 :     return args[0];
     408                 :            : }
     409                 :            : 
     410                 :            : 
     411                 :          5 : JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *expected, jl_value_t *x, jl_value_t *success_order_sym, jl_value_t *failure_order_sym)
     412                 :            : {
     413         [ -  + ]:          5 :     JL_TYPECHK(atomic_pointerreplace, pointer, p);
     414         [ -  + ]:          5 :     JL_TYPECHK(atomic_pointerreplace, symbol, success_order_sym);
     415         [ -  + ]:          5 :     JL_TYPECHK(atomic_pointerreplace, symbol, failure_order_sym);
     416                 :          5 :     enum jl_memory_order success_order = jl_get_atomic_order_checked((jl_sym_t*)success_order_sym, 1, 1);
     417                 :          5 :     enum jl_memory_order failure_order = jl_get_atomic_order_checked((jl_sym_t*)failure_order_sym, 1, 0);
     418         [ -  + ]:          5 :     if (failure_order > success_order)
     419                 :          0 :         jl_atomic_error("atomic_pointerreplace: invalid atomic ordering");
     420                 :            :     // TODO: filter other invalid orderings
     421                 :          5 :     jl_value_t *ety = jl_tparam0(jl_typeof(p));
     422                 :          5 :     char *pp = (char*)jl_unbox_long(p);
     423                 :          5 :     jl_datatype_t *rettyp = jl_apply_cmpswap_type(ety);
     424                 :            :     JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE)
     425         [ -  + ]:          5 :     if (ety == (jl_value_t*)jl_any_type) {
     426                 :            :         jl_value_t *result;
     427                 :          0 :         JL_GC_PUSH1(&result);
     428                 :          0 :         result = expected;
     429                 :            :         int success;
     430                 :            :         while (1) {
     431                 :          0 :             success = jl_atomic_cmpswap((_Atomic(jl_value_t*)*)pp, &result, x);
     432   [ #  #  #  # ]:          0 :             if (success || !jl_egal(result, expected))
     433                 :            :                 break;
     434                 :            :         }
     435         [ #  # ]:          0 :         result = jl_new_struct(rettyp, result, success ? jl_true : jl_false);
     436                 :          0 :         JL_GC_POP();
     437                 :          0 :         return result;
     438                 :            :     }
     439                 :            :     else {
     440         [ -  + ]:          5 :         if (!is_valid_intrinsic_elptr(ety))
     441                 :          0 :             jl_error("atomic_pointerreplace: invalid pointer");
     442         [ -  + ]:          5 :         if (jl_typeof(x) != ety)
     443                 :          0 :             jl_type_error("atomic_pointerreplace", ety, x);
     444                 :          5 :         size_t nb = jl_datatype_size(ety);
     445   [ +  -  -  + ]:          5 :         if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
     446                 :          0 :             jl_error("atomic_pointerreplace: invalid pointer for atomic operation");
     447                 :          5 :         return jl_atomic_cmpswap_bits((jl_datatype_t*)ety, rettyp, pp, expected, x, nb);
     448                 :            :     }
     449                 :            : }
     450                 :            : 
     451                 :         27 : JL_DLLEXPORT jl_value_t *jl_atomic_fence(jl_value_t *order_sym)
     452                 :            : {
     453         [ -  + ]:         27 :     JL_TYPECHK(fence, symbol, order_sym);
     454                 :         27 :     enum jl_memory_order order = jl_get_atomic_order_checked((jl_sym_t*)order_sym, 1, 1);
     455         [ +  + ]:         24 :     if (order > jl_memory_order_monotonic)
     456                 :         18 :         jl_fence();
     457                 :         24 :     return jl_nothing;
     458                 :            : }
     459                 :            : 
     460                 :          2 : JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty)
     461                 :            : {
     462         [ -  + ]:          2 :     JL_TYPECHK(cglobal, type, ty);
     463                 :          2 :     JL_GC_PUSH1(&v);
     464                 :          2 :     jl_value_t *rt =
     465         [ +  + ]:          2 :         ty == (jl_value_t*)jl_nothing_type ? (jl_value_t*)jl_voidpointer_type : // a common case
     466                 :          1 :             (jl_value_t*)jl_apply_type1((jl_value_t*)jl_pointer_type, ty);
     467                 :            :     JL_GC_PROMISE_ROOTED(rt); // (JL_ALWAYS_LEAFTYPE)
     468                 :            : 
     469         [ -  + ]:          2 :     if (!jl_is_concrete_type(rt))
     470                 :          0 :         jl_error("cglobal: type argument not concrete");
     471                 :            : 
     472   [ +  -  -  + ]:          2 :     if (jl_is_tuple(v) && jl_nfields(v) == 1)
     473                 :          0 :         v = jl_fieldref(v, 0);
     474                 :            : 
     475         [ -  + ]:          2 :     if (jl_is_pointer(v)) {
     476                 :          0 :         v = jl_bitcast(rt, v);
     477                 :          0 :         JL_GC_POP();
     478                 :          0 :         return v;
     479                 :            :     }
     480                 :            : 
     481                 :          2 :     char *f_lib = NULL;
     482   [ +  -  +  - ]:          2 :     if (jl_is_tuple(v) && jl_nfields(v) > 1) {
     483                 :          2 :         jl_value_t *t1 = jl_fieldref_noalloc(v, 1);
     484                 :          2 :         v = jl_fieldref(v, 0);
     485         [ -  + ]:          2 :         if (jl_is_symbol(t1))
     486                 :          0 :             f_lib = jl_symbol_name((jl_sym_t*)t1);
     487         [ +  - ]:          2 :         else if (jl_is_string(t1))
     488                 :          2 :             f_lib = jl_string_data(t1);
     489                 :            :         else
     490         [ #  # ]:          0 :             JL_TYPECHK(cglobal, symbol, t1)
     491                 :            :     }
     492                 :            : 
     493                 :          2 :     char *f_name = NULL;
     494         [ +  - ]:          2 :     if (jl_is_symbol(v))
     495                 :          2 :         f_name = jl_symbol_name((jl_sym_t*)v);
     496         [ #  # ]:          0 :     else if (jl_is_string(v))
     497                 :          0 :         f_name = jl_string_data(v);
     498                 :            :     else
     499         [ #  # ]:          0 :         JL_TYPECHK(cglobal, symbol, v)
     500                 :            : 
     501                 :            : #ifdef _OS_WINDOWS_
     502                 :            :     if (!f_lib)
     503                 :            :         f_lib = (char*)jl_dlfind_win32(f_name);
     504                 :            : #endif
     505                 :            : 
     506                 :            :     void *ptr;
     507                 :          2 :     jl_dlsym(jl_get_library(f_lib), f_name, &ptr, 1);
     508                 :          2 :     jl_value_t *jv = jl_gc_alloc_1w();
     509                 :          2 :     jl_set_typeof(jv, rt);
     510                 :          2 :     *(void**)jl_data_ptr(jv) = ptr;
     511                 :          2 :     JL_GC_POP();
     512                 :          2 :     return jv;
     513                 :            : }
     514                 :            : 
     515                 :          1 : JL_DLLEXPORT jl_value_t *jl_cglobal_auto(jl_value_t *v) {
     516                 :          1 :     return jl_cglobal(v, (jl_value_t*)jl_nothing_type);
     517                 :            : }
     518                 :            : 
     519                 :          0 : static inline char signbitbyte(void *a, unsigned bytes) JL_NOTSAFEPOINT
     520                 :            : {
     521                 :            :     // sign bit of an signed number of n bytes, as a byte
     522         [ #  # ]:          0 :     return (((signed char*)a)[bytes - 1] < 0) ? ~0 : 0;
     523                 :            : }
     524                 :            : 
     525                 :          4 : static inline char usignbitbyte(void *a, unsigned bytes) JL_NOTSAFEPOINT
     526                 :            : {
     527                 :            :     // sign bit of an unsigned number
     528                 :          4 :     return 0;
     529                 :            : }
     530                 :            : 
     531                 :   33770200 : static inline unsigned select_by_size(unsigned sz) JL_NOTSAFEPOINT
     532                 :            : {
     533                 :            :     /* choose the right sized function specialization */
     534   [ +  +  +  +  :   33770200 :     switch (sz) {
                   +  + ]
     535                 :          3 :     default: return 0;
     536                 :    3462140 :     case  1: return 1;
     537                 :        650 :     case  2: return 2;
     538                 :     773622 :     case  4: return 3;
     539                 :   29533200 :     case  8: return 4;
     540                 :        603 :     case 16: return 5;
     541                 :            :     }
     542                 :            : }
     543                 :            : 
     544                 :            : #define SELECTOR_FUNC(intrinsic) \
     545                 :            :     typedef intrinsic##_t select_##intrinsic##_t[6]; \
     546                 :            :     static inline intrinsic##_t select_##intrinsic(unsigned sz, const select_##intrinsic##_t list) JL_NOTSAFEPOINT \
     547                 :            :     { \
     548                 :            :         intrinsic##_t thunk = list[select_by_size(sz)]; \
     549                 :            :         if (!thunk) thunk = list[0]; \
     550                 :            :         return thunk; \
     551                 :            :     }
     552                 :            : 
     553                 :            : #define fp_select(a, func) \
     554                 :            :     sizeof(a) == sizeof(float) ? func##f((float)a) : func(a)
     555                 :            : #define fp_select2(a, b, func) \
     556                 :            :     sizeof(a) == sizeof(float) ? func##f(a, b) : func(a, b)
     557                 :            : 
     558                 :            : // fast-function generators //
     559                 :            : 
     560                 :            : // integer input
     561                 :            : // OP::Function macro(input)
     562                 :            : // name::unique string
     563                 :            : // nbits::number of bits
     564                 :            : // c_type::c_type corresponding to nbits
     565                 :            : #define un_iintrinsic_ctype(OP, name, nbits, c_type) \
     566                 :            : static inline void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pr) JL_NOTSAFEPOINT \
     567                 :            : { \
     568                 :            :     c_type a = *(c_type*)pa; \
     569                 :            :     *(c_type*)pr = OP(a); \
     570                 :            : }
     571                 :            : 
     572                 :            : // integer input, unsigned output
     573                 :            : // OP::Function macro(input)
     574                 :            : // name::unique string
     575                 :            : // nbits::number of bits
     576                 :            : // c_type::c_type corresponding to nbits
     577                 :            : #define uu_iintrinsic_ctype(OP, name, nbits, c_type) \
     578                 :            : static inline unsigned jl_##name##nbits(unsigned runtime_nbits, void *pa) JL_NOTSAFEPOINT \
     579                 :            : { \
     580                 :            :     c_type a = *(c_type*)pa; \
     581                 :            :     return OP(a); \
     582                 :            : }
     583                 :            : 
     584                 :            : // floating point
     585                 :            : // OP::Function macro(output pointer, input)
     586                 :            : // name::unique string
     587                 :            : // nbits::number of bits in the *input*
     588                 :            : // c_type::c_type corresponding to nbits
     589                 :            : #define un_fintrinsic_ctype(OP, name, c_type) \
     590                 :            : static inline void name(unsigned osize, void *pa, void *pr) JL_NOTSAFEPOINT \
     591                 :            : { \
     592                 :            :     c_type a = *(c_type*)pa; \
     593                 :            :     OP((c_type*)pr, a); \
     594                 :            : }
     595                 :            : 
     596                 :            : #define un_fintrinsic_half(OP, name) \
     597                 :            : static inline void name(unsigned osize, void *pa, void *pr) JL_NOTSAFEPOINT \
     598                 :            : { \
     599                 :            :     uint16_t a = *(uint16_t*)pa; \
     600                 :            :     float A = __gnu_h2f_ieee(a); \
     601                 :            :     if (osize == 16) { \
     602                 :            :         float R; \
     603                 :            :         OP(&R, A); \
     604                 :            :         *(uint16_t*)pr = __gnu_f2h_ieee(R); \
     605                 :            :     } else { \
     606                 :            :         OP((uint16_t*)pr, A); \
     607                 :            :     } \
     608                 :            :     }
     609                 :            : 
     610                 :            : // float or integer inputs
     611                 :            : // OP::Function macro(inputa, inputb)
     612                 :            : // name::unique string
     613                 :            : // nbits::number of bits
     614                 :            : // c_type::c_type corresponding to nbits
     615                 :            : #define bi_intrinsic_ctype(OP, name, nbits, c_type) \
     616                 :            : static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr) JL_NOTSAFEPOINT \
     617                 :            : { \
     618                 :            :     c_type a = *(c_type*)pa; \
     619                 :            :     c_type b = *(c_type*)pb; \
     620                 :            :     *(c_type*)pr = (c_type)OP(a, b); \
     621                 :            : }
     622                 :            : 
     623                 :            : #define bi_intrinsic_half(OP, name) \
     624                 :            : static void jl_##name##16(unsigned runtime_nbits, void *pa, void *pb, void *pr) JL_NOTSAFEPOINT \
     625                 :            : { \
     626                 :            :     uint16_t a = *(uint16_t*)pa; \
     627                 :            :     uint16_t b = *(uint16_t*)pb; \
     628                 :            :     float A = __gnu_h2f_ieee(a); \
     629                 :            :     float B = __gnu_h2f_ieee(b); \
     630                 :            :     runtime_nbits = 16; \
     631                 :            :     float R = OP(A, B); \
     632                 :            :     *(uint16_t*)pr = __gnu_f2h_ieee(R); \
     633                 :            : }
     634                 :            : 
     635                 :            : // float or integer inputs, bool output
     636                 :            : // OP::Function macro(inputa, inputb)
     637                 :            : // name::unique string
     638                 :            : // nbits::number of bits
     639                 :            : // c_type::c_type corresponding to nbits
     640                 :            : #define bool_intrinsic_ctype(OP, name, nbits, c_type) \
     641                 :            : static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb) JL_NOTSAFEPOINT \
     642                 :            : { \
     643                 :            :     c_type a = *(c_type*)pa; \
     644                 :            :     c_type b = *(c_type*)pb; \
     645                 :            :     return OP(a, b); \
     646                 :            : }
     647                 :            : 
     648                 :            : #define bool_intrinsic_half(OP, name) \
     649                 :            : static int jl_##name##16(unsigned runtime_nbits, void *pa, void *pb) JL_NOTSAFEPOINT \
     650                 :            : { \
     651                 :            :     uint16_t a = *(uint16_t*)pa; \
     652                 :            :     uint16_t b = *(uint16_t*)pb; \
     653                 :            :     float A = __gnu_h2f_ieee(a); \
     654                 :            :     float B = __gnu_h2f_ieee(b); \
     655                 :            :     runtime_nbits = 16; \
     656                 :            :     return OP(A, B); \
     657                 :            : }
     658                 :            : 
     659                 :            : 
     660                 :            : // integer inputs, with precondition test
     661                 :            : // OP::Function macro(inputa, inputb)
     662                 :            : // name::unique string
     663                 :            : // nbits::number of bits
     664                 :            : // c_type::c_type corresponding to nbits
     665                 :            : #define checked_intrinsic_ctype(CHECK_OP, OP, name, nbits, c_type) \
     666                 :            : static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr) JL_NOTSAFEPOINT \
     667                 :            : { \
     668                 :            :     c_type a = *(c_type*)pa; \
     669                 :            :     c_type b = *(c_type*)pb; \
     670                 :            :     *(c_type*)pr = (c_type)OP(a, b); \
     671                 :            :     return CHECK_OP(c_type, a, b);    \
     672                 :            : }
     673                 :            : 
     674                 :            : // float inputs
     675                 :            : // OP::Function macro(inputa, inputb, inputc)
     676                 :            : // name::unique string
     677                 :            : // nbits::number of bits
     678                 :            : // c_type::c_type corresponding to nbits
     679                 :            : #define ter_intrinsic_ctype(OP, name, nbits, c_type) \
     680                 :            : static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pc, void *pr) JL_NOTSAFEPOINT \
     681                 :            : { \
     682                 :            :     c_type a = *(c_type*)pa; \
     683                 :            :     c_type b = *(c_type*)pb; \
     684                 :            :     c_type c = *(c_type*)pc; \
     685                 :            :     *(c_type*)pr = (c_type)OP(a, b, c); \
     686                 :            : }
     687                 :            : 
     688                 :            : #define ter_intrinsic_half(OP, name) \
     689                 :            : static void jl_##name##16(unsigned runtime_nbits, void *pa, void *pb, void *pc, void *pr) JL_NOTSAFEPOINT \
     690                 :            : { \
     691                 :            :     uint16_t a = *(uint16_t*)pa; \
     692                 :            :     uint16_t b = *(uint16_t*)pb; \
     693                 :            :     uint16_t c = *(uint16_t*)pc; \
     694                 :            :     float A = __gnu_h2f_ieee(a); \
     695                 :            :     float B = __gnu_h2f_ieee(b); \
     696                 :            :     float C = __gnu_h2f_ieee(c); \
     697                 :            :     runtime_nbits = 16; \
     698                 :            :     float R = OP(A, B, C); \
     699                 :            :     *(uint16_t*)pr = __gnu_f2h_ieee(R); \
     700                 :            : }
     701                 :            : 
     702                 :            : 
     703                 :            : // unary operator generator //
     704                 :            : 
     705                 :            : typedef void (*intrinsic_1_t)(unsigned, void*, void*);
     706         [ +  + ]:    2529980 : SELECTOR_FUNC(intrinsic_1)
     707                 :            : #define un_iintrinsic(name, u) \
     708                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a) \
     709                 :            : { \
     710                 :            :     return jl_iintrinsic_1(jl_typeof(a), a, #name, u##signbitbyte, jl_intrinsiclambda_ty1, name##_list); \
     711                 :            : }
     712                 :            : #define un_iintrinsic_fast(LLVMOP, OP, name, u) \
     713                 :            : un_iintrinsic_ctype(OP, name, 8, u##int##8_t) \
     714                 :            : un_iintrinsic_ctype(OP, name, 16, u##int##16_t) \
     715                 :            : un_iintrinsic_ctype(OP, name, 32, u##int##32_t) \
     716                 :            : un_iintrinsic_ctype(OP, name, 64, u##int##64_t) \
     717                 :            : static const select_intrinsic_1_t name##_list = { \
     718                 :            :     LLVMOP, \
     719                 :            :     jl_##name##8, \
     720                 :            :     jl_##name##16, \
     721                 :            :     jl_##name##32, \
     722                 :            :     jl_##name##64, \
     723                 :            : }; \
     724                 :            : un_iintrinsic(name, u)
     725                 :            : #define un_iintrinsic_slow(LLVMOP, name, u) \
     726                 :            : static const select_intrinsic_1_t name##_list = { \
     727                 :            :     LLVMOP \
     728                 :            : }; \
     729                 :            : un_iintrinsic(name, u)
     730                 :            : 
     731                 :            : typedef unsigned (*intrinsic_u1_t)(unsigned, void*);
     732         [ +  - ]:      11330 : SELECTOR_FUNC(intrinsic_u1)
     733                 :            : #define uu_iintrinsic(name, u) \
     734                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a) \
     735                 :            : { \
     736                 :            :     return jl_iintrinsic_1(jl_typeof(a), a, #name, u##signbitbyte, jl_intrinsiclambda_u1, name##_list); \
     737                 :            : }
     738                 :            : #define uu_iintrinsic_fast(LLVMOP, OP, name, u) \
     739                 :            : uu_iintrinsic_ctype(OP, name, 8, u##int##8_t) \
     740                 :            : uu_iintrinsic_ctype(OP, name, 16, u##int##16_t) \
     741                 :            : uu_iintrinsic_ctype(OP, name, 32, u##int##32_t) \
     742                 :            : uu_iintrinsic_ctype(OP, name, 64, u##int##64_t) \
     743                 :            : static const select_intrinsic_u1_t name##_list = { \
     744                 :            :     LLVMOP, \
     745                 :            :     jl_##name##8, \
     746                 :            :     jl_##name##16, \
     747                 :            :     jl_##name##32, \
     748                 :            :     jl_##name##64, \
     749                 :            : }; \
     750                 :            : uu_iintrinsic(name, u)
     751                 :            : #define uu_iintrinsic_slow(LLVMOP, name, u) \
     752                 :            : static const select_intrinsic_u1_t name##_list = { \
     753                 :            :     LLVMOP \
     754                 :            : }; \
     755                 :            : uu_iintrinsic(name, u)
     756                 :            : 
     757                 :            : static inline
     758                 :    2541310 : jl_value_t *jl_iintrinsic_1(jl_value_t *ty, jl_value_t *a, const char *name,
     759                 :            :                             char (*getsign)(void*, unsigned),
     760                 :            :                             jl_value_t *(*lambda1)(jl_value_t*, void*, unsigned, unsigned, const void*), const void *list)
     761                 :            : {
     762         [ +  + ]:    2541310 :     if (!jl_is_primitivetype(jl_typeof(a)))
     763                 :          2 :         jl_errorf("%s: value is not a primitive type", name);
     764         [ -  + ]:    2541310 :     if (!jl_is_primitivetype(ty))
     765                 :          0 :         jl_errorf("%s: type is not a primitive type", name);
     766                 :    2541310 :     void *pa = jl_data_ptr(a);
     767                 :    2541310 :     unsigned isize = jl_datatype_size(jl_typeof(a));
     768                 :    2541310 :     unsigned isize2 = next_power_of_two(isize);
     769                 :    2541310 :     unsigned osize = jl_datatype_size(ty);
     770                 :    2541310 :     unsigned osize2 = next_power_of_two(osize);
     771         [ -  + ]:    2541310 :     if (isize2 > osize2)
     772                 :          0 :         osize2 = isize2;
     773   [ +  -  -  + ]:    2541310 :     if (osize2 > isize || isize2 > isize) {
     774                 :            :         /* if needed, round type up to a real c-type and set/clear the unused bits */
     775                 :            :         void *pa2;
     776                 :          0 :         pa2 = alloca(osize2);
     777                 :            :         /* TODO: this memcpy assumes little-endian,
     778                 :            :          * for big-endian, need to align the copy to the other end */ \
     779                 :          0 :         memcpy(pa2, pa, isize);
     780                 :          0 :         memset((char*)pa2 + isize, getsign(pa, isize), osize2 - isize);
     781                 :          0 :         pa = pa2;
     782                 :            :     }
     783                 :    2541310 :     jl_value_t *newv = lambda1(ty, pa, osize, osize2, list);
     784         [ +  + ]:    2541310 :     if (ty == (jl_value_t*)jl_bool_type)
     785         [ +  + ]:    2413490 :         return *(uint8_t*)jl_data_ptr(newv) & 1 ? jl_true : jl_false;
     786                 :     127817 :     return newv;
     787                 :            : }
     788                 :            : 
     789                 :    2529980 : static inline jl_value_t *jl_intrinsiclambda_ty1(jl_value_t *ty, void *pa, unsigned osize, unsigned osize2, const void *voidlist)
     790                 :            : {
     791                 :    2529980 :     intrinsic_1_t op = select_intrinsic_1(osize2, (const intrinsic_1_t*)voidlist);
     792                 :    2529980 :     void *pr = alloca(osize2);
     793                 :    2529980 :     op(osize * host_char_bit, pa, pr);
     794                 :    2529980 :     return jl_new_bits(ty, pr);
     795                 :            : }
     796                 :            : 
     797                 :      11330 : static inline jl_value_t *jl_intrinsiclambda_u1(jl_value_t *ty, void *pa, unsigned osize, unsigned osize2, const void *voidlist)
     798                 :            : {
     799                 :      11330 :     jl_task_t *ct = jl_current_task;
     800                 :      11330 :     intrinsic_u1_t op = select_intrinsic_u1(osize2, (const intrinsic_u1_t*)voidlist);
     801                 :      11330 :     uint64_t cnt = op(osize * host_char_bit, pa);
     802                 :            :     // TODO: the following assume little-endian
     803                 :            :     // for big-endian, need to copy from the other end of cnt
     804         [ +  - ]:      11330 :     if (osize <= sizeof(cnt)) {
     805                 :      11330 :         return jl_new_bits(ty, &cnt);
     806                 :            :     }
     807                 :          0 :     jl_value_t *newv = jl_gc_alloc(ct->ptls, osize, ty);
     808                 :            :     // perform zext, if needed
     809                 :          0 :     memset((char*)jl_data_ptr(newv) + sizeof(cnt), 0, osize - sizeof(cnt));
     810                 :          0 :     memcpy(jl_data_ptr(newv), &cnt, sizeof(cnt));
     811                 :          0 :     return newv;
     812                 :            : }
     813                 :            : 
     814                 :            : // conversion operator
     815                 :            : 
     816                 :            : typedef void (*intrinsic_cvt_t)(unsigned, void*, unsigned, void*);
     817                 :            : typedef unsigned (*intrinsic_cvt_check_t)(unsigned, unsigned, void*);
     818                 :            : #define cvt_iintrinsic(LLVMOP, name) \
     819                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *ty, jl_value_t *a) \
     820                 :            : { \
     821                 :            :     return jl_intrinsic_cvt(ty, a, #name, LLVMOP); \
     822                 :            : }
     823                 :            : 
     824                 :     136624 : static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const char *name, intrinsic_cvt_t op)
     825                 :            : {
     826                 :     136624 :     jl_value_t *aty = jl_typeof(a);
     827         [ +  + ]:     136624 :     if (!jl_is_primitivetype(aty))
     828                 :          1 :         jl_errorf("%s: value is not a primitive type", name);
     829         [ -  + ]:     136623 :     if (!jl_is_primitivetype(ty))
     830                 :          0 :         jl_errorf("%s: type is not a primitive type", name);
     831                 :     136623 :     void *pa = jl_data_ptr(a);
     832                 :     136623 :     unsigned isize = jl_datatype_size(aty);
     833                 :     136623 :     unsigned osize = jl_datatype_size(ty);
     834                 :     136623 :     void *pr = alloca(osize);
     835                 :     136623 :     unsigned isize_bits = isize * host_char_bit;
     836                 :     136623 :     unsigned osize_bits = osize * host_char_bit;
     837                 :     136623 :     op(isize_bits, pa, osize_bits, pr);
     838                 :     136617 :     return jl_new_bits(ty, pr);
     839                 :            : }
     840                 :            : 
     841                 :            : // floating point
     842                 :            : 
     843                 :            : #define un_fintrinsic_withtype(OP, name) \
     844                 :            : un_fintrinsic_half(OP, jl_##name##16) \
     845                 :            : un_fintrinsic_ctype(OP, jl_##name##32, float) \
     846                 :            : un_fintrinsic_ctype(OP, jl_##name##64, double) \
     847                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *ty, jl_value_t *a) \
     848                 :            : { \
     849                 :            :     return jl_fintrinsic_1(ty, a, #name, jl_##name##16, jl_##name##32, jl_##name##64); \
     850                 :            : }
     851                 :            : 
     852                 :            : #define un_fintrinsic(OP, name) \
     853                 :            : un_fintrinsic_withtype(OP, name##_withtype) \
     854                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a) \
     855                 :            : { \
     856                 :            :     return jl_##name##_withtype(jl_typeof(a), a); \
     857                 :            : }
     858                 :            : 
     859                 :            : typedef void (fintrinsic_op1)(unsigned, void*, void*);
     860                 :            : 
     861                 :         47 : static inline jl_value_t *jl_fintrinsic_1(jl_value_t *ty, jl_value_t *a, const char *name, fintrinsic_op1 *halfop, fintrinsic_op1 *floatop, fintrinsic_op1 *doubleop)
     862                 :            : {
     863                 :         47 :     jl_task_t *ct = jl_current_task;
     864         [ -  + ]:         47 :     if (!jl_is_primitivetype(jl_typeof(a)))
     865                 :          0 :         jl_errorf("%s: value is not a primitive type", name);
     866         [ -  + ]:         47 :     if (!jl_is_primitivetype(ty))
     867                 :          0 :         jl_errorf("%s: type is not a primitive type", name);
     868                 :         47 :     unsigned sz2 = jl_datatype_size(ty);
     869                 :         47 :     jl_value_t *newv = jl_gc_alloc(ct->ptls, sz2, ty);
     870                 :         47 :     void *pa = jl_data_ptr(a), *pr = jl_data_ptr(newv);
     871                 :         47 :     unsigned sz = jl_datatype_size(jl_typeof(a));
     872   [ +  +  +  - ]:         47 :     switch (sz) {
     873                 :            :     /* choose the right size c-type operation based on the input */
     874                 :          6 :     case 2:
     875                 :          6 :         halfop(sz2 * host_char_bit, pa, pr);
     876                 :          6 :         break;
     877                 :          4 :     case 4:
     878                 :          4 :         floatop(sz2 * host_char_bit, pa, pr);
     879                 :          2 :         break;
     880                 :         37 :     case 8:
     881                 :         37 :         doubleop(sz2 * host_char_bit, pa, pr);
     882                 :         36 :         break;
     883                 :          0 :     default:
     884                 :          0 :         jl_errorf("%s: runtime floating point intrinsics are not implemented for bit sizes other than 16, 32 and 64", name);
     885                 :            :     }
     886                 :         44 :     return newv;
     887                 :            : }
     888                 :            : 
     889                 :            : // binary operator generator //
     890                 :            : 
     891                 :            : // integer
     892                 :            : 
     893                 :            : typedef void (*intrinsic_2_t)(unsigned, void*, void*, void*);
     894         [ +  + ]:   25565300 : SELECTOR_FUNC(intrinsic_2)
     895                 :            : #define bi_iintrinsic(name, u, cvtb) \
     896                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b) \
     897                 :            : { \
     898                 :            :     return jl_iintrinsic_2(a, b, #name, u##signbitbyte, jl_intrinsiclambda_2, name##_list, cvtb); \
     899                 :            : }
     900                 :            : #define bi_iintrinsic_cnvtb_fast(LLVMOP, OP, name, u, cvtb) \
     901                 :            : bi_intrinsic_ctype(OP, name, 8, u##int##8_t) \
     902                 :            : bi_intrinsic_ctype(OP, name, 16, u##int##16_t) \
     903                 :            : bi_intrinsic_ctype(OP, name, 32, u##int##32_t) \
     904                 :            : bi_intrinsic_ctype(OP, name, 64, u##int##64_t) \
     905                 :            : static const select_intrinsic_2_t name##_list = { \
     906                 :            :     LLVMOP, \
     907                 :            :     jl_##name##8, \
     908                 :            :     jl_##name##16, \
     909                 :            :     jl_##name##32, \
     910                 :            :     jl_##name##64, \
     911                 :            : }; \
     912                 :            : bi_iintrinsic(name, u, cvtb)
     913                 :            : #define bi_iintrinsic_fast(LLVMOP, OP, name, u) \
     914                 :            :     bi_iintrinsic_cnvtb_fast(LLVMOP, OP, name, u, 0)
     915                 :            : 
     916                 :            : typedef int (*intrinsic_cmp_t)(unsigned, void*, void*);
     917         [ -  + ]:    5661240 : SELECTOR_FUNC(intrinsic_cmp)
     918                 :            : #define cmp_iintrinsic(name, u) \
     919                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b) \
     920                 :            : { \
     921                 :            :     return jl_iintrinsic_2(a, b, #name, u##signbitbyte, jl_intrinsiclambda_cmp, name##_list, 0); \
     922                 :            : }
     923                 :            : #define bool_iintrinsic_fast(LLVMOP, OP, name, u) \
     924                 :            : bool_intrinsic_ctype(OP, name, 8, u##int##8_t) \
     925                 :            : bool_intrinsic_ctype(OP, name, 16, u##int##16_t) \
     926                 :            : bool_intrinsic_ctype(OP, name, 32, u##int##32_t) \
     927                 :            : bool_intrinsic_ctype(OP, name, 64, u##int##64_t) \
     928                 :            : static const select_intrinsic_cmp_t name##_list = { \
     929                 :            :     LLVMOP, \
     930                 :            :     jl_##name##8, \
     931                 :            :     jl_##name##16, \
     932                 :            :     jl_##name##32, \
     933                 :            :     jl_##name##64, \
     934                 :            : }; \
     935                 :            : cmp_iintrinsic(name, u)
     936                 :            : 
     937                 :            : typedef int (*intrinsic_checked_t)(unsigned, void*, void*, void*) JL_NOTSAFEPOINT;
     938         [ +  - ]:       2337 : SELECTOR_FUNC(intrinsic_checked)
     939                 :            : #define checked_iintrinsic(name, u, lambda_checked) \
     940                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b) \
     941                 :            : { \
     942                 :            :     return jl_iintrinsic_2(a, b, #name, u##signbitbyte, lambda_checked, name##_list, 0); \
     943                 :            : }
     944                 :            : #define checked_iintrinsic_fast(LLVMOP, CHECK_OP, OP, name, u) \
     945                 :            : checked_intrinsic_ctype(CHECK_OP, OP, name, 8, u##int##8_t) \
     946                 :            : checked_intrinsic_ctype(CHECK_OP, OP, name, 16, u##int##16_t) \
     947                 :            : checked_intrinsic_ctype(CHECK_OP, OP, name, 32, u##int##32_t) \
     948                 :            : checked_intrinsic_ctype(CHECK_OP, OP, name, 64, u##int##64_t) \
     949                 :            : static const select_intrinsic_checked_t name##_list = { \
     950                 :            :     LLVMOP, \
     951                 :            :     jl_##name##8, \
     952                 :            :     jl_##name##16, \
     953                 :            :     jl_##name##32, \
     954                 :            :     jl_##name##64, \
     955                 :            : }; \
     956                 :            : checked_iintrinsic(name, u, jl_intrinsiclambda_checked)
     957                 :            : #define checked_iintrinsic_slow(LLVMOP, name, u) \
     958                 :            : static const select_intrinsic_checked_t name##_list = { \
     959                 :            :     LLVMOP \
     960                 :            : }; \
     961                 :            : checked_iintrinsic(name, u, jl_intrinsiclambda_checked)
     962                 :            : #define checked_iintrinsic_div(LLVMOP, name, u) \
     963                 :            : static const select_intrinsic_checked_t name##_list = { \
     964                 :            :     LLVMOP \
     965                 :            : }; \
     966                 :            : checked_iintrinsic(name, u, jl_intrinsiclambda_checkeddiv)
     967                 :            : 
     968                 :            : static inline
     969                 :   31228900 : jl_value_t *jl_iintrinsic_2(jl_value_t *a, jl_value_t *b, const char *name,
     970                 :            :                             char (*getsign)(void*, unsigned),
     971                 :            :                             jl_value_t *(*lambda2)(jl_value_t*, void*, void*, unsigned, unsigned, const void*),
     972                 :            :                             const void *list, int cvtb)
     973                 :            : {
     974                 :   31228900 :     jl_value_t *ty = jl_typeof(a);
     975                 :   31228900 :     jl_value_t *tyb = jl_typeof(b);
     976         [ +  + ]:   31228900 :     if (tyb != ty) {
     977         [ +  + ]:     446010 :         if (!cvtb)
     978                 :          4 :             jl_errorf("%s: types of a and b must match", name);
     979         [ -  + ]:     446006 :         if (!jl_is_primitivetype(tyb))
     980                 :          0 :             jl_errorf("%s: b is not a primitive type", name);
     981                 :            :     }
     982         [ -  + ]:   31228900 :     if (!jl_is_primitivetype(ty))
     983                 :          0 :         jl_errorf("%s: a is not a primitive type", name);
     984                 :   31228900 :     void *pa = jl_data_ptr(a), *pb = jl_data_ptr(b);
     985                 :   31228900 :     unsigned sz = jl_datatype_size(ty);
     986                 :   31228900 :     unsigned sz2 = next_power_of_two(sz);
     987         [ +  + ]:   31228900 :     unsigned szb = cvtb ? jl_datatype_size(tyb) : sz;
     988         [ +  + ]:   31228900 :     if (sz2 > sz) {
     989                 :            :         /* round type up to the appropriate c-type and set/clear the unused bits */
     990                 :          2 :         void *pa2 = alloca(sz2);
     991                 :          2 :         memcpy(pa2, pa, sz);
     992                 :          2 :         memset((char*)pa2 + sz, getsign(pa, sz), sz2 - sz);
     993                 :          2 :         pa = pa2;
     994                 :            :     }
     995         [ +  + ]:   31228900 :     if (sz2 > szb) {
     996                 :            :         /* round type up to the appropriate c-type and set/clear/truncate the unused bits
     997                 :            :          * (zero-extend if cvtb is set, since in that case b is unsigned while the sign of a comes from the op)
     998                 :            :          */
     999                 :      38635 :         void *pb2 = alloca(sz2);
    1000                 :      38635 :         memcpy(pb2, pb, szb);
    1001         [ +  + ]:      38635 :         memset((char*)pb2 + szb, cvtb ? 0 : getsign(pb, szb), sz2 - szb);
    1002                 :      38635 :         pb = pb2;
    1003                 :            :     }
    1004                 :   31228900 :     jl_value_t *newv = lambda2(ty, pa, pb, sz, sz2, list);
    1005                 :   31228900 :     return newv;
    1006                 :            : }
    1007                 :            : 
    1008                 :   25565300 : static inline jl_value_t *jl_intrinsiclambda_2(jl_value_t *ty, void *pa, void *pb, unsigned sz, unsigned sz2, const void *voidlist)
    1009                 :            : {
    1010                 :   25565300 :     void *pr = alloca(sz2);
    1011                 :   25565300 :     intrinsic_2_t op = select_intrinsic_2(sz2, (const intrinsic_2_t*)voidlist);
    1012                 :   25565300 :     op(sz * host_char_bit, pa, pb, pr);
    1013                 :   25565300 :     return jl_new_bits(ty, pr);
    1014                 :            : }
    1015                 :            : 
    1016                 :    5661240 : static inline jl_value_t *jl_intrinsiclambda_cmp(jl_value_t *ty, void *pa, void *pb, unsigned sz, unsigned sz2, const void *voidlist)
    1017                 :            : {
    1018                 :    5661240 :     intrinsic_cmp_t op = select_intrinsic_cmp(sz2, (const intrinsic_cmp_t*)voidlist);
    1019                 :    5661240 :     int cmp = op(sz * host_char_bit, pa, pb);
    1020         [ +  + ]:    5661240 :     return cmp ? jl_true : jl_false;
    1021                 :            : }
    1022                 :            : 
    1023                 :        461 : static inline jl_value_t *jl_intrinsiclambda_checked(jl_value_t *ty, void *pa, void *pb, unsigned sz, unsigned sz2, const void *voidlist)
    1024                 :            : {
    1025                 :            :     jl_value_t *params[2];
    1026                 :        461 :     params[0] = ty;
    1027                 :        461 :     params[1] = (jl_value_t*)jl_bool_type;
    1028                 :        461 :     jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2);
    1029                 :            :     JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE)
    1030                 :        461 :     jl_task_t *ct = jl_current_task;
    1031                 :        461 :     jl_value_t *newv = jl_gc_alloc(ct->ptls, ((jl_datatype_t*)tuptyp)->size, tuptyp);
    1032                 :            : 
    1033                 :        461 :     intrinsic_checked_t op = select_intrinsic_checked(sz2, (const intrinsic_checked_t*)voidlist);
    1034                 :        461 :     int ovflw = op(sz * host_char_bit, pa, pb, jl_data_ptr(newv));
    1035                 :            : 
    1036                 :        461 :     char *ao = (char*)jl_data_ptr(newv) + sz;
    1037                 :        461 :     *ao = (char)ovflw;
    1038                 :        461 :     return newv;
    1039                 :            : }
    1040                 :       1876 : static inline jl_value_t *jl_intrinsiclambda_checkeddiv(jl_value_t *ty, void *pa, void *pb, unsigned sz, unsigned sz2, const void *voidlist)
    1041                 :            : {
    1042                 :       1876 :     void *pr = alloca(sz2);
    1043                 :       1876 :     intrinsic_checked_t op = select_intrinsic_checked(sz2, (const intrinsic_checked_t*)voidlist);
    1044                 :       1876 :     int ovflw = op(sz * host_char_bit, pa, pb, pr);
    1045         [ -  + ]:       1876 :     if (ovflw)
    1046                 :          0 :         jl_throw(jl_diverror_exception);
    1047                 :       1876 :     return jl_new_bits(ty, pr);
    1048                 :            : }
    1049                 :            : 
    1050                 :            : // floating point
    1051                 :            : 
    1052                 :            : #define bi_fintrinsic(OP, name) \
    1053                 :            :     bi_intrinsic_half(OP, name) \
    1054                 :            :     bi_intrinsic_ctype(OP, name, 32, float) \
    1055                 :            :     bi_intrinsic_ctype(OP, name, 64, double) \
    1056                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b) \
    1057                 :            : { \
    1058                 :            :     jl_task_t *ct = jl_current_task; \
    1059                 :            :     jl_value_t *ty = jl_typeof(a); \
    1060                 :            :     if (jl_typeof(b) != ty) \
    1061                 :            :         jl_error(#name ": types of a and b must match"); \
    1062                 :            :     if (!jl_is_primitivetype(ty)) \
    1063                 :            :         jl_error(#name ": values are not primitive types"); \
    1064                 :            :     int sz = jl_datatype_size(ty); \
    1065                 :            :     jl_value_t *newv = jl_gc_alloc(ct->ptls, sz, ty); \
    1066                 :            :     void *pa = jl_data_ptr(a), *pb = jl_data_ptr(b), *pr = jl_data_ptr(newv); \
    1067                 :            :     switch (sz) { \
    1068                 :            :     /* choose the right size c-type operation */ \
    1069                 :            :     case 2: \
    1070                 :            :         jl_##name##16(16, pa, pb, pr); \
    1071                 :            :         break; \
    1072                 :            :     case 4: \
    1073                 :            :         jl_##name##32(32, pa, pb, pr); \
    1074                 :            :         break; \
    1075                 :            :     case 8: \
    1076                 :            :         jl_##name##64(64, pa, pb, pr); \
    1077                 :            :         break; \
    1078                 :            :     default: \
    1079                 :            :         jl_error(#name ": runtime floating point intrinsics are not implemented for bit sizes other than 16, 32 and 64"); \
    1080                 :            :     } \
    1081                 :            :     return newv; \
    1082                 :            : }
    1083                 :            : 
    1084                 :            : #define bool_fintrinsic(OP, name) \
    1085                 :            :     bool_intrinsic_half(OP, name) \
    1086                 :            :     bool_intrinsic_ctype(OP, name, 32, float) \
    1087                 :            :     bool_intrinsic_ctype(OP, name, 64, double) \
    1088                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b) \
    1089                 :            : { \
    1090                 :            :     jl_value_t *ty = jl_typeof(a); \
    1091                 :            :     if (jl_typeof(b) != ty) \
    1092                 :            :         jl_error(#name ": types of a and b must match"); \
    1093                 :            :     if (!jl_is_primitivetype(ty)) \
    1094                 :            :         jl_error(#name ": values are not primitive types"); \
    1095                 :            :     void *pa = jl_data_ptr(a), *pb = jl_data_ptr(b); \
    1096                 :            :     int sz = jl_datatype_size(ty); \
    1097                 :            :     int cmp; \
    1098                 :            :     switch (sz) { \
    1099                 :            :     /* choose the right size c-type operation */ \
    1100                 :            :     case 2: \
    1101                 :            :         cmp = jl_##name##16(16, pa, pb); \
    1102                 :            :         break; \
    1103                 :            :     case 4: \
    1104                 :            :         cmp = jl_##name##32(32, pa, pb); \
    1105                 :            :         break; \
    1106                 :            :     case 8: \
    1107                 :            :         cmp = jl_##name##64(64, pa, pb); \
    1108                 :            :         break; \
    1109                 :            :     default: \
    1110                 :            :         jl_error(#name ": runtime floating point intrinsics are not implemented for bit sizes other than 32 and 64"); \
    1111                 :            :     } \
    1112                 :            :     return cmp ? jl_true : jl_false; \
    1113                 :            : }
    1114                 :            : 
    1115                 :            : #define ter_fintrinsic(OP, name) \
    1116                 :            :     ter_intrinsic_half(OP, name) \
    1117                 :            :     ter_intrinsic_ctype(OP, name, 32, float) \
    1118                 :            :     ter_intrinsic_ctype(OP, name, 64, double) \
    1119                 :            : JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b, jl_value_t *c) \
    1120                 :            : { \
    1121                 :            :     jl_task_t *ct = jl_current_task; \
    1122                 :            :     jl_value_t *ty = jl_typeof(a); \
    1123                 :            :     if (jl_typeof(b) != ty || jl_typeof(c) != ty) \
    1124                 :            :         jl_error(#name ": types of a, b, and c must match"); \
    1125                 :            :     if (!jl_is_primitivetype(ty)) \
    1126                 :            :         jl_error(#name ": values are not primitive types"); \
    1127                 :            :     int sz = jl_datatype_size(ty); \
    1128                 :            :     jl_value_t *newv = jl_gc_alloc(ct->ptls, sz, ty); \
    1129                 :            :     void *pa = jl_data_ptr(a), *pb = jl_data_ptr(b), *pc = jl_data_ptr(c), *pr = jl_data_ptr(newv); \
    1130                 :            :     switch (sz) { \
    1131                 :            :     /* choose the right size c-type operation */ \
    1132                 :            :     case 2: \
    1133                 :            :         jl_##name##16(16, pa, pb, pc, pr); \
    1134                 :            :         break; \
    1135                 :            :     case 4: \
    1136                 :            :         jl_##name##32(32, pa, pb, pc, pr); \
    1137                 :            :         break; \
    1138                 :            :     case 8: \
    1139                 :            :         jl_##name##64(64, pa, pb, pc, pr); \
    1140                 :            :         break; \
    1141                 :            :     default: \
    1142                 :            :         jl_error(#name ": runtime floating point intrinsics are not implemented for bit sizes other than 16, 32 and 64"); \
    1143                 :            :     } \
    1144                 :            :     return newv; \
    1145                 :            : }
    1146                 :            : 
    1147                 :            : // arithmetic
    1148                 :            : #define neg(a) -a
    1149                 :            : #define neg_float(pr, a) *pr = -a
    1150                 :      33858 : un_iintrinsic_fast(LLVMNeg, neg, neg_int, u)
    1151                 :            : #define add(a,b) a + b
    1152                 :   42198026 : bi_iintrinsic_fast(LLVMAdd, add, add_int, u)
    1153                 :     112898 : bi_iintrinsic_fast(LLVMAdd, add, add_ptr, u)
    1154                 :            : #define sub(a,b) a - b
    1155                 :    4772960 : bi_iintrinsic_fast(LLVMSub, sub, sub_int, u)
    1156                 :          0 : bi_iintrinsic_fast(LLVMSub, sub, sub_ptr, u)
    1157                 :            : #define mul(a,b) a * b
    1158                 :     438104 : bi_iintrinsic_fast(LLVMMul, mul, mul_int, u)
    1159                 :            : #define div(a,b) a / b
    1160                 :          0 : bi_iintrinsic_fast(LLVMSDiv, div, sdiv_int,  )
    1161                 :          0 : bi_iintrinsic_fast(LLVMUDiv, div, udiv_int, u)
    1162                 :            : #define rem(a,b) a % b
    1163                 :          0 : bi_iintrinsic_fast(LLVMSRem, rem, srem_int,  )
    1164                 :          0 : bi_iintrinsic_fast(LLVMURem, rem, urem_int, u)
    1165                 :            : #define smod(a,b) ((a < 0) == (b < 0)) ? a % b : (b + (a % b)) % b
    1166         [ #  # ]:          0 : bi_iintrinsic_fast(jl_LLVMSMod, smod, smod_int,  )
    1167                 :            : #define frem(a, b) \
    1168                 :            :     fp_select2(a, b, fmod)
    1169                 :            : 
    1170         [ +  - ]:          9 : un_fintrinsic(neg_float,neg_float)
    1171   [ +  +  +  +  :          7 : bi_fintrinsic(add,add_float)
             +  -  -  + ]
    1172   [ -  +  -  +  :          6 : bi_fintrinsic(sub,sub_float)
             +  -  +  - ]
    1173   [ -  +  -  +  :          4 : bi_fintrinsic(mul,mul_float)
             +  -  -  - ]
    1174   [ -  +  -  +  :          4 : bi_fintrinsic(div,div_float)
             +  -  -  - ]
    1175   [ -  +  -  +  :          4 : bi_fintrinsic(frem,rem_float)
             +  -  -  - ]
    1176                 :            : 
    1177                 :            : // ternary operators //
    1178                 :            : // runtime fma is broken on windows, define julia_fma(f) ourself with fma_emulated as reference.
    1179                 :            : #if defined(_OS_WINDOWS_)
    1180                 :            : // reinterpret(UInt64, ::Float64)
    1181                 :            : uint64_t bitcast_d2u(double d) {
    1182                 :            :     uint64_t r;
    1183                 :            :     memcpy(&r, &d, 8);
    1184                 :            :     return r;
    1185                 :            : }
    1186                 :            : // reinterpret(Float64, ::UInt64)
    1187                 :            : double bitcast_u2d(uint64_t d) {
    1188                 :            :     double r;
    1189                 :            :     memcpy(&r, &d, 8);
    1190                 :            :     return r;
    1191                 :            : }
    1192                 :            : // Base.splitbits(::Float64)
    1193                 :            : void splitbits(double *hi, double *lo, double d) {
    1194                 :            :     *hi = bitcast_u2d(bitcast_d2u(d) & 0xfffffffff8000000);
    1195                 :            :     *lo = d - *hi;
    1196                 :            : }
    1197                 :            : // Base.exponent(::Float64)
    1198                 :            : int exponent(double a) {
    1199                 :            :     int e;
    1200                 :            :     frexp(a, &e);
    1201                 :            :     return e - 1;
    1202                 :            : }
    1203                 :            : // Base.fma_emulated(::Float32, ::Float32, ::Float32)
    1204                 :            : float julia_fmaf(float a, float b, float c) {
    1205                 :            :     double ab, res;
    1206                 :            :     ab = (double)a * b;
    1207                 :            :     res = ab + (double)c;
    1208                 :            :     if ((bitcast_d2u(res) & 0x1fffffff) == 0x10000000){
    1209                 :            :         double reslo = fabsf(c) > fabs(ab) ? ab-(res - c) : c-(res - ab);
    1210                 :            :         if (reslo != 0)
    1211                 :            :             res = nextafter(res, copysign(1.0/0.0, reslo));
    1212                 :            :     }
    1213                 :            :     return (float)res;
    1214                 :            : }
    1215                 :            : // Base.twomul(::Float64, ::Float64)
    1216                 :            : void two_mul(double *abhi, double *ablo, double a, double b) {
    1217                 :            :     double ahi, alo, bhi, blo, blohi, blolo;
    1218                 :            :     splitbits(&ahi, &alo, a);
    1219                 :            :     splitbits(&bhi, &blo, b);
    1220                 :            :     splitbits(&blohi, &blolo, blo);
    1221                 :            :     *abhi = a*b;
    1222                 :            :     *ablo = alo*blohi - (((*abhi - ahi*bhi) - alo*bhi) - ahi*blo) + blolo*alo;
    1223                 :            : }
    1224                 :            : // Base.issubnormal(::Float64) (Win32's fpclassify seems broken)
    1225                 :            : int issubnormal(double d) {
    1226                 :            :     uint64_t y = bitcast_d2u(d);
    1227                 :            :     return ((y & 0x7ff0000000000000) == 0) & ((y & 0x000fffffffffffff) != 0);
    1228                 :            : }
    1229                 :            : #if defined(_WIN32)
    1230                 :            : // Win32 needs volatile (avoid over optimization?)
    1231                 :            : #define VDOUBLE volatile double
    1232                 :            : #else
    1233                 :            : #define VDOUBLE double
    1234                 :            : #endif
    1235                 :            : 
    1236                 :            : // Base.fma_emulated(::Float64, ::Float64, ::Float64)
    1237                 :            : double julia_fma(double a, double b, double c) {
    1238                 :            :     double abhi, ablo, r, s;
    1239                 :            :     two_mul(&abhi, &ablo, a, b);
    1240                 :            :     if (!isfinite(abhi+c) || fabs(abhi) < 2.0041683600089732e-292 ||
    1241                 :            :         issubnormal(a) || issubnormal(b)) {
    1242                 :            :         int aandbfinite = isfinite(a) && isfinite(b);
    1243                 :            :         if (!(aandbfinite && isfinite(c)))
    1244                 :            :             return aandbfinite ? c : abhi+c;
    1245                 :            :         if (a == 0 || b == 0)
    1246                 :            :             return abhi+c;
    1247                 :            :         int bias = exponent(a) + exponent(b);
    1248                 :            :         VDOUBLE c_denorm = ldexp(c, -bias);
    1249                 :            :         if (isfinite(c_denorm)) {
    1250                 :            :             if (issubnormal(a))
    1251                 :            :                 a *= 4.503599627370496e15;
    1252                 :            :             if (issubnormal(b))
    1253                 :            :                 b *= 4.503599627370496e15;
    1254                 :            :             a = bitcast_u2d((bitcast_d2u(a) & 0x800fffffffffffff) | 0x3ff0000000000000);
    1255                 :            :             b = bitcast_u2d((bitcast_d2u(b) & 0x800fffffffffffff) | 0x3ff0000000000000);
    1256                 :            :             c = c_denorm;
    1257                 :            :             two_mul(&abhi, &ablo, a, b);
    1258                 :            :             r = abhi+c;
    1259                 :            :             s = (fabs(abhi) > fabs(c)) ? (abhi-r+c+ablo) : (c-r+abhi+ablo);
    1260                 :            :             double sumhi = r+s;
    1261                 :            :             if (issubnormal(ldexp(sumhi, bias))) {
    1262                 :            :                 double sumlo = r-sumhi+s;
    1263                 :            :                 int bits_lost = -bias-exponent(sumhi)-1022;
    1264                 :            :                 if ((bits_lost != 1) ^ ((bitcast_d2u(sumhi)&1) == 1))
    1265                 :            :                     if (sumlo != 0)
    1266                 :            :                         sumhi = nextafter(sumhi, copysign(1.0/0.0, sumlo));
    1267                 :            :             }
    1268                 :            :             return ldexp(sumhi, bias);
    1269                 :            :         }
    1270                 :            :         if (isinf(abhi) && signbit(c) == signbit(a*b))
    1271                 :            :             return abhi;
    1272                 :            :     }
    1273                 :            :     r = abhi+c;
    1274                 :            :     s = (fabs(abhi) > fabs(c)) ? (abhi-r+c+ablo) : (c-r+abhi+ablo);
    1275                 :            :     return r+s;
    1276                 :            : }
    1277                 :            : #define fma(a, b, c) \
    1278                 :            :     sizeof(a) == sizeof(float) ? julia_fmaf(a, b, c) : julia_fma(a, b, c)
    1279                 :            : #else // On other systems use fma(f) directly
    1280                 :            : #define fma(a, b, c) \
    1281                 :            :     sizeof(a) == sizeof(float) ? fmaf(a, b, c) : fma(a, b, c)
    1282                 :            : #endif
    1283                 :            : 
    1284                 :            : #define muladd(a, b, c) a * b + c
    1285   [ +  -  -  +  :    1048626 : ter_fintrinsic(fma,fma_float)
          -  +  +  +  +  
                      - ]
    1286   [ +  -  -  +  :          4 : ter_fintrinsic(muladd,muladd_float)
          -  +  +  -  -  
                      - ]
    1287                 :            : 
    1288                 :            : // same-type comparisons
    1289                 :            : #define eq(a,b) a == b
    1290                 :     152426 : bool_iintrinsic_fast(LLVMICmpEQ, eq, eq_int, u)
    1291                 :            : #define ne(a,b) a != b
    1292                 :          0 : bool_iintrinsic_fast(LLVMICmpNE, ne, ne_int, u)
    1293                 :            : #define lt(a,b) a < b
    1294                 :    5118540 : bool_iintrinsic_fast(LLVMICmpSLT, lt, slt_int,  )
    1295                 :     878076 : bool_iintrinsic_fast(LLVMICmpULT, lt, ult_int, u)
    1296                 :            : #define le(a,b) a <= b
    1297                 :    4766100 : bool_iintrinsic_fast(LLVMICmpSLE, le, sle_int,  )
    1298                 :     407338 : bool_iintrinsic_fast(LLVMICmpULE, le, ule_int, u)
    1299                 :            : 
    1300                 :            : typedef union {
    1301                 :            :     float f;
    1302                 :            :     int32_t d;
    1303                 :            :     uint32_t ud;
    1304                 :            : } bits32;
    1305                 :            : typedef union {
    1306                 :            :     double f;
    1307                 :            :     int64_t d;
    1308                 :            :     uint64_t ud;
    1309                 :            : } bits64;
    1310                 :            : 
    1311                 :            : #define fpiseq_n(c_type, nbits) \
    1312                 :            : static inline int fpiseq##nbits(c_type a, c_type b) JL_NOTSAFEPOINT { \
    1313                 :            :     bits##nbits ua, ub; \
    1314                 :            :     ua.f = a; \
    1315                 :            :     ub.f = b; \
    1316                 :            :     return (isnan(a) && isnan(b)) || ua.d == ub.d; \
    1317                 :            : }
    1318   [ #  #  #  #  :          0 : fpiseq_n(float, 32)
                   #  # ]
    1319   [ #  #  #  #  :          0 : fpiseq_n(double, 64)
                   #  # ]
    1320                 :            : #define fpiseq(a,b) \
    1321                 :            :     sizeof(a) == sizeof(float) ? fpiseq32(a, b) : fpiseq64(a, b)
    1322                 :            : 
    1323   [ -  +  -  +  :          8 : bool_fintrinsic(eq,eq_float)
          +  -  -  -  +  
                      + ]
    1324   [ -  +  -  +  :          8 : bool_fintrinsic(ne,ne_float)
          +  -  -  -  +  
                      + ]
    1325   [ #  #  #  #  :          0 : bool_fintrinsic(lt,lt_float)
          #  #  #  #  #  
                      # ]
    1326   [ -  +  -  +  :          8 : bool_fintrinsic(le,le_float)
          +  -  -  -  +  
                      + ]
    1327   [ #  #  #  #  :          0 : bool_fintrinsic(fpiseq,fpiseq)
          #  #  #  #  #  
                      # ]
    1328                 :            : 
    1329                 :            : // bitwise operators
    1330                 :            : #define and_op(a,b) a & b
    1331                 :    2244619 : bi_iintrinsic_fast(LLVMAnd, and_op, and_int, u)
    1332                 :            : #define or_op(a,b) a | b
    1333                 :     285179 : bi_iintrinsic_fast(LLVMOr, or_op, or_int, u)
    1334                 :            : #define xor_op(a,b) a ^ b
    1335                 :      22114 : bi_iintrinsic_fast(LLVMXor, xor_op, xor_int, u)
    1336                 :            : #define shl_op(a,b) b >= 8 * sizeof(a) ? 0 : a << b
    1337         [ +  + ]:     489534 : bi_iintrinsic_cnvtb_fast(LLVMShl, shl_op, shl_int, u, 1)
    1338                 :            : #define lshr_op(a,b) (b >= 8 * sizeof(a)) ? 0 : a >> b
    1339         [ +  + ]:     485899 : bi_iintrinsic_cnvtb_fast(LLVMLShr, lshr_op, lshr_int, u, 1)
    1340                 :            : #define ashr_op(a,b) ((b < 0 || b >= 8 * sizeof(a)) ? a >> (8 * sizeof(a) - 1) : a >> b)
    1341   [ +  +  +  + ]:      80772 : bi_iintrinsic_cnvtb_fast(LLVMAShr, ashr_op, ashr_int, , 1)
    1342                 :            : //#define bswap_op(a) __builtin_bswap(a)
    1343                 :            : //un_iintrinsic_fast(LLVMByteSwap, bswap_op, bswap_int, u)
    1344                 :          0 : un_iintrinsic_slow(LLVMByteSwap, bswap_int, u)
    1345                 :            : //#define ctpop_op(a) __builtin_ctpop(a)
    1346                 :            : //uu_iintrinsic_fast(LLVMCountPopulation, ctpop_op, ctpop_int, u)
    1347                 :       2057 : uu_iintrinsic_slow(LLVMCountPopulation, ctpop_int, u)
    1348                 :            : //#define ctlz_op(a) __builtin_ctlz(a)
    1349                 :            : //uu_iintrinsic_fast(LLVMCountLeadingZeros, ctlz_op, ctlz_int, u)
    1350                 :         80 : uu_iintrinsic_slow(LLVMCountLeadingZeros, ctlz_int, u)
    1351                 :            : //#define cttz_op(a) __builtin_cttz(a)
    1352                 :            : //uu_iintrinsic_fast(LLVMCountTrailingZeros, cttz_op, cttz_int, u)
    1353                 :       9193 : uu_iintrinsic_slow(LLVMCountTrailingZeros, cttz_int, u)
    1354                 :            : #define not_op(a) ~a
    1355                 :    5025993 : un_iintrinsic_fast(LLVMFlipAllBits, not_op, not_int, u)
    1356                 :            : 
    1357                 :            : // conversions
    1358                 :      76244 : cvt_iintrinsic(LLVMTrunc, trunc_int)
    1359                 :       4784 : cvt_iintrinsic(LLVMSExt, sext_int)
    1360                 :      55586 : cvt_iintrinsic(LLVMZExt, zext_int)
    1361                 :          4 : cvt_iintrinsic(LLVMSItoFP, sitofp)
    1362                 :          2 : cvt_iintrinsic(LLVMUItoFP, uitofp)
    1363                 :          2 : cvt_iintrinsic(LLVMFPtoSI, fptosi)
    1364                 :          2 : cvt_iintrinsic(LLVMFPtoUI, fptoui)
    1365                 :            : 
    1366                 :            : #define fptrunc(pr, a) \
    1367                 :            :         if (!(osize < 8 * sizeof(a))) \
    1368                 :            :             jl_error("fptrunc: output bitsize must be < input bitsize"); \
    1369                 :            :         else if (osize == 16) \
    1370                 :            :             *(uint16_t*)pr = __gnu_f2h_ieee(a); \
    1371                 :            :         else if (osize == 32) \
    1372                 :            :             *(float*)pr = a; \
    1373                 :            :         else if (osize == 64) \
    1374                 :            :             *(double*)pr = a; \
    1375                 :            :         else \
    1376                 :            :             jl_error("fptrunc: runtime floating point intrinsics are not implemented for bit sizes other than 16, 32 and 64");
    1377                 :            : #define fpext(pr, a) \
    1378                 :            :         if (!(osize >= 8 * sizeof(a))) \
    1379                 :            :             jl_error("fpext: output bitsize must be >= input bitsize"); \
    1380                 :            :         if (osize == 32) \
    1381                 :            :             *(float*)pr = a; \
    1382                 :            :         else if (osize == 64) \
    1383                 :            :             *(double*)pr = a; \
    1384                 :            :         else \
    1385                 :            :             jl_error("fpext: runtime floating point intrinsics are not implemented for bit sizes other than 32 and 64");
    1386   [ +  +  +  +  :         36 : un_fintrinsic_withtype(fptrunc,fptrunc)
          +  -  -  -  #  
          #  #  #  #  #  
             #  #  #  # ]
    1387   [ +  +  -  -  :         10 : un_fintrinsic_withtype(fpext,fpext)
          -  -  -  -  -  
             +  +  +  +  
                      - ]
    1388                 :            : 
    1389                 :            : // checked arithmetic
    1390                 :            : /**
    1391                 :            :  * s_typemin = - s_typemax - 1
    1392                 :            :  * s_typemax = ((t)1 << (runtime_nbits - 1)) - 1
    1393                 :            :  * u_typemin = 0
    1394                 :            :  * u_typemax = ((t)1 << runtime_nbits) - 1
    1395                 :            :  **/
    1396                 :            : #define sTYPEMIN(t) -sTYPEMAX(t) - 1
    1397                 :            : #define sTYPEMAX(t)                                                \
    1398                 :            :     ((t)(8 * sizeof(a) == runtime_nbits                            \
    1399                 :            :          ? ((((((t)1) << (8 * sizeof(t) - 2)) - 1) << 1) + 1)      \
    1400                 :            :          : (  (((t)1) << (runtime_nbits - 1)) - 1)))
    1401                 :            : 
    1402                 :            : #define uTYPEMIN(t) ((t)0)
    1403                 :            : #define uTYPEMAX(t)                                             \
    1404                 :            :     ((t)(8 * sizeof(t) == runtime_nbits                         \
    1405                 :            :          ? (~((t)0)) : (~(((t)~((t)0)) << runtime_nbits))))
    1406                 :            : #define check_sadd_int(t, a, b)                                         \
    1407                 :            :         /* this test checks for (b >= 0) ? (a + b > typemax) : (a + b < typemin) ==> overflow */ \
    1408                 :            :         (b >= 0) ? (a > sTYPEMAX(t) - b) : (a < sTYPEMIN(t) - b)
    1409   [ #  #  #  #  :          0 : checked_iintrinsic_fast(LLVMAdd_sov, check_sadd_int, add, checked_sadd_int,  )
                   #  # ]
    1410                 :            : #define check_uadd_int(t, a, b)                                       \
    1411                 :            :     /* this test checks for (a + b) > typemax(a) ==> overflow */      \
    1412                 :            :     a > uTYPEMAX(t) - b
    1413         [ #  # ]:          0 : checked_iintrinsic_fast(LLVMAdd_uov, check_uadd_int, add, checked_uadd_int, u)
    1414                 :            : #define check_ssub_int(t, a, b)                                         \
    1415                 :            :     /* this test checks for (b >= 0) ? (a - b < typemin) : (a - b > typemax) ==> overflow */ \
    1416                 :            :     (b >= 0) ? (a < sTYPEMIN(t) + b) : (a > sTYPEMAX(t) + b)
    1417   [ #  #  #  #  :          0 : checked_iintrinsic_fast(LLVMSub_sov, check_ssub_int, sub, checked_ssub_int,  )
                   #  # ]
    1418                 :            : #define check_usub_int(t, a, b)                                   \
    1419                 :            :     /* this test checks for (a - b) < typemin ==> overflow */     \
    1420                 :            :     a < uTYPEMIN(t) + b
    1421                 :          0 : checked_iintrinsic_fast(LLVMSub_uov, check_usub_int, sub, checked_usub_int, u)
    1422                 :        461 : checked_iintrinsic_slow(LLVMMul_sov, checked_smul_int,  )
    1423                 :          0 : checked_iintrinsic_slow(LLVMMul_uov, checked_umul_int, u)
    1424                 :            : 
    1425                 :         69 : checked_iintrinsic_div(LLVMDiv_sov, checked_sdiv_int,  )
    1426                 :          0 : checked_iintrinsic_div(LLVMDiv_uov, checked_udiv_int, u)
    1427                 :       1807 : checked_iintrinsic_div(LLVMRem_sov, checked_srem_int,  )
    1428                 :          0 : checked_iintrinsic_div(LLVMRem_uov, checked_urem_int, u)
    1429                 :            : 
    1430                 :            : // functions
    1431                 :            : #define flipsign(a, b) \
    1432                 :            :         (b >= 0) ? a : -a
    1433         [ #  # ]:          0 : bi_iintrinsic_fast(jl_LLVMFlipSign, flipsign, flipsign_int,  )
    1434                 :            : #define abs_float(pr, a)      *pr = fp_select(a, fabs)
    1435                 :            : #define ceil_float(pr, a)     *pr = fp_select(a, ceil)
    1436                 :            : #define floor_float(pr, a)    *pr = fp_select(a, floor)
    1437                 :            : #define trunc_float(pr, a)    *pr = fp_select(a, trunc)
    1438                 :            : #define rint_float(pr, a)     *pr = fp_select(a, rint)
    1439                 :            : #define sqrt_float(pr, a)     *pr = fp_select(a, sqrt)
    1440                 :            : #define copysign_float(a, b)  fp_select2(a, b, copysign)
    1441                 :            : 
    1442         [ #  # ]:         63 : un_fintrinsic(abs_float,abs_float)
    1443   [ #  #  #  #  :          0 : bi_fintrinsic(copysign_float,copysign_float)
             #  #  #  # ]
    1444         [ #  # ]:          0 : un_fintrinsic(ceil_float,ceil_llvm)
    1445         [ #  # ]:          0 : un_fintrinsic(floor_float,floor_llvm)
    1446         [ #  # ]:          0 : un_fintrinsic(trunc_float,trunc_llvm)
    1447         [ #  # ]:          0 : un_fintrinsic(rint_float,rint_llvm)
    1448         [ #  # ]:          0 : un_fintrinsic(sqrt_float,sqrt_llvm)
    1449         [ #  # ]:          0 : un_fintrinsic(sqrt_float,sqrt_llvm_fast)
    1450                 :            : 
    1451                 :      18181 : JL_DLLEXPORT jl_value_t *jl_arraylen(jl_value_t *a)
    1452                 :            : {
    1453         [ +  + ]:      18181 :     JL_TYPECHK(arraylen, array, a);
    1454                 :      18180 :     return jl_box_long(jl_array_len((jl_array_t*)a));
    1455                 :            : }
    1456                 :            : 
    1457                 :          9 : JL_DLLEXPORT jl_value_t *jl_have_fma(jl_value_t *typ)
    1458                 :            : {
    1459         [ -  + ]:          9 :     JL_TYPECHK(have_fma, datatype, typ);
    1460                 :            :     // TODO: run-time feature check?
    1461                 :          9 :     return jl_false;
    1462                 :            : }

Generated by: LCOV version 1.14