* @author Jose Fonseca <jfonseca@vmware.com>
*/
+#include <float.h>
#include "util/u_debug.h"
#include "lp_bld_const.h"
+unsigned
+lp_mantissa(struct lp_type type)
+{
+ assert(type.floating);
+
+ if(type.floating) {
+ switch(type.width) {
+ case 32:
+ return 23;
+ case 64:
+ return 53;
+ default:
+ assert(0);
+ return 0;
+ }
+ }
+ else {
+ if(type.sign)
+ return type.width - 1;
+ else
+ return type.width;
+ }
+}
+
+
/**
* Shift of the unity.
*
* Same as lp_const_scale(), but in terms of shifts.
*/
unsigned
-lp_const_shift(union lp_type type)
+lp_const_shift(struct lp_type type)
{
if(type.floating)
return 0;
unsigned
-lp_const_offset(union lp_type type)
+lp_const_offset(struct lp_type type)
{
if(type.floating || type.fixed)
return 0;
* else for the fixed points types and normalized integers.
*/
double
-lp_const_scale(union lp_type type)
+lp_const_scale(struct lp_type type)
{
unsigned long long llscale;
double dscale;
}
+/**
+ * Minimum value representable by the type.
+ */
+double
+lp_const_min(struct lp_type type)
+{
+ unsigned bits;
+
+ if(!type.sign)
+ return 0.0;
+
+ if(type.norm)
+ return -1.0;
+
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return -FLT_MAX;
+ case 64:
+ return -DBL_MAX;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+
+ if(type.fixed)
+ /* FIXME: consider the fractional bits? */
+ bits = type.width / 2 - 1;
+ else
+ bits = type.width - 1;
+
+ return (double)-((long long)1 << bits);
+}
+
+
+/**
+ * Maximum value representable by the type.
+ */
+double
+lp_const_max(struct lp_type type)
+{
+ unsigned bits;
+
+ if(type.norm)
+ return 1.0;
+
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return FLT_MAX;
+ case 64:
+ return DBL_MAX;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+
+ if(type.fixed)
+ bits = type.width / 2;
+ else
+ bits = type.width;
+
+ if(type.sign)
+ bits -= 1;
+
+ return (double)(((unsigned long long)1 << bits) - 1);
+}
+
+
+double
+lp_const_eps(struct lp_type type)
+{
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return FLT_EPSILON;
+ case 64:
+ return DBL_EPSILON;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+ else {
+ double scale = lp_const_scale(type);
+ return 1.0/scale;
+ }
+}
+
+
LLVMValueRef
-lp_build_undef(union lp_type type)
+lp_build_undef(struct lp_type type)
{
LLVMTypeRef vec_type = lp_build_vec_type(type);
return LLVMGetUndef(vec_type);
LLVMValueRef
-lp_build_zero(union lp_type type)
+lp_build_zero(struct lp_type type)
{
LLVMTypeRef vec_type = lp_build_vec_type(type);
return LLVMConstNull(vec_type);
LLVMValueRef
-lp_build_one(union lp_type type)
+lp_build_one(struct lp_type type)
{
LLVMTypeRef elem_type;
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0);
else if(!type.norm)
elems[0] = LLVMConstInt(elem_type, 1, 0);
+ else if(type.sign)
+ elems[0] = LLVMConstInt(elem_type, (1LL << (type.width - 1)) - 1, 0);
else {
/* special case' -- 1.0 for normalized types is more easily attained if
* we start with a vector consisting of all bits set */
LLVMTypeRef vec_type = LLVMVectorType(elem_type, type.length);
LLVMValueRef vec = LLVMConstAllOnes(vec_type);
+#if 0
if(type.sign)
- vec = LLVMConstLShr(vec, LLVMConstInt(LLVMInt32Type(), 1, 0));
+ /* TODO: Unfortunately this caused "Tried to create a shift operation
+ * on a non-integer type!" */
+ vec = LLVMConstLShr(vec, lp_build_int_const_scalar(type, 1));
+#endif
return vec;
}
LLVMValueRef
-lp_build_const_uni(union lp_type type,
- double val)
+lp_build_const_scalar(struct lp_type type,
+ double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
LLVMValueRef
-lp_build_int_const_uni(union lp_type type,
- long long val)
+lp_build_int_const_scalar(struct lp_type type,
+ long long val)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
LLVMValueRef
-lp_build_const_aos(union lp_type type,
+lp_build_const_aos(struct lp_type type,
double r, double g, double b, double a,
const unsigned char *swizzle)
{
LLVMValueRef
-lp_build_const_mask_aos(union lp_type type,
- boolean cond[4])
+lp_build_const_mask_aos(struct lp_type type,
+ const boolean cond[4])
{
LLVMTypeRef elem_type = LLVMIntType(type.width);
LLVMValueRef masks[LP_MAX_VECTOR_LENGTH];