Skip to content

Commit

Permalink
Merge pull request #3703 from ibuclaw/targetpaint
Browse files Browse the repository at this point in the history
Move CTFE paintFloatInt to Target::paintAsType
  • Loading branch information
WalterBright authored and 9rnsr committed Jul 7, 2014
1 parent 5f7cc0b commit 25403df
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 42 deletions.
45 changes: 3 additions & 42 deletions src/ctfeexpr.c
Expand Up @@ -23,6 +23,7 @@
#include "id.h"
#include "template.h"
#include "ctfe.h"
#include "target.h"

int RealEquals(real_t x1, real_t x2);

Expand Down Expand Up @@ -804,18 +805,6 @@ int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t of
return cmp;
}

union UnionFloatInt
{
float f;
d_int32 x;
};

union UnionDoubleLong
{
double f;
d_int64 x;
};

// True if conversion from type 'from' to 'to' involves a reinterpret_cast
// floating point -> integer or integer -> floating point
bool isFloatIntPaint(Type *to, Type *from)
Expand All @@ -831,36 +820,8 @@ Expression *paintFloatInt(Expression *fromVal, Type *to)
if (exceptionOrCantInterpret(fromVal))
return fromVal;

if (to->size() == 4)
{
UnionFloatInt u;
if (to->isintegral())
{
u.f = fromVal->toReal();
return new IntegerExp(fromVal->loc, (dinteger_t)ldouble(u.x), to);
}
else
{
u.x = (d_int32)fromVal->toInteger();
return new RealExp(fromVal->loc, ldouble(u.f), to);
}
}
else if (to->size() == 8)
{
UnionDoubleLong v;
if (to->isintegral())
{
v.f = fromVal->toReal();
return new IntegerExp(fromVal->loc, v.x, to);
}
else
{
v.x = fromVal->toInteger();
return new RealExp(fromVal->loc, ldouble(v.f), to);
}
}
assert(0);
return NULL; // avoid warning
assert(to->size() == 4 || to->size() == 8);
return Target::paintAsType(fromVal, to);
}


Expand Down
65 changes: 65 additions & 0 deletions src/target.c
Expand Up @@ -197,3 +197,68 @@ Type *Target::va_listType()
return NULL;
}
}

/******************************
* Encode the given expression, which is assumed to be an rvalue literal
* as another type for use in CTFE.
* This corresponds roughly to the idiom *(Type *)&e.
*/

Expression *Target::paintAsType(Expression *e, Type *type)
{
union
{
d_int32 int32value;
d_int64 int64value;
float float32value;
double float64value;
} u;

assert(e->type->size() == type->size());

switch (e->type->ty)
{
case Tint32:
case Tuns32:
u.int32value = e->toInteger();
break;

case Tint64:
case Tuns64:
u.int64value = e->toInteger();
break;

case Tfloat32:
u.float32value = e->toReal();
break;

case Tfloat64:
u.float64value = e->toReal();
break;

default:
assert(0);
}

switch (type->ty)
{
case Tint32:
case Tuns32:
return new IntegerExp(e->loc, u.int32value, type);

case Tint64:
case Tuns64:
return new IntegerExp(e->loc, u.int64value, type);

case Tfloat32:
return new RealExp(e->loc, ldouble(u.float32value), type);

case Tfloat64:
return new RealExp(e->loc, ldouble(u.float64value), type);

default:
assert(0);
}

return NULL; // avoid warning
}
2 changes: 2 additions & 0 deletions src/target.h
Expand Up @@ -16,6 +16,7 @@
// At present it is incomplete, but in future it should grow to contain
// most or all target machine and target O/S specific information.

class Expression;
class Type;

struct Target
Expand All @@ -32,6 +33,7 @@ struct Target
static unsigned fieldalign(Type* type);
static unsigned critsecsize();
static Type *va_listType(); // get type of va_list
static Expression *paintAsType(Expression *e, Type *type);
};

#endif

0 comments on commit 25403df

Please sign in to comment.