diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index bcd9592e6..342bc520b 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -99,3 +99,4 @@ proc initDefines*() = defineSymbol("nimKnowsNimvm") defineSymbol("nimArrIdx") defineSymbol("nimImmediateDeprecated") + defineSymbol("nimNewShiftOps") diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 2fec8c757..641dc3304 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -243,7 +243,16 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType = proc makeOrType*(c: PContext, t1, t2: PType): PType = result = newTypeS(tyOr, c) - result.sons = @[t1, t2] + if t1.kind != tyOr and t2.kind != tyOr: + result.sons = @[t1, t2] + else: + template addOr(t1) = + if t1.kind == tyOr: + for x in t1.sons: result.rawAddSon x + else: + result.rawAddSon t1 + addOr(t1) + addOr(t2) propagateToOwner(result, t1) propagateToOwner(result, t2) result.flags.incl((t1.flags + t2.flags) * {tfHasStatic}) diff --git a/lib/system.nim b/lib/system.nim index 564117573..405d93f50 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -868,29 +868,43 @@ when defined(nimnomagic64): 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.} -proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.} -proc `shr` *(x, y: int64): int64 {.magic: "ShrI", noSideEffect.} - ## computes the `shift right` operation of `x` and `y`, filling - ## vacant bit positions with zeros. - ## - ## .. code-block:: Nim - ## 0b0001_0000'i8 shr 2 == 0b0000_0100'i8 - ## 0b1000_0000'i8 shr 8 == 0b0000_0000'i8 - ## 0b0000_0001'i8 shr 1 == 0b0000_0000'i8 +when defined(nimNewShiftOps): + proc `shr` *(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect.} + proc `shr` *(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect.} + proc `shr` *(x: int16, y: SomeInteger): int16 {.magic: "ShrI", noSideEffect.} + proc `shr` *(x: int32, y: SomeInteger): int32 {.magic: "ShrI", noSideEffect.} + proc `shr` *(x: int64, y: SomeInteger): int64 {.magic: "ShrI", noSideEffect.} + ## computes the `shift right` operation of `x` and `y`, filling + ## vacant bit positions with zeros. + ## + ## .. code-block:: Nim + ## 0b0001_0000'i8 shr 2 == 0b0000_0100'i8 + ## 0b1000_0000'i8 shr 8 == 0b0000_0000'i8 + ## 0b0000_0001'i8 shr 1 == 0b0000_0000'i8 -proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.} -proc `shl` *(x, y: int8): int8 {.magic: "ShlI", noSideEffect.} -proc `shl` *(x, y: int16): int16 {.magic: "ShlI", noSideEffect.} -proc `shl` *(x, y: int32): int32 {.magic: "ShlI", noSideEffect.} -proc `shl` *(x, y: int64): int64 {.magic: "ShlI", noSideEffect.} - ## computes the `shift left` operation of `x` and `y`. - ## - ## .. code-block:: Nim - ## 1'i32 shl 4 == 0x0000_0010 - ## 1'i64 shl 4 == 0x0000_0000_0000_0010 + + proc `shl` *(x: int, y: SomeInteger): int {.magic: "ShlI", noSideEffect.} + proc `shl` *(x: int8, y: SomeInteger): int8 {.magic: "ShlI", noSideEffect.} + proc `shl` *(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.} + proc `shl` *(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.} + proc `shl` *(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.} + ## computes the `shift left` operation of `x` and `y`. + ## + ## .. code-block:: Nim + ## 1'i32 shl 4 == 0x0000_0010 + ## 1'i64 shl 4 == 0x0000_0000_0000_0010 +else: + 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.} + proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.} + proc `shr` *(x, y: int64): int64 {.magic: "ShrI", noSideEffect.} + + proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.} + proc `shl` *(x, y: int8): int8 {.magic: "ShlI", noSideEffect.} + proc `shl` *(x, y: int16): int16 {.magic: "ShlI", noSideEffect.} + proc `shl` *(x, y: int32): int32 {.magic: "ShlI", noSideEffect.} + proc `shl` *(x, y: int64): int64 {.magic: "ShlI", noSideEffect.} proc `and` *(x, y: int): int {.magic: "BitandI", noSideEffect.} proc `and` *(x, y: int8): int8 {.magic: "BitandI", noSideEffect.} @@ -991,11 +1005,18 @@ proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.} proc `not`*[T: SomeUnsignedInt](x: T): T {.magic: "BitnotI", noSideEffect.} ## computes the `bitwise complement` of the integer `x`. -proc `shr`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShrI", noSideEffect.} - ## computes the `shift right` operation of `x` and `y`. +when defined(nimNewShiftOps): + proc `shr`*[T: SomeUnsignedInt](x: T, y: SomeInteger): T {.magic: "ShrI", noSideEffect.} + ## computes the `shift right` operation of `x` and `y`. -proc `shl`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShlI", noSideEffect.} - ## computes the `shift left` operation of `x` and `y`. + proc `shl`*[T: SomeUnsignedInt](x: T, y: SomeInteger): T {.magic: "ShlI", noSideEffect.} + ## computes the `shift left` operation of `x` and `y`. +else: + proc `shr`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShrI", noSideEffect.} + ## computes the `shift right` operation of `x` and `y`. + + proc `shl`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShlI", noSideEffect.} + ## computes the `shift left` operation of `x` and `y`. proc `and`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitandI", noSideEffect.} ## computes the `bitwise and` of numbers `x` and `y`.