fix operators containing percent for VM usage (#13536)

* fixes #13513
* merge tarithmetics in tarithm
This commit is contained in:
Arne Döring
2020-03-11 01:01:25 +01:00
committed by GitHub
parent e64f1c7ee4
commit 2f557652d4
11 changed files with 165 additions and 137 deletions

View File

@@ -342,45 +342,6 @@ proc `xor`*(x, y: int16): int16 {.magic: "BitxorI", noSideEffect.}
proc `xor`*(x, y: int32): int32 {.magic: "BitxorI", noSideEffect.}
proc `xor`*(x, y: int64): int64 {.magic: "BitxorI", noSideEffect.}
type
IntMax32 = int|int8|int16|int32
proc `+%`*(x, y: IntMax32): IntMax32 {.magic: "AddU", noSideEffect.}
proc `+%`*(x, y: int64): int64 {.magic: "AddU", noSideEffect.}
## Treats `x` and `y` as unsigned and adds them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
proc `-%`*(x, y: IntMax32): IntMax32 {.magic: "SubU", noSideEffect.}
proc `-%`*(x, y: int64): int64 {.magic: "SubU", noSideEffect.}
## Treats `x` and `y` as unsigned and subtracts them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
proc `*%`*(x, y: IntMax32): IntMax32 {.magic: "MulU", noSideEffect.}
proc `*%`*(x, y: int64): int64 {.magic: "MulU", noSideEffect.}
## Treats `x` and `y` as unsigned and multiplies them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
proc `/%`*(x, y: IntMax32): IntMax32 {.magic: "DivU", noSideEffect.}
proc `/%`*(x, y: int64): int64 {.magic: "DivU", noSideEffect.}
## Treats `x` and `y` as unsigned and divides them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
proc `%%`*(x, y: IntMax32): IntMax32 {.magic: "ModU", noSideEffect.}
proc `%%`*(x, y: int64): int64 {.magic: "ModU", noSideEffect.}
## Treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
# unsigned integer operations:
proc `not`*(x: uint): uint {.magic: "BitnotI", noSideEffect.}
## Computes the `bitwise complement` of the integer `x`.
@@ -461,8 +422,60 @@ proc `mod`*(x, y: uint16): uint16 {.magic: "ModU", noSideEffect.}
proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
proc `+%`*(x, y: int): int {.inline.} =
## Treats `x` and `y` as unsigned and adds them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
cast[int](cast[uint](x) + cast[uint](y))
proc `+%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) + cast[uint8](y))
proc `+%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) + cast[uint16](y))
proc `+%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) + cast[uint32](y))
proc `+%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) + cast[uint64](y))
proc `-%`*(x, y: int): int {.inline.} =
## Treats `x` and `y` as unsigned and subtracts them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
cast[int](cast[uint](x) - cast[uint](y))
proc `-%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) - cast[uint8](y))
proc `-%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) - cast[uint16](y))
proc `-%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) - cast[uint32](y))
proc `-%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) - cast[uint64](y))
proc `*%`*(x, y: int): int {.inline.} =
## Treats `x` and `y` as unsigned and multiplies them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
cast[int](cast[uint](x) * cast[uint](y))
proc `*%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) * cast[uint8](y))
proc `*%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) * cast[uint16](y))
proc `*%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) * cast[uint32](y))
proc `*%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) * cast[uint64](y))
proc `/%`*(x, y: int): int {.inline.} =
## Treats `x` and `y` as unsigned and divides them.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
cast[int](cast[uint](x) div cast[uint](y))
proc `/%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) div cast[uint8](y))
proc `/%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) div cast[uint16](y))
proc `/%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) div cast[uint32](y))
proc `/%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) div cast[uint64](y))
proc `%%`*(x, y: int): int {.inline.} =
## Treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
##
## The result is truncated to fit into the result.
## This implements modulo arithmetic. No overflow errors are possible.
cast[int](cast[uint](x) mod cast[uint](y))
proc `%%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) mod cast[uint8](y))
proc `%%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) mod cast[uint16](y))
proc `%%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) mod cast[uint32](y))
proc `%%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) mod cast[uint64](y))
proc `+=`*[T: SomeInteger](x: var T, y: T) {.
magic: "Inc", noSideEffect.}

