summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vm.nim8
-rw-r--r--compiler/vmdef.nim8
-rw-r--r--compiler/vmgen.nim14
-rw-r--r--tests/vm/tcastint.nim13
-rw-r--r--tools/nim-gdb.py8
5 files changed, 34 insertions, 17 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index b57db3aaa..40d12db97 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -550,19 +550,19 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcAsgnFloat:
       decodeB(rkFloat)
       regs[ra].floatVal = regs[rb].floatVal
-    of opcAsgnIntFromFloat32:
+    of opcCastFloatToInt32:
       let rb = instr.regB
       ensureKind(rkInt)
       regs[ra].intVal = cast[int32](float32(regs[rb].floatVal))
-    of opcAsgnIntFromFloat64:
+    of opcCastFloatToInt64:
       let rb = instr.regB
       ensureKind(rkInt)
       regs[ra].intVal = cast[int64](regs[rb].floatVal)
-    of opcAsgnFloat32FromInt:
+    of opcCastIntToFloat32:
       let rb = instr.regB
       ensureKind(rkFloat)
       regs[ra].floatVal = cast[float32](int32(regs[rb].intVal))
-    of opcAsgnFloat64FromInt:
+    of opcCastIntToFloat64:
       let rb = instr.regB
       ensureKind(rkFloat)
       regs[ra].floatVal = cast[float64](int64(regs[rb].intVal))
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index f530ceeb2..2f6cbcb85 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -33,11 +33,11 @@ type
     opcAsgnInt,
     opcAsgnFloat,
     opcAsgnRef,
-    opcAsgnIntFromFloat32,    # int and float must be of the same byte size
-    opcAsgnIntFromFloat64,    # int and float must be of the same byte size
-    opcAsgnFloat32FromInt,    # int and float must be of the same byte size
-    opcAsgnFloat64FromInt,    # int and float must be of the same byte size
     opcAsgnComplex,
+    opcCastIntToFloat32,    # int and float must be of the same byte size
+    opcCastIntToFloat64,    # int and float must be of the same byte size
+    opcCastFloatToInt32,    # int and float must be of the same byte size
+    opcCastFloatToInt64,    # int and float must be of the same byte size
     opcFastAsgnComplex,
     opcNodeToReg,
 
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 58e3a35eb..0b41fed28 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -843,9 +843,9 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
     let tmp = c.genx(n[1])
     if dest < 0: dest = c.getTemp(n[0].typ)
     if dst.kind == tyFloat32:
-      c.gABC(n, opcAsgnFloat32FromInt, dest, tmp)
+      c.gABC(n, opcCastIntToFloat32, dest, tmp)
     else:
-      c.gABC(n, opcAsgnFloat64FromInt, dest, tmp)
+      c.gABC(n, opcCastIntToFloat64, dest, tmp)
     c.freeTemp(tmp)
 
   elif srcSize == dstSize and src.kind in {tyFloat, tyFloat32, tyFloat64} and
@@ -853,11 +853,15 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
     let tmp = c.genx(n[1])
     if dest < 0: dest = c.getTemp(n[0].typ)
     if src.kind == tyFloat32:
-      c.gABC(n, opcAsgnIntFromFloat32, dest, tmp)
+      c.gABC(n, opcCastFloatToInt32, dest, tmp)
+      if dst.kind in unsignedIntegers:
+        # integers are sign extended by default.
+        # since there is no opcCastFloatToUInt32, narrowing should do the trick.
+        c.gABC(n, opcNarrowU, dest, TRegister(32))
     else:
-      c.gABC(n, opcAsgnIntFromFloat64, dest, tmp)
+      c.gABC(n, opcCastFloatToInt64, dest, tmp)
+      # narrowing for 64 bits not needed (no extended sign bits available).
     c.freeTemp(tmp)
-
   else:
     globalError(c.config, n.info, "VM is only allowed to 'cast' between integers and/or floats of same size")
 
diff --git a/tests/vm/tcastint.nim b/tests/vm/tcastint.nim
index c64dbc666..35d15b08b 100644
--- a/tests/vm/tcastint.nim
+++ b/tests/vm/tcastint.nim
@@ -281,14 +281,27 @@ proc test_float32_cast =
   let xf = cast[float32](xx)
   doAssert(xf == 16.0'f32, $xf)
 
+proc test_float32_castB() =
+  let a: float32 = -123.125
+  let b = cast[int32](a)
+  let c = cast[uint32](a)
+  doAssert b == -1024049152
+  doAssert cast[uint64](b) == 18446744072685502464'u64
+  doAssert c == 3270918144'u32
+  # ensure the unsused bits in the internal representation don't have
+  # any surprising content.
+  doAssert cast[uint64](c) == 3270918144'u64
+
 test()
 test_float_cast()
 test_float32_cast()
 free_integer_casting()
+test_float32_castB()
 static:
   test()
   test_float_cast()
   test_float32_cast()
   free_integer_casting()
+  test_float32_castB()
 
 echo "OK"
diff --git a/tools/nim-gdb.py b/tools/nim-gdb.py
index 7804ad6e5..76c504658 100644
--- a/tools/nim-gdb.py
+++ b/tools/nim-gdb.py
@@ -285,7 +285,7 @@ class NimStringPrinter:
      return ""
 
 class NimRopePrinter:
-  pattern = re.compile(r'^tyObject_RopeObj_OFzf0kSiPTcNreUIeJgWVA \*$')
+  pattern = re.compile(r'^tyObject_RopeObj__([A-Za-z0-9]*) \*$')
 
   def __init__(self, val):
     self.val = val
@@ -398,7 +398,7 @@ class NimSetPrinter:
 ################################################################################
 
 class NimHashSetPrinter:
-  pattern = re.compile(r'^tyObject_(HashSet)_([A-Za-z0-9]*)$')
+  pattern = re.compile(r'^tyObject_(HashSet)__([A-Za-z0-9]*)$')
 
   def __init__(self, val):
     self.val = val
@@ -475,7 +475,7 @@ class NimArrayPrinter:
 ################################################################################
 
 class NimStringTablePrinter:
-  pattern = re.compile(r'^tyObject_(StringTableObj)_([A-Za-z0-9]*)(:? \*)?$')
+  pattern = re.compile(r'^tyObject_(StringTableObj)__([A-Za-z0-9]*)(:? \*)?$')
 
   def __init__(self, val):
     self.val = val
@@ -504,7 +504,7 @@ class NimStringTablePrinter:
 ################################################################
 
 class NimTablePrinter:
-  pattern = re.compile(r'^tyObject_(Table)_([A-Za-z0-9]*)(:? \*)?$')
+  pattern = re.compile(r'^tyObject_(Table)__([A-Za-z0-9]*)(:? \*)?$')
 
   def __init__(self, val):
     self.val = val