/* Copyright (c) 2008 by FlightSafety International, Inc. - Unpublished. ** All rights reserved under the copyright laws of the United States. ** @(#) $Id: DXTcompress.c,v 1.2 2008/03/25 18:25:24 carter Exp $ */ // gcc -O3 -c -masm=intel DXTcompress.c #include #include typedef unsigned char byte; #define ALIGN16(a) a __attribute__ ((aligned (16))) /* SIMD Optimized Calculation of Line Through Color Space Copyright (C) 2006 Id Software, Inc. Written by J.M.P. van Waveren This code is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ ALIGN16(const byte SIMD_SSE2_byte_0[16]) = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static void GetMinMaxColors_SSE2( const byte *colorBlock, byte *minColor, byte *maxColor) { asm ( "mov eax, %2 \n\t" "mov esi, %0 \n\t" "mov edi, %1 \n\t" // get bounding box "movdqa xmm0, qword ptr [eax+ 0] \n\t" "movdqa xmm1, qword ptr [eax+ 0] \n\t" "pminub xmm0, qword ptr [eax+16] \n\t" "pmaxub xmm1, qword ptr [eax+16] \n\t" "pminub xmm0, qword ptr [eax+32] \n\t" "pmaxub xmm1, qword ptr [eax+32] \n\t" "pminub xmm0, qword ptr [eax+48] \n\t" "pmaxub xmm1, qword ptr [eax+48] \n\t" "pshufd xmm3, xmm0, 2 | (3<<2) | (2<<4) | (3<<6) \n\t" "pshufd xmm4, xmm1, 2 | (3<<2) | (2<<4) | (3<<6) \n\t" "pminub xmm0, xmm3 \n\t" "pmaxub xmm1, xmm4 \n\t" "pshuflw xmm6, xmm0, 2 | (3<<2) | (2<<4) | (3<<6) \n\t" "pshuflw xmm7, xmm1, 2 | (3<<2) | (2<<4) | (3<<6) \n\t" "pminub xmm0, xmm6 \n\t" "pmaxub xmm1, xmm7 \n\t" // inset the bounding box "punpcklbw xmm0, _SIMD_SSE2_byte_0 \n\t" "punpcklbw xmm1, _SIMD_SSE2_byte_0 \n\t" "movdqa xmm2, xmm1 \n\t" "psubw xmm2, xmm0 \n\t" "psrlw xmm2, 4 \n\t" "paddw xmm0, xmm2 \n\t" "psubw xmm1, xmm2 \n\t" "packuswb xmm0, xmm0 \n\t" "packuswb xmm1, xmm1 \n\t" // store bounding box extents "movd dword ptr [esi], xmm0 \n\t" "movd dword ptr [edi], xmm1 \n\t" : "=m" (minColor), "=m" (maxColor) : "m" (colorBlock) : "eax", "esi", "edi", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm6", "xmm7" ); } // default to SSE2 (the fastest) static typeof(GetMinMaxColors_SSE2) *GetMinMaxColors_ = GetMinMaxColors_SSE2; int main(int argc, char *argv[]) { byte block[64]; byte minColor[4]; byte maxColor[4]; GetMinMaxColors_(block, minColor, maxColor); return 0; }