summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/rtasm/rtasm_x86sse.c')
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c182
1 files changed, 168 insertions, 14 deletions
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index 6cd88ebca3d..698389ffb7b 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -38,11 +38,8 @@
#define DUMP_SSE 0
-#if DUMP_SSE
-static void
-_print_reg(
- struct x86_reg reg )
+void x86_print_reg( struct x86_reg reg )
{
if (reg.mod != mod_REG)
debug_printf( "[" );
@@ -79,6 +76,7 @@ _print_reg(
debug_printf( "]" );
}
+#if DUMP_SSE
#define DUMP_START() debug_printf( "\n" )
#define DUMP_END() debug_printf( "\n" )
@@ -89,7 +87,7 @@ _print_reg(
foo++; \
if (*foo) \
foo++; \
- debug_printf( "\n% 15s ", foo ); \
+ debug_printf( "\n% 4x% 15s ", p->csr - p->store, foo ); \
} while (0)
#define DUMP_I( I ) do { \
@@ -99,27 +97,27 @@ _print_reg(
#define DUMP_R( R0 ) do { \
DUMP(); \
- _print_reg( R0 ); \
+ x86_print_reg( R0 ); \
} while( 0 )
#define DUMP_RR( R0, R1 ) do { \
DUMP(); \
- _print_reg( R0 ); \
+ x86_print_reg( R0 ); \
debug_printf( ", " ); \
- _print_reg( R1 ); \
+ x86_print_reg( R1 ); \
} while( 0 )
#define DUMP_RI( R0, I ) do { \
DUMP(); \
- _print_reg( R0 ); \
+ x86_print_reg( R0 ); \
debug_printf( ", %u", I ); \
} while( 0 )
#define DUMP_RRI( R0, R1, I ) do { \
DUMP(); \
- _print_reg( R0 ); \
+ x86_print_reg( R0 ); \
debug_printf( ", " ); \
- _print_reg( R1 ); \
+ x86_print_reg( R1 ); \
debug_printf( ", %u", I ); \
} while( 0 )
@@ -222,6 +220,8 @@ static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1
/* Build a modRM byte + possible displacement. No treatment of SIB
* indexing. BZZT - no way to encode an absolute address.
+ *
+ * This is the "/r" field in the x86 manuals...
*/
static void emit_modrm( struct x86_function *p,
struct x86_reg reg,
@@ -260,7 +260,8 @@ static void emit_modrm( struct x86_function *p,
}
}
-
+/* Emits the "/0".."/7" specialized versions of the modrm ("/r") bytes.
+ */
static void emit_modrm_noreg( struct x86_function *p,
unsigned op,
struct x86_reg regmem )
@@ -369,8 +370,7 @@ void x86_jcc( struct x86_function *p,
DUMP_I(cc);
if (offset < 0) {
- int amt = p->csr - p->store;
- assert(amt > -offset);
+ assert(p->csr - p->store > -offset);
}
if (offset <= 127 && offset >= -128) {
@@ -447,6 +447,16 @@ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )
emit_1i(p, imm);
}
+void x86_add_reg_imm8( struct x86_function *p, struct x86_reg dst, ubyte imm )
+{
+ DUMP_RI( dst, imm );
+ assert(dst.mod == mod_REG);
+ emit_1ub(p, 0x80);
+ emit_modrm_noreg(p, 0, dst);
+ emit_1ub(p, imm);
+}
+
+
void x86_push( struct x86_function *p,
struct x86_reg reg )
{
@@ -463,6 +473,17 @@ void x86_push( struct x86_function *p,
p->stack_offset += 4;
}
+void x86_push_imm32( struct x86_function *p,
+ int imm32 )
+{
+ DUMP_I( imm32 );
+ emit_1ub(p, 0x68);
+ emit_1i(p, imm32);
+
+ p->stack_offset += 4;
+}
+
+
void x86_pop( struct x86_function *p,
struct x86_reg reg )
{
@@ -990,6 +1011,24 @@ void sse2_movd( struct x86_function *p,
/***********************************************************************
* x87 instructions
*/
+static void note_x87_pop( struct x86_function *p )
+{
+ p->x87_stack--;
+ assert(p->x87_stack >= 0);
+}
+
+static void note_x87_push( struct x86_function *p )
+{
+ p->x87_stack++;
+ assert(p->x87_stack <= 7);
+}
+
+void x87_assert_stack_empty( struct x86_function *p )
+{
+ assert (p->x87_stack == 0);
+}
+
+
void x87_fist( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
@@ -1002,6 +1041,7 @@ void x87_fistp( struct x86_function *p, struct x86_reg dst )
DUMP_R( dst );
emit_1ub(p, 0xdb);
emit_modrm_noreg(p, 3, dst);
+ note_x87_pop(p);
}
void x87_fild( struct x86_function *p, struct x86_reg arg )
@@ -1009,12 +1049,14 @@ void x87_fild( struct x86_function *p, struct x86_reg arg )
DUMP_R( arg );
emit_1ub(p, 0xdf);
emit_modrm_noreg(p, 0, arg);
+ note_x87_push(p);
}
void x87_fldz( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xd9, 0xee);
+ note_x87_push(p);
}
@@ -1031,18 +1073,21 @@ void x87_fld1( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xd9, 0xe8);
+ note_x87_push(p);
}
void x87_fldl2e( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xd9, 0xea);
+ note_x87_push(p);
}
void x87_fldln2( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xd9, 0xed);
+ note_x87_push(p);
}
void x87_fwait( struct x86_function *p )
@@ -1063,6 +1108,49 @@ void x87_fclex( struct x86_function *p )
x87_fnclex(p);
}
+void x87_fcmovb( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ assert(arg.file == file_x87);
+ emit_2ub(p, 0xda, 0xc0+arg.idx);
+}
+
+void x87_fcmove( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ assert(arg.file == file_x87);
+ emit_2ub(p, 0xda, 0xc8+arg.idx);
+}
+
+void x87_fcmovbe( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ assert(arg.file == file_x87);
+ emit_2ub(p, 0xda, 0xd0+arg.idx);
+}
+
+void x87_fcmovnb( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ assert(arg.file == file_x87);
+ emit_2ub(p, 0xdb, 0xc0+arg.idx);
+}
+
+void x87_fcmovne( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ assert(arg.file == file_x87);
+ emit_2ub(p, 0xdb, 0xc8+arg.idx);
+}
+
+void x87_fcmovnbe( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ assert(arg.file == file_x87);
+ emit_2ub(p, 0xdb, 0xd0+arg.idx);
+}
+
+
static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg,
unsigned char dst0ub0,
@@ -1150,6 +1238,7 @@ void x87_fmulp( struct x86_function *p, struct x86_reg dst )
assert(dst.file == file_x87);
assert(dst.idx >= 1);
emit_2ub(p, 0xde, 0xc8+dst.idx);
+ note_x87_pop(p);
}
void x87_fsubp( struct x86_function *p, struct x86_reg dst )
@@ -1158,6 +1247,7 @@ void x87_fsubp( struct x86_function *p, struct x86_reg dst )
assert(dst.file == file_x87);
assert(dst.idx >= 1);
emit_2ub(p, 0xde, 0xe8+dst.idx);
+ note_x87_pop(p);
}
void x87_fsubrp( struct x86_function *p, struct x86_reg dst )
@@ -1166,6 +1256,7 @@ void x87_fsubrp( struct x86_function *p, struct x86_reg dst )
assert(dst.file == file_x87);
assert(dst.idx >= 1);
emit_2ub(p, 0xde, 0xe0+dst.idx);
+ note_x87_pop(p);
}
void x87_faddp( struct x86_function *p, struct x86_reg dst )
@@ -1174,6 +1265,7 @@ void x87_faddp( struct x86_function *p, struct x86_reg dst )
assert(dst.file == file_x87);
assert(dst.idx >= 1);
emit_2ub(p, 0xde, 0xc0+dst.idx);
+ note_x87_pop(p);
}
void x87_fdivp( struct x86_function *p, struct x86_reg dst )
@@ -1182,6 +1274,7 @@ void x87_fdivp( struct x86_function *p, struct x86_reg dst )
assert(dst.file == file_x87);
assert(dst.idx >= 1);
emit_2ub(p, 0xde, 0xf8+dst.idx);
+ note_x87_pop(p);
}
void x87_fdivrp( struct x86_function *p, struct x86_reg dst )
@@ -1190,6 +1283,13 @@ void x87_fdivrp( struct x86_function *p, struct x86_reg dst )
assert(dst.file == file_x87);
assert(dst.idx >= 1);
emit_2ub(p, 0xde, 0xf0+dst.idx);
+ note_x87_pop(p);
+}
+
+void x87_ftst( struct x86_function *p )
+{
+ DUMP();
+ emit_2ub(p, 0xd9, 0xe4);
}
void x87_fucom( struct x86_function *p, struct x86_reg arg )
@@ -1204,12 +1304,15 @@ void x87_fucomp( struct x86_function *p, struct x86_reg arg )
DUMP_R( arg );
assert(arg.file == file_x87);
emit_2ub(p, 0xdd, 0xe8+arg.idx);
+ note_x87_pop(p);
}
void x87_fucompp( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xda, 0xe9);
+ note_x87_pop(p); /* pop twice */
+ note_x87_pop(p); /* pop twice */
}
void x87_fxch( struct x86_function *p, struct x86_reg arg )
@@ -1291,6 +1394,7 @@ void x87_fyl2x( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xd9, 0xf1);
+ note_x87_pop(p);
}
/* st1 = st1 * log2(st0 + 1.0);
@@ -1302,6 +1406,7 @@ void x87_fyl2xp1( struct x86_function *p )
{
DUMP();
emit_2ub(p, 0xd9, 0xf9);
+ note_x87_pop(p);
}
@@ -1314,6 +1419,7 @@ void x87_fld( struct x86_function *p, struct x86_reg arg )
emit_1ub(p, 0xd9);
emit_modrm_noreg(p, 0, arg);
}
+ note_x87_push(p);
}
void x87_fst( struct x86_function *p, struct x86_reg dst )
@@ -1336,8 +1442,15 @@ void x87_fstp( struct x86_function *p, struct x86_reg dst )
emit_1ub(p, 0xd9);
emit_modrm_noreg(p, 3, dst);
}
+ note_x87_pop(p);
}
+void x87_fpop( struct x86_function *p )
+{
+ x87_fstp( p, x86_make_reg( file_x87, 0 ));
+}
+
+
void x87_fcom( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
@@ -1349,6 +1462,7 @@ void x87_fcom( struct x86_function *p, struct x86_reg dst )
}
}
+
void x87_fcomp( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
@@ -1358,6 +1472,20 @@ void x87_fcomp( struct x86_function *p, struct x86_reg dst )
emit_1ub(p, 0xd8);
emit_modrm_noreg(p, 3, dst);
}
+ note_x87_pop(p);
+}
+
+void x87_fcomi( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ emit_2ub(p, 0xdb, 0xf0+arg.idx);
+}
+
+void x87_fcomip( struct x86_function *p, struct x86_reg arg )
+{
+ DUMP_R( arg );
+ emit_2ub(p, 0xdb, 0xf0+arg.idx);
+ note_x87_pop(p);
}
@@ -1376,6 +1504,17 @@ void x87_fnstsw( struct x86_function *p, struct x86_reg dst )
}
+void x87_fnstcw( struct x86_function *p, struct x86_reg dst )
+{
+ DUMP_R( dst );
+ assert(dst.file == file_REG32);
+
+ emit_1ub(p, 0x9b); /* WAIT -- needed? */
+ emit_1ub(p, 0xd9);
+ emit_modrm_noreg(p, 7, dst);
+}
+
+
/***********************************************************************
@@ -1444,6 +1583,21 @@ void mmx_movq( struct x86_function *p,
*/
+void x86_cdecl_caller_push_regs( struct x86_function *p )
+{
+ x86_push(p, x86_make_reg(file_REG32, reg_AX));
+ x86_push(p, x86_make_reg(file_REG32, reg_CX));
+ x86_push(p, x86_make_reg(file_REG32, reg_DX));
+}
+
+void x86_cdecl_caller_pop_regs( struct x86_function *p )
+{
+ x86_pop(p, x86_make_reg(file_REG32, reg_DX));
+ x86_pop(p, x86_make_reg(file_REG32, reg_CX));
+ x86_pop(p, x86_make_reg(file_REG32, reg_AX));
+}
+
+
/* Retreive a reference to one of the function arguments, taking into
* account any push/pop activity:
*/