diff options
author | Araq <rumpf_a@web.de> | 2018-01-03 02:36:49 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2018-01-03 02:36:49 +0100 |
commit | 49a00fe6ffa06a5aaa09915fbf918cc089ca2a67 (patch) | |
tree | ccbeeb08b1b9750df143b509f61858db059f14c4 /compiler | |
parent | 720c73e6d5c8b21a2d6d528a3a8947e498e9d1ad (diff) | |
parent | b7e69e7cbbf6139316841bcc7c596e93ac78d994 (diff) | |
download | Nim-49a00fe6ffa06a5aaa09915fbf918cc089ca2a67.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/extccomp.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 47 |
2 files changed, 46 insertions, 3 deletions
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 5299b2dbf..62990593d 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -253,7 +253,7 @@ compiler tcc: compilerExe: "tcc", cppCompiler: "", compileTmpl: "-c $options $include -o $objfile $file", - buildGui: "UNAVAILABLE!", + buildGui: "-Wl,-subsystem=gui", buildDll: " -shared", buildLib: "", # XXX: not supported yet linkerExe: "tcc", diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 3790a8392..17878b656 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -30,7 +30,7 @@ import strutils, ast, astalgo, types, msgs, renderer, vmdef, trees, intsets, rodread, magicsys, options, lowerings - +import platform from os import splitFile when hasFFI: @@ -761,6 +761,49 @@ proc genCard(c: PCtx; n: PNode; dest: var TDest) = c.gABC(n, opcCard, dest, tmp) c.freeTemp(tmp) +proc genIntCast(c: PCtx; n: PNode; dest: var TDest) = + const allowedIntegers = {tyInt..tyInt64, tyUInt..tyUInt64, tyChar} + var signedIntegers = {tyInt8..tyInt32} + var unsignedIntegers = {tyUInt8..tyUInt32, tyChar} + let src = n.sons[1].typ.skipTypes(abstractRange)#.kind + let dst = n.sons[0].typ.skipTypes(abstractRange)#.kind + let src_size = src.getSize + + if platform.intSize < 8: + signedIntegers.incl(tyInt) + unsignedIntegers.incl(tyUInt) + if src_size == dst.getSize and src.kind in allowedIntegers and + dst.kind in allowedIntegers: + let tmp = c.genx(n.sons[1]) + var tmp2 = c.getTemp(n.sons[1].typ) + let tmp3 = c.getTemp(n.sons[1].typ) + if dest < 0: dest = c.getTemp(n[0].typ) + proc mkIntLit(ival: int): int = + result = genLiteral(c, newIntTypeNode(nkIntLit, ival, getSysType(tyInt))) + if src.kind in unsignedIntegers and dst.kind in signedIntegers: + # cast unsigned to signed integer of same size + # signedVal = (unsignedVal xor offset) -% offset + let offset = 1 shl (src_size * 8 - 1) + c.gABx(n, opcLdConst, tmp2, mkIntLit(offset)) + c.gABC(n, opcBitxorInt, tmp3, tmp, tmp2) + c.gABC(n, opcSubInt, dest, tmp3, tmp2) + elif src.kind in signedIntegers and dst.kind in unsignedIntegers: + # cast signed to unsigned integer of same size + # unsignedVal = (offset +% signedVal +% 1) and offset + let offset = (1 shl (src_size * 8)) - 1 + c.gABx(n, opcLdConst, tmp2, mkIntLit(offset)) + c.gABx(n, opcLdConst, dest, mkIntLit(offset+1)) + c.gABC(n, opcAddu, tmp3, tmp, dest) + c.gABC(n, opcNarrowU, tmp3, TRegister(src_size*8)) + c.gABC(n, opcBitandInt, dest, tmp3, tmp2) + else: + c.gABC(n, opcAsgnInt, dest, tmp) + c.freeTemp(tmp) + c.freeTemp(tmp2) + c.freeTemp(tmp3) + else: + globalError(n.info, errGenerated, "VM is only allowed to 'cast' between integers of same size") + proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = case m of mAnd: c.genAndOr(n, opcFJmp, dest) @@ -1844,7 +1887,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = if allowCast in c.features: genConv(c, n, n.sons[1], dest, opcCast) else: - globalError(n.info, errGenerated, "VM is not allowed to 'cast'") + genIntCast(c, n, dest) of nkTypeOfExpr: genTypeLit(c, n.typ, dest) of nkComesFrom: |