summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2011-04-01 19:19:42 +0100
committerJosé Fonseca <jfonseca@vmware.com>2011-04-01 20:18:18 +0100
commit17bbc1f0425b3768e26473eccea5f2570dcb26d3 (patch)
treed08ff87c5ef8bbf3fce5472d93f17fa57c3e7c98
parent3733da31e8b4405b65e1b6ca3b6599ecc5af5fe7 (diff)
translate: Respect translate_buffer::max_index.
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c10
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.h1
-rw-r--r--src/gallium/auxiliary/translate/translate_sse.c19
3 files changed, 28 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index b03dd3a0cf8..5231bb08374 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -726,6 +726,16 @@ void x86_movzx16(struct x86_function *p, struct x86_reg dst, struct x86_reg src
emit_modrm(p, dst, src);
}
+void x86_cmovcc( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src,
+ enum x86_cc cc)
+{
+ DUMP_RRI( dst, src, cc );
+ emit_2ub( p, 0x0f, 0x40 + cc );
+ emit_modrm( p, dst, src );
+}
+
void x86_xor( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src )
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
index 2b9678b1765..af0565bb59d 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
@@ -309,6 +309,7 @@ void sse_movmskps( struct x86_function *p, struct x86_reg dst, struct x86_reg sr
void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void x86_cmovcc( struct x86_function *p, struct x86_reg dst, struct x86_reg src, enum x86_cc cc );
void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void x86_dec( struct x86_function *p, struct x86_reg reg );
void x86_inc( struct x86_function *p, struct x86_reg reg );
diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c
index ef7f4be4c3e..b00242d8b20 100644
--- a/src/gallium/auxiliary/translate/translate_sse.c
+++ b/src/gallium/auxiliary/translate/translate_sse.c
@@ -1067,6 +1067,8 @@ static boolean init_inputs( struct translate_sse *p,
struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
if (!index_size || varient->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,
@@ -1100,14 +1102,17 @@ static boolean init_inputs( struct translate_sse *p,
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.
@@ -1163,6 +1168,10 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p,
x86_make_disp(p->machine_EDI,
get_offset(p, &p->buffer[varient->buffer_index].base_ptr));
+ struct x86_reg buf_max_index =
+ x86_make_disp(p->machine_EDI,
+ get_offset(p, &p->buffer[varient->buffer_index].max_index));
+
/* Calculate pointer to current attrib:
@@ -1179,6 +1188,12 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p,
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);