tgsi: Implement LOG opcode for SSE2 codegen.
authorMichal Krol <michal@tungstengraphics.com>
Tue, 19 Aug 2008 10:07:25 +0000 (12:07 +0200)
committerMichal Krol <michal@tungstengraphics.com>
Tue, 19 Aug 2008 10:08:14 +0000 (12:08 +0200)
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_sse2.c

index d584a4e4fa4d11e19a442d6484daa2218e31bb9e..88a34a69613d7045c8b01a2c265209e544dfdce7 100644 (file)
@@ -1777,18 +1777,18 @@ exec_instruction(
       micro_lg2( &r[1], &r[2] );  /* r1 = lg2(r2) */
       micro_flr( &r[0], &r[1] );  /* r0 = floor(r1) */
       if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
-        STORE( &r[0], 0, CHAN_X );
+         STORE( &r[0], 0, CHAN_X );
       }
       if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
          micro_exp2( &r[0], &r[0] );       /* r0 = 2 ^ r0 */
          micro_div( &r[0], &r[2], &r[0] ); /* r0 = r2 / r0 */
-        STORE( &r[0], 0, CHAN_Y );
+         STORE( &r[0], 0, CHAN_Y );
       }
       if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-        STORE( &r[1], 0, CHAN_Z );
+         STORE( &r[1], 0, CHAN_Z );
       }
       if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
-        STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
+         STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
       }
       break;
 
index 684bc081e5549aee67567c43ba51ee99ae1658f9..485e5a0e6f571d528d110831dd4e1f37e0a897ce 100644 (file)
@@ -1367,7 +1367,38 @@ emit_instruction(
       break;
 
    case TGSI_OPCODE_LOG:
-      return 0;
+      if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
+          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
+          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) {
+         FETCH( func, *inst, 0, 0, CHAN_X );
+         emit_abs( func, 0 );
+         emit_MOV( func, 1, 0 );
+         emit_lg2( func, 1 );
+         /* dst.z = lg2(abs(src.x)) */
+         if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) {
+            STORE( func, *inst, 1, 0, CHAN_Z );
+         }
+         if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
+             IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) {
+            emit_flr( func, 1 );
+            /* dst.x = floor(lg2(abs(src.x))) */
+            if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X )) {
+               STORE( func, *inst, 1, 0, CHAN_X );
+            }
+            /* dst.x = abs(src)/ex2(floor(lg2(abs(src.x)))) */
+            if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) {
+               emit_ex2( func, 1 );
+               emit_rcp( func, 1, 1 );
+               emit_mul( func, 0, 1 );
+               STORE( func, *inst, 0, 0, CHAN_Y );
+            }
+         }
+      }
+      /* dst.w = 1.0 */
+      if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W )) {
+         emit_tempf( func, 0, TEMP_ONE_I, TEMP_ONE_C );
+         STORE( func, *inst, 0, 0, CHAN_W );
+      }
       break;
 
    case TGSI_OPCODE_MUL: