Rename emit functions to reflect instruction set in use (ie
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 19 May 2005 14:42:09 +0000 (14:42 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 19 May 2005 14:42:09 +0000 (14:42 +0000)
x86,sse,sse2,mmx).  Add paths for sse+mmx vs. the initial version
which assumed sse2 was available everywhere.

src/mesa/tnl/t_vertex_sse.c

index d6c1f08..109fdfb 100644 (file)
 #include "t_vertex.h"
 #include "simple_list.h"
 
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
 #define X    0
 #define Y    1
 #define Z    2
@@ -61,6 +56,8 @@ struct x86_program {
 
    GLboolean inputs_safe;
    GLboolean outputs_safe;
+   GLboolean have_sse2;
+   GLboolean need_emms;
    
    struct x86_reg identity;
    struct x86_reg vp0;
@@ -74,6 +71,7 @@ struct x86_program {
  */
 enum x86_reg_file {
    file_REG32,
+   file_MMX,
    file_XMM
 };
 
@@ -167,23 +165,11 @@ static struct x86_reg make_fn_arg( struct x86_program *p,
                    p->stack_offset + arg * 4); /* ??? */
 }
 
-
 static struct x86_reg get_identity( struct x86_program *p )
 {
    return p->identity;
 }
 
-static struct x86_reg get_sse_temp( struct x86_program *p )
-{
-   return make_reg(file_XMM, 7); /* hardwired */
-}
-
-static void release_temp( struct x86_program *p,
-                         struct x86_reg reg )
-{
-   assert(reg.file == file_XMM &&
-         reg.idx == 7);
-}
 
 /* Emit bytes to the instruction stream:
  */
@@ -242,7 +228,7 @@ static GLubyte *get_label( struct x86_program *p )
    return p->csr;
 }
 
-static void emit_jcc( struct x86_program *p,
+static void x86_jcc( struct x86_program *p,
                      GLuint cc,
                      GLubyte *label )
 {
@@ -261,8 +247,8 @@ static void emit_jcc( struct x86_program *p,
 
 /* Always use a 32bit offset for forward jumps:
  */
-static GLubyte *emit_jcc_forward( struct x86_program *p,
-                              GLuint cc )
+static GLubyte *x86_jcc_forward( struct x86_program *p,
+                                GLuint cc )
 {
    emit_2ub(p, 0x0f, 0x80 + cc);
    emit_1i(p, 0);
@@ -277,7 +263,7 @@ static void do_fixup( struct x86_program *p,
    *(int *)(fixup - 4) = get_label(p) - fixup;
 }
 
-static void emit_push( struct x86_program *p,
+static void x86_push( struct x86_program *p,
                       struct x86_reg reg )
 {
    assert(reg.mod == mod_REG);
@@ -285,7 +271,7 @@ static void emit_push( struct x86_program *p,
    p->stack_offset += 4;
 }
 
-static void emit_pop( struct x86_program *p,
+static void x86_pop( struct x86_program *p,
                       struct x86_reg reg )
 {
    assert(reg.mod == mod_REG);
@@ -293,25 +279,32 @@ static void emit_pop( struct x86_program *p,
    p->stack_offset -= 4;
 }
 
-static void emit_inc( struct x86_program *p,
+static void x86_inc( struct x86_program *p,
                       struct x86_reg reg )
 {
    assert(reg.mod == mod_REG);
    emit_1ub(p, 0x40 + reg.idx);
 }
 
-static void emit_dec( struct x86_program *p,
+static void x86_dec( struct x86_program *p,
                       struct x86_reg reg )
 {
    assert(reg.mod == mod_REG);
    emit_1ub(p, 0x48 + reg.idx);
 }
 
-static void emit_ret( struct x86_program *p )
+static void x86_ret( struct x86_program *p )
 {
    emit_1ub(p, 0xc3);
 }
 
+static void mmx_emms( struct x86_program *p )
+{
+   assert(p->need_emms);
+   emit_2ub(p, 0x0f, 0x0e);
+   p->need_emms = 0;
+}
+
 
 
 
@@ -377,52 +370,56 @@ static void emit_op_modrm( struct x86_program *p,
    }
 }
 
-static void emit_mov( struct x86_program *p,
+static void x86_mov( struct x86_program *p,
                      struct x86_reg dst,
                      struct x86_reg src )
 {
    emit_op_modrm( p, 0x8b, 0x89, dst, src );
 }
 
-static void emit_xor( struct x86_program *p,
+static void x86_xor( struct x86_program *p,
                      struct x86_reg dst,
                      struct x86_reg src )
 {
    emit_op_modrm( p, 0x33, 0x31, dst, src );
 }
 
-static void emit_cmp( struct x86_program *p,
+static void x86_cmp( struct x86_program *p,
                      struct x86_reg dst,
                      struct x86_reg src )
 {
    emit_op_modrm( p, 0x3b, 0x39, dst, src );
 }
 
-static void emit_movlps( struct x86_program *p,
-                        struct x86_reg dst,
-                        struct x86_reg src )
+static void sse2_movd( struct x86_program *p,
+                      struct x86_reg dst,
+                      struct x86_reg src )
 {
-   emit_1ub(p, X86_TWOB);
-   emit_op_modrm( p, 0x12, 0x13, dst, src );
+   assert(p->have_sse2);
+   emit_2ub(p, 0x66, X86_TWOB);
+   emit_op_modrm( p, 0x6e, 0x7e, dst, src );
 }
 
-static void emit_movhps( struct x86_program *p,
-                        struct x86_reg dst,
-                        struct x86_reg src )
+static void mmx_movd( struct x86_program *p,
+                      struct x86_reg dst,
+                      struct x86_reg src )
 {
+   p->need_emms = 1;
    emit_1ub(p, X86_TWOB);
-   emit_op_modrm( p, 0x16, 0x17, dst, src );
+   emit_op_modrm( p, 0x6e, 0x7e, dst, src );
 }
 
-static void emit_movd( struct x86_program *p,
+static void mmx_movq( struct x86_program *p,
                       struct x86_reg dst,
                       struct x86_reg src )
 {
-   emit_2ub(p, 0x66, X86_TWOB);
-   emit_op_modrm( p, 0x6e, 0x7e, dst, src );
+   p->need_emms = 1;
+   emit_1ub(p, X86_TWOB);
+   emit_op_modrm( p, 0x6f, 0x7f, dst, src );
 }
 
-static void emit_movss( struct x86_program *p,
+
+static void sse_movss( struct x86_program *p,
                       struct x86_reg dst,
                       struct x86_reg src )
 {
@@ -430,7 +427,7 @@ static void emit_movss( struct x86_program *p,
    emit_op_modrm( p, 0x10, 0x11, dst, src );
 }
 
-static void emit_movaps( struct x86_program *p,
+static void sse_movaps( struct x86_program *p,
                         struct x86_reg dst,
                         struct x86_reg src )
 {
@@ -438,7 +435,7 @@ static void emit_movaps( struct x86_program *p,
    emit_op_modrm( p, 0x28, 0x29, dst, src );
 }
 
-static void emit_movups( struct x86_program *p,
+static void sse_movups( struct x86_program *p,
                         struct x86_reg dst,
                         struct x86_reg src )
 {
@@ -446,10 +443,28 @@ static void emit_movups( struct x86_program *p,
    emit_op_modrm( p, 0x10, 0x11, dst, src );
 }
 
+static void sse_movhps( struct x86_program *p,
+                       struct x86_reg dst,
+                       struct x86_reg src )
+{
+   assert(dst.mod != mod_REG || src.mod != mod_REG);
+   emit_1ub(p, X86_TWOB);
+   emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */
+}
+
+static void sse_movlps( struct x86_program *p,
+                       struct x86_reg dst,
+                       struct x86_reg src )
+{
+   assert(dst.mod != mod_REG || src.mod != mod_REG);
+   emit_1ub(p, X86_TWOB);
+   emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */
+}
+
 /* SSE operations often only have one format, with dest constrained to
  * be a register:
  */
-static void emit_mulps( struct x86_program *p,
+static void sse_mulps( struct x86_program *p,
                        struct x86_reg dst,
                        struct x86_reg src )
 {
@@ -457,7 +472,7 @@ static void emit_mulps( struct x86_program *p,
    emit_modrm( p, dst, src );
 }
 
-static void emit_addps( struct x86_program *p,
+static void sse_addps( struct x86_program *p,
                        struct x86_reg dst,
                        struct x86_reg src )
 {
@@ -465,59 +480,113 @@ static void emit_addps( struct x86_program *p,
    emit_modrm( p, dst, src );
 }
 
-static void emit_cvtps2dq( struct x86_program *p,
+static void sse_movhlps( struct x86_program *p,
+                        struct x86_reg dst,
+                        struct x86_reg src )
+{
+   assert(dst.mod == mod_REG && src.mod == mod_REG);
+   emit_2ub(p, X86_TWOB, 0x12);
+   emit_modrm( p, dst, src );
+}
+
+static void sse_movlhps( struct x86_program *p,
+                        struct x86_reg dst,
+                        struct x86_reg src )
+{
+   assert(dst.mod == mod_REG && src.mod == mod_REG);
+   emit_2ub(p, X86_TWOB, 0x16);
+   emit_modrm( p, dst, src );
+}
+
+static void sse2_cvtps2dq( struct x86_program *p,
                        struct x86_reg dst,
                        struct x86_reg src )
 {
+   assert(p->have_sse2);
    emit_3ub(p, 0x66, X86_TWOB, 0x5B);
    emit_modrm( p, dst, src );
 }
 
-static void emit_packssdw( struct x86_program *p,
+static void sse2_packssdw( struct x86_program *p,
                        struct x86_reg dst,
                        struct x86_reg src )
 {
+   assert(p->have_sse2);
    emit_3ub(p, 0x66, X86_TWOB, 0x6B);
    emit_modrm( p, dst, src );
 }
 
-static void emit_packsswb( struct x86_program *p,
+static void sse2_packsswb( struct x86_program *p,
                        struct x86_reg dst,
                        struct x86_reg src )
 {
+   assert(p->have_sse2);
    emit_3ub(p, 0x66, X86_TWOB, 0x63);
    emit_modrm( p, dst, src );
 }
 
-static void emit_packuswb( struct x86_program *p,
-                       struct x86_reg dst,
-                       struct x86_reg src )
+static void sse2_packuswb( struct x86_program *p,
+                          struct x86_reg dst,
+                          struct x86_reg src )
 {
+   assert(p->have_sse2);
    emit_3ub(p, 0x66, X86_TWOB, 0x67);
    emit_modrm( p, dst, src );
 }
 
-/* Load effective address:
- */
-static void emit_lea( struct x86_program *p,
-                     struct x86_reg dst,
-                     struct x86_reg src )
+static void sse_cvtps2pi( struct x86_program *p,
+                         struct x86_reg dst,
+                         struct x86_reg src )
 {
-   emit_1ub(p, 0x8d);
+   assert(dst.file == file_MMX && 
+         (src.file == file_XMM || src.mod != mod_REG));
+
+   p->need_emms = 1;
+
+   emit_2ub(p, X86_TWOB, 0x2d);
+   emit_modrm( p, dst, src );
+}
+
+static void mmx_packssdw( struct x86_program *p,
+                         struct x86_reg dst,
+                         struct x86_reg src )
+{
+   assert(dst.file == file_MMX && 
+         (src.file == file_MMX || src.mod != mod_REG));
+
+   p->need_emms = 1;
+
+   emit_2ub(p, X86_TWOB, 0x6b);
    emit_modrm( p, dst, src );
 }
 
-static void emit_add_imm( struct x86_program *p,
+static void mmx_packuswb( struct x86_program *p,
                          struct x86_reg dst,
-                         struct x86_reg src,
-                         GLint value )
+                         struct x86_reg src )
 {
-   emit_lea(p, dst, make_disp(src, value));
+   assert(dst.file == file_MMX && 
+         (src.file == file_MMX || src.mod != mod_REG));
+
+   p->need_emms = 1;
+
+   emit_2ub(p, X86_TWOB, 0x67);
+   emit_modrm( p, dst, src );
 }
 
-static void emit_test( struct x86_program *p,
-                      struct x86_reg dst,
-                      struct x86_reg src )
+
+/* Load effective address:
+ */
+static void x86_lea( struct x86_program *p,
+                    struct x86_reg dst,
+                    struct x86_reg src )
+{
+   emit_1ub(p, 0x8d);
+   emit_modrm( p, dst, src );
+}
+
+static void x86_test( struct x86_program *p,
+                     struct x86_reg dst,
+                     struct x86_reg src )
 {
    emit_1ub(p, 0x85);
    emit_modrm( p, dst, src );
@@ -529,7 +598,7 @@ static void emit_test( struct x86_program *p,
 /**
  * Perform a reduced swizzle:
  */
-static void emit_pshufd( struct x86_program *p,
+static void sse2_pshufd( struct x86_program *p,
                         struct x86_reg dest,
                         struct x86_reg arg0,
                         GLubyte x,
@@ -537,26 +606,35 @@ static void emit_pshufd( struct x86_program *p,
                         GLubyte z,
                         GLubyte w) 
 {
+   assert(p->have_sse2);
    emit_3ub(p, 0x66, X86_TWOB, 0x70);
    emit_modrm(p, dest, arg0);
    emit_1ub(p, (x|(y<<2)|(z<<4)|w<<6)); 
 }
 
 
-static void emit_pk4ub( struct x86_program *p, 
-                       struct x86_reg dest,
-                       struct x86_reg arg0 )
+/* Shufps can also be used to implement a reduced swizzle when dest ==
+ * arg0.
+ */
+static void sse_shufps( struct x86_program *p,
+                        struct x86_reg dest,
+                        struct x86_reg arg0,
+                        GLubyte x,
+                        GLubyte y,
+                        GLubyte z,
+                        GLubyte w) 
 {
-   emit_cvtps2dq(p, dest, arg0);
-   emit_packssdw(p, dest, dest);
-   emit_packuswb(p, dest, dest);
+   emit_2ub(p, X86_TWOB, 0xC6);
+   emit_modrm(p, dest, arg0);
+   emit_1ub(p, (x|(y<<2)|(z<<4)|w<<6)); 
 }
 
+
 static void emit_load4f_4( struct x86_program *p,                         
                           struct x86_reg dest,
                           struct x86_reg arg0 )
 {
-   emit_movups(p, dest, arg0);
+   sse_movups(p, dest, arg0);
 }
 
 static void emit_load4f_3( struct x86_program *p, 
@@ -570,10 +648,10 @@ static void emit_load4f_3( struct x86_program *p,
     * 0 0 c 1
     * a b c 1 
     */
-   emit_movups(p, dest, get_identity(p));
-   emit_movss(p, dest, make_disp(arg0, 8));
-   emit_pshufd(p, dest, dest, Y,Z,X,W );
-   emit_movlps(p, dest, arg0);
+   sse_movaps(p, dest, get_identity(p));
+   sse_movss(p, dest, make_disp(arg0, 8));
+   sse_shufps(p, dest, dest, Y,Z,X,W );
+   sse_movlps(p, dest, arg0);
 }
 
 static void emit_load4f_2( struct x86_program *p, 
@@ -582,8 +660,8 @@ static void emit_load4f_2( struct x86_program *p,
 {
    /* Pull in 2 dwords, then copy the top 2 dwords with 0,1 from id.
     */
-   emit_movlps(p, dest, arg0);
-   emit_movhps(p, dest, get_identity(p));
+   sse_movlps(p, dest, arg0);
+   sse_movhps(p, dest, get_identity(p));
 }
 
 static void emit_load4f_1( struct x86_program *p, 
@@ -593,8 +671,8 @@ static void emit_load4f_1( struct x86_program *p,
    /* Initialized with [0,0,0,1] from id, then pull in the single low
     * word.
     */
-   emit_movups(p, dest, get_identity(p));
-   emit_movss(p, dest, arg0);
+   sse_movaps(p, dest, get_identity(p));
+   sse_movss(p, dest, arg0);
 }
 
 
@@ -607,16 +685,16 @@ static void emit_load3f_3( struct x86_program *p,
     * array.
     */
    if (p->inputs_safe) {
-      emit_movups(p, dest, arg0);
+      sse_movups(p, dest, arg0);
    } 
    else {
       /* c . . .
        * c c c c
        * a b c c 
        */
-      emit_movss(p, dest, make_disp(arg0, 8));
-      emit_pshufd(p, dest, dest, X,X,X,X);
-      emit_movlps(p, dest, arg0);
+      sse_movss(p, dest, make_disp(arg0, 8));
+      sse_shufps(p, dest, dest, X,X,X,X);
+      sse_movlps(p, dest, arg0);
    }
 }
 
@@ -638,7 +716,7 @@ static void emit_load2f_2( struct x86_program *p,
                           struct x86_reg dest,
                           struct x86_reg arg0 )
 {
-   emit_movlps(p, dest, arg0);
+   sse_movlps(p, dest, arg0);
 }
 
 static void emit_load2f_1( struct x86_program *p, 
@@ -652,7 +730,7 @@ static void emit_load1f_1( struct x86_program *p,
                           struct x86_reg dest,
                           struct x86_reg arg0 )
 {
-   emit_movss(p, dest, arg0);
+   sse_movss(p, dest, arg0);
 }
 
 static void (*load[4][4])( struct x86_program *p, 
@@ -685,7 +763,8 @@ static void emit_load( struct x86_program *p,
                       struct x86_reg src,
                       GLuint src_sz)
 {
-   _mesa_printf("load %d/%d\n", sz, src_sz);
+   if (DISASSEM)
+      _mesa_printf("load %d/%d\n", sz, src_sz);
    load[sz-1][src_sz-1](p, dest, src);
 }
 
@@ -694,7 +773,7 @@ static void emit_store4f( struct x86_program *p,
                          struct x86_reg dest,
                          struct x86_reg arg0 )
 {
-   emit_movups(p, dest, arg0);
+   sse_movups(p, dest, arg0);
 }
 
 static void emit_store3f( struct x86_program *p, 
@@ -705,17 +784,14 @@ static void emit_store3f( struct x86_program *p,
       /* Emit the extra dword anyway.  This may hurt writecombining,
        * may cause other problems.
        */
-      emit_movups(p, dest, arg0);
+      sse_movups(p, dest, arg0);
    }
    else {
       /* Alternate strategy - emit two, shuffle, emit one.
        */
-      struct x86_reg tmp = get_sse_temp(p);
-      emit_movlps(p, dest, arg0);
-
-      emit_pshufd(p, tmp, arg0, Z, Z, Z, Z );
-      emit_movss(p, make_disp(dest,8), tmp);
-      release_temp(p, tmp);
+      sse_movlps(p, dest, arg0);
+      sse_shufps(p, arg0, arg0, Z, Z, Z, Z ); /* NOTE! destructive */
+      sse_movss(p, make_disp(dest,8), arg0);
    }
 }
 
@@ -723,14 +799,14 @@ static void emit_store2f( struct x86_program *p,
                           struct x86_reg dest,
                           struct x86_reg arg0 )
 {
-   emit_movlps(p, dest, arg0);
+   sse_movlps(p, dest, arg0);
 }
 
 static void emit_store1f( struct x86_program *p, 
                          struct x86_reg dest,
                          struct x86_reg arg0 )
 {
-   emit_movss(p, dest, arg0);
+   sse_movss(p, dest, arg0);
 }
 
 
@@ -750,9 +826,32 @@ static void emit_store( struct x86_program *p,
                        struct x86_reg temp )
 
 {
+   if (DISASSEM)
+      _mesa_printf("store %d\n", sz);
    store[sz-1](p, dest, temp);
 }
 
+static void emit_pack_store_4ub( struct x86_program *p,
+                                struct x86_reg dest,
+                                struct x86_reg temp )
+{
+   if (p->have_sse2) {
+      sse2_cvtps2dq(p, temp, temp);
+      sse2_packssdw(p, temp, temp);
+      sse2_packuswb(p, temp, temp);
+      sse_movss(p, dest, temp);
+   }
+   else {
+      struct x86_reg mmx0 = make_reg(file_MMX, 0);
+      struct x86_reg mmx1 = make_reg(file_MMX, 1);
+      sse_cvtps2pi(p, mmx0, temp);
+      sse_movhlps(p, temp, temp);
+      sse_cvtps2pi(p, mmx1, temp);
+      mmx_packssdw(p, mmx0, mmx1);
+      mmx_packuswb(p, mmx0, mmx0);
+      mmx_movd(p, dest, mmx0);
+   }
+}
 
 static GLint get_offset( const void *a, const void *b )
 {
@@ -779,7 +878,7 @@ static GLboolean build_vertex_emit( struct x86_program *p )
    struct x86_reg srcEDI = make_reg(file_REG32, reg_CX);
    struct x86_reg countEBP = make_reg(file_REG32, reg_BP);
    struct x86_reg vtxESI = make_reg(file_REG32, reg_SI);
-   struct x86_reg tmp = make_reg(file_XMM, 0);
+   struct x86_reg temp = make_reg(file_XMM, 0);
    struct x86_reg vp0 = make_reg(file_XMM, 1);
    struct x86_reg vp1 = make_reg(file_XMM, 2);
    struct x86_reg chan0 = make_reg(file_XMM, 3);
@@ -789,41 +888,40 @@ static GLboolean build_vertex_emit( struct x86_program *p )
    
    /* Push a few regs?
     */
-   emit_push(p, srcEDI);
-   emit_push(p, countEBP);
-   emit_push(p, vtxESI);
+   x86_push(p, srcEDI);
+   x86_push(p, countEBP);
+   x86_push(p, vtxESI);
 
 
    /* Get vertex count, compare to zero
     */
-   emit_xor(p, srcEDI, srcEDI);
-   emit_mov(p, countEBP, make_fn_arg(p, 2));
-   emit_cmp(p, countEBP, srcEDI);
-   fixup = emit_jcc_forward(p, cc_E);
-
+   x86_xor(p, srcEDI, srcEDI);
+   x86_mov(p, countEBP, make_fn_arg(p, 2));
+   x86_cmp(p, countEBP, srcEDI);
+   fixup = x86_jcc_forward(p, cc_E);
 
    /* Initialize destination register. 
     */
-   emit_mov(p, vertexEAX, make_fn_arg(p, 3));
+   x86_mov(p, vertexEAX, make_fn_arg(p, 3));
 
    /* Dereference ctx to get tnl, then vtx:
     */
-   emit_mov(p, vtxESI, make_fn_arg(p, 1));
-   emit_mov(p, vtxESI, make_disp(vtxESI, get_offset(ctx, &ctx->swtnl_context)));
+   x86_mov(p, vtxESI, make_fn_arg(p, 1));
+   x86_mov(p, vtxESI, make_disp(vtxESI, get_offset(ctx, &ctx->swtnl_context)));
    vtxESI = make_disp(vtxESI, get_offset(tnl, &tnl->clipspace));
 
    
    /* Possibly load vp0, vp1 for viewport calcs:
     */
    if (vtx->need_viewport) {
-      emit_movups(p, vp0, make_disp(vtxESI, get_offset(vtx, &vtx->vp_scale[0])));
-      emit_movups(p, vp1, make_disp(vtxESI, get_offset(vtx, &vtx->vp_xlate[0])));
+      sse_movups(p, vp0, make_disp(vtxESI, get_offset(vtx, &vtx->vp_scale[0])));
+      sse_movups(p, vp1, make_disp(vtxESI, get_offset(vtx, &vtx->vp_xlate[0])));
    }
 
    /* always load, needed or not:
     */
-   emit_movups(p, chan0, make_disp(vtxESI, get_offset(vtx, &vtx->chan_scale[0])));
-   emit_movups(p, p->identity, make_disp(vtxESI, get_offset(vtx, &vtx->identity[0])));
+   sse_movups(p, chan0, make_disp(vtxESI, get_offset(vtx, &vtx->chan_scale[0])));
+   sse_movups(p, p->identity, make_disp(vtxESI, get_offset(vtx, &vtx->identity[0])));
 
    /* Note address for loop jump */
    label = get_label(p);
@@ -840,52 +938,52 @@ static GLboolean build_vertex_emit( struct x86_program *p )
 
       /* Load current a[j].inputptr
        */
-      emit_mov(p, srcEDI, ptr_to_src);
+      x86_mov(p, srcEDI, ptr_to_src);
 
       /* Now, load an XMM reg from src, perhaps transform, then save.
        * Could be shortcircuited in specific cases:
        */
       switch (a[j].format) {
       case EMIT_1F:
-        emit_load(p, tmp, 1, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_store(p, dest, 1, tmp);
+        emit_load(p, temp, 1, deref(srcEDI), vtx->attr[j].inputsize);
+        emit_store(p, dest, 1, temp);
         break;
       case EMIT_2F:
-        emit_load(p, tmp, 2, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_store(p, dest, 2, tmp);
+        emit_load(p, temp, 2, deref(srcEDI), vtx->attr[j].inputsize);
+        emit_store(p, dest, 2, temp);
         break;
       case EMIT_3F:
         /* Potentially the worst case - hardcode 2+1 copying:
          */
-        emit_load(p, tmp, 3, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_store(p, dest, 3, tmp);
+        emit_load(p, temp, 3, deref(srcEDI), vtx->attr[j].inputsize);
+        emit_store(p, dest, 3, temp);
         break;
       case EMIT_4F:
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_store(p, dest, 4, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        emit_store(p, dest, 4, temp);
         break;
       case EMIT_2F_VIEWPORT: 
-        emit_load(p, tmp, 2, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_mulps(p, tmp, vp0);
-        emit_addps(p, tmp, vp1);
-        emit_store(p, dest, 2, tmp);
+        emit_load(p, temp, 2, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_mulps(p, temp, vp0);
+        sse_addps(p, temp, vp1);
+        emit_store(p, dest, 2, temp);
         break;
       case EMIT_3F_VIEWPORT: 
-        emit_load(p, tmp, 3, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_mulps(p, tmp, vp0);
-        emit_addps(p, tmp, vp1);
-        emit_store(p, dest, 3, tmp);
+        emit_load(p, temp, 3, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_mulps(p, temp, vp0);
+        sse_addps(p, temp, vp1);
+        emit_store(p, dest, 3, temp);
         break;
       case EMIT_4F_VIEWPORT: 
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_mulps(p, tmp, vp0);
-        emit_addps(p, tmp, vp1);
-        emit_store(p, dest, 4, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_mulps(p, temp, vp0);
+        sse_addps(p, temp, vp1);
+        emit_store(p, dest, 4, temp);
         break;
       case EMIT_3F_XYW:
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_pshufd(p, tmp, tmp, X, Y, W, Z);
-        emit_store(p, dest, 3, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_shufps(p, temp, temp, X, Y, W, Z);
+        emit_store(p, dest, 3, temp);
         break;
 
         /* Try and bond 3ub + 1ub pairs into a single 4ub operation?
@@ -897,43 +995,38 @@ static GLboolean build_vertex_emit( struct x86_program *p )
         return GL_FALSE;       /* add this later */
 
       case EMIT_4UB_4F_RGBA:
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_mulps(p, tmp, chan0);
-        emit_pk4ub(p, tmp, tmp);
-        emit_store(p, dest, 1, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_mulps(p, temp, chan0);
+        emit_pack_store_4ub(p, dest, temp);
         break;
       case EMIT_4UB_4F_BGRA:
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_pshufd(p, tmp, tmp, Z, Y, X, W);
-        emit_mulps(p, tmp, chan0);
-        emit_pk4ub(p, tmp, tmp);
-        emit_store(p, dest, 1, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_shufps(p, temp, temp, Z, Y, X, W);
+        sse_mulps(p, temp, chan0);
+        emit_pack_store_4ub(p, dest, temp);
         break;
       case EMIT_4UB_4F_ARGB:
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_pshufd(p, tmp, tmp, W, X, Y, Z);
-        emit_mulps(p, tmp, chan0);
-        emit_pk4ub(p, tmp, tmp);
-        emit_store(p, dest, 1, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_shufps(p, temp, temp, W, X, Y, Z);
+        sse_mulps(p, temp, chan0);
+        emit_pack_store_4ub(p, dest, temp);
         break;
       case EMIT_4UB_4F_ABGR:
-        emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-        emit_pshufd(p, tmp, tmp, W, Z, Y, X);
-        emit_mulps(p, tmp, chan0);
-        emit_pk4ub(p, tmp, tmp);
-        emit_store(p, dest, 1, tmp);
+        emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+        sse_shufps(p, temp, temp, W, Z, Y, X);
+        sse_mulps(p, temp, chan0);
+        emit_pack_store_4ub(p, dest, temp);
         break;
       case EMIT_4CHAN_4F_RGBA:
         switch (CHAN_TYPE) {
         case GL_UNSIGNED_BYTE:
-           emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-           emit_mulps(p, tmp, chan0);
-           emit_pk4ub(p, tmp, tmp);
-           emit_store(p, dest, 1, tmp);
+           emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+           sse_mulps(p, temp, chan0);
+           emit_pack_store_4ub(p, dest, temp);
            break;
         case GL_FLOAT:
-           emit_load(p, tmp, 4, deref(srcEDI), vtx->attr[j].inputsize);
-           emit_store(p, dest, 4, tmp);
+           emit_load(p, temp, 4, deref(srcEDI), vtx->attr[j].inputsize);
+           emit_store(p, dest, 4, temp);
            break;
         case GL_UNSIGNED_SHORT:
         default:
@@ -949,23 +1042,28 @@ static GLboolean build_vertex_emit( struct x86_program *p )
       /* add a[j].inputstride (hardcoded value - could just as easily
        * pull the stride value from memory each time).
        */
-      emit_add_imm(p, srcEDI, srcEDI, a[j].inputstride);
+      x86_lea(p, srcEDI, make_disp(srcEDI, a[j].inputstride));
       
       /* save new value of a[j].inputptr 
        */
-      emit_mov(p, ptr_to_src, srcEDI);
+      x86_mov(p, ptr_to_src, srcEDI);
 
    }
 
    /* Next vertex:
     */
-   emit_add_imm(p, vertexEAX, vertexEAX, vtx->vertex_size);
+   x86_lea(p, vertexEAX, make_disp(vertexEAX, vtx->vertex_size));
 
    /* decr count, loop if not zero
     */
-   emit_dec(p, countEBP);
-   emit_test(p, countEBP, countEBP); 
-   emit_jcc(p, cc_NZ, label);
+   x86_dec(p, countEBP);
+   x86_test(p, countEBP, countEBP); 
+   x86_jcc(p, cc_NZ, label);
+
+   /* Exit mmx state?
+    */
+   if (p->need_emms)
+      mmx_emms(p);
 
    /* Land forward jump here:
     */
@@ -973,10 +1071,10 @@ static GLboolean build_vertex_emit( struct x86_program *p )
 
    /* Pop regs and return
     */
-   emit_pop(p, get_base_reg(vtxESI));
-   emit_pop(p, countEBP);
-   emit_pop(p, srcEDI);
-   emit_ret(p);
+   x86_pop(p, get_base_reg(vtxESI));
+   x86_pop(p, countEBP);
+   x86_pop(p, srcEDI);
+   x86_ret(p);
 
    vtx->emit = (tnl_emit_func)p->store;
    return GL_TRUE;
@@ -993,6 +1091,7 @@ void _tnl_generate_sse_emit( GLcontext *ctx )
 
    p.inputs_safe = 1;          /* for now */
    p.outputs_safe = 1;         /* for now */
+   p.have_sse2 = 0;            /* testing */
    p.identity = make_reg(file_XMM, 6);
    
    if (build_vertex_emit(&p)) {
@@ -1007,7 +1106,7 @@ void _tnl_generate_sse_emit( GLcontext *ctx )
       FREE(p.store);
    }
 
-   (void)emit_movd;
-   (void)emit_inc;
-   (void)emit_xor;
+   (void)sse2_movd;
+   (void)x86_inc;
+   (void)x86_xor;
 }