mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-18 08:58:39 +00:00
VM: attempt to get integer ops right
This commit is contained in:
@@ -948,17 +948,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
of opcReset:
|
||||
internalError(c.debug[pc], "too implement")
|
||||
of opcNarrowS:
|
||||
decodeBC(rkInt)
|
||||
let min = -(1 shl (rc-1))
|
||||
let max = (1 shl (rc-1))-1
|
||||
if regs[rb].intVal >= min and regs[rb].intVal <= max:
|
||||
regs[ra].intVal = regs[rb].intVal
|
||||
else:
|
||||
decodeB(rkInt)
|
||||
let min = -(1 shl (rb-1))
|
||||
let max = (1 shl (rb-1))-1
|
||||
if regs[ra].intVal < min or regs[ra].intVal > max:
|
||||
stackTrace(c, tos, pc, errGenerated,
|
||||
msgKindToString(errUnhandledExceptionX) % "value out of range")
|
||||
of opcNarrowU:
|
||||
decodeBC(rkInt)
|
||||
regs[ra].intVal = regs[rb].intVal and ((1'i64 shl rc)-1)
|
||||
decodeB(rkInt)
|
||||
regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
|
||||
of opcIsNil:
|
||||
decodeB(rkInt)
|
||||
regs[ra].intVal = ord(regs[rb].node.kind == nkNilLit)
|
||||
|
||||
@@ -543,6 +543,30 @@ proc genBinaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
||||
c.freeTemp(tmp)
|
||||
c.freeTemp(tmp2)
|
||||
|
||||
proc genNarrow(c: PCtx; n: PNode; dest: TDest) =
|
||||
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:
|
||||
if t.kind in {tyUInt8..tyUInt32}:
|
||||
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
|
||||
elif t.kind in {tyInt8..tyInt32}:
|
||||
c.gABC(n, opcNarrowS, dest, TRegister(t.size*8))
|
||||
|
||||
proc genNarrowU(c: PCtx; n: PNode; dest: TDest) =
|
||||
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:
|
||||
if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32}:
|
||||
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
|
||||
|
||||
proc genBinaryABCnarrow(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
||||
genBinaryABC(c, n, dest, opc)
|
||||
genNarrow(c, n, dest)
|
||||
|
||||
proc genBinaryABCnarrowU(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
||||
genBinaryABC(c, n, dest, opc)
|
||||
genNarrowU(c, n, dest)
|
||||
|
||||
proc genSetType(c: PCtx; n: PNode; dest: TRegister) =
|
||||
let t = skipTypes(n.typ, abstractInst-{tyTypeDesc})
|
||||
if t.kind == tySet:
|
||||
@@ -604,6 +628,7 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
||||
c.freeTemp(tmp)
|
||||
else:
|
||||
genBinaryABC(c, n, dest, opc)
|
||||
c.genNarrow(n, dest)
|
||||
|
||||
proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =
|
||||
let tmp = c.genx(arg)
|
||||
@@ -644,6 +669,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||
let tmp = c.genx(n.sons[2])
|
||||
c.gABC(n, opc, d, d, tmp)
|
||||
c.freeTemp(tmp)
|
||||
c.genNarrow(n.sons[1], d)
|
||||
c.genAsgnPatch(n.sons[1], d)
|
||||
c.freeTemp(d)
|
||||
of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest)
|
||||
@@ -678,23 +704,23 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||
c.freeTemp(d)
|
||||
c.freeTemp(tmp)
|
||||
of mCard: genCard(c, n, dest)
|
||||
of mMulI, mMulI64: genBinaryABC(c, n, dest, opcMulInt)
|
||||
of mDivI, mDivI64: genBinaryABC(c, n, dest, opcDivInt)
|
||||
of mModI, mModI64: genBinaryABC(c, n, dest, opcModInt)
|
||||
of mMulI, mMulI64: genBinaryABCnarrow(c, n, dest, opcMulInt)
|
||||
of mDivI, mDivI64: genBinaryABCnarrow(c, n, dest, opcDivInt)
|
||||
of mModI, mModI64: genBinaryABCnarrow(c, n, dest, opcModInt)
|
||||
of mAddF64: genBinaryABC(c, n, dest, opcAddFloat)
|
||||
of mSubF64: genBinaryABC(c, n, dest, opcSubFloat)
|
||||
of mMulF64: genBinaryABC(c, n, dest, opcMulFloat)
|
||||
of mDivF64: genBinaryABC(c, n, dest, opcDivFloat)
|
||||
of mShrI, mShrI64: genBinaryABC(c, n, dest, opcShrInt)
|
||||
of mShlI, mShlI64: genBinaryABC(c, n, dest, opcShlInt)
|
||||
of mBitandI, mBitandI64: genBinaryABC(c, n, dest, opcBitandInt)
|
||||
of mBitorI, mBitorI64: genBinaryABC(c, n, dest, opcBitorInt)
|
||||
of mBitxorI, mBitxorI64: genBinaryABC(c, n, dest, opcBitxorInt)
|
||||
of mAddU: genBinaryABC(c, n, dest, opcAddu)
|
||||
of mSubU: genBinaryABC(c, n, dest, opcSubu)
|
||||
of mMulU: genBinaryABC(c, n, dest, opcMulu)
|
||||
of mDivU: genBinaryABC(c, n, dest, opcDivu)
|
||||
of mModU: genBinaryABC(c, n, dest, opcModu)
|
||||
of mShrI, mShrI64: genBinaryABCnarrowU(c, n, dest, opcShrInt)
|
||||
of mShlI, mShlI64: genBinaryABCnarrowU(c, n, dest, opcShlInt)
|
||||
of mBitandI, mBitandI64: genBinaryABCnarrowU(c, n, dest, opcBitandInt)
|
||||
of mBitorI, mBitorI64: genBinaryABCnarrowU(c, n, dest, opcBitorInt)
|
||||
of mBitxorI, mBitxorI64: genBinaryABCnarrowU(c, n, dest, opcBitxorInt)
|
||||
of mAddU: genBinaryABCnarrowU(c, n, dest, opcAddu)
|
||||
of mSubU: genBinaryABCnarrowU(c, n, dest, opcSubu)
|
||||
of mMulU: genBinaryABCnarrowU(c, n, dest, opcMulu)
|
||||
of mDivU: genBinaryABCnarrowU(c, n, dest, opcDivu)
|
||||
of mModU: genBinaryABCnarrowU(c, n, dest, opcModu)
|
||||
of mEqI, mEqI64, mEqB, mEqEnum, mEqCh:
|
||||
genBinaryABC(c, n, dest, opcEqInt)
|
||||
of mLeI, mLeI64, mLeEnum, mLeCh, mLeB:
|
||||
@@ -708,12 +734,16 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||
of mLtPtr, mLtU, mLtU64: genBinaryABC(c, n, dest, opcLtu)
|
||||
of mEqProc, mEqRef, mEqUntracedRef, mEqCString:
|
||||
genBinaryABC(c, n, dest, opcEqRef)
|
||||
of mXor: genBinaryABC(c, n, dest, opcXor)
|
||||
of mXor: genBinaryABCnarrowU(c, n, dest, opcXor)
|
||||
of mNot: genUnaryABC(c, n, dest, opcNot)
|
||||
of mUnaryMinusI, mUnaryMinusI64: genUnaryABC(c, n, dest, opcUnaryMinusInt)
|
||||
of mUnaryMinusI, mUnaryMinusI64:
|
||||
genUnaryABC(c, n, dest, opcUnaryMinusInt)
|
||||
genNarrow(c, n, dest)
|
||||
of mUnaryMinusF64: genUnaryABC(c, n, dest, opcUnaryMinusFloat)
|
||||
of mUnaryPlusI, mUnaryPlusI64, mUnaryPlusF64: gen(c, n.sons[1], dest)
|
||||
of mBitnotI, mBitnotI64: genUnaryABC(c, n, dest, opcBitnotInt)
|
||||
of mBitnotI, mBitnotI64:
|
||||
genUnaryABC(c, n, dest, opcBitnotInt)
|
||||
genNarrowU(c, n, dest)
|
||||
of mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64,
|
||||
mToU8, mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt,
|
||||
mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr,
|
||||
|
||||
4
todo.txt
4
todo.txt
@@ -2,9 +2,6 @@ version 0.9.4
|
||||
=============
|
||||
|
||||
- fix gensym capture bug
|
||||
- vm
|
||||
- at least try to get the basic type zoo ops right
|
||||
- optimize opcAsgnStr
|
||||
- fix GC issues
|
||||
|
||||
|
||||
@@ -39,6 +36,7 @@ version 0.9.x
|
||||
- ``=`` should be overloadable; requires specialization for ``=``; general
|
||||
lift mechanism in the compiler is already implemented for 'fields'
|
||||
- built-in 'getImpl'
|
||||
- VM: optimize opcAsgnStr
|
||||
|
||||
- change comment handling in the AST; that's lots of work as c2nim and pas2nim
|
||||
make use of the fact every node can have a comment!
|
||||
|
||||
Reference in New Issue
Block a user