Blame libdjvu/MMX.h

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifndef _MMX_H_
Packit df99a1
#define _MMX_H_
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
#include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma interface
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#include "DjVuGlobal.h"
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
/** @name MMX.h
Packit df99a1
    Files #"MMX.h"# and #"MMX.cpp"# implement basic routines for
Packit df99a1
    supporting the MMX instructions on x86.  Future instruction sets
Packit df99a1
    for other processors may be supported in this file as well.
Packit df99a1
Packit df99a1
    Macro #MMX# is defined if the compiler supports the X86-MMX instructions.
Packit df99a1
    It does not mean however that the processor supports the instruction set.
Packit df99a1
    Variable #MMXControl::mmxflag# must be used to decide whether MMX.
Packit df99a1
    instructions can be executed.  MMX instructions are entered in the middle
Packit df99a1
    of C++ code using the following macros.  Examples can be found in
Packit df99a1
    #"IWTransform.cpp"#.
Packit df99a1
Packit df99a1
    \begin{description}
Packit df99a1
    \item[MMXrr( insn, srcreg, dstreg)] 
Packit df99a1
       Encode a register to register MMX instruction 
Packit df99a1
       (e.g. #paddw# or #punpcklwd#).
Packit df99a1
    \item[MMXar( insn, addr, dstreg )]
Packit df99a1
       Encode a memory to register MMX instruction 
Packit df99a1
       (e.g. #moveq# from memory).
Packit df99a1
    \item[MMXra( insn, srcreg, addr )]
Packit df99a1
       Encode a register to memory MMX instruction 
Packit df99a1
       (e.g. #moveq# to memory).
Packit df99a1
    \item[MMXir( insn, imm, dstreg )]
Packit df99a1
       Encode a immediate to register MMX instruction 
Packit df99a1
       (e.g #psraw#).
Packit df99a1
    \item[MMXemms]
Packit df99a1
       Execute the #EMMS# instruction to reset the FPU state.
Packit df99a1
    \end{description}
Packit df99a1
Packit df99a1
    @memo
Packit df99a1
    Essential support for MMX.
Packit df99a1
    @author: 
Packit df99a1
    L\'eon Bottou <leonb@research.att.com> -- initial implementation */
Packit df99a1
//@{
Packit df99a1
Packit df99a1
Packit df99a1
/** MMX Control. 
Packit df99a1
    Class #MMXControl# encapsulates a few static functions for 
Packit df99a1
    globally enabling or disabling MMX support. */
Packit df99a1
Packit df99a1
class MMXControl
Packit df99a1
{
Packit df99a1
 public:
Packit df99a1
  // MMX DETECTION
Packit df99a1
  /** Detects and enable MMX or similar technologies.  This function checks
Packit df99a1
      whether the CPU supports a vectorial instruction set (such as Intel's
Packit df99a1
      MMX) and enables them.  Returns a boolean indicating whether such an
Packit df99a1
      instruction set is available.  Speedups factors may vary. */
Packit df99a1
  static int enable_mmx();
Packit df99a1
  /** Disables MMX or similar technologies.  The transforms will then be
Packit df99a1
      performed using the baseline code. */
Packit df99a1
  static int disable_mmx();
Packit df99a1
  /** Contains a value greater than zero if the CPU supports vectorial
Packit df99a1
      instructions. A negative value means that you must call \Ref{enable_mmx}
Packit df99a1
      and test the value again. Direct access to this member should only be
Packit df99a1
      used to transfer the instruction flow to the vectorial branch of the
Packit df99a1
      code. Never modify the value of this variable.  Use #enable_mmx# or
Packit df99a1
      #disable_mmx# instead. */
Packit df99a1
  static int mmxflag;  // readonly
Packit df99a1
};
Packit df99a1
Packit df99a1
//@}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ----------------------------------------
Packit df99a1
// GCC MMX MACROS
Packit df99a1
Packit df99a1
#ifndef NO_MMX
Packit df99a1
Packit df99a1
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
Packit df99a1
typedef struct{ char c[8]; } MMX_t;
Packit df99a1
#define MMXemms \
Packit df99a1
  __asm__ volatile("emms" : : : "memory" ) 
Packit df99a1
#define MMXrr(op,src,dst) \
Packit df99a1
  __asm__ volatile( #op " %%" #src ",%%" #dst : : : "memory" ) 
Packit df99a1
#define MMXir(op,imm,dst) \
Packit df99a1
  __asm__ volatile( #op " %0,%%" #dst : : "i" (imm) : "memory" )
Packit df99a1
#define MMXar(op,addr,dst) \
Packit df99a1
  __asm__ volatile( #op " %0,%%" #dst : : "m" (*(MMX_t*)(addr)) : "memory" ) 
Packit df99a1
#define MMXra(op,src,addr) \
Packit df99a1
  __asm__ volatile( #op " %%" #src ",%0" : "=m" (*(MMX_t*)(addr)) : : "memory") 
Packit df99a1
#define MMX 1
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
// ----------------------------------------
Packit df99a1
// MSVC MMX MACROS
Packit df99a1
Packit df99a1
#if defined(_MSC_VER) && defined(_M_IX86)
Packit df99a1
// Compiler option /GM is required
Packit df99a1
#pragma warning( disable : 4799 )
Packit df99a1
#define MMXemms \
Packit df99a1
  __asm { emms }
Packit df99a1
#define MMXrr(op,src,dst) \
Packit df99a1
  __asm { op dst,src }
Packit df99a1
#define MMXir(op,imm,dst) \
Packit df99a1
  __asm { op dst,imm }
Packit df99a1
#define MMXar(op,addr,dst) \
Packit df99a1
  { register __int64 var=*(__int64*)(addr); __asm { op dst,var } }
Packit df99a1
#define MMXra(op,src,addr) \
Packit df99a1
  { register __int64 var; __asm { op [var],src };  *(__int64*)addr = var; } 
Packit df99a1
// Probably not as efficient as GCC macros
Packit df99a1
#define MMX 1
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#endif
Packit df99a1
Packit df99a1
// -----------
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif
Packit df99a1
#endif