summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorParashurama <Rhagdamaziel@ymail.com>2017-06-05 17:25:04 +0200
committerAndreas Rumpf <rumpf_a@web.de>2017-06-05 17:25:04 +0200
commitf603e1b268659085b8b9e51d55e78217bfe2e3c3 (patch)
tree4b6c12032c2a7bc993e46ed0a9357e4987366074
parent2c5053caef531245cb976a2571a9aac42b63d000 (diff)
downloadNim-f603e1b268659085b8b9e51d55e78217bfe2e3c3.tar.gz
fix logical right shift in VM. (#5916)
-rw-r--r--compiler/vmgen.nim18
-rw-r--r--tests/arithm/tshr.nim2
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()