+ if (src_type.floating) {
+ for (j = 0; j < dst_type.length / 4; ++j) {
+ /*
+ * XXX This is not actually fully correct. The float to int
+ * conversion will produce 0x80000000 value for everything
+ * out of range and NaNs (on x86, llvm.x86.sse2.cvtps2dq).
+ * Hence, NaNs and negatives will get clamped just fine to zero
+ * (relying on clamping pack behavior) when converting to unorm,
+ * however too large values (both finite and infinite) will also
+ * end up as zero, not 255.
+ * For snorm, for now we'll keep bug compatibility with generic
+ * conversion path (meaning too large values are fine, but
+ * NaNs get converted to -128 (purely by luck, as we don't
+ * specify nan behavior for the max there) instead of 0).
+ */
+ if (dst_type.sign) {
+ tmp[j] = lp_build_min(&bld, bld.one, src[j]);
+
+ }
+ else {
+ if (0) {
+ tmp[j] = lp_build_min_ext(&bld, bld.one, src[j],
+ GALLIVM_NAN_RETURN_NAN_FIRST_NONNAN);
+ }
+ tmp[j] = src[j];
+ }
+ tmp[j] = LLVMBuildFMul(builder, tmp[j], const_scale, "");
+ tmp[j] = lp_build_iround(&bld, tmp[j]);
+ }
+ } else {
+ for (j = 0; j < dst_type.length / 4; ++j) {
+ if (!dst_type.sign) {
+ /*
+ * Pack clamp is always signed->unsigned (or signed->signed).
+ * Hence need min.
+ */
+ LLVMValueRef const_max;
+ const_max = lp_build_const_int_vec(gallivm, src_type, 255);
+ tmp[j] = lp_build_min(&bld, src[j], const_max);
+ } else {
+ tmp[j] = src[j];
+ }
+ }