summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2008-02-13 11:35:54 +0000
committerKeith Whitwell <[email protected]>2008-02-13 12:36:32 +0000
commit6046c54cc40d32d4c1a47c061494a37fadefd947 (patch)
treea80c3c9dfd403e04980304b29cbc60e4b7c67d97
parent7f342a20d2c7f59b8dd8daed21f3b44f5215a05a (diff)
x86: reallocate exec mem when we run out
-rw-r--r--src/mesa/x86/rtasm/x86sse.c95
-rw-r--r--src/mesa/x86/rtasm/x86sse.h1
2 files changed, 61 insertions, 35 deletions
diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c
index f8da6e405f4..385fb84c01f 100644
--- a/src/mesa/x86/rtasm/x86sse.c
+++ b/src/mesa/x86/rtasm/x86sse.c
@@ -12,55 +12,75 @@ static unsigned char *cptr( void (*label)() )
}
+static void do_realloc( struct x86_function *p )
+{
+ _mesa_printf("do_realloc %d %p\n", p->size, p->store);
+
+ if (p->size == 0) {
+ p->size = 1024;
+ p->store = _mesa_exec_malloc(p->size);
+ p->csr = p->store;
+ }
+ else {
+ unsigned used = p->csr - p->store;
+ unsigned char *tmp = p->store;
+ p->size *= 2;
+ p->store = _mesa_exec_malloc(p->size);
+ memcpy(p->store, tmp, used);
+ p->csr = p->store + used;
+ _mesa_exec_free(tmp);
+ }
+}
+
/* Emit bytes to the instruction stream:
*/
-static void emit_1b( struct x86_function *p, char b0 )
+static unsigned char *reserve( struct x86_function *p, int bytes )
{
- *(char *)(p->csr++) = b0;
+ if (p->csr + bytes - p->store > p->size)
+ do_realloc(p);
+
+ {
+ unsigned char *csr = p->csr;
+ p->csr += bytes;
+ return csr;
+ }
}
-static void emit_1i( struct x86_function *p, int i0 )
+
+
+static void emit_1b( struct x86_function *p, char b0 )
{
- *(int *)(p->csr) = i0;
- p->csr += 4;
+ char *csr = (char *)reserve(p, 1);
+ *csr = b0;
}
-static void disassem( struct x86_function *p, const char *fn )
+static void emit_1i( struct x86_function *p, int i0 )
{
-#if DISASSEM && 0
- if (fn && fn != p->fn) {
- _mesa_printf("0x%x: %s\n", p->csr, fn);
- p->fn = fn;
- }
-#endif
+ int *icsr = (int *)reserve(p, sizeof(i0));
+ *icsr = i0;
}
-static void emit_1ub_fn( struct x86_function *p, unsigned char b0, const char *fn )
+static void emit_1ub( struct x86_function *p, unsigned char b0 )
{
- disassem(p, fn);
- *(p->csr++) = b0;
+ unsigned char *csr = reserve(p, 1);
+ *csr++ = b0;
}
-static void emit_2ub_fn( struct x86_function *p, unsigned char b0, unsigned char b1, const char *fn )
+static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 )
{
- disassem(p, fn);
- *(p->csr++) = b0;
- *(p->csr++) = b1;
+ unsigned char *csr = reserve(p, 2);
+ *csr++ = b0;
+ *csr++ = b1;
}
-static void emit_3ub_fn( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2, const char *fn )
+static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 )
{
- disassem(p, fn);
- *(p->csr++) = b0;
- *(p->csr++) = b1;
- *(p->csr++) = b2;
+ unsigned char *csr = reserve(p, 3);
+ *csr++ = b0;
+ *csr++ = b1;
+ *csr++ = b2;
}
-#define emit_1ub(p, b0) emit_1ub_fn(p, b0, __FUNCTION__)
-#define emit_2ub(p, b0, b1) emit_2ub_fn(p, b0, b1, __FUNCTION__)
-#define emit_3ub(p, b0, b1, b2) emit_3ub_fn(p, b0, b1, b2, __FUNCTION__)
-
-
/* Build a modRM byte + possible displacement. No treatment of SIB
* indexing. BZZT - no way to encode an absolute address.
@@ -77,13 +97,13 @@ static void emit_modrm( struct x86_function *p,
val |= reg.idx << 3; /* reg field */
val |= regmem.idx; /* r/m field */
- emit_1ub_fn(p, val, 0);
+ emit_1ub(p, val);
/* Oh-oh we've stumbled into the SIB thing.
*/
if (regmem.file == file_REG32 &&
regmem.idx == reg_SP) {
- emit_1ub_fn(p, 0x24, 0); /* simplistic! */
+ emit_1ub(p, 0x24); /* simplistic! */
}
switch (regmem.mod) {
@@ -124,14 +144,14 @@ static void emit_op_modrm( struct x86_function *p,
{
switch (dst.mod) {
case mod_REG:
- emit_1ub_fn(p, op_dst_is_reg, 0);
+ emit_1ub(p, op_dst_is_reg);
emit_modrm(p, dst, src);
break;
case mod_INDIRECT:
case mod_DISP32:
case mod_DISP8:
assert(src.mod == mod_REG);
- emit_1ub_fn(p, op_dst_is_mem, 0);
+ emit_1ub(p, op_dst_is_mem);
emit_modrm(p, src, dst);
break;
default:
@@ -1125,11 +1145,14 @@ struct x86_reg x86_fn_arg( struct x86_function *p,
void x86_init_func( struct x86_function *p )
{
- x86_init_func_size(p, 2048);
+ p->size = 0;
+ p->store = NULL;
+ p->csr = p->store;
}
void x86_init_func_size( struct x86_function *p, unsigned code_size )
{
+ p->size = code_size;
p->store = _mesa_exec_malloc(code_size);
p->csr = p->store;
}
@@ -1138,12 +1161,14 @@ void x86_release_func( struct x86_function *p )
{
_mesa_exec_free(p->store);
p->store = NULL;
+ p->csr = NULL;
+ p->size = 0;
}
void (*x86_get_func( struct x86_function *p ))(void)
{
- if (DISASSEM)
+ if (DISASSEM && p->store)
_mesa_printf("disassemble %p %p\n", p->store, p->csr);
return (void (*)(void)) (unsigned long) p->store;
}
diff --git a/src/mesa/x86/rtasm/x86sse.h b/src/mesa/x86/rtasm/x86sse.h
index 63b9a36392a..d53b6d71a6b 100644
--- a/src/mesa/x86/rtasm/x86sse.h
+++ b/src/mesa/x86/rtasm/x86sse.h
@@ -16,6 +16,7 @@ struct x86_reg {
};
struct x86_function {
+ unsigned size;
unsigned char *store;
unsigned char *csr;
unsigned stack_offset;