Unfortunately overflows and carry flags are where the "C is a portable 
assembly" narratives die ...

You can't access those flags even though they would be incredibly useful for 
cryptography and interpreters. Sometimes you can trick the compiler to generate 
the proper code but other times you get silly code that sets flag explicitly 
instead of reusing the result of the previous operation.

Anyway, this is what I use to be portable for my bigint library, obviously the 
builtins are better but I'm not sure MSVC also provides some and they don't 
work anyway for uint256+:

[https://github.com/status-im/nim-stint/blob/master/stint/private/int_addsub.nim](https://github.com/status-im/nim-stint/blob/master/stint/private/int_addsub.nim)
    
    
    func `+`*(x, y: IntImpl): IntImpl {.inline.}=
      # Addition for multi-precision signed int.
      type SubTy = type x.hi
      result.lo = x.lo + y.lo
      result.hi = (result.lo < y.lo).toSubtype(SubTy) + x.hi + y.hi
      
      when compileOption("boundChecks"):
        if unlikely(
          not(result.isNegative xor x.isNegative) or
          not(result.isNegative xor y.isNegative)
        ):
          return
        raise newException(OverflowError, "Addition overflow")
    
    func `-`*(x, y: IntImpl): IntImpl {.inline.}=
      # Substraction for multi-precision signed int.
      
      type SubTy = type x.hi
      result.lo = x.lo - y.lo
      result.hi = x.hi - y.hi - (x.lo < y.lo).toSubtype(SubTy)
      
      when compileOption("boundChecks"):
        if unlikely(
          not(result.isNegative xor x.isNegative) or
          not(result.isNegative xor y.isNegative.not)
        ):
          return
        raise newException(OverflowError, "Substraction underflow")
    
    
    Run

Reply via email to