Monday, April 12, 2010

Using the MMX extensions without -msse (GCC)

Introduction

Yesterday I ported the Fog-Framework to the MinGW. The biggest problem was with porting current pure MMX-EXT code to GCC without using a -msse parameter (this means you can't include xmmintrin.h).

Problem is that if you not enable SSE then you can't use MMX extensions in the code. Fog-Framework contains MMX, MMX+SSE, MMX+3dNow and SSE2 stack so I really needed to take advantage of one intrinsic in the MMX+3dNow code - _mm_movemask_pi8() (PMOVMSKB in assembler).

Solution

I created new IntrinMMXExt.h header file that is included only if SSE is not used. This header currently defines only the missing function I needed, but it can be extended in the future. The function is here, it's written using GCC assembly (GAS) and it should fit into your code without any changes:

static inline int _mm_movemask_pi8(__m64 a)
{
  int result;
  __asm__("pmovmskb %1, %0\n\t" : "=r"(result) : "y"(a));
  return result;
}

The most interesting part of code is :"y"(a) that tells GCC that a must be in MMX register. If you want to use XMM register then it will be "x". I never expected that it will be so easy to write such function, enjoy:)

Letters explanation used in __asm__ block

  • "abcd" - AX, BX, CX or DX register.
  • "q" - AX, BX, CX or DX register, low-byte when using 8-bit register (AL, BL, CL, DL).
  • "Q" - AX, BX, CX or DX register, high-byte when using 8-bit register (AH, BH, CH, DH).
  • "SD" - SI or DI registers.
  • "A" - EDX:EAX registers (64-bit value in two registers).
  • "y" - MM register.
  • "x" - XMM register.
  • "t" - ST(0) register (floating point).
  • "r" - General purpose register.
  • "m" - Memory.
  • "i" - Immediate.
  • "g" - Memory, general purpose register or immediate.

No comments:

Post a Comment