# HG changeset patch # User Anders Halager # Date 1211739535 -7200 # Node ID 7d0898f77685d2ffc486bf5b207668eae979602e # Parent c0b531362ca688e14f873fe86990cebf776b6369 Implement the cast expression - works for integers and real/float/double diff -r c0b531362ca6 -r 7d0898f77685 gen/CodeGen.d --- a/gen/CodeGen.d Sun May 25 19:13:07 2008 +0200 +++ b/gen/CodeGen.d Sun May 25 20:18:55 2008 +0200 @@ -357,14 +357,13 @@ return RValue(r); case ExpType.CastExp: auto castExp = cast(CastExp)exp; - auto value = genExpression(castExp.exp).value; + exp = castExp.exp; + auto value = genExpression(exp); - if (!castExp.exp.type.hasImplicitConversionTo(castExp.type)) + if (!exp.type.hasImplicitConversionTo(castExp.type)) assert(0, "Invalid cast"); - Value v = buildCastLoad(castExp.exp.type, castExp.type, value); - - return RValue(v); + return genTypeCast(value, exp.type, castExp.type); case ExpType.Identifier: auto identifier = cast(Identifier)exp; @@ -400,7 +399,7 @@ { Operation op = t_a.getOperationWith(op2op(e.op), t_b); assert(op.isBuiltin(), - "integers should only use builtin ops"); + "numbers should only use builtin ops"); alias BuiltinOperation BO; BO val = op.builtinOp(); // map val to buildAdd or similar @@ -610,19 +609,6 @@ } } - /** - Given the address of something, load it into an alloc. - **/ - RValue loadLValue(LValue addr, char[] name = null) - { - Value val = addr.getAddress(); - if (name is null) - name = val.name.length > 0? val.name : "load"; - - auto res = b.buildLoad(val, name); - return RValue(res); - } - /* Get the address of an expression - allowing us to modify something in memory or on the stack. @@ -735,6 +721,57 @@ } /** + Generate the statements necessary to convert V, from type 'from' to type + 'to'. + **/ + RValue genTypeCast(RValue V, DType from, DType to) + { + Value delegate(Value, Type, char[]) extend, trunc; + if(auto ito = to.asInteger()) + { + extend = ito.unsigned? &b.buildZExt : &b.buildSExt; + trunc = &b.buildTrunc; + if(auto rfrom = from.isReal()) + { + extend = ito.unsigned? &b.buildFPToUI : &b.buildFPToSI; + trunc = extend; + } + } + else if (auto rto = to.asReal()) + { + extend = &b.buildFPExt; + trunc = &b.buildFPTrunc; + if(auto ifrom = from.isInteger()) + { + extend = rto.unsigned? &b.buildUIToFP : &b.buildSIToFP; + trunc = extend; + } + } + else + assert(0, "implicit cast need implimentation"); + + Value res; + if (from.byteSize() < to.byteSize()) + res = extend(V.value, llvm(to), "ext"); + else + res = trunc(V.value, llvm(to), "trunc"); + return RValue(res); + } + + /** + Given the address of something, load it into an alloc. + **/ + RValue loadLValue(LValue addr, char[] name = null) + { + Value val = addr.getAddress(); + if (name is null) + name = val.name.length > 0? val.name : "load"; + + auto res = b.buildLoad(val, name); + return RValue(res); + } + + /** Get the LLVM Type corresponding to a DType. Currently using the built-in associative array - not sure if it works @@ -830,25 +867,6 @@ assert(0, "Only integers, structs and functions are supported"); } - Value buildCastLoad(DType from, DType to, Value value) - { - if(typeof(from) == DInteger) - { - if(to == Type.Double) - return b.buildFPTrunc(value, llvm(_to), "fptrunc"); - if(to == Type.Float) - return b.buildFPTrunc(value, llvm(_to), "fptrunc"); - } - /* - if(from == Type.Int64) - if(castExp.exp.type.byteSize <= castExp.type.byteSize) - v = b.buildZExt(value, llvm(castExp.type), "zext"); - else - v = b.buildTrunc(value, llvm(castExp.type), "trunc"); - } -*/ - assert(0, "implicit cast need implimentation"); - } // Might as well insert all the basic types from the start void createBasicTypes() { diff -r c0b531362ca6 -r 7d0898f77685 sema/DType.d --- a/sema/DType.d Sun May 25 19:13:07 2008 +0200 +++ b/sema/DType.d Sun May 25 20:18:55 2008 +0200 @@ -252,7 +252,7 @@ override bool hasImplicitConversionTo(DType that) { - if (auto o = cast(DInteger)that) + if (that.isInteger() || that.isReal()) return true; return false; } @@ -270,9 +270,7 @@ override bool hasImplicitConversionTo(DType that) { - if (auto o = cast(DInteger)that) - return true; - if (auto o = cast(DReal)that) + if (that.isInteger() || that.isReal()) return true; return false; }