int128/uint128 maps to hardware and/or compiler intrinsics and need some 
codegen fixes for shifts.

Or you can use the hacky approach I started in 
[https://github.com/nim-lang/Nim/issues/7675#issuecomment-383409664](https://github.com/nim-lang/Nim/issues/7675#issuecomment-383409664),
 don't put that in the standard lib though.
    
    
    {.emit:"""
    typedef unsigned __int128 NU128;
    typedef          __int128 NI128;
    """.}
    
    type
      int128*{.importc: "NI128".} = object
        # Size missing https://github.com/nim-lang/Nim/issues/7674
        do_not_use1, do_not_use2: uint64
      
      helper128 = object
        lo, hi: uint64
    
    func `+`(x, y: int128): int128 {.magic: "AddI".}
    # func `shl`(x, y: int128): int128 {.magic: "ShlI".}
    #   # Generates c_3kT3fyGcLUlO9cGAfoG5F0w = 
()((NU128)(a_H4uaduhuKIzzvSo9a5XGckw) << (NU128)(b_s7Jde6jEzqXVu63vxBEZxg));
    #   # Notice how the parenthesis is empty
    
    func `shl`(x, y: int128): int128 =
      {.emit: "`result` = (NI128)((NU128)(`x`) << (NU128)(`y`));".}
      # Works
    
    var
      helperA = helper128(lo: 10)
      helperB = helper128(lo: 3)
    
    let
      a = (cast[ptr int128](helperA.addr))[]
      b = (cast[ptr int128](helperB.addr))[]
    
    var c = a shl b
    echo (cast[ptr helper128](c.addr))[] # (lo: 80, hi: 0)
    
    
    Run

Both int128 and bignum would be nice in the standard library but while int128 
have a very defined API (drop-in replacement for int64), bignum might need some 
API tuning and so should probably start as a package.

Reply via email to