projects
/
mesa.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git]
/
src
/
mesa
/
x86
/
rtasm
/
x86sse.c
diff --git
a/src/mesa/x86/rtasm/x86sse.c
b/src/mesa/x86/rtasm/x86sse.c
index f8da6e405f40d64625b1ca2c6e453d6b77c9af1e..5c4bab733128285978668013ef72f7cc41edf6a2 100644
(file)
--- a/
src/mesa/x86/rtasm/x86sse.c
+++ b/
src/mesa/x86/rtasm/x86sse.c
@@
-1,6
+1,7
@@
+#ifdef USE_X86_ASM
#if defined(__i386__) || defined(__386__)
#if defined(__i386__) || defined(__386__)
-#include "imports.h"
+#include "
main/
imports.h"
#include "x86sse.h"
#define DISASSEM 0
#include "x86sse.h"
#define DISASSEM 0
@@
-12,55
+13,73
@@
static unsigned char *cptr( void (*label)() )
}
}
+static void do_realloc( struct x86_function *p )
+{
+ 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:
*/
/* 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.
/* Build a modRM byte + possible displacement. No treatment of SIB
* indexing. BZZT - no way to encode an absolute address.
@@
-77,13
+96,13
@@
static void emit_modrm( struct x86_function *p,
val |= reg.idx << 3; /* reg field */
val |= regmem.idx; /* r/m field */
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) {
/* 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) {
}
switch (regmem.mod) {
@@
-124,14
+143,14
@@
static void emit_op_modrm( struct x86_function *p,
{
switch (dst.mod) {
case mod_REG:
{
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_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:
emit_modrm(p, src, dst);
break;
default:
@@
-258,11
+277,24
@@
void x86_jmp( struct x86_function *p, unsigned char *label)
emit_1i(p, label - x86_get_label(p) - 4);
}
emit_1i(p, label - x86_get_label(p) - 4);
}
+#if 0
+/* This doesn't work once we start reallocating & copying the
+ * generated code on buffer fills, because the call is relative to the
+ * current pc.
+ */
void x86_call( struct x86_function *p, void (*label)())
{
emit_1ub(p, 0xe8);
emit_1i(p, cptr(label) - x86_get_label(p) - 4);
}
void x86_call( struct x86_function *p, void (*label)())
{
emit_1ub(p, 0xe8);
emit_1i(p, cptr(label) - x86_get_label(p) - 4);
}
+#else
+void x86_call( struct x86_function *p, struct x86_reg reg)
+{
+ emit_1ub(p, 0xff);
+ emit_modrm_noreg(p, 2, reg);
+}
+#endif
+
/* michal:
* Temporary. As I need immediate operands, and dont want to mess with the codegen,
/* michal:
* Temporary. As I need immediate operands, and dont want to mess with the codegen,
@@
-789,7
+821,7
@@
static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86
assert(0);
}
else if (dst.idx == 0) {
assert(0);
}
else if (dst.idx == 0) {
- assert(arg.file = file_REG32);
+ assert(arg.file =
=
file_REG32);
emit_1ub(p, 0xd8);
emit_modrm_noreg(p, argmem_noreg, arg);
}
emit_1ub(p, 0xd8);
emit_modrm_noreg(p, argmem_noreg, arg);
}
@@
-1125,11
+1157,14
@@
struct x86_reg x86_fn_arg( struct x86_function *p,
void x86_init_func( 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 )
{
}
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;
}
p->store = _mesa_exec_malloc(code_size);
p->csr = p->store;
}
@@
-1138,12
+1173,14
@@
void x86_release_func( struct x86_function *p )
{
_mesa_exec_free(p->store);
p->store = NULL;
{
_mesa_exec_free(p->store);
p->store = NULL;
+ p->csr = NULL;
+ p->size = 0;
}
void (*x86_get_func( struct x86_function *p ))(void)
{
}
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;
}
_mesa_printf("disassemble %p %p\n", p->store, p->csr);
return (void (*)(void)) (unsigned long) p->store;
}
@@
-1155,3
+1192,9
@@
void x86sse_dummy( void )
}
#endif
}
#endif
+
+#else /* USE_X86_ASM */
+
+int x86sse_c_dummy_var; /* silence warning */
+
+#endif /* USE_X86_ASM */