View File

@@ -161,16 +161,37 @@ proc `<`*(x, y: int16): bool {.magic: "LtI", noSideEffect.}
proc `<`*(x, y: int32): bool {.magic: "LtI", noSideEffect.}
proc `<`*(x, y: int64): bool {.magic: "LtI", noSideEffect.}
proc `<=`*(x, y: uint): bool {.magic: "LeU", noSideEffect.}
## Returns true if ``x <= y``.
proc `<=`*(x, y: uint8): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint16): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint32): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint64): bool {.magic: "LeU", noSideEffect.}
proc `<=%`*(x, y: IntMax32): bool {.magic: "LeU", noSideEffect.}
proc `<=%`*(x, y: int64): bool {.magic: "LeU64", noSideEffect.}
proc `<`*(x, y: uint): bool {.magic: "LtU", noSideEffect.}
## Returns true if ``x < y``.
proc `<`*(x, y: uint8): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint16): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint32): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint64): bool {.magic: "LtU", noSideEffect.}
proc `<=%`*(x, y: int): bool {.inline.} =
## Treats `x` and `y` as unsigned and compares them.
## Returns true if ``unsigned(x) <= unsigned(y)``.
cast[uint](x) <= cast[uint](y)
proc `<=%`*(x, y: int8): bool {.inline.} = cast[uint8](x) <= cast[uint8](y)
proc `<=%`*(x, y: int16): bool {.inline.} = cast[uint16](x) <= cast[uint16](y)
proc `<=%`*(x, y: int32): bool {.inline.} = cast[uint32](x) <= cast[uint32](y)
proc `<=%`*(x, y: int64): bool {.inline.} = cast[uint64](x) <= cast[uint64](y)
proc `<%`*(x, y: IntMax32): bool {.magic: "LtU", noSideEffect.}
proc `<%`*(x, y: int64): bool {.magic: "LtU64", noSideEffect.}
proc `<%`*(x, y: int): bool {.inline.} =
## Treats `x` and `y` as unsigned and compares them.
## Returns true if ``unsigned(x) < unsigned(y)``.
cast[uint](x) < cast[uint](y)
proc `<%`*(x, y: int8): bool {.inline.} = cast[uint8](x) < cast[uint8](y)
proc `<%`*(x, y: int16): bool {.inline.} = cast[uint16](x) < cast[uint16](y)
proc `<%`*(x, y: int32): bool {.inline.} = cast[uint32](x) < cast[uint32](y)
proc `<%`*(x, y: int64): bool {.inline.} = cast[uint64](x) < cast[uint64](y)
template `>=%`*(x, y: untyped): untyped = y <=% x
## Treats `x` and `y` as unsigned and compares them.
@@ -180,7 +201,6 @@ template `>%`*(x, y: untyped): untyped = y <% x
## Treats `x` and `y` as unsigned and compares them.
## Returns true if ``unsigned(x) > unsigned(y)``.
proc `==`*(x, y: uint): bool {.magic: "EqI", noSideEffect.}
## Compares two unsigned integers for equality.
proc `==`*(x, y: uint8): bool {.magic: "EqI", noSideEffect.}
@@ -189,21 +209,6 @@ proc `==`*(x, y: uint32): bool {.magic: "EqI", noSideEffect.}
proc `==`*(x, y: uint64): bool {.magic: "EqI", noSideEffect.}
proc `<=`*(x, y: uint): bool {.magic: "LeU", noSideEffect.}
## Returns true if ``x <= y``.
proc `<=`*(x, y: uint8): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint16): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint32): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint64): bool {.magic: "LeU", noSideEffect.}
proc `<`*(x, y: uint): bool {.magic: "LtU", noSideEffect.}
## Returns true if ``unsigned(x) < unsigned(y)``.
proc `<`*(x, y: uint8): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint16): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint32): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint64): bool {.magic: "LtU", noSideEffect.}
{.push stackTrace: off.}
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} =