mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-09 14:32:53 +00:00
Add test
This commit is contained in:
@@ -489,17 +489,21 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
decodeB(rkFloat)
|
||||
regs[ra].floatVal = regs[rb].floatVal
|
||||
of opcAsgnIntFromFloat32:
|
||||
decodeB(rkFloat)
|
||||
let rb = instr.regB
|
||||
ensureKind(rkInt)
|
||||
regs[ra].intVal = cast[int32](float32(regs[rb].floatVal))
|
||||
of opcAsgnIntFromFloat64:
|
||||
decodeB(rkFloat)
|
||||
let rb = instr.regB
|
||||
ensureKind(rkInt)
|
||||
regs[ra].intVal = cast[int64](regs[rb].floatVal)
|
||||
of opcAsgnFloat32FromInt:
|
||||
decodeB(rkInt)
|
||||
let rb = instr.regB
|
||||
ensureKind(rkFloat)
|
||||
regs[ra].floatVal = cast[float32](int32(regs[rb].intVal))
|
||||
of opcAsgnFloat64FromInt:
|
||||
decodeB(rkInt)
|
||||
regs[ra].floatVal = cast[float64](int64(regs[rb].intVal))
|
||||
let rb = instr.regB
|
||||
ensureKind(rkFloat)
|
||||
regs[ra].floatVal = cast[float64](int64(regs[rb].intVal))
|
||||
of opcAsgnComplex:
|
||||
asgnComplex(regs[ra], regs[instr.regB])
|
||||
of opcAsgnRef:
|
||||
|
||||
@@ -811,8 +811,7 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
|
||||
c.freeTemp(tmp3)
|
||||
elif src_size == dst_size and src.kind in allowedIntegers and
|
||||
dst.kind in {tyFloat, tyFloat32, tyFloat64}:
|
||||
|
||||
let tmp = c.getTemp(n.sons[1].typ)
|
||||
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)
|
||||
@@ -821,15 +820,15 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
|
||||
c.freeTemp(tmp)
|
||||
|
||||
elif src_size == dst_size and src.kind in {tyFloat, tyFloat32, tyFloat64} and
|
||||
dst.kind in allowedIntegers:
|
||||
|
||||
let tmp = c.getTemp(n.sons[1].typ)
|
||||
dst.kind in allowedIntegers:
|
||||
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)
|
||||
else:
|
||||
c.gABC(n, opcAsgnIntFromFloat64, dest, tmp)
|
||||
c.freeTemp(tmp)
|
||||
|
||||
else:
|
||||
globalError(c.config, n.info, "VM is only allowed to 'cast' between integers and/or floats of same size")
|
||||
|
||||
|
||||
@@ -113,8 +113,55 @@ proc test() =
|
||||
doAssert(not compiles(cast[uint32](I8)))
|
||||
doAssert(not compiles(cast[uint64](I8)))
|
||||
|
||||
|
||||
proc test_float_cast =
|
||||
|
||||
const
|
||||
exp_bias = 1023'i64
|
||||
exp_shift = 52
|
||||
exp_mask = 0x7ff'i64 shl exp_shift
|
||||
mantissa_mask = 0xfffffffffffff'i64
|
||||
|
||||
let f = 8.0
|
||||
let fx = cast[int64](f)
|
||||
let exponent = ((fx and exp_mask) shr exp_shift) - exp_bias
|
||||
let mantissa = fx and mantissa_mask
|
||||
doAssert(exponent == 3, $exponent)
|
||||
doAssert(mantissa == 0, $mantissa)
|
||||
|
||||
# construct 2^N float, where N is integer
|
||||
let x = -2'i64
|
||||
let xx = (x + exp_bias) shl exp_shift
|
||||
let xf = cast[float](xx)
|
||||
doAssert(xf == 0.25, $xf)
|
||||
|
||||
proc test_float32_cast =
|
||||
|
||||
const
|
||||
exp_bias = 127'i32
|
||||
exp_shift = 23
|
||||
exp_mask = 0x7f800000'i32
|
||||
mantissa_mask = 0x007ffff'i32
|
||||
|
||||
let f = -0.5'f32
|
||||
let fx = cast[int32](f)
|
||||
let exponent = ((fx and exp_mask) shr exp_shift) - exp_bias
|
||||
let mantissa = fx and mantissa_mask
|
||||
doAssert(exponent == -1, $exponent)
|
||||
doAssert(mantissa == 0, $mantissa)
|
||||
|
||||
# construct 2^N float32 where N is integer
|
||||
let x = 4'i32
|
||||
let xx = (x + exp_bias) shl exp_shift
|
||||
let xf = cast[float32](xx)
|
||||
doAssert(xf == 16.0'f32, $xf)
|
||||
|
||||
test()
|
||||
test_float_cast()
|
||||
test_float32_cast()
|
||||
static:
|
||||
test()
|
||||
test_float_cast()
|
||||
test_float32_cast()
|
||||
|
||||
echo "OK"
|
||||
|
||||
Reference in New Issue
Block a user