Thread overview
Re: [dmd-internals] Painting literals in CTFE
Aug 27, 2013
Iain Buclaw
Aug 28, 2013
Don Clugston
Aug 28, 2013
Iain Buclaw
Jul 02, 2014
Iain Buclaw
August 27, 2013
On 20 August 2013 13:03, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
> Hi,
>
> Question aimed vaguely at Don.
>
> The routine paintFloatInt in ctfeexpr.c is not portable across compilers (gdc implements its own way of painting float<->int, double<->long through something other than using a union).   Would it be possible to split this off somewhere, such as port.c/target.c - depending on how much of the front-end we need access to in order to carry out the operation?
>
>

Ping on this.


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

August 28, 2013
There are actually two operations being performed.
(1) Converting an IEEE float <-> int and double<->long.  This is 100%
portable. It does not depend on endianness. (Unless endianness of floating
point values is different from endianness of integer values, but I don't
think you could define BigEndian/LittleEndian in that case, so I'm not sure
that D could ever support such a system, and according to Wikipedia there
are no such systems which support IEEE754).

(2) Converting the compilers internal representation, into an IEEE float.
This is not portable.

In theory, CTFE only needs (1). But, because it is currently using the
compiler's internal representation, it's using (2).

I plan to move CTFE to a JIT-compatible implementation, which will mean it
will only be using (1) internally. But it will still need (2) when doing
the CTFE compile step.

Really what should happen is that (2) should be put into port.c/target.c. To some degree I'm waiting for the D port, when we will have defined sizes for builtin types.



On 27 August 2013 17:42, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> On 20 August 2013 13:03, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
> > Hi,
> >
> > Question aimed vaguely at Don.
> >
> > The routine paintFloatInt in ctfeexpr.c is not portable across compilers (gdc implements its own way of painting float<->int, double<->long through something other than using a union).   Would it be possible to split this off somewhere, such as port.c/target.c - depending on how much of the front-end we need access to in order to carry out the operation?
> >
> >
>
> Ping on this.
>
>
> --
> Iain Buclaw
>
> *(p < e ? p++ : p) = (c & 0x0f) + '0';
> _______________________________________________
> dmd-internals mailing list
> dmd-internals@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals
>


August 28, 2013
On 28 August 2013 10:18, Don Clugston <dclugston@gmail.com> wrote:
> There are actually two operations being performed.
> (1) Converting an IEEE float <-> int and double<->long.  This is 100%
> portable. It does not depend on endianness. (Unless endianness of floating
> point values is different from endianness of integer values, but I don't
> think you could define BigEndian/LittleEndian in that case, so I'm not sure
> that D could ever support such a system, and according to Wikipedia there
> are no such systems which support IEEE754).
>
> (2) Converting the compilers internal representation, into an IEEE float.
> This is not portable.
>
> In theory, CTFE only needs (1). But, because it is currently using the
> compiler's internal representation, it's using (2).
>
> I plan to move CTFE to a JIT-compatible implementation, which will mean it
> will only be using (1) internally. But it will still need (2) when doing the
> CTFE compile step.
>

My stance of course would be to avoid using IEEE floats directly, and instead perform all operation on an internal type in JIT (eg: std.numeric.CustomFloat as an example).

> Really what should happen is that (2) should be put into port.c/target.c. To some degree I'm waiting for the D port, when we will have defined sizes for builtin types.
>

OK, I propose port.c, as that is really where all compiler specific things should go...  However target.c does look more convenient.

---
assert(to->size() == 4 || to->size() == 8);
return Target::paintFloatInt(fromVal, to);
---

vs.

---
if (to->size() == 4)
{
    if (to->isintegral())
    {
        real_t f = fromVal->toReal();
        return new IntegerExp(fromVal->loc, Port::paintToInt(f), to);
    }
    else
    {
        dinteger_t x = fromVal->toInteger();
        return new RealExp(fromVal->loc, Port::paintToFloat(x), to);
    }
}
else if (to->size() == 8)
{
    if (to->isintegral())
    {
        real_t f = fromVal->toReal();
        return new IntegerExp(fromVal->loc, Port::paintToLong(f), to);
    }
    else
    {
        dinteger_t = fromVal->toInteger();
        return new RealExp(fromVal->loc, Port::paintToDouble(x), to);
    }
}

assert(0);
---



-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

July 02, 2014
On 28 August 2013 11:08, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
> On 28 August 2013 10:18, Don Clugston <dclugston@gmail.com> wrote:
>> There are actually two operations being performed.
>> (1) Converting an IEEE float <-> int and double<->long.  This is 100%
>> portable. It does not depend on endianness. (Unless endianness of floating
>> point values is different from endianness of integer values, but I don't
>> think you could define BigEndian/LittleEndian in that case, so I'm not sure
>> that D could ever support such a system, and according to Wikipedia there
>> are no such systems which support IEEE754).
>>
>> (2) Converting the compilers internal representation, into an IEEE float.
>> This is not portable.
>>
>> In theory, CTFE only needs (1). But, because it is currently using the
>> compiler's internal representation, it's using (2).
>>
>> I plan to move CTFE to a JIT-compatible implementation, which will mean it
>> will only be using (1) internally. But it will still need (2) when doing the
>> CTFE compile step.
>>
>
> My stance of course would be to avoid using IEEE floats directly, and instead perform all operation on an internal type in JIT (eg: std.numeric.CustomFloat as an example).
>
>> Really what should happen is that (2) should be put into port.c/target.c. To some degree I'm waiting for the D port, when we will have defined sizes for builtin types.
>>
>
> OK, I propose port.c, as that is really where all compiler specific things should go...  However target.c does look more convenient.
>
> ---
> assert(to->size() == 4 || to->size() == 8);
> return Target::paintFloatInt(fromVal, to);
> ---
>
> vs.
>
> ---
> if (to->size() == 4)
> {
>     if (to->isintegral())
>     {
>         real_t f = fromVal->toReal();
>         return new IntegerExp(fromVal->loc, Port::paintToInt(f), to);
>     }
>     else
>     {
>         dinteger_t x = fromVal->toInteger();
>         return new RealExp(fromVal->loc, Port::paintToFloat(x), to);
>     }
> }
> else if (to->size() == 8)
> {
>     if (to->isintegral())
>     {
>         real_t f = fromVal->toReal();
>         return new IntegerExp(fromVal->loc, Port::paintToLong(f), to);
>     }
>     else
>     {
>         dinteger_t = fromVal->toInteger();
>         return new RealExp(fromVal->loc, Port::paintToDouble(x), to);
>     }
> }
>
> assert(0);
> ---
>
>

I forgot that I ever wrote this...

Anyway, a year on and I got round to raising a PR:

https://github.com/D-Programming-Language/dmd/pull/3703
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals