This commit is contained in:
Araq 2015-06-15 00:56:20 +02:00
commit 8d39669233
6 changed files with 71 additions and 37 deletions

View file

@ -504,6 +504,11 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
"$# = #mulInt($#, $#);$n", "$# = #divInt($#, $#);$n", "$# = #mulInt($#, $#);$n", "$# = #divInt($#, $#);$n",
"$# = #modInt($#, $#);$n", "$# = #modInt($#, $#);$n",
"$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n"] "$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n"]
prc64: array[mAddI..mPred, string] = [
"$# = #addInt64($#, $#);$n", "$# = #subInt64($#, $#);$n",
"$# = #mulInt64($#, $#);$n", "$# = #divInt64($#, $#);$n",
"$# = #modInt64($#, $#);$n",
"$# = #addInt64($#, $#);$n", "$# = #subInt64($#, $#);$n"]
opr: array[mAddI..mPred, string] = [ opr: array[mAddI..mPred, string] = [
"($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)", "($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
"($#)($# / $#)", "($#)($# % $#)", "($#)($# / $#)", "($#)($# % $#)",
@ -520,7 +525,8 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
let res = opr[m] % [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)] let res = opr[m] % [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)]
putIntoDest(p, d, e.typ, res) putIntoDest(p, d, e.typ, res)
else: else:
let res = binaryArithOverflowRaw(p, t, a, b, prc[m]) let res = binaryArithOverflowRaw(p, t, a, b,
if t.kind == tyInt64: prc64[m] else: prc[m])
putIntoDest(p, d, e.typ, "($#)($#)" % [getTypeDesc(p.module, t), res]) putIntoDest(p, d, e.typ, "($#)($#)" % [getTypeDesc(p.module, t), res])
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =

View file

@ -88,3 +88,4 @@ proc initDefines*() =
defineSymbol("nimalias") defineSymbol("nimalias")
defineSymbol("nimlocks") defineSymbol("nimlocks")
defineSymbol("nimnode") defineSymbol("nimnode")
defineSymbol("nimnomagic64")

View file

@ -262,10 +262,6 @@ template eatChar(L: var TLexer, t: var TToken) =
add(t.literal, L.buf[L.bufpos]) add(t.literal, L.buf[L.bufpos])
inc(L.bufpos) inc(L.bufpos)
proc getNumber(L: var TLexer): TToken = proc getNumber(L: var TLexer): TToken =
proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]) = proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]) =
var pos = L.bufpos # use registers for pos, buf var pos = L.bufpos # use registers for pos, buf
@ -495,7 +491,7 @@ proc getNumber(L: var TLexer): TToken =
else: false else: false
if outOfRange: if outOfRange:
echo "out of range num: ", result.iNumber, " vs ", xi #echo "out of range num: ", result.iNumber, " vs ", xi
lexMessageLitNum(L, errNumberOutOfRange, startpos) lexMessageLitNum(L, errNumberOutOfRange, startpos)
else: else:
@ -528,8 +524,8 @@ proc getNumber(L: var TLexer): TToken =
# Promote int literal to int64? Not always necessary, but more consistent # Promote int literal to int64? Not always necessary, but more consistent
if result.tokType == tkIntLit: if result.tokType == tkIntLit:
if (result.iNumber < low(int32)) or (result.iNumber > high(int32)): if (result.iNumber < low(int32)) or (result.iNumber > high(int32)):
result.tokType = tkInt64Lit result.tokType = tkInt64Lit
except ValueError: except ValueError:
lexMessageLitNum(L, errInvalidNumber, startpos) lexMessageLitNum(L, errInvalidNumber, startpos)

View file

@ -214,7 +214,7 @@ proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {.
## `EOverflow` is raised if an overflow occurs. ## `EOverflow` is raised if an overflow occurs.
var res: BiggestInt var res: BiggestInt
# use 'res' for exception safety (don't write to 'number' in case of an # use 'res' for exception safety (don't write to 'number' in case of an
# overflow exception: # overflow exception):
result = rawParseInt(s, res, start) result = rawParseInt(s, res, start)
number = res number = res

View file

@ -677,35 +677,50 @@ proc `not` *(x: int): int {.magic: "BitnotI", noSideEffect.}
proc `not` *(x: int8): int8 {.magic: "BitnotI", noSideEffect.} proc `not` *(x: int8): int8 {.magic: "BitnotI", noSideEffect.}
proc `not` *(x: int16): int16 {.magic: "BitnotI", noSideEffect.} proc `not` *(x: int16): int16 {.magic: "BitnotI", noSideEffect.}
proc `not` *(x: int32): int32 {.magic: "BitnotI", noSideEffect.} proc `not` *(x: int32): int32 {.magic: "BitnotI", noSideEffect.}
proc `not` *(x: int64): int64 {.magic: "BitnotI", noSideEffect.}
## computes the `bitwise complement` of the integer `x`. ## computes the `bitwise complement` of the integer `x`.
when defined(nimnomagic64):
proc `not` *(x: int64): int64 {.magic: "BitnotI", noSideEffect.}
else:
proc `not` *(x: int64): int64 {.magic: "BitnotI64", noSideEffect.}
proc `+` *(x, y: int): int {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int): int {.magic: "AddI", noSideEffect.}
proc `+` *(x, y: int8): int8 {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int8): int8 {.magic: "AddI", noSideEffect.}
proc `+` *(x, y: int16): int16 {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int16): int16 {.magic: "AddI", noSideEffect.}
proc `+` *(x, y: int32): int32 {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int32): int32 {.magic: "AddI", noSideEffect.}
proc `+` *(x, y: int64): int64 {.magic: "AddI", noSideEffect.}
## Binary `+` operator for an integer. ## Binary `+` operator for an integer.
when defined(nimnomagic64):
proc `+` *(x, y: int64): int64 {.magic: "AddI", noSideEffect.}
else:
proc `+` *(x, y: int64): int64 {.magic: "AddI64", noSideEffect.}
proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int8): int8 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int8): int8 {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int32): int32 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int32): int32 {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int64): int64 {.magic: "SubI", noSideEffect.}
## Binary `-` operator for an integer. ## Binary `-` operator for an integer.
when defined(nimnomagic64):
proc `-` *(x, y: int64): int64 {.magic: "SubI", noSideEffect.}
else:
proc `-` *(x, y: int64): int64 {.magic: "SubI64", noSideEffect.}
proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int8): int8 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int8): int8 {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int32): int32 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int32): int32 {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int64): int64 {.magic: "MulI", noSideEffect.}
## Binary `*` operator for an integer. ## Binary `*` operator for an integer.
when defined(nimnomagic64):
proc `*` *(x, y: int64): int64 {.magic: "MulI", noSideEffect.}
else:
proc `*` *(x, y: int64): int64 {.magic: "MulI64", noSideEffect.}
proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.}
proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.}
proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.}
proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.}
proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.}
## computes the integer division. This is roughly the same as ## computes the integer division. This is roughly the same as
## ``floor(x/y)``. ## ``floor(x/y)``.
## ##
@ -714,14 +729,23 @@ proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.}
## 2 div 2 == 1 ## 2 div 2 == 1
## 3 div 2 == 1 ## 3 div 2 == 1
when defined(nimnomagic64):
proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.}
else:
proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.}
proc `mod` *(x, y: int): int {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int): int {.magic: "ModI", noSideEffect.}
proc `mod` *(x, y: int8): int8 {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int8): int8 {.magic: "ModI", noSideEffect.}
proc `mod` *(x, y: int16): int16 {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
proc `mod` *(x, y: int32): int32 {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
proc `mod` *(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
## computes the integer modulo operation. This is the same as ## computes the integer modulo operation. This is the same as
## ``x - (x div y) * y``. ## ``x - (x div y) * y``.
when defined(nimnomagic64):
proc `mod` *(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
else:
proc `mod` *(x, y: int64): int64 {.magic: "ModI64", noSideEffect.}
proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.}
proc `shr` *(x, y: int8): int8 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int8): int8 {.magic: "ShrI", noSideEffect.}
proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}
@ -2304,11 +2328,18 @@ proc abs*(x: int16): int16 {.magic: "AbsI", noSideEffect.} =
if x < 0: -x else: x if x < 0: -x else: x
proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.} = proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.} =
if x < 0: -x else: x if x < 0: -x else: x
proc abs*(x: int64): int64 {.magic: "AbsI", noSideEffect.} = when defined(nimnomagic64):
## returns the absolute value of `x`. If `x` is ``low(x)`` (that proc abs*(x: int64): int64 {.magic: "AbsI", noSideEffect.} =
## is -MININT for its type), an overflow exception is thrown (if overflow ## returns the absolute value of `x`. If `x` is ``low(x)`` (that
## checking is turned on). ## is -MININT for its type), an overflow exception is thrown (if overflow
if x < 0: -x else: x ## checking is turned on).
if x < 0: -x else: x
else:
proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.} =
## returns the absolute value of `x`. If `x` is ``low(x)`` (that
## is -MININT for its type), an overflow exception is thrown (if overflow
## checking is turned on).
if x < 0: -x else: x
{.pop.} {.pop.}
when not defined(JS): #and not defined(NimrodVM): when not defined(JS): #and not defined(NimrodVM):

View file

@ -18,7 +18,7 @@ proc raiseDivByZero {.compilerproc, noinline.} =
sysFatal(DivByZeroError, "division by zero") sysFatal(DivByZeroError, "division by zero")
when defined(builtinOverflow): when defined(builtinOverflow):
# Builtin compiler functions for improved performance # Builtin compiler functions for improved performance
when sizeof(clong) == 8: when sizeof(clong) == 8:
proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {. proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
importc: "__builtin_saddl_overflow", nodecl, nosideeffect.} importc: "__builtin_saddl_overflow", nodecl, nosideeffect.}