summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-06-15 00:56:20 +0200
committerAraq <rumpf_a@web.de>2015-06-15 00:56:20 +0200
commit8d39669233880870a1c744e165a8510f5cc8d3c5 (patch)
treeda358a095b0eee0b530b5365e768ec281207e3d9
parent1452edfbb9d7de1d654248cc709a7436d8d404c2 (diff)
downloadNim-8d39669233880870a1c744e165a8510f5cc8d3c5.tar.gz
fixes #2909
-rw-r--r--compiler/ccgexprs.nim8
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/lexer.nim12
-rw-r--r--lib/pure/parseutils.nim32
-rw-r--r--lib/system.nim53
-rw-r--r--lib/system/arithm.nim2
6 files changed, 71 insertions, 37 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 862776740..55fa7564c 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -504,6 +504,11 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
       "$# = #mulInt($#, $#);$n", "$# = #divInt($#, $#);$n",
       "$# = #modInt($#, $#);$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] = [
       "($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
       "($#)($# / $#)", "($#)($# % $#)",
@@ -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)]
     putIntoDest(p, d, e.typ, res)
   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])
 
 proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index ad7d80c85..34322471f 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -88,3 +88,4 @@ proc initDefines*() =
   defineSymbol("nimalias")
   defineSymbol("nimlocks")
   defineSymbol("nimnode")
+  defineSymbol("nimnomagic64")
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 5c7baf7d3..cea42ad1e 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -262,10 +262,6 @@ template eatChar(L: var TLexer, t: var TToken) =
   add(t.literal, L.buf[L.bufpos])
   inc(L.bufpos)
 
-
-
-
-
 proc getNumber(L: var TLexer): TToken =
   proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]) =
     var pos = L.bufpos              # use registers for pos, buf
@@ -483,7 +479,7 @@ proc getNumber(L: var TLexer): TToken =
       else: internalError(getLineInfo(L), "getNumber")
 
       # Bounds checks. Non decimal literals are allowed to overflow the range of
-      # the datatype as long as their pattern don't overflow _bitwise_, hence 
+      # the datatype as long as their pattern don't overflow _bitwise_, hence
       # below checks of signed sizes against uint*.high is deliberate:
       # (0x80'u8 = 128, 0x80'i8 = -128, etc == OK)
       if result.tokType notin floatTypes:
@@ -495,7 +491,7 @@ proc getNumber(L: var TLexer): TToken =
         else: false
 
         if outOfRange:
-          echo "out of range num: ", result.iNumber, " vs ", xi
+          #echo "out of range num: ", result.iNumber, " vs ", xi
           lexMessageLitNum(L, errNumberOutOfRange, startpos)
 
     else:
@@ -528,8 +524,8 @@ proc getNumber(L: var TLexer): TToken =
 
     # Promote int literal to int64? Not always necessary, but more consistent
     if result.tokType == tkIntLit:
-        if (result.iNumber < low(int32)) or (result.iNumber > high(int32)):
-          result.tokType = tkInt64Lit
+      if (result.iNumber < low(int32)) or (result.iNumber > high(int32)):
+        result.tokType = tkInt64Lit
 
   except ValueError:
     lexMessageLitNum(L, errInvalidNumber, startpos)
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index c07b713de..b3708838a 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -26,7 +26,7 @@ proc toLower(c: char): char {.inline.} =
   result = if c in {'A'..'Z'}: chr(ord(c)-ord('A')+ord('a')) else: c
 
 proc parseHex*(s: string, number: var int, start = 0): int {.
-  rtl, extern: "npuParseHex", noSideEffect.}  = 
+  rtl, extern: "npuParseHex", noSideEffect.}  =
   ## Parses a hexadecimal number and stores its value in ``number``.
   ##
   ## Returns the number of the parsed characters or 0 in case of an error. This
@@ -49,7 +49,7 @@ proc parseHex*(s: string, number: var int, start = 0): int {.
   var foundDigit = false
   if s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2)
   elif s[i] == '#': inc(i)
-  while true: 
+  while true:
     case s[i]
     of '_': discard
     of '0'..'9':
@@ -66,13 +66,13 @@ proc parseHex*(s: string, number: var int, start = 0): int {.
   if foundDigit: result = i-start
 
 proc parseOct*(s: string, number: var int, start = 0): int  {.
-  rtl, extern: "npuParseOct", noSideEffect.} = 
+  rtl, extern: "npuParseOct", noSideEffect.} =
   ## parses an octal number and stores its value in ``number``. Returns
   ## the number of the parsed characters or 0 in case of an error.
   var i = start
   var foundDigit = false
   if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2)
-  while true: 
+  while true:
     case s[i]
     of '_': discard
     of '0'..'7':
@@ -93,7 +93,7 @@ proc parseIdent*(s: string, ident: var string, start = 0): int =
     result = i-start
 
 proc parseIdent*(s: string, start = 0): string =
-  ## parses an identifier and stores it in ``ident``. 
+  ## parses an identifier and stores it in ``ident``.
   ## Returns the parsed identifier or an empty string in case of an error.
   result = ""
   var i = start
@@ -101,14 +101,14 @@ proc parseIdent*(s: string, start = 0): string =
   if s[i] in IdentStartChars:
     inc(i)
     while s[i] in IdentChars: inc(i)
-    
+
     result = substr(s, start, i-1)
 
 proc parseToken*(s: string, token: var string, validChars: set[char],
                  start = 0): int {.inline, deprecated.} =
   ## parses a token and stores it in ``token``. Returns
   ## the number of the parsed characters or 0 in case of an error. A token
