diff options
author | Parashurama <Rhagdamaziel@ymail.com> | 2017-06-05 17:25:04 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-06-05 17:25:04 +0200 |
commit | f603e1b268659085b8b9e51d55e78217bfe2e3c3 (patch) | |
tree | 4b6c12032c2a7bc993e46ed0a9357e4987366074 | |
parent | 2c5053caef531245cb976a2571a9aac42b63d000 (diff) | |
download | Nim-f603e1b268659085b8b9e51d55e78217bfe2e3c3.tar.gz |
fix logical right shift in VM. (#5916)
-rw-r--r-- | compiler/vmgen.nim | 18 | ||||
-rw-r--r-- | tests/arithm/tshr.nim | 2 |
2 files changed, 19 insertions, 1 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index c7d9be48c..ba89f88d4 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -826,7 +826,23 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = of mSubF64: genBinaryABC(c, n, dest, opcSubFloat) of mMulF64: genBinaryABC(c, n, dest, opcMulFloat) of mDivF64: genBinaryABC(c, n, dest, opcDivFloat) - of mShrI: genBinaryABCnarrowU(c, n, dest, opcShrInt) + of mShrI: + # the idea here is to narrow type if needed before executing right shift + # inlined modified: genNarrowU(c, n, dest) + let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) + # uint is uint64 in the VM, we we only need to mask the result for + # other unsigned types: + let tmp = c.genx(n.sons[1]) + if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32}: + c.gABC(n, opcNarrowU, tmp, TRegister(t.size*8)) + + # inlined modified: genBinaryABC(c, n, dest, opcShrInt) + let tmp2 = c.genx(n.sons[2]) + if dest < 0: dest = c.getTemp(n.typ) + c.gABC(n, opcShrInt, dest, tmp, tmp2) + c.freeTemp(tmp) + c.freeTemp(tmp2) + of mShlI: genBinaryABCnarrowU(c, n, dest, opcShlInt) of mBitandI: genBinaryABCnarrowU(c, n, dest, opcBitandInt) of mBitorI: genBinaryABCnarrowU(c, n, dest, opcBitorInt) diff --git a/tests/arithm/tshr.nim b/tests/arithm/tshr.nim index 09e6e570c..e9b72f1df 100644 --- a/tests/arithm/tshr.nim +++ b/tests/arithm/tshr.nim @@ -16,3 +16,5 @@ proc T() = T() +static: + T() |