#include "translate.h"
-#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+#if (defined(PIPE_ARCH_X86) || (defined(PIPE_ARCH_X86_64) && !defined(__MINGW32__))) && !defined(PIPE_SUBSYSTEM_EMBEDDED)
#include "rtasm/rtasm_cpu.h"
#include "rtasm/rtasm_x86sse.h"
unsigned max_index;
};
-struct translate_buffer_varient {
+struct translate_buffer_variant {
unsigned buffer_index;
unsigned instance_divisor;
void *ptr; /* updated either per vertex or per instance */
#define ELEMENT_BUFFER_INSTANCE_ID 1001
+#define NUM_CONSTS 7
+
+enum
+{
+ CONST_IDENTITY,
+ CONST_INV_127,
+ CONST_INV_255,
+ CONST_INV_32767,
+ CONST_INV_65535,
+ CONST_INV_2147483647,
+ CONST_255
+};
+
+#define C(v) {(float)(v), (float)(v), (float)(v), (float)(v)}
+static float consts[NUM_CONSTS][4] = {
+ {0, 0, 0, 1},
+ C(1.0 / 127.0),
+ C(1.0 / 255.0),
+ C(1.0 / 32767.0),
+ C(1.0 / 65535.0),
+ C(1.0 / 2147483647.0),
+ C(255.0)
+};
+#undef C
struct translate_sse {
struct translate translate;
struct x86_function elt8_func;
struct x86_function *func;
- boolean loaded_identity;
- boolean loaded_const[5];
-
- float identity[4];
- float const_value[5][4];
+ PIPE_ALIGN_VAR(16) float consts[NUM_CONSTS][4];
+ int8_t reg_to_const[16];
+ int8_t const_to_reg[NUM_CONSTS];
struct translate_buffer buffer[PIPE_MAX_ATTRIBS];
unsigned nr_buffers;
- /* Multiple buffer varients can map to a single buffer. */
- struct translate_buffer_varient buffer_varient[PIPE_MAX_ATTRIBS];
- unsigned nr_buffer_varients;
+ /* Multiple buffer variants can map to a single buffer. */
+ struct translate_buffer_variant buffer_variant[PIPE_MAX_ATTRIBS];
+ unsigned nr_buffer_variants;
- /* Multiple elements can map to a single buffer varient. */
- unsigned element_to_buffer_varient[PIPE_MAX_ATTRIBS];
+ /* Multiple elements can map to a single buffer variant. */
+ unsigned element_to_buffer_variant[PIPE_MAX_ATTRIBS];
boolean use_instancing;
unsigned instance_id;
+ unsigned start_instance;
/* these are actually known values, but putting them in a struct
* like this is helpful to keep them in sync across the file.
return (const char *)b - (const char *)a;
}
-
-
-static struct x86_reg get_identity( struct translate_sse *p )
+static struct x86_reg get_const( struct translate_sse *p, unsigned id)
{
- struct x86_reg reg = x86_make_reg(file_XMM, 7);
-
- if (!p->loaded_identity) {
- p->loaded_identity = TRUE;
- p->identity[0] = 0;
- p->identity[1] = 0;
- p->identity[2] = 0;
- p->identity[3] = 1;
-
- sse_movups(p->func, reg,
- x86_make_disp(p->machine_EDI,
- get_offset(p, &p->identity[0])));
- }
+ struct x86_reg reg;
+ unsigned i;
- return reg;
-}
+ if(p->const_to_reg[id] >= 0)
+ return x86_make_reg(file_XMM, p->const_to_reg[id]);
-static struct x86_reg get_const( struct translate_sse *p, unsigned i, float v)
-{
- struct x86_reg reg = x86_make_reg(file_XMM, 2 + i);
-
- if (!p->loaded_const[i]) {
- p->loaded_const[i] = TRUE;
- p->const_value[i][0] =
- p->const_value[i][1] =
- p->const_value[i][2] =
- p->const_value[i][3] = v;
-
- sse_movups(p->func, reg,
- x86_make_disp(p->machine_EDI,
- get_offset(p, &p->const_value[i][0])));
+ for(i = 2; i < 8; ++i)
+ {
+ if(p->reg_to_const[i] < 0)
+ break;
}
- return reg;
-}
+ /* TODO: be smarter here */
+ if(i == 8)
+ --i;
-static struct x86_reg get_inv_127( struct translate_sse *p )
-{
- return get_const(p, 0, 1.0f / 127.0f);
-}
+ reg = x86_make_reg(file_XMM, i);
-static struct x86_reg get_inv_255( struct translate_sse *p )
-{
- return get_const(p, 1, 1.0f / 255.0f);
-}
+ if(p->reg_to_const[i] >= 0)
+ p->const_to_reg[p->reg_to_const[i]] = -1;
-static struct x86_reg get_inv_32767( struct translate_sse *p )
-{
- return get_const(p, 2, 1.0f / 32767.0f);
-}
+ p->reg_to_const[i] = id;
+ p->const_to_reg[id] = i;
-static struct x86_reg get_inv_65535( struct translate_sse *p )
-{
- return get_const(p, 3, 1.0f / 65535.0f);
-}
+ /* TODO: this should happen outside the loop, if possible */
+ sse_movaps(p->func, reg,
+ x86_make_disp(p->machine_EDI,
+ get_offset(p, &p->consts[id][0])));
-static struct x86_reg get_inv_2147483647( struct translate_sse *p )
-{
- return get_const(p, 4, 1.0f / 2147483647.0f);
+ return reg;
}
/* load the data in a SSE2 register, padding with zeros */
case 2:
x86_movzx16(p->func, tmp, src);
sse2_movd(p->func, data, tmp);
+ break;
case 3:
x86_movzx8(p->func, tmp, x86_make_disp(src, 2));
x86_shl_imm(p->func, tmp, 16);
x86_mov16(p->func, tmp, src);
sse2_movd(p->func, data, tmp);
+ break;
case 4:
sse2_movd(p->func, data, src);
break;
*/
sse_movss(p->func, data, arg0);
if(out_chans == CHANNELS_0001)
- sse_orps(p->func, data, get_identity(p) );
+ sse_orps(p->func, data, get_const(p, CONST_IDENTITY) );
break;
case 2:
/* 0 0 0 1
* a b 0 1
*/
if(out_chans == CHANNELS_0001)
- sse_shufps(p->func, data, get_identity(p), SHUF(X, Y, Z, W) );
+ sse_shufps(p->func, data, get_const(p, CONST_IDENTITY), SHUF(X, Y, Z, W) );
else if(out_chans > 2)
- sse_movlhps(p->func, data, get_identity(p) );
+ sse_movlhps(p->func, data, get_const(p, CONST_IDENTITY) );
sse_movlps(p->func, data, arg0);
break;
case 3:
*/
sse_movss(p->func, data, x86_make_disp(arg0, 8));
if(out_chans == CHANNELS_0001)
- sse_shufps(p->func, data, get_identity(p), SHUF(X,Y,Z,W) );
+ sse_shufps(p->func, data, get_const(p, CONST_IDENTITY), SHUF(X,Y,Z,W) );
sse_shufps(p->func, data, data, SHUF(Y,Z,X,W) );
sse_movlps(p->func, data, arg0);
break;
else
sse2_cvtsd2ss(p->func, data, data);
if(out_chans == CHANNELS_0001)
- sse_shufps(p->func, data, get_identity(p), SHUF(X, Y, Z, W) );
+ sse_shufps(p->func, data, get_const(p, CONST_IDENTITY), SHUF(X, Y, Z, W) );
break;
case 2:
sse2_movupd(p->func, data, arg0);
sse2_cvtpd2ps(p->func, data, data);
if(out_chans == CHANNELS_0001)
- sse_shufps(p->func, data, get_identity(p), SHUF(X, Y, Z, W) );
+ sse_shufps(p->func, data, get_const(p, CONST_IDENTITY), SHUF(X, Y, Z, W) );
else if(out_chans > 2)
- sse_movlhps(p->func, data, get_identity(p) );
+ sse_movlhps(p->func, data, get_const(p, CONST_IDENTITY) );
break;
case 3:
sse2_movupd(p->func, data, arg0);
sse2_cvtsd2ss(p->func, tmpXMM, tmpXMM);
sse_movlhps(p->func, data, tmpXMM);
if(out_chans == CHANNELS_0001)
- sse_orps(p->func, data, get_identity(p) );
+ sse_orps(p->func, data, get_const(p, CONST_IDENTITY) );
break;
case 4:
sse2_movupd(p->func, data, arg0);
{
case 8:
/* TODO: this may be inefficient due to get_identity() being used both as a float and integer register */
- sse2_punpcklbw(p->func, dataXMM, get_identity(p));
- sse2_punpcklbw(p->func, dataXMM, get_identity(p));
+ sse2_punpcklbw(p->func, dataXMM, get_const(p, CONST_IDENTITY));
+ sse2_punpcklbw(p->func, dataXMM, get_const(p, CONST_IDENTITY));
break;
case 16:
- sse2_punpcklwd(p->func, dataXMM, get_identity(p));
+ sse2_punpcklwd(p->func, dataXMM, get_const(p, CONST_IDENTITY));
break;
case 32: /* we lose precision here */
sse2_psrld_imm(p->func, dataXMM, 1);
switch(input_desc->channel[0].size)
{
case 8:
- factor = get_inv_255(p);
+ factor = get_const(p, CONST_INV_255);
break;
case 16:
- factor = get_inv_65535(p);
+ factor = get_const(p, CONST_INV_65535);
break;
case 32:
- factor = get_inv_2147483647(p);
+ factor = get_const(p, CONST_INV_2147483647);
+ break;
+ default:
+ assert(0);
+ factor.disp = 0;
+ factor.file = 0;
+ factor.idx = 0;
+ factor.mod = 0;
break;
}
sse_mulps(p->func, dataXMM, factor);
switch(input_desc->channel[0].size)
{
case 8:
- factor = get_inv_127(p);
+ factor = get_const(p, CONST_INV_127);
break;
case 16:
- factor = get_inv_32767(p);
+ factor = get_const(p, CONST_INV_32767);
break;
case 32:
- factor = get_inv_2147483647(p);
+ factor = get_const(p, CONST_INV_2147483647);
+ break;
+ default:
+ assert(0);
+ factor.disp = 0;
+ factor.file = 0;
+ factor.idx = 0;
+ factor.mod = 0;
break;
}
sse_mulps(p->func, dataXMM, factor);
sse2_psrlw_imm(p->func, dataXMM, 1);
}
else
- sse2_punpcklbw(p->func, dataXMM, get_identity(p));
+ sse2_punpcklbw(p->func, dataXMM, get_const(p, CONST_IDENTITY));
break;
case UTIL_FORMAT_TYPE_SIGNED:
if(input_desc->channel[0].normalized)
{
- sse2_movq(p->func, tmpXMM, get_identity(p));
+ sse2_movq(p->func, tmpXMM, get_const(p, CONST_IDENTITY));
sse2_punpcklbw(p->func, tmpXMM, dataXMM);
sse2_psllw_imm(p->func, dataXMM, 9);
sse2_psrlw_imm(p->func, dataXMM, 8);
}
return TRUE;
}
+ /* special case for draw's EMIT_4UB (RGBA) and EMIT_4UB_BGRA */
+ else if((x86_target_caps(p->func) & X86_SSE2) &&
+ a->input_format == PIPE_FORMAT_R32G32B32A32_FLOAT && (0
+ || a->output_format == PIPE_FORMAT_B8G8R8A8_UNORM
+ || a->output_format == PIPE_FORMAT_R8G8B8A8_UNORM
+ ))
+ {
+ struct x86_reg dataXMM = x86_make_reg(file_XMM, 0);
+
+ /* load */
+ sse_movups(p->func, dataXMM, src);
+
+ if (a->output_format == PIPE_FORMAT_B8G8R8A8_UNORM)
+ sse_shufps(p->func, dataXMM, dataXMM, SHUF(2,1,0,3));
+
+ /* scale by 255.0 */
+ sse_mulps(p->func, dataXMM, get_const(p, CONST_255));
+
+ /* pack and emit */
+ sse2_cvtps2dq(p->func, dataXMM, dataXMM);
+ sse2_packssdw(p->func, dataXMM, dataXMM);
+ sse2_packuswb(p->func, dataXMM, dataXMM);
+ sse2_movd(p->func, dst, dataXMM);
+
+ return TRUE;
+ }
+
return FALSE;
}
unsigned i;
struct x86_reg instance_id = x86_make_disp(p->machine_EDI,
get_offset(p, &p->instance_id));
+ struct x86_reg start_instance = x86_make_disp(p->machine_EDI,
+ get_offset(p, &p->start_instance));
- for (i = 0; i < p->nr_buffer_varients; i++) {
- struct translate_buffer_varient *varient = &p->buffer_varient[i];
- struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
+ for (i = 0; i < p->nr_buffer_variants; i++) {
+ struct translate_buffer_variant *variant = &p->buffer_variant[i];
+ struct translate_buffer *buffer = &p->buffer[variant->buffer_index];
- if (!index_size || varient->instance_divisor) {
+ if (!index_size || variant->instance_divisor) {
+ struct x86_reg buf_max_index = x86_make_disp(p->machine_EDI,
+ get_offset(p, &buffer->max_index));
struct x86_reg buf_stride = x86_make_disp(p->machine_EDI,
get_offset(p, &buffer->stride));
struct x86_reg buf_ptr = x86_make_disp(p->machine_EDI,
- get_offset(p, &varient->ptr));
+ get_offset(p, &variant->ptr));
struct x86_reg buf_base_ptr = x86_make_disp(p->machine_EDI,
get_offset(p, &buffer->base_ptr));
struct x86_reg elt = p->idx_ESI;
/* Calculate pointer to first attrib:
* base_ptr + stride * index, where index depends on instance divisor
*/
- if (varient->instance_divisor) {
- /* Our index is instance ID divided by instance divisor.
+ if (variant->instance_divisor) {
+ /* Start with instance = instance_id
+ * which is true if divisor is 1.
*/
x86_mov(p->func, tmp_EAX, instance_id);
- if (varient->instance_divisor != 1) {
+ if (variant->instance_divisor != 1) {
struct x86_reg tmp_EDX = p->tmp2_EDX;
struct x86_reg tmp_ECX = p->src_ECX;
+ /* instance_num = instance_id - start_instance */
+ x86_mov(p->func, tmp_EDX, start_instance);
+ x86_sub(p->func, tmp_EAX, tmp_EDX);
+
/* TODO: Add x86_shr() to rtasm and use it whenever
* instance divisor is power of two.
*/
-
x86_xor(p->func, tmp_EDX, tmp_EDX);
- x86_mov_reg_imm(p->func, tmp_ECX, varient->instance_divisor);
+ x86_mov_reg_imm(p->func, tmp_ECX, variant->instance_divisor);
x86_div(p->func, tmp_ECX); /* EAX = EDX:EAX / ECX */
+
+ /* instance = (instance_id - start_instance) / divisor +
+ * start_instance
+ */
+ x86_mov(p->func, tmp_EDX, start_instance);
+ x86_add(p->func, tmp_EAX, tmp_EDX);
}
+
+ /* XXX we need to clamp the index here too, but to a
+ * per-array max value, not the draw->pt.max_index value
+ * that's being given to us via translate->set_buffer().
+ */
} else {
x86_mov(p->func, tmp_EAX, elt);
- }
- /*
- * TODO: Respect translate_buffer::max_index.
- */
+ /* Clamp to max_index
+ */
+ x86_cmp(p->func, tmp_EAX, buf_max_index);
+ x86_cmovcc(p->func, tmp_EAX, buf_max_index, cc_AE);
+ }
x86_imul(p->func, tmp_EAX, buf_stride);
x64_rexw(p->func);
x86_add(p->func, tmp_EAX, buf_base_ptr);
+ x86_cmp(p->func, p->count_EBP, p->tmp_EAX);
/* In the linear case, keep the buffer pointer instead of the
* index number.
*/
- if (!index_size && p->nr_buffer_varients == 1)
+ if (!index_size && p->nr_buffer_variants == 1)
{
x64_rexw(p->func);
x86_mov(p->func, elt, tmp_EAX);
return x86_make_disp(p->machine_EDI,
get_offset(p, &p->instance_id));
}
- if (!index_size && p->nr_buffer_varients == 1) {
+ if (!index_size && p->nr_buffer_variants == 1) {
return p->idx_ESI;
}
- else if (!index_size || p->buffer_varient[var_idx].instance_divisor) {
+ else if (!index_size || p->buffer_variant[var_idx].instance_divisor) {
struct x86_reg ptr = p->src_ECX;
struct x86_reg buf_ptr =
x86_make_disp(p->machine_EDI,
- get_offset(p, &p->buffer_varient[var_idx].ptr));
+ get_offset(p, &p->buffer_variant[var_idx].ptr));
x64_rexw(p->func);
x86_mov(p->func, ptr, buf_ptr);
}
else {
struct x86_reg ptr = p->src_ECX;
- const struct translate_buffer_varient *varient = &p->buffer_varient[var_idx];
+ const struct translate_buffer_variant *variant = &p->buffer_variant[var_idx];
struct x86_reg buf_stride =
x86_make_disp(p->machine_EDI,
- get_offset(p, &p->buffer[varient->buffer_index].stride));
+ get_offset(p, &p->buffer[variant->buffer_index].stride));
struct x86_reg buf_base_ptr =
x86_make_disp(p->machine_EDI,
- get_offset(p, &p->buffer[varient->buffer_index].base_ptr));
+ get_offset(p, &p->buffer[variant->buffer_index].base_ptr));
+
+ struct x86_reg buf_max_index =
+ x86_make_disp(p->machine_EDI,
+ get_offset(p, &p->buffer[variant->buffer_index].max_index));
x86_mov(p->func, ptr, elt);
break;
}
+
+ /* Clamp to max_index
+ */
+ x86_cmp(p->func, ptr, buf_max_index);
+ x86_cmovcc(p->func, ptr, buf_max_index, cc_AE);
+
x86_imul(p->func, ptr, buf_stride);
x64_rexw(p->func);
x86_add(p->func, ptr, buf_base_ptr);
static boolean incr_inputs( struct translate_sse *p,
unsigned index_size )
{
- if (!index_size && p->nr_buffer_varients == 1) {
+ if (!index_size && p->nr_buffer_variants == 1) {
struct x86_reg stride = x86_make_disp(p->machine_EDI,
get_offset(p, &p->buffer[0].stride));
- if (p->buffer_varient[0].instance_divisor == 0) {
+ if (p->buffer_variant[0].instance_divisor == 0) {
x64_rexw(p->func);
x86_add(p->func, p->idx_ESI, stride);
sse_prefetchnta(p->func, x86_make_disp(p->idx_ESI, 192));
/* Is this worthwhile??
*/
- for (i = 0; i < p->nr_buffer_varients; i++) {
- struct translate_buffer_varient *varient = &p->buffer_varient[i];
+ for (i = 0; i < p->nr_buffer_variants; i++) {
+ struct translate_buffer_variant *variant = &p->buffer_variant[i];
struct x86_reg buf_ptr = x86_make_disp(p->machine_EDI,
- get_offset(p, &varient->ptr));
+ get_offset(p, &variant->ptr));
struct x86_reg buf_stride = x86_make_disp(p->machine_EDI,
- get_offset(p, &p->buffer[varient->buffer_index].stride));
+ get_offset(p, &p->buffer[variant->buffer_index].stride));
- if (varient->instance_divisor == 0) {
+ if (variant->instance_divisor == 0) {
x86_mov(p->func, p->tmp_EAX, buf_stride);
x64_rexw(p->func);
x86_add(p->func, p->tmp_EAX, buf_ptr);
}
}
else {
+ x64_rexw(p->func);
x86_lea(p->func, p->idx_ESI, x86_make_disp(p->idx_ESI, index_size));
}
int fixup, label;
unsigned j;
+ memset(p->reg_to_const, 0xff, sizeof(p->reg_to_const));
+ memset(p->const_to_reg, 0xff, sizeof(p->const_to_reg));
+
p->tmp_EAX = x86_make_reg(file_REG32, reg_AX);
p->idx_ESI = x86_make_reg(file_REG32, reg_SI);
p->outbuf_EBX = x86_make_reg(file_REG32, reg_BX);
p->src_ECX = x86_make_reg(file_REG32, reg_CX);
p->func = func;
- memset(&p->loaded_const, 0, sizeof(p->loaded_const));
- p->loaded_identity = FALSE;
x86_init_func(p->func);
x86_mov(p->func, p->count_EBP, x86_fn_arg(p->func, 3));
if(x86_target(p->func) != X86_32)
- x64_mov64(p->func, p->outbuf_EBX, x86_fn_arg(p->func, 5));
+ x64_mov64(p->func, p->outbuf_EBX, x86_fn_arg(p->func, 6));
else
- x86_mov(p->func, p->outbuf_EBX, x86_fn_arg(p->func, 5));
+ x86_mov(p->func, p->outbuf_EBX, x86_fn_arg(p->func, 6));
/* Load instance ID.
*/
- if (p->use_instancing) {
+ if (p->use_instancing) {
x86_mov(p->func,
- p->tmp_EAX,
+ p->tmp2_EDX,
x86_fn_arg(p->func, 4));
+ x86_mov(p->func,
+ x86_make_disp(p->machine_EDI, get_offset(p, &p->start_instance)),
+ p->tmp2_EDX);
+
+ x86_mov(p->func,
+ p->tmp_EAX,
+ x86_fn_arg(p->func, 5));
x86_mov(p->func,
x86_make_disp(p->machine_EDI, get_offset(p, &p->instance_id)),
p->tmp_EAX);
label = x86_get_label(p->func);
{
struct x86_reg elt = !index_size ? p->idx_ESI : x86_deref(p->idx_ESI);
- int last_varient = -1;
+ int last_variant = -1;
struct x86_reg vb;
for (j = 0; j < p->translate.key.nr_elements; j++) {
const struct translate_element *a = &p->translate.key.element[j];
- unsigned varient = p->element_to_buffer_varient[j];
+ unsigned variant = p->element_to_buffer_variant[j];
/* Figure out source pointer address:
*/
- if (varient != last_varient) {
- last_varient = varient;
- vb = get_buffer_ptr(p, index_size, varient, elt);
+ if (variant != last_variant) {
+ last_variant = variant;
+ vb = get_buffer_ptr(p, index_size, variant, elt);
}
if (!translate_attr( p, a,
{
struct translate_sse *p = (struct translate_sse *)translate;
- x86_release_func( &p->linear_func );
+ x86_release_func( &p->elt8_func );
+ x86_release_func( &p->elt16_func );
x86_release_func( &p->elt_func );
+ x86_release_func( &p->linear_func );
- FREE(p);
+ os_free_aligned(p);
}
if (!rtasm_cpu_has_sse())
goto fail;
- p = CALLOC_STRUCT( translate_sse );
+ p = os_malloc_aligned(sizeof(struct translate_sse), 16);
if (p == NULL)
goto fail;
+ memset(p, 0, sizeof(*p));
+ memcpy(p->consts, consts, sizeof(consts));
p->translate.key = *key;
p->translate.release = translate_sse_release;
}
/*
- * Map vertex element to vertex buffer varient.
+ * Map vertex element to vertex buffer variant.
*/
- for (j = 0; j < p->nr_buffer_varients; j++) {
- if (p->buffer_varient[j].buffer_index == key->element[i].input_buffer &&
- p->buffer_varient[j].instance_divisor == key->element[i].instance_divisor) {
+ for (j = 0; j < p->nr_buffer_variants; j++) {
+ if (p->buffer_variant[j].buffer_index == key->element[i].input_buffer &&
+ p->buffer_variant[j].instance_divisor == key->element[i].instance_divisor) {
break;
}
}
- if (j == p->nr_buffer_varients) {
- p->buffer_varient[j].buffer_index = key->element[i].input_buffer;
- p->buffer_varient[j].instance_divisor = key->element[i].instance_divisor;
- p->nr_buffer_varients++;
+ if (j == p->nr_buffer_variants) {
+ p->buffer_variant[j].buffer_index = key->element[i].input_buffer;
+ p->buffer_variant[j].instance_divisor = key->element[i].instance_divisor;
+ p->nr_buffer_variants++;
}
- p->element_to_buffer_varient[i] = j;
+ p->element_to_buffer_variant[i] = j;
} else {
assert(key->element[i].type == TRANSLATE_ELEMENT_INSTANCE_ID);
- p->element_to_buffer_varient[i] = ELEMENT_BUFFER_INSTANCE_ID;
+ p->element_to_buffer_variant[i] = ELEMENT_BUFFER_INSTANCE_ID;
}
}
if (!build_vertex_emit(p, &p->elt8_func, 1))
goto fail;
- p->translate.run = (void*)x86_get_func(&p->linear_func);
+ p->translate.run = (run_func) x86_get_func(&p->linear_func);
if (p->translate.run == NULL)
goto fail;
- p->translate.run_elts = (void*)x86_get_func(&p->elt_func);
+ p->translate.run_elts = (run_elts_func) x86_get_func(&p->elt_func);
if (p->translate.run_elts == NULL)
goto fail;
- p->translate.run_elts16 = (void*)x86_get_func(&p->elt16_func);
+ p->translate.run_elts16 = (run_elts16_func) x86_get_func(&p->elt16_func);
if (p->translate.run_elts16 == NULL)
goto fail;
- p->translate.run_elts8 = (void*)x86_get_func(&p->elt8_func);
+ p->translate.run_elts8 = (run_elts8_func) x86_get_func(&p->elt8_func);
if (p->translate.run_elts8 == NULL)
goto fail;