553
expr.cpp
553
expr.cpp
@@ -93,6 +93,10 @@ lMaybeIssuePrecisionWarning(const AtomicType *toAtomicType,
|
||||
SourcePos pos, const char *errorMsgBase) {
|
||||
switch (toAtomicType->basicType) {
|
||||
case AtomicType::TYPE_BOOL:
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
@@ -101,6 +105,10 @@ lMaybeIssuePrecisionWarning(const AtomicType *toAtomicType,
|
||||
case AtomicType::TYPE_DOUBLE:
|
||||
if ((int)toAtomicType->basicType < (int)fromAtomicType->basicType &&
|
||||
toAtomicType->basicType != AtomicType::TYPE_BOOL &&
|
||||
!(toAtomicType->basicType == AtomicType::TYPE_INT8 &&
|
||||
fromAtomicType->basicType == AtomicType::TYPE_UINT8) &&
|
||||
!(toAtomicType->basicType == AtomicType::TYPE_INT16 &&
|
||||
fromAtomicType->basicType == AtomicType::TYPE_UINT16) &&
|
||||
!(toAtomicType->basicType == AtomicType::TYPE_INT32 &&
|
||||
fromAtomicType->basicType == AtomicType::TYPE_UINT32) &&
|
||||
!(toAtomicType->basicType == AtomicType::TYPE_INT64 &&
|
||||
@@ -363,15 +371,33 @@ lLLVMConstantValue(const Type *type, llvm::LLVMContext *ctx, double value) {
|
||||
return (value != 0.) ? LLVMTrue : LLVMFalse;
|
||||
else
|
||||
return LLVMBoolVector(value != 0.);
|
||||
case AtomicType::TYPE_UINT32: {
|
||||
case AtomicType::TYPE_INT8: {
|
||||
int i = (int)value;
|
||||
assert((double)i == value);
|
||||
return isUniform ? LLVMInt8(i) : LLVMInt8Vector(i);
|
||||
}
|
||||
case AtomicType::TYPE_UINT8: {
|
||||
unsigned int i = (unsigned int)value;
|
||||
return isUniform ? LLVMUInt32(i) : LLVMUInt32Vector(i);
|
||||
return isUniform ? LLVMUInt8(i) : LLVMUInt8Vector(i);
|
||||
}
|
||||
case AtomicType::TYPE_INT16: {
|
||||
int i = (int)value;
|
||||
assert((double)i == value);
|
||||
return isUniform ? LLVMInt16(i) : LLVMInt16Vector(i);
|
||||
}
|
||||
case AtomicType::TYPE_UINT16: {
|
||||
unsigned int i = (unsigned int)value;
|
||||
return isUniform ? LLVMUInt16(i) : LLVMUInt16Vector(i);
|
||||
}
|
||||
case AtomicType::TYPE_INT32: {
|
||||
int i = (int)value;
|
||||
assert((double)i == value);
|
||||
return isUniform ? LLVMInt32(i) : LLVMInt32Vector(i);
|
||||
}
|
||||
case AtomicType::TYPE_UINT32: {
|
||||
unsigned int i = (unsigned int)value;
|
||||
return isUniform ? LLVMUInt32(i) : LLVMUInt32Vector(i);
|
||||
}
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
return isUniform ? LLVMFloat((float)value) :
|
||||
LLVMFloatVector((float)value);
|
||||
@@ -590,14 +616,13 @@ UnaryExpr::Optimize() {
|
||||
const Type *type = constExpr->GetType();
|
||||
bool isEnumType = dynamic_cast<const EnumType *>(type) != NULL;
|
||||
|
||||
if (type == AtomicType::UniformInt64 ||
|
||||
type == AtomicType::VaryingInt64 ||
|
||||
type == AtomicType::UniformUInt64 ||
|
||||
type == AtomicType::VaryingUInt64 ||
|
||||
type == AtomicType::UniformConstInt64 ||
|
||||
type == AtomicType::VaryingConstInt64 ||
|
||||
type == AtomicType::UniformConstUInt64 ||
|
||||
type == AtomicType::VaryingConstUInt64)
|
||||
const Type *baseType = type->GetAsNonConstType()->GetAsUniformType();
|
||||
if (baseType == AtomicType::UniformInt8 ||
|
||||
baseType == AtomicType::UniformUInt8 ||
|
||||
baseType == AtomicType::UniformInt16 ||
|
||||
baseType == AtomicType::UniformUInt16 ||
|
||||
baseType == AtomicType::UniformInt64 ||
|
||||
baseType == AtomicType::UniformUInt64)
|
||||
// FIXME: should handle these at some point; for now we only do
|
||||
// constant folding for bool, int32 and float types...
|
||||
return this;
|
||||
@@ -3058,6 +3083,86 @@ MemberExpr::getCandidateNearMatches() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ConstExpr
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, int8_t i, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformConstInt8);
|
||||
int8Val[0] = i;
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, int8_t *i, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformConstInt8 ||
|
||||
type == AtomicType::VaryingConstInt8);
|
||||
for (int j = 0; j < Count(); ++j)
|
||||
int8Val[j] = i[j];
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, uint8_t u, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformUInt8);
|
||||
uint8Val[0] = u;
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, uint8_t *u, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformConstUInt8 ||
|
||||
type == AtomicType::VaryingConstUInt8);
|
||||
for (int j = 0; j < Count(); ++j)
|
||||
uint8Val[j] = u[j];
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, int16_t i, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformConstInt16);
|
||||
int16Val[0] = i;
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, int16_t *i, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformConstInt16 ||
|
||||
type == AtomicType::VaryingConstInt16);
|
||||
for (int j = 0; j < Count(); ++j)
|
||||
int16Val[j] = i[j];
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, uint16_t u, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformUInt16);
|
||||
uint16Val[0] = u;
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, uint16_t *u, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
type = type->GetAsConstType();
|
||||
assert(type == AtomicType::UniformConstUInt16 ||
|
||||
type == AtomicType::VaryingConstUInt16);
|
||||
for (int j = 0; j < Count(); ++j)
|
||||
uint16Val[j] = u[j];
|
||||
}
|
||||
|
||||
|
||||
ConstExpr::ConstExpr(const Type *t, int32_t i, SourcePos p)
|
||||
: Expr(p) {
|
||||
type = t;
|
||||
@@ -3212,6 +3317,22 @@ ConstExpr::ConstExpr(ConstExpr *old, double *v)
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
boolVal[i] = (v[i] != 0.);
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
int8Val[i] = (int)v[i];
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
uint8Val[i] = (unsigned int)v[i];
|
||||
break;
|
||||
case AtomicType::TYPE_INT16:
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
int16Val[i] = (int)v[i];
|
||||
break;
|
||||
case AtomicType::TYPE_UINT16:
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
uint16Val[i] = (unsigned int)v[i];
|
||||
break;
|
||||
case AtomicType::TYPE_INT32:
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
int32Val[i] = (int)v[i];
|
||||
@@ -3270,6 +3391,18 @@ ConstExpr::GetValue(FunctionEmitContext *ctx) const {
|
||||
return LLVMBoolVector(boolVal);
|
||||
else
|
||||
return boolVal[0] ? LLVMTrue : LLVMFalse;
|
||||
case AtomicType::TYPE_INT8:
|
||||
return isVarying ? LLVMInt8Vector(int8Val) :
|
||||
LLVMInt8(int8Val[0]);
|
||||
case AtomicType::TYPE_UINT8:
|
||||
return isVarying ? LLVMUInt8Vector(uint8Val) :
|
||||
LLVMUInt8(uint8Val[0]);
|
||||
case AtomicType::TYPE_INT16:
|
||||
return isVarying ? LLVMInt16Vector(int16Val) :
|
||||
LLVMInt16(int16Val[0]);
|
||||
case AtomicType::TYPE_UINT16:
|
||||
return isVarying ? LLVMUInt16Vector(uint16Val) :
|
||||
LLVMUInt16(uint16Val[0]);
|
||||
case AtomicType::TYPE_INT32:
|
||||
return isVarying ? LLVMInt32Vector(int32Val) :
|
||||
LLVMInt32(int32Val[0]);
|
||||
@@ -3351,6 +3484,10 @@ int
|
||||
ConstExpr::AsInt64(int64_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, ip, Count(), forceVarying); break;
|
||||
@@ -3368,6 +3505,10 @@ int
|
||||
ConstExpr::AsUInt64(uint64_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, up, Count(), forceVarying); break;
|
||||
@@ -3385,6 +3526,10 @@ int
|
||||
ConstExpr::AsDouble(double *d, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, d, Count(), forceVarying); break;
|
||||
@@ -3402,6 +3547,10 @@ int
|
||||
ConstExpr::AsFloat(float *fp, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, fp, Count(), forceVarying); break;
|
||||
@@ -3419,6 +3568,10 @@ int
|
||||
ConstExpr::AsBool(bool *b, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, b, Count(), forceVarying); break;
|
||||
@@ -3432,10 +3585,98 @@ ConstExpr::AsBool(bool *b, bool forceVarying) const {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt8(int8_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT64: lConvert(int64Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT64: lConvert(uint64Val, ip, Count(), forceVarying); break;
|
||||
default:
|
||||
FATAL("unimplemented const type");
|
||||
}
|
||||
return Count();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsUInt8(uint8_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT64: lConvert(int64Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT64: lConvert(uint64Val, up, Count(), forceVarying); break;
|
||||
default:
|
||||
FATAL("unimplemented const type");
|
||||
}
|
||||
return Count();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt16(int16_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT64: lConvert(int64Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT64: lConvert(uint64Val, ip, Count(), forceVarying); break;
|
||||
default:
|
||||
FATAL("unimplemented const type");
|
||||
}
|
||||
return Count();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsUInt16(uint16_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT64: lConvert(int64Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT64: lConvert(uint64Val, up, Count(), forceVarying); break;
|
||||
default:
|
||||
FATAL("unimplemented const type");
|
||||
}
|
||||
return Count();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt32(int32_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, ip, Count(), forceVarying); break;
|
||||
@@ -3453,6 +3694,10 @@ int
|
||||
ConstExpr::AsUInt32(uint32_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT8: lConvert(uint8Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT16: lConvert(int16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT32: lConvert(int32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_FLOAT: lConvert(floatVal, up, Count(), forceVarying); break;
|
||||
@@ -3488,6 +3733,40 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else
|
||||
return LLVMBoolVector(bv);
|
||||
}
|
||||
else if (type == AtomicType::UniformInt8 || type == AtomicType::VaryingInt8) {
|
||||
int8_t iv[ISPC_MAX_NVEC];
|
||||
AsInt8(iv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMInt8(iv[0]);
|
||||
else
|
||||
return LLVMInt8Vector(iv);
|
||||
}
|
||||
else if (type == AtomicType::UniformUInt8 || type == AtomicType::VaryingUInt8 ||
|
||||
dynamic_cast<const EnumType *>(type) != NULL) {
|
||||
uint8_t uiv[ISPC_MAX_NVEC];
|
||||
AsUInt8(uiv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMUInt8(uiv[0]);
|
||||
else
|
||||
return LLVMUInt8Vector(uiv);
|
||||
}
|
||||
else if (type == AtomicType::UniformInt16 || type == AtomicType::VaryingInt16) {
|
||||
int16_t iv[ISPC_MAX_NVEC];
|
||||
AsInt16(iv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMInt16(iv[0]);
|
||||
else
|
||||
return LLVMInt16Vector(iv);
|
||||
}
|
||||
else if (type == AtomicType::UniformUInt16 || type == AtomicType::VaryingUInt16 ||
|
||||
dynamic_cast<const EnumType *>(type) != NULL) {
|
||||
uint16_t uiv[ISPC_MAX_NVEC];
|
||||
AsUInt16(uiv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMUInt16(uiv[0]);
|
||||
else
|
||||
return LLVMUInt16Vector(uiv);
|
||||
}
|
||||
else if (type == AtomicType::UniformInt32 || type == AtomicType::VaryingInt32) {
|
||||
int32_t iv[ISPC_MAX_NVEC];
|
||||
AsInt32(iv, type->IsVaryingType());
|
||||
@@ -3564,6 +3843,18 @@ ConstExpr::Print() const {
|
||||
case AtomicType::TYPE_BOOL:
|
||||
printf("%s", boolVal[i] ? "true" : "false");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
printf("%d", (int)int8Val[i]);
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
printf("%u", (int)uint8Val[i]);
|
||||
break;
|
||||
case AtomicType::TYPE_INT16:
|
||||
printf("%d", (int)int16Val[i]);
|
||||
break;
|
||||
case AtomicType::TYPE_UINT16:
|
||||
printf("%u", (int)uint16Val[i]);
|
||||
break;
|
||||
case AtomicType::TYPE_INT32:
|
||||
printf("%d", int32Val[i]);
|
||||
break;
|
||||
@@ -3637,11 +3928,15 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
cast = ctx->CastInst(llvm::Instruction::UIToFP, // unsigned int
|
||||
exprVal, targetType, "bool2float");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_INT64:
|
||||
cast = ctx->CastInst(llvm::Instruction::SIToFP, // signed int to float
|
||||
exprVal, targetType, "int2float");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_UINT64:
|
||||
if (fromType->IsVaryingType())
|
||||
@@ -3675,11 +3970,15 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
cast = ctx->CastInst(llvm::Instruction::UIToFP, // unsigned int to double
|
||||
exprVal, targetType, "bool2double");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_INT64:
|
||||
cast = ctx->CastInst(llvm::Instruction::SIToFP, // signed int
|
||||
exprVal, targetType, "int2double");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_UINT64:
|
||||
if (fromType->IsVaryingType())
|
||||
@@ -3699,6 +3998,170 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_INT8: {
|
||||
LLVM_TYPE_CONST llvm::Type *targetType =
|
||||
fromType->IsUniformType() ? LLVMTypes::Int8Type :
|
||||
LLVMTypes::Int8VectorType;
|
||||
switch (fromType->basicType) {
|
||||
case AtomicType::TYPE_BOOL:
|
||||
if (fromType->IsVaryingType() &&
|
||||
LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2int");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_UINT8:
|
||||
cast = exprVal;
|
||||
break;
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_INT64:
|
||||
case AtomicType::TYPE_UINT64:
|
||||
cast = ctx->TruncInst(exprVal, targetType, "int64_to_int8");
|
||||
break;
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
|
||||
exprVal, targetType, "float2int");
|
||||
break;
|
||||
case AtomicType::TYPE_DOUBLE:
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
|
||||
exprVal, targetType, "double2int");
|
||||
break;
|
||||
default:
|
||||
FATAL("unimplemented");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_UINT8: {
|
||||
LLVM_TYPE_CONST llvm::Type *targetType =
|
||||
fromType->IsUniformType() ? LLVMTypes::Int8Type :
|
||||
LLVMTypes::Int8VectorType;
|
||||
switch (fromType->basicType) {
|
||||
case AtomicType::TYPE_BOOL:
|
||||
if (fromType->IsVaryingType() &&
|
||||
LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_UINT8:
|
||||
cast = exprVal;
|
||||
break;
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_INT64:
|
||||
case AtomicType::TYPE_UINT64:
|
||||
cast = ctx->TruncInst(exprVal, targetType, "int64_to_uint8");
|
||||
break;
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
if (fromType->IsVaryingType())
|
||||
PerformanceWarning(pos, "Conversion from float to unsigned int is slow. "
|
||||
"Use \"int\" if possible");
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
|
||||
exprVal, targetType, "float2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_DOUBLE:
|
||||
if (fromType->IsVaryingType())
|
||||
PerformanceWarning(pos, "Conversion from double to unsigned int is slow. "
|
||||
"Use \"int\" if possible");
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
|
||||
exprVal, targetType, "double2uint");
|
||||
break;
|
||||
default:
|
||||
FATAL("unimplemented");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_INT16: {
|
||||
LLVM_TYPE_CONST llvm::Type *targetType =
|
||||
fromType->IsUniformType() ? LLVMTypes::Int16Type :
|
||||
LLVMTypes::Int16VectorType;
|
||||
switch (fromType->basicType) {
|
||||
case AtomicType::TYPE_BOOL:
|
||||
if (fromType->IsVaryingType() &&
|
||||
LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2int");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
cast = ctx->SExtInst(exprVal, targetType, "int2int16");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint2uint16");
|
||||
break;
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
cast = exprVal;
|
||||
break;
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
|
||||
exprVal, targetType, "float2int");
|
||||
break;
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_INT64:
|
||||
case AtomicType::TYPE_UINT64:
|
||||
cast = ctx->TruncInst(exprVal, targetType, "int64_to_int16");
|
||||
break;
|
||||
case AtomicType::TYPE_DOUBLE:
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
|
||||
exprVal, targetType, "double2int");
|
||||
break;
|
||||
default:
|
||||
FATAL("unimplemented");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_UINT16: {
|
||||
LLVM_TYPE_CONST llvm::Type *targetType =
|
||||
fromType->IsUniformType() ? LLVMTypes::Int16Type :
|
||||
LLVMTypes::Int16VectorType;
|
||||
switch (fromType->basicType) {
|
||||
case AtomicType::TYPE_BOOL:
|
||||
if (fromType->IsVaryingType() &&
|
||||
LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2uint16");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
cast = ctx->SExtInst(exprVal, targetType, "uint2uint16");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint2uint16");
|
||||
break;
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
cast = exprVal;
|
||||
break;
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
if (fromType->IsVaryingType())
|
||||
PerformanceWarning(pos, "Conversion from float to unsigned int is slow. "
|
||||
"Use \"int\" if possible");
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
|
||||
exprVal, targetType, "float2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
case AtomicType::TYPE_INT64:
|
||||
case AtomicType::TYPE_UINT64:
|
||||
cast = ctx->TruncInst(exprVal, targetType, "int64_to_uint16");
|
||||
break;
|
||||
case AtomicType::TYPE_DOUBLE:
|
||||
if (fromType->IsVaryingType())
|
||||
PerformanceWarning(pos, "Conversion from double to unsigned int is slow. "
|
||||
"Use \"int\" if possible");
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
|
||||
exprVal, targetType, "double2uint");
|
||||
break;
|
||||
default:
|
||||
FATAL("unimplemented");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_INT32: {
|
||||
LLVM_TYPE_CONST llvm::Type *targetType =
|
||||
fromType->IsUniformType() ? LLVMTypes::Int32Type :
|
||||
@@ -3710,6 +4173,14 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2int");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
cast = ctx->SExtInst(exprVal, targetType, "int2int32");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint2uint32");
|
||||
break;
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
cast = exprVal;
|
||||
@@ -3742,6 +4213,14 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
cast = ctx->SExtInst(exprVal, targetType, "uint2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
cast = exprVal;
|
||||
@@ -3780,11 +4259,15 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2int64");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
cast = ctx->SExtInst(exprVal, targetType, "int32_to_int64");
|
||||
cast = ctx->SExtInst(exprVal, targetType, "int_to_int64");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint32_to_int64");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint_to_int64");
|
||||
break;
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
|
||||
@@ -3796,7 +4279,7 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
break;
|
||||
case AtomicType::TYPE_DOUBLE:
|
||||
cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
|
||||
exprVal, targetType, "double2int");
|
||||
exprVal, targetType, "double2int64");
|
||||
break;
|
||||
default:
|
||||
FATAL("unimplemented");
|
||||
@@ -3814,11 +4297,15 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, "bool_to_i1");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "bool2uint");
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_INT32:
|
||||
cast = ctx->SExtInst(exprVal, targetType, "int32_to_uint64");
|
||||
cast = ctx->SExtInst(exprVal, targetType, "int_to_uint64");
|
||||
break;
|
||||
case AtomicType::TYPE_UINT8:
|
||||
case AtomicType::TYPE_UINT16:
|
||||
case AtomicType::TYPE_UINT32:
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint32_to_uint64");
|
||||
cast = ctx->ZExtInst(exprVal, targetType, "uint_to_uint64");
|
||||
break;
|
||||
case AtomicType::TYPE_FLOAT:
|
||||
if (fromType->IsVaryingType())
|
||||
@@ -3848,6 +4335,22 @@ lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal,
|
||||
case AtomicType::TYPE_BOOL:
|
||||
cast = exprVal;
|
||||
break;
|
||||
case AtomicType::TYPE_INT8:
|
||||
case AtomicType::TYPE_UINT8: {
|
||||
llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt8(0) :
|
||||
(llvm::Value *)LLVMInt8Vector((int8_t)0);
|
||||
cast = ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
||||
exprVal, zero, "cmpi0");
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_INT16:
|
||||
case AtomicType::TYPE_UINT16: {
|
||||
llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt16(0) :
|
||||
(llvm::Value *)LLVMInt16Vector((int16_t)0);
|
||||
cast = ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
||||
exprVal, zero, "cmpi0");
|
||||
break;
|
||||
}
|
||||
case AtomicType::TYPE_INT32:
|
||||
case AtomicType::TYPE_UINT32: {
|
||||
llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt32(0) :
|
||||
@@ -4195,6 +4698,26 @@ TypeCastExpr::Optimize() {
|
||||
constExpr->AsBool(bv, forceVarying);
|
||||
return new ConstExpr(toType, bv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT8: {
|
||||
int8_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt8(iv, forceVarying);
|
||||
return new ConstExpr(toType, iv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_UINT8: {
|
||||
uint8_t uv[ISPC_MAX_NVEC];
|
||||
constExpr->AsUInt8(uv, forceVarying);
|
||||
return new ConstExpr(toType, uv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT16: {
|
||||
int16_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt16(iv, forceVarying);
|
||||
return new ConstExpr(toType, iv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_UINT16: {
|
||||
uint16_t uv[ISPC_MAX_NVEC];
|
||||
constExpr->AsUInt16(uv, forceVarying);
|
||||
return new ConstExpr(toType, uv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT32: {
|
||||
int32_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt32(iv, forceVarying);
|
||||
|
||||
Reference in New Issue
Block a user