#define INSTID(I) ctx->dump_printf( ctx, "% 3u", I )
#define SID(I) ctx->dump_printf( ctx, "%d", I )
#define FLT(F) ctx->dump_printf( ctx, "%10.4f", F )
+#define DBL(D) ctx->dump_printf( ctx, "%10.8f", D )
#define ENM(E,ENUMS) dump_enum( ctx, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) )
const char *
assert( num_tokens <= 4 );
for (i = 0; i < num_tokens; i++) {
switch (data_type) {
+ case TGSI_IMM_FLOAT64: {
+ union di d;
+ d.ui = data[i].Uint | (uint64_t)data[i+1].Uint << 32;
+ DBL( d.d );
+ i++;
+ break;
+ }
case TGSI_IMM_FLOAT32:
FLT( data[i].Float );
break;
return TRUE;
}
+static boolean parse_double( const char **pcur, uint32_t *val0, uint32_t *val1)
+{
+ const char *cur = *pcur;
+ union {
+ double dval;
+ uint32_t uval[2];
+ } v;
+
+ v.dval = strtod(cur, pcur);
+ if (*pcur == cur)
+ return FALSE;
+
+ *val0 = v.uval[0];
+ *val1 = v.uval[1];
+
+ return TRUE;
+}
+
struct translate_ctx
{
const char *text;
}
switch (type) {
+ case TGSI_IMM_FLOAT64:
+ ret = parse_double(&ctx->cur, &values[i].Uint, &values[i+1].Uint);
+ i++;
+ break;
case TGSI_IMM_FLOAT32:
ret = parse_float(&ctx->cur, &values[i].Float);
break;
return reg;
}
+static int
+match_or_expand_immediate64( const unsigned *v,
+ int type,
+ unsigned nr,
+ unsigned *v2,
+ unsigned *pnr2,
+ unsigned *swizzle )
+{
+ unsigned nr2 = *pnr2;
+ unsigned i, j;
+ *swizzle = 0;
+
+ for (i = 0; i < nr; i += 2) {
+ boolean found = FALSE;
+
+ for (j = 0; j < nr2 && !found; j += 2) {
+ if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) {
+ *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2));
+ found = TRUE;
+ }
+ }
+ if (!found) {
+ if ((nr2) >= 4) {
+ return FALSE;
+ }
+
+ v2[nr2] = v[i];
+ v2[nr2 + 1] = v[i + 1];
+
+ *swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2));
+ nr2 += 2;
+ }
+ }
+
+ /* Actually expand immediate only when fully succeeded.
+ */
+ *pnr2 = nr2;
+ return TRUE;
+}
+
static int
match_or_expand_immediate( const unsigned *v,
+ int type,
unsigned nr,
unsigned *v2,
unsigned *pnr2,
unsigned nr2 = *pnr2;
unsigned i, j;
+ if (type == TGSI_IMM_FLOAT64)
+ return match_or_expand_immediate64(v, type, nr, v2, pnr2, swizzle);
+
*swizzle = 0;
for (i = 0; i < nr; i++) {
continue;
}
if (match_or_expand_immediate(v,
+ type,
nr,
ureg->immediate[i].value.u,
&ureg->immediate[i].nr,
i = ureg->nr_immediates++;
ureg->immediate[i].type = type;
if (match_or_expand_immediate(v,
+ type,
nr,
ureg->immediate[i].value.u,
&ureg->immediate[i].nr,
/* Make sure that all referenced elements are from this immediate.
* Has the effect of making size-one immediates into scalars.
*/
- for (j = nr; j < 4; j++) {
- swizzle |= (swizzle & 0x3) << (j * 2);
+ if (type == TGSI_IMM_FLOAT64) {
+ for (j = nr; j < 4; j+=2) {
+ swizzle |= (swizzle & 0xf) << (j * 2);
+ }
+ } else {
+ for (j = nr; j < 4; j++) {
+ swizzle |= (swizzle & 0x3) << (j * 2);
+ }
}
-
return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
(swizzle >> 0) & 0x3,
(swizzle >> 2) & 0x3,
return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
}
+struct ureg_src
+ureg_DECL_immediate_f64( struct ureg_program *ureg,
+ const double *v,
+ unsigned nr )
+{
+ union {
+ unsigned u[4];
+ double d[2];
+ } fu;
+ unsigned int i;
+
+ assert((nr / 2) < 3);
+ for (i = 0; i < nr / 2; i++) {
+ fu.d[i] = v[i];
+ }
+
+ return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64);
+}
struct ureg_src
ureg_DECL_immediate_uint( struct ureg_program *ureg,