-  ## consists of the characters in `validChars`. 
+  ## consists of the characters in `validChars`.
   ##
   ## **Deprecated since version 0.8.12**: Use ``parseWhile`` instead.
   var i = start
@@ -126,13 +126,13 @@ proc skip*(s, token: string, start = 0): int {.inline.} =
   ## or 0 if there was no `token` at ``s[start]``.
   while result < token.len and s[result+start] == token[result]: inc(result)
   if result != token.len: result = 0
-  
+
 proc skipIgnoreCase*(s, token: string, start = 0): int =
   ## same as `skip` but case is ignored for token matching.
   while result < token.len and
       toLower(s[result+start]) == toLower(token[result]): inc(result)
   if result != token.len: result = 0
-  
+
 proc skipUntil*(s: string, until: set[char], start = 0): int {.inline.} =
   ## Skips all characters until one char from the set `until` is found
   ## or the end is reached.
@@ -154,7 +154,7 @@ proc parseUntil*(s: string, token: var string, until: set[char],
                  start = 0): int {.inline.} =
   ## parses a token and stores it in ``token``. Returns
   ## the number of the parsed characters or 0 in case of an error. A token
-  ## consists of the characters notin `until`. 
+  ## consists of the characters notin `until`.
   var i = start
   while i < s.len and s[i] notin until: inc(i)
   result = i-start
@@ -174,7 +174,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char],
                  start = 0): int {.inline.} =
   ## parses a token and stores it in ``token``. Returns
   ## the number of the parsed characters or 0 in case of an error. A token
-  ## consists of the characters in `validChars`. 
+  ## consists of the characters in `validChars`.
   var i = start
   while s[i] in validChars: inc(i)
   result = i-start
@@ -214,7 +214,7 @@ proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {.
   ## `EOverflow` is raised if an overflow occurs.
   var res: BiggestInt
   # use 'res' for exception safety (don't write to 'number' in case of an
-  # overflow exception:
+  # overflow exception):
   result = rawParseInt(s, res, start)
   number = res
 
@@ -246,7 +246,7 @@ proc parseFloat*(s: string, number: var float, start = 0): int {.
   result = parseBiggestFloat(s, bf, start)
   if result != 0:
     number = bf
-  
+
 type
   InterpolatedKind* = enum   ## describes for `interpolatedFragments`
                              ## which part of the interpolated string is
@@ -289,12 +289,12 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
           case s[j]
           of '{': inc nesting
           of '}':
-            if nesting == 0: 
+            if nesting == 0:
               inc j
               break
             dec nesting
           of '\0':
-            raise newException(ValueError, 
+            raise newException(ValueError,
               "Expected closing '}': " & substr(s, i, s.high))
           else: discard
           inc j
@@ -310,7 +310,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
         inc i # skip $
         kind = ikDollar
       else:
-        raise newException(ValueError, 
+        raise newException(ValueError,
           "Unable to parse a varible name at " & substr(s, i, s.high))
     else:
       while j < s.len and s[j] != '$': inc j
diff --git a/lib/system.nim b/lib/system.nim
index 2204a5436..62c024d77 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -677,35 +677,50 @@ proc `not` *(x: int): int {.magic: "BitnotI", noSideEffect.}
 proc `not` *(x: int8): int8 {.magic: "BitnotI", noSideEffect.}
 proc `not` *(x: int16): int16 {.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`.
 
+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: int8): int8 {.magic: "AddI", noSideEffect.}
 proc `+` *(x, y: int16): int16 {.magic: "AddI", noSideEffect.}
 proc `+` *(x, y: int32): int32 {.magic: "AddI", noSideEffect.}
-proc `+` *(x, y: int64): int64 {.magic: "AddI", noSideEffect.}
   ## 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: int8): int8 {.magic: "SubI", noSideEffect.}
 proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.}
 proc `-` *(x, y: int32): int32 {.magic: "SubI", noSideEffect.}
-proc `-` *(x, y: int64): int64 {.magic: "SubI", noSideEffect.}
   ## 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: int8): int8 {.magic: "MulI", noSideEffect.}
 proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.}
 proc `*` *(x, y: int32): int32 {.magic: "MulI", noSideEffect.}
-proc `*` *(x, y: int64): int64 {.magic: "MulI", noSideEffect.}
   ## 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: int8): int8 {.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: int64): int64 {.magic: "DivI", noSideEffect.}
   ## computes the integer division. This is roughly the same as
   ## ``floor(x/y)``.
   ##
@@ -714,14 +729,23 @@ proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.}
   ##   2 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: int8): int8 {.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: int64): int64 {.magic: "ModI", noSideEffect.}
   ## computes the integer modulo operation. This is the same as
   ## ``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: int8): int8 {.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
 proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.} =
   if x < 0: -x else: x
-proc abs*(x: int64): int64 {.magic: "AbsI", 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
+when defined(nimnomagic64):
+  proc abs*(x: int64): int64 {.magic: "AbsI", 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
+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.}
 
 when not defined(JS): #and not defined(NimrodVM):
diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim
index 907907e24..69c558799 100644
--- a/lib/system/arithm.nim
+++ b/lib/system/arithm.nim
@@ -18,7 +18,7 @@ proc raiseDivByZero {.compilerproc, noinline.} =
   sysFatal(DivByZeroError, "division by zero")
 
 when defined(builtinOverflow):
-# Builtin compiler functions for improved performance
+  # Builtin compiler functions for improved performance
   when sizeof(clong) == 8:
     proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
       importc: "__builtin_saddl_overflow", nodecl, nosideeffect.}