This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/11910] New: inline assembler causes compiler error


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11910

           Summary: inline assembler causes compiler error
           Product: gcc
           Version: 3.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: paradox at bbhc dot org
                CC: gcc-bugs at gcc dot gnu dot org

gcc -c -ffreestanding -fno-rtti -fno-exceptions -fno-builtin -nostdlib -
Iinclude out/surface.o modules/aqua/surface.cpp

Reading specs from ../lib/gcc-lib/mingw32/3.2/specs
Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --
host=
mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --
enable
-languages=f77,c++,objc,ada --disable-win32-registry --disable-shared
Thread model: win32
gcc version 3.2 (mingw special 20020817-1)

Windows XP Professional

Internal compiler error in instantiate_virtual_regs_1 at function.c:3972

Apparently the inline asm causes some sort of error. Anything else I can 
include that would be helpful, let me know.ex

--- preprocessed source ---

# 1 "modules/aqua/surface.cpp"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "modules/aqua/surface.cpp"
# 1 "include/aqua/surface.h" 1



# 1 "include/d_types.h" 1
# 17 "include/d_types.h"
        typedef long long octa;
        typedef long tetra;
        typedef short wyde;
        typedef char byte;

        typedef unsigned long long octa_u;
        typedef unsigned long tetra_u;
        typedef unsigned short wyde_u;
        typedef unsigned char byte_u;
# 5 "include/aqua/surface.h" 2
# 1 "include/lib/geom/g_rect.h" 1
# 27 "include/lib/geom/g_rect.h"
# 1 "include/lib/geom/g_segment.h" 1
# 22 "include/lib/geom/g_segment.h"
# 1 "include/lib/geom/g_point.h" 1
# 23 "include/lib/geom/g_point.h"
namespace dosadi
{
        namespace geom
        {
# 39 "include/lib/geom/g_point.h"
                class gPoint
                {
                public:

                  float x, y;


                  gPoint () {}


                  gPoint (float ix, float iy) : x(ix), y(iy) {}


                  gPoint (const gPoint &copy) : x(copy.x), y(copy.y) {}


                  virtual ~gPoint () {}
                };


        };

};
# 23 "include/lib/geom/g_segment.h" 2

namespace dosadi
{
        namespace geom
        {
# 40 "include/lib/geom/g_segment.h"
                class gSegment
                {
                public:

                  gPoint start, end;


                  gSegment () {}


                  gSegment (float ix, float iy, float ix2, float iy2) : start
(ix, iy), end(ix2, iy2) {}


                  gSegment (const gSegment &copy) : start(copy.start), end
(copy.end) {}


                  virtual ~gSegment () {}


                  void Start(float x, float y) { start.x=x; start.y=y; }


                  void End(float x, float y) { end.x=x; end.y=y; }
                };

        };
};
# 28 "include/lib/geom/g_rect.h" 2

namespace dosadi
{
        namespace geom
        {
# 66 "include/lib/geom/g_rect.h"
class gRect
{
public:

  float xmin, ymin, xmax, ymax;


  gRect ();


  gRect (float ixmin, float iymin, float ixmax, float iymax);


  gRect (const gRect &copy);


  virtual ~gRect ();


  void intersect (float ixmin, float iymin, float ixmax, float iymax);


  inline void intersect (const gRect &other)
  { intersect (other.xmin, other.ymin, other.xmax, other.ymax); }


  bool intersects (const gRect &target) const;





  void Union (float ixmin, float iymin, float ixmax, float iymax);





  inline void Union (const gRect &other)
  { Union (other.xmin, other.ymin, other.xmax, other.ymax); }






  void Exclude (float ixmin, float iymin, float ixmax, float iymax);


  inline void Exclude (const gRect &other)
  { Exclude (other.xmin, other.ymin, other.xmax, other.ymax); }





  void Subtract (const gRect &rect);


  inline bool IsEmpty () const
  { return (xmin >= xmax) || (ymin >= ymax); }


  inline void MakeEmpty ()
  { xmin = xmax = 0; }


  inline void Set (float ixmin, float iymin, float ixmax, float iymax)
  {
    xmin = ixmin; xmax = ixmax;
    ymin = iymin; ymax = iymax;
  }


  inline void Set (const gRect &target)
  {
    xmin = target.xmin; xmax = target.xmax;
    ymin = target.ymin; ymax = target.ymax;
  }


  inline void SetPos (float x, float y)
  { xmin = x; ymin = y; }


  inline void SetSize (float w, float h)
  { xmax = xmin + w; ymax = ymin + h; }


  inline void Move (float dX, float dY)
  { xmin += dX; xmax += dX; ymin += dY; ymax += dY; }


  inline float Width () const { return xmax - xmin; }


  inline float Height () const { return ymax - ymin; }


  inline bool Contains (float x, float y) const
  { return (x >= xmin) && (x < xmax) && (y >= ymin) && (y < ymax); }


  inline bool ContainsRel (float x, float y) const
  { return (x >= 0) && (x < Width ()) && (y >= 0) && (y < Height ()); }


  inline bool Equal (float ixmin, float iymin, float ixmax, float iymax) const
  { return (xmin == ixmin) && (ymin == iymin) &&
           (xmax == ixmax) && (ymax == iymax); }

  inline bool Equal (const gRect &other) const
  { return Equal (other.xmin, other.ymin, other.xmax, other.ymax); }


  inline void Normalize ()
  {
    if (xmin > xmax) { float tmp = xmin; xmin = xmax; xmax = tmp; }
    if (ymin > ymax) { float tmp = ymin; ymin = ymax; ymax = tmp; }
  }


  inline float Area () const
  {
    if (IsEmpty ())
      return 0;
    else
      return Width () * Height ();
  }


  void AddAdjanced (const gRect &rect);


  inline bool operator == (const gRect& rect) const
  {
    return Equal (rect);
  }


  inline bool operator != (const gRect &rect) const
  {
    return !Equal (rect);
  }


  inline void Extend (float x, float y)
  {
    if (xmin > x) xmin = x; if (xmax < x) xmax = x;
    if (ymin > y) ymin = y; if (ymax < y) ymax = y;
  }


  inline void Minimum(const gRect& rect)
  {
          if (Width()>rect.Width())
                xmax = xmin+rect.Width();

          if (Height()>rect.Height())
                ymax = ymin+rect.Height();
  }


  inline void Maximum(const gRect& rect)
  {
          if (Width()<rect.Width())
                xmax = xmin+rect.Width();

          if (Height()<rect.Height())
                ymax = ymin+rect.Height();
  }


  void Join (const gRect &rect);


  void Outset(float n);


  void Inset(float n);
# 254 "include/lib/geom/g_rect.h"
  bool ClipLineGeneral (float& x1, float& y1, float& x2, float& y2);
# 263 "include/lib/geom/g_rect.h"
  bool ClipLine (float& x1, float& y1, float& x2, float& y2);
# 272 "include/lib/geom/g_rect.h"
  bool ClipLineSafe (float& x1, float& y1, float& x2, float& y2);
# 281 "include/lib/geom/g_rect.h"
  bool ClipLineSafe (gSegment &seg) { ClipLineSafe(seg.start.x, seg.start.y, 
seg.end.x, seg.end.y); }

};



        };
};
# 6 "include/aqua/surface.h" 2
# 1 "include/lib/geom/g_clip.h" 1





# 1 "include/lib/geom/g_rect_region.h" 1
# 31 "include/lib/geom/g_rect_region.h"
namespace dosadi
{
        namespace geom
        {

const int FRAGMENT_BUFFER_SIZE=64;
# 50 "include/lib/geom/g_rect_region.h"
class gRectRegion
{
protected:

  gRect* region;

  int region_count;

  int region_max;

  gRect fragment[FRAGMENT_BUFFER_SIZE];

  int gather_mark;


  void pushRect(gRect const &);

  void deleteRect(int);



  void fragmentRect(gRect&, gRect&, int mode);
  void nkSplit(gRect& r1, gRect& r2);

  void fragmentContainedRect(gRect &r1, gRect &r2);

  void markForGather();

  void gatherFragments();

public:

  gRectRegion();


  gRectRegion(const gRectRegion &region);


  ~gRectRegion();


  void Include(const gRect &rect);

  void Exclude(const gRect &rect);

  void ClipTo(gRect &clip);


  int Count() const { return region_count; }

  gRect& RectAt(int i) const { return region[i]; }

  bool Contains (float x, float y);

  void makeEmpty();

  void Copy(const gRectRegion &region);
};


        };
};
# 7 "include/lib/geom/g_clip.h" 2



# 1 "include/lib/containers/c_vector.h" 1



# 1 "include/lib/dosadi_libc/stddef.h" 1
# 22 "include/lib/dosadi_libc/stddef.h"
typedef unsigned int size_t;





typedef size_t size_type;
# 5 "include/lib/containers/c_vector.h" 2
# 1 "include/lib/dosadi_libc/string.h" 1
# 44 "include/lib/dosadi_libc/string.h"
extern "C" {



extern void *malloc(size_t size);


extern void free(void *p);



size_t _dosadi_libc_strlen(const char *s);




size_t _dosadi_libc_wstrlen(const wchar_t *s);






size_t _dosadi_libc_strnlen(const char *s, size_t maxlen);





size_t _dosadi_libc_wstrnlen(const wchar_t *s, size_t maxlen);



int _dosadi_libc_strcmp(const char *s1, const char *s2);




int _dosadi_libc_strncmp(const char *s1, const char *s2, size_t size);



char *_dosadi_libc_strcpy(char *s1, const char *s2);



char *_dosadi_libc_wcscpy(wchar_t *s1, const wchar_t *s2);




char *_dosadi_libc_strncpy(char *s1, const char *s2, size_t size);




char *_dosadi_libc_wcsncpy(wchar_t *s1, const wchar_t *s2, size_t size);







char *_dosadi_libc_strpncpy(char *s1, char *s2, size_t size);







char *_dosadi_libc_wcspncpy(char *s1, char *s2, size_t size);



char *_dosadi_libc_strpcpy(char *s1, char *s2);



char *_dosadi_libc_wcspcpy(char *s1, char *s2);



char *_dosadi_libc_strstr(const char *haystack, const char *needle);



wchar_t *_dosadi_libc_wstrstr(const wchar_t *haystack, const wchar_t *needle);




size_t _dosadi_libc_strspn(const char *string, const char *skipset);




size_t _dosadi_libc_strcspn(const char *string, const char *stopset);



char * _dosadi_libc_strpbrk(const char *string, const char *stopset);



char *_dosadi_libc_strchr(const char *string, int c);



char *_dosadi_libc_strrchr(const char *string, int c, size_t size);



char *_dosadi_libc_strchrnul(const char *string, int c);




char *_dosadi_libc_strrchrnul(const char *string, int c, size_t size);





void *_dosadi_libc_memmem(const void *haystack, size_t haystack_size, const 
void *needle, size_t needle_size);




void *_dosadi_libc_memcpy(void *to, const void *from, size_t size);




void *_dosadi_libc_wmemcpy(wchar_t *to, const wchar_t *from, size_t size);




void *_dosadi_libc_mempcpy(void *to, const void *from, size_t size);




void *_dosadi_libc_wmempcpy(wchar_t *to, const wchar_t *from, size_t size);



void *_dosadi_libc_memmove(void *to, const void *from, size_t size);



void *_dosadi_libc_wmemmove(void *to, const void *from, size_t size);




void *_dosadi_libc_memccpy(void *to, void *from, int c, size_t size);




void *_dosadi_libc_wmemccpy(void *to, void *from, int c, size_t size);



void *_dosadi_libc_memset(void *block, int c, size_t size);



wchar_t *_dosadi_libc_wmemset(wchar_t *block, int c, size_t size);



int _dosadi_libc_memcmp(const void *a1, const void *a2, size_t size);


};




static inline char *strdup(const char *s)
{
 size_t size = _dosadi_libc_strlen(s)+1;
 char *s2 = (char *)malloc(size);

 if (!s2) return 0;
 else return (char *)_dosadi_libc_memcpy(s2, s, size);
}



static inline char *wcsdup(const wchar_t *s)
{
 size_t size = (_dosadi_libc_wstrlen(s)<<1)+2;
 wchar_t *s2 = (wchar_t *)malloc(size);

 if (!s2) return 0;
 else return (char *)_dosadi_libc_wmemcpy(s2, s, size>>1);
}




static inline char *strndup(const char *s, size_t max)
{
 size_t size = _dosadi_libc_strlen(s)+1;
 size_t sl = (max < size ? max+1 : size);

 char *s2 = (char *)malloc(sl);

 if (!s2) return 0;
 else
 {
   _dosadi_libc_memcpy(s2, s, sl-1);
   s2[sl]=0;

   return s2;
 }
}
# 274 "include/lib/dosadi_libc/string.h"
static inline char *strncat (char *to, const char *from, size_t size)
{
  to[_dosadi_libc_strlen(to) + size] = '\0';
  _dosadi_libc_strncpy (to + _dosadi_libc_strlen(to), from, size);
  return to;
}
# 288 "include/lib/dosadi_libc/string.h"
static inline wchar_t *wcsncat (wchar_t *wto, const wchar_t *wfrom, size_t 
size)
{
  wto[_dosadi_libc_wstrlen (wto) + size] = L'\0';
  _dosadi_libc_wcsncpy (wto + _dosadi_libc_wstrlen (wto), wfrom, size);
  return wto;
}
# 6 "include/lib/containers/c_vector.h" 2

namespace dosadi
{
        namespace container {

                const size_type vector_grow_delta = 16;
# 22 "include/lib/containers/c_vector.h"
                template <class T>
                class vector
                {
                private:

                 int buffer_size,
                         stack_top;


                 T *buffer;

                public:



                  vector ():buffer_size(0), stack_top(0), buffer(0)
                  {
                  }



                  vector (vector<T> &v){
                        buffer_size = v.buffer_size;
                        stack_top = v.stack_top;

                        buffer = new T[buffer_size];
                        _dosadi_libc_memcpy(buffer, v.buffer, stack_top*sizeof
(T));
                  }

                  ~vector()
                  {
                        if (buffer) delete [] buffer;
                  }


                  size_type size() const { return stack_top; }


                  size_type max_size() const { return 1<<30; }






                   void resize(size_type new_size)
                   {
                           if (new_size==buffer_size) return;

                           T *nb = new T[new_size];

                           if (new_size<buffer_size && buffer!=0)
                           {
                                   _dosadi_libc_memcpy(nb, buffer, 
new_size*sizeof(T));
                                   buffer_size=new_size;

                                   if (stack_top>buffer_size)
                                        stack_top=buffer_size;

                           }
                           else if (buffer!=0)
                           {
                                   _dosadi_libc_memcpy(nb, buffer, 
stack_top*sizeof(T));
                                   buffer_size=new_size;
                           }
                           else
                           {
                                   buffer_size=new_size;
                           }

                           delete [] buffer;
                           buffer = nb;
                   }


                   size_type capacity() const { return buffer_size; }
# 106 "include/lib/containers/c_vector.h"
                    void reserve(size_type n)
                    {
                            if (n<buffer_size) return;

                            resize(n);
                    }


                    bool empty() const
                    {
                                return stack_top == 0;
                    }


                    void pop_back()
                    {
                            if (stack_top>0) --stack_top;
                    }


                    void erase(size_type i)
                    {
                            if (i>=stack_top) return;
                            if (i==stack_top-1) { pop_back(); return; }

                                T *tmp = &buffer[i];
                                T *tmp2 = &buffer[i+i];

                                _dosadi_libc_memcpy(tmp, tmp2, (size()-i-1) * 
sizeof(T));
                                --stack_top;
                    }


                    void push_back(const T& x)
                    {
                                if (stack_top >= buffer_size)
                                        reserve(buffer_size+vector_grow_delta);

                                buffer[stack_top++] = x;
                    }


                    void clear()
                    {
                                stack_top = 0;
                    }


                    T& front()
                    {
                            return buffer[0];
                    }


                    T& back()
                    {
                            return buffer[stack_top-1];
                    }


                    size_type begin()
                    { return 0; }


                    size_type end()
                    { return stack_top; }


                    size_type find(const T& x)
                    {
                            for(size_type i=begin(); i<end(); ++i)
                            {
                                        if (buffer[i] == x)
                                                return i;
                            }

                            return end();
                    }




                    T& at(size_type i)
                    {
                            return buffer[i];
                    }




                    T& operator[](size_type i)
                    {
                            return buffer[i];
                    }

                    vector<T>& operator=(const vector<T> &b)
                        {
                                if (buffer)
                                        delete [] buffer;

                                buffer_size = b.buffer_size;
                                stack_top = b.stack_top;

                                buffer = new T[buffer_size];
                                _dosadi_libc_memcpy(buffer, b.buffer, 
b.stack_top*sizeof(T));

                                return *this;
                        }

                };



        };
};
# 11 "include/lib/geom/g_clip.h" 2

namespace dosadi
{
        namespace geom
        {
                class gClippingRegion
                {

                        gRectRegion clip_region;
                        gRect clip_bounds;


                public:
                        gClippingRegion(tetra_u w, tetra_u h): clip_bounds(0, 
0, w, h)
                        {

                        }

                        ~gClippingRegion()
                        {

                        }



                        void Include(gRect &rect);



                        void Exclude(gRect &rect);


                        void Set(float xmin, float ymin, float xmax, float 
ymax)
                        { clip_bounds.Set(xmin, ymin, xmax, ymax); }


                        bool Contains(float x, float y) { return Contains
(gPoint(x,y)); }


                        bool Contains(gPoint p);



                        container::vector<gSegment>
                        SegmentLine(gSegment &seg);



                        container::vector<gRect>
                        SegmentRect(gRect &rect);


                };


        };

};
# 7 "include/aqua/surface.h" 2

namespace dosadi
{



        namespace Aqua
        {

                const byte_u PEN_COPY = 0;
                const byte_u PEN_ALPHA_AVG = 1;
                const byte_u PEN_ALPHA_SRC = 2;
                const byte_u PEN_ALPHA_DST = 3;
                const byte_u PEN_XOR = 4;
                const byte_u PEN_AND = 5;
                const byte_u PEN_OR = 6;
                const byte_u PEN_RUB = 7;
                const byte_u PEN_RUB_MAP = 8;
                const byte_u PEN_ADD = 9;
                const byte_u PEN_SUB = 10;

                const byte_u CURVE_QUAD_UL = 0;
                const byte_u CURVE_QUAD_LL = 1;
                const byte_u CURVE_QUAD_UR = 2;
                const byte_u CURVE_QUAD_LR = 3;




                union Pixel
                {
                        struct color_component
                        {
                                byte_u r,
                                                g,
                                                b,
                                                a;
                        } b;

                        tetra_u t;


                        Pixel() {};


                        Pixel(tetra_u c):t(c) {}


                        Pixel(byte_u _r, byte_u _g, byte_u _b, byte_u _a)
                        { b.r =_r; b.g=_g; b.b=_b; b.a=_a; }


                        Pixel(Pixel &c):t(c.t) {}
                };




                class Surface
                {

                        Pixel *surf;


                        Surface *rub_surf;

                        tetra_u width,
                                        height;

                        byte_u pen_mode;


                        geom::gRect clip;

                public:

                        Surface();


                        ~Surface();





                        Surface(tetra_u w, tetra_u h);
# 101 "include/aqua/surface.h"
                        bool Create(tetra_u w, tetra_u h);




                        bool isEmpty() { return surf==0; }






                        void Select(Surface *rub);




                        geom::gRect getClip()
                        { return clip; }




                        void setClip(const geom::gRect &r);


                        tetra_u Width() { return width; }


                        tetra_u Height() { return height; }


                public:




                        void Clear(Pixel c);
# 147 "include/aqua/surface.h"
                        bool getPixel(float x, float y, Pixel &c);
# 159 "include/aqua/surface.h"
                        bool getMappedPixel(float x, float y, float w, float 
h, Pixel &c);
# 169 "include/aqua/surface.h"
                        bool getTiledPixel(float x, float y, Pixel &c);
# 178 "include/aqua/surface.h"
                        bool putPixel(float x, float y, const Pixel &c);
# 188 "include/aqua/surface.h"
                        void drawHLine(float x, float y, float w, const Pixel 
&c);
# 198 "include/aqua/surface.h"
                        void drawVLine(float x, float y, float h, const Pixel 
&c);
# 207 "include/aqua/surface.h"
                        void drawLine(const geom::gRect &r, const Pixel &c);
# 216 "include/aqua/surface.h"
                        void drawRect(const geom::gRect &r, const Pixel &c);
# 225 "include/aqua/surface.h"
                        void fillRect(const geom::gRect &r, const Pixel &c);
# 235 "include/aqua/surface.h"
                        void drawCircle(const geom::gRect &r, const Pixel &c);
# 245 "include/aqua/surface.h"
                        void fillCircle(const geom::gRect &r, const Pixel &c);
# 255 "include/aqua/surface.h"
                        void drawEllipse(const geom::gRect &r, const Pixel &c);
# 265 "include/aqua/surface.h"
                        void fillEllipse(const geom::gRect &r, const Pixel &c);
# 276 "include/aqua/surface.h"
                        void drawQuarterCircle(const geom::gRect &r, byte_u 
quadrant, const Pixel &c);
# 287 "include/aqua/surface.h"
                        void fillQuarterCircle(const geom::gRect &r, byte_u 
quadrant, const Pixel &c);
# 298 "include/aqua/surface.h"
                        void drawQuarterEllipse(const geom::gRect &r, byte_u 
quadrant, const Pixel &c);
# 309 "include/aqua/surface.h"
                        void fillQuarterEllipse(const geom::gRect &r, byte_u 
quadrant, const Pixel &c);
# 321 "include/aqua/surface.h"
                        void blitSurface(Surface &s, const geom::gRect &src, 
const geom::gRect &dst);
# 334 "include/aqua/surface.h"
                        void blitMaskedSurface(Surface &s, const geom::gRect 
&src, const geom::gRect &dst, const Pixel &c);

                };

        };
};
# 2 "modules/aqua/surface.cpp" 2
# 1 "include/lib/dosadi_libc/math.h" 1



# 1 "include/lib/dosadi_libc/fdlibm.h" 1
# 42 "include/lib/dosadi_libc/fdlibm.h"
extern int signgam;



enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
# 58 "include/lib/dosadi_libc/fdlibm.h"
extern enum fdversion _fdlib_version;






struct exception {
        int type;
        char *name;
        double arg1;
        double arg2;
        double retval;
};
# 94 "include/lib/dosadi_libc/fdlibm.h"
extern double acos (double);
extern double asin (double);
extern double atan (double);
extern double atan2 (double, double);
extern double cos (double);
extern double sin (double);
extern double tan (double);

extern double cosh (double);
extern double sinh (double);
extern double tanh (double);

extern double exp (double);
extern double frexp (double, int *);
extern double ldexp (double, int);
extern double log (double);
extern double log10 (double);
extern double modf (double, double *);

extern double pow (double, double);
extern double sqrt (double);

extern double ceil (double);
extern double fabs (double);
extern double floor (double);
extern double fmod (double, double);

extern double erf (double);
extern double erfc (double);
extern double gamma (double);
extern double hypot (double, double);
extern int isnan (double);
extern int finite (double);
extern double j0 (double);
extern double j1 (double);
extern double jn (int, double);
extern double lgamma (double);
extern double y0 (double);
extern double y1 (double);
extern double yn (int, double);

extern double acosh (double);
extern double asinh (double);
extern double atanh (double);
extern double cbrt (double);
extern double logb (double);
extern double nextafter (double, double);
extern double remainder (double, double);



extern double scalb (double, double);


extern int matherr (struct exception *);




extern double significand (double);




extern double copysign (double, double);
extern int ilogb (double);
extern double rint (double);
extern double scalbn (double, int);




extern double expm1 (double);
extern double log1p (double);
# 179 "include/lib/dosadi_libc/fdlibm.h"
extern double __ieee754_sqrt (double);
extern double __ieee754_acos (double);
extern double __ieee754_acosh (double);
extern double __ieee754_log (double);
extern double __ieee754_atanh (double);
extern double __ieee754_asin (double);
extern double __ieee754_atan2 (double,double);
extern double __ieee754_exp (double);
extern double __ieee754_cosh (double);
extern double __ieee754_fmod (double,double);
extern double __ieee754_pow (double,double);
extern double __ieee754_lgamma_r (double,int *);
extern double __ieee754_gamma_r (double,int *);
extern double __ieee754_lgamma (double);
extern double __ieee754_gamma (double);
extern double __ieee754_log10 (double);
extern double __ieee754_sinh (double);
extern double __ieee754_hypot (double,double);
extern double __ieee754_j0 (double);
extern double __ieee754_j1 (double);
extern double __ieee754_y0 (double);
extern double __ieee754_y1 (double);
extern double __ieee754_jn (int,double);
extern double __ieee754_yn (int,double);
extern double __ieee754_remainder (double,double);
extern int __ieee754_rem_pio2 (double,double*);



extern double __ieee754_scalb (double,double);
# 5 "include/lib/dosadi_libc/math.h" 2
# 3 "modules/aqua/surface.cpp" 2
# 17 "modules/aqua/surface.cpp"
inline byte_u CLAMP_BYTE(int x)
 { return (x > 255 ? 255 :
    ( x < 0 ? 0 : (byte_u)x )); }


static byte_u *blend_table=0;


static void init_blend_table()
{
# 42 "modules/aqua/surface.cpp"
        float color;

        blend_table = new byte_u[256*256];

        for(int i=0; i<256; ++i)
        {
                color = i;

                for(int j=0; j<256; ++j)
                {
                        blend_table[((j)<<8) + (i)] = (byte_u)(color * 
(((float)j) / 255.0));
                }
        }
}

dosadi::Aqua::Surface::Surface():surf(0), width(0), height(0), pen_mode(0), 
rub_surf(0)
{
        if (blend_table==0)
                init_blend_table();

}

dosadi::Aqua::Surface::~Surface()
{
        if (surf) delete [] surf;
}

dosadi::Aqua::Surface::Surface(tetra_u w, tetra_u h):width(w), height(h), 
pen_mode(0), rub_surf(0)
{
        surf = new Pixel[w*h];

        clip.Set(0,0,w,h);
}

bool
dosadi::Aqua::Surface::Create(tetra_u w, tetra_u h)
{
        if (surf) return false;

        width=w;
        height=h;

        surf = new Pixel[w*h];

        clip.Set(0,0,w-1,h-1);

        if (surf==0)
                return false;
        else
                return true;

}

void
dosadi::Aqua::Surface::Select(Surface *rub)
{
 rub_surf = rub;
}

void
dosadi::Aqua::Surface::setClip(const geom::gRect &r)
{
        clip.Set(r);

        if (clip.xmin < 0) clip.xmin=0;
        if (clip.ymin < 0) clip.ymin=0;

        if (clip.xmax > width-1) clip.xmax=width-1;
        if (clip.ymax > height-1) clip.ymax=height-1;
}

void
dosadi::Aqua::Surface::Clear(Pixel c)
{
        __asm__ __volatile__("cld\n"
                                                 "movl %0, %%edi\n"
                                                 "movl %1, %%eax\n"
                                                 "movl %2, %%ecx\n"
                                                 "repnz stosl\n"
                                                 :
                                                 : "rm" (surf), "rm" 
(c.t), "rm" ((width*height)>>2)
                                                 : "eax", "edi", "ecx", "flags"
);
}

bool
dosadi::Aqua::Surface::getPixel(float x, float y, Pixel &c)
{

        if (surf==0 || !clip.Contains(x,y))
        return false;

        c = surf[(int)(((y)*width)+(x))];

        return true;
}

bool
dosadi::Aqua::Surface::getMappedPixel(float x, float y, float w, float h, 
Pixel &c)
{
        if (surf==0)
                return false;

        float u = (x*width) / w,
                  v = (y*height) / h;

        if (!clip.Contains(u,v))
        return false;

        c = surf[(int)(((v)*width)+(u))];

        return true;
}

bool
dosadi::Aqua::Surface::getTiledPixel(float x, float y, Pixel &c)
{
        if (surf==0)
                return false;

        float tx, ty;






        asm("fild %3\n"
                "fld %2\n"
                "fprem1\n"
                "fstp %1\n"
                "fild %5\n"
                "fld %4\n"
                "fprem1\n"
                "fstp %0\n"
                : "=rm" (tx), "=rm" (ty)
                : "rm" (y), "rm" (height), "rm" (x), "rm" (width)
                : "st", "st(1)"
                );

        if (!clip.Contains(tx,ty))
        return false;

        c = surf[(int)(((ty)*width)+(tx))];

        return true;
}

bool
dosadi::Aqua::Surface::putPixel(float x, float y, const Pixel &c)
{
        Pixel t;
        byte_u src_alpha, dst_alpha;

        if (surf==0 || !clip.Contains(x,y))
        return false;

    switch(pen_mode)
    {
                case PEN_COPY:
                        surf[(int)(((y)*width)+(x))].t = c.t;
                        break;

                case PEN_ALPHA_AVG:
                        t.t = surf[(int)(((y)*width)+(x))].t;

                        dst_alpha = (c.b.a+t.b.a)>>1;
                        src_alpha = 255-dst_alpha;

                        t.b.b = blend_table[((src_alpha)<<8) + (t.b.b)] + 
blend_table[((dst_alpha)<<8) + (c.b.b)];
                        t.b.g = blend_table[((src_alpha)<<8) + (t.b.g)] + 
blend_table[((dst_alpha)<<8) + (c.b.g)];
                        t.b.r = blend_table[((src_alpha)<<8) + (t.b.r)] + 
blend_table[((dst_alpha)<<8) + (c.b.r)];

                        surf[(int)(((y)*width)+(x))].t = t.t;
                        break;

                case PEN_ALPHA_SRC:
                        t.t = surf[(int)(((y)*width)+(x))].t;

                        dst_alpha = t.b.a;
                        src_alpha = 255-dst_alpha;

                        t.b.b = blend_table[((src_alpha)<<8) + (t.b.b)] + 
blend_table[((dst_alpha)<<8) + (c.b.b)];
                        t.b.g = blend_table[((src_alpha)<<8) + (t.b.g)] + 
blend_table[((dst_alpha)<<8) + (c.b.g)];
                        t.b.r = blend_table[((src_alpha)<<8) + (t.b.r)] + 
blend_table[((dst_alpha)<<8) + (c.b.r)];

                        surf[(int)(((y)*width)+(x))].t = t.t;
                        break;

                case PEN_ALPHA_DST:
                        t.t = surf[(int)(((y)*width)+(x))].t;

                        dst_alpha = c.b.a;
                        src_alpha = 255-dst_alpha;

                        t.b.b = blend_table[((src_alpha)<<8) + (t.b.b)] + 
blend_table[((dst_alpha)<<8) + (c.b.b)];
                        t.b.g = blend_table[((src_alpha)<<8) + (t.b.g)] + 
blend_table[((dst_alpha)<<8) + (c.b.g)];
                        t.b.r = blend_table[((src_alpha)<<8) + (t.b.r)] + 
blend_table[((dst_alpha)<<8) + (c.b.r)];

                        surf[(int)(((y)*width)+(x))].t = t.t;
                        break;

                case PEN_XOR:
                        surf[(int)(((y)*width)+(x))].t ^= c.t;
                        break;

                case PEN_AND:
                        surf[(int)(((y)*width)+(x))].t &= c.t;
                        break;

                case PEN_OR:
                        surf[(int)(((y)*width)+(x))].t |= c.t;
                        break;

                case PEN_ADD:
                        t.t = surf[(int)(((y)*width)+(x))].t;

                        t.b.r = CLAMP_BYTE(t.b.r + c.b.r);
                        t.b.g = CLAMP_BYTE(t.b.g + c.b.g);
                        t.b.b = CLAMP_BYTE(t.b.b + c.b.b);

                        surf[(int)(((y)*width)+(x))].t = t.t;
                        break;

                case PEN_SUB:
                        t.t = surf[(int)(((y)*width)+(x))].t;

                        t.b.r = CLAMP_BYTE(t.b.r - c.b.r);
                        t.b.g = CLAMP_BYTE(t.b.g - c.b.g);
                        t.b.b = CLAMP_BYTE(t.b.b - c.b.b);

                        surf[(int)(((y)*width)+(x))].t = t.t;
                        break;

                case PEN_RUB:
                {
                        Pixel rc;

                        if (rub_surf && rub_surf->getPixel(x,y,rc))
                        {
                                if (rc.t!=c.t)
                                        surf[(int)(((y)*width)+(x))].t = rc.t;
                        }
                        else return false;
                }
                break;

                case PEN_RUB_MAP:
                {
                        Pixel rc;

                        if (rub_surf && rub_surf->getMappedPixel
(x,y,width,height,rc))
                        {
                                if (rc.t!=c.t)
                                        surf[(int)(((y)*width)+(x))].t = rc.t;
                        }
                        else return false;
                }
                break;

                default:
                        return false;
        };

        return true;
}

void
dosadi::Aqua::Surface::drawHLine(float x, float y, float w, const Pixel &c)
{
        for(float i=x; i<x+w; ++i)
                putPixel(i,y,c);
}

void
dosadi::Aqua::Surface::drawVLine(float x, float y, float h, const Pixel &c)
{
        for(float i=y; i<y+h; ++i)
                putPixel(x,i,c);
}


void
dosadi::Aqua::Surface::drawLine(const geom::gRect &r, const Pixel &c)
{
        float x1=r.xmin,
                  x2=r.xmax,
                  y1=r.ymin,
                  y2=r.ymax,
                  x, y, dx, dy, sx, sy, m;


        dx = x2-x1;
        dy = y2-y1;

        sx = (((dx)<0) ? -1 : (dx)>0 ? 1 : 0);
        sy = (((dy)<0) ? -1 : (dy)>0 ? 1 : 0);

        if (dx > dy)
        {



                m = dy/dx;

                y = y1;

                for(x=x1; x<=x2; x+=sx)
                {
                        putPixel(x, y, c);
                        y+=m;
                }
        }
        else
        {


                m = dx/dy;

                x = x1;

                for(y=y1; y<=y2; y+=sy)
                {
                        putPixel(x, y, c);
                        x+=m;
                }
        }
}

void
dosadi::Aqua::Surface::drawRect(const geom::gRect &r, const Pixel &c)
{
        drawHLine(r.xmin, r.ymin, r.Width(), c);
        drawHLine(r.xmin, r.ymax, r.Width(), c);
        drawVLine(r.xmin, r.ymin, r.Height(), c);
        drawVLine(r.xmax, r.ymin, r.Height(), c);
}


void
dosadi::Aqua::Surface::fillRect(const geom::gRect &r, const Pixel &c)
{
        float w = r.Width();

        for(float y=r.ymin; y<=r.ymax; ++y)
                drawHLine(r.xmin, y, w, c);

}
# 410 "modules/aqua/surface.cpp"
void
dosadi::Aqua::Surface::drawCircle(const geom::gRect &r, const Pixel &c)
{
        float radius = (r.Width() + r.Height()) / 4.0,
                  cx = r.xmin+radius,
                  cy = r.ymin+radius,
                  x = radius,
                  y = 0,
                  x_change = 1 - 2 * radius,
                  y_change = 1,
                  radius_error = 0;


        while(x>=y)
        {
                putPixel(cx+x, cy+y, c); putPixel(cx-x, cy+y, c); putPixel(cx-
x, cy-y, c); putPixel(cx+x, cy-y, c); putPixel(cx+y, cy+x, c); putPixel(cx-y, 
cy+x, c); putPixel(cx-y, cy-x, c); putPixel(cx+y, cy-x, c);;
                ++y;
                radius_error+=y_change;
                y_change+=2;
                if (2*radius_error + x_change > 0)
                {
                        --x;
                        radius_error+=x_change;
                        x_change+=2;
                }
        }
}

void
dosadi::Aqua::Surface::fillCircle(const geom::gRect &r, const Pixel &c)
{
        float radius = (r.Width() + r.Height()) / 4.0,
                  cx = r.xmin+radius,
                  cy = r.ymin+radius,
                  x = radius,
                  y = 0,
                  x_change = 1 - 2 * radius,
                  y_change = 1,
                  radius_error = 0;


        while(x>=y)
        {
                { float x2 = x*2, y2 = y*2; drawHLine(cx-x, cy+y, x2, c); 
drawHLine(cx-y, cy+x, y2, c); drawHLine(cx-x, cy-y, x2, c); drawHLine(cx-y, cy-
x, y2, c); };
                ++y;
                radius_error+=y_change;
                y_change+=2;
                if (2*radius_error + x_change > 0)
                {
                        --x;
                        radius_error+=x_change;
                        x_change+=2;
                }
        }
}
# 478 "modules/aqua/surface.cpp"
void
dosadi::Aqua::Surface::drawEllipse(const geom::gRect &r, const Pixel &c)
{
        float rx = r.Width() / 2.0,
                  ry = r.Height() / 2.0,
                  cx = r.xmin+rx,
                  cy = r.ymin+ry,
                  x = rx,
                  y = 0,
                  x_change = ry*ry*(1-2*rx),
                  y_change = rx*rx,
                  two_a_square = 2*rx*rx,
                  two_b_square = 2*ry*ry,
                  stopping_x = two_b_square * rx,
                  stopping_y = 0,
                  ellipse_error = 0;


        while(stopping_x >= stopping_y)
        {
                putPixel(cx+x, cy+y, c); putPixel(cx-x, cy+y, c); putPixel(cx-
x, cy-y, c); putPixel(cx+x, cy-y, c);;

                ++y;
                stopping_y+=two_a_square;
                ellipse_error+=y_change;
                y_change+=two_a_square;

                if ((2 * ellipse_error + x_change) > 0)
                {
                        --x;
                        stopping_x-=two_b_square;
                        ellipse_error+=x_change;
                        x_change+=two_b_square;
                }
        }


        x=0;
        y=ry;
        x_change = ry*ry;
        y_change = rx*rx*(1-2*ry);
        ellipse_error = 0;
        stopping_x = 0;
        stopping_y = two_a_square * ry;

        while(stopping_x <= stopping_y)
        {
                putPixel(cx+x, cy+y, c); putPixel(cx-x, cy+y, c); putPixel(cx-
x, cy-y, c); putPixel(cx+x, cy-y, c);;

                ++x;
                stopping_x+=two_b_square;
                ellipse_error+=x_change;
                x_change+=two_b_square;

                if((2 * ellipse_error + y_change) > 0)
                {
                        --y;
                        stopping_y-=two_a_square;
                        ellipse_error+=y_change;
                        y_change+=two_a_square;
                }
        }
}

void
dosadi::Aqua::Surface::fillEllipse(const geom::gRect &r, const Pixel &c)
{
        float rx = r.Width() / 2.0,
                  ry = r.Height() / 2.0,
                  cx = r.xmin+rx,
                  cy = r.ymin+ry,
                  x = rx,
                  y = 0,
                  x_change = ry*ry*(1-2*rx),
                  y_change = rx*rx,
                  two_a_square = 2*rx*rx,
                  two_b_square = 2*ry*ry,
                  stopping_x = two_b_square * rx,
                  stopping_y = 0,
                  ellipse_error = 0;


        while(stopping_x >= stopping_y)
        {
                { float x2 = x*2; drawHLine(cx-x, cy+y, x2, c); drawHLine(cx-
x, cy-y, x2, c); };

                ++y;
                stopping_y+=two_a_square;
                ellipse_error+=y_change;
                y_change+=two_a_square;

                if ((2 * ellipse_error + x_change) > 0)
                {
                        --x;
                        stopping_x-=two_b_square;
                        ellipse_error+=x_change;
                        x_change+=two_b_square;
                }
        }


        x=0;
        y=ry;
        x_change = ry*ry;
        y_change = rx*rx*(1-2*ry);
        ellipse_error = 0;
        stopping_x = 0;
        stopping_y = two_a_square * ry;

        while(stopping_x <= stopping_y)
        {
                { float x2 = x*2; drawHLine(cx-x, cy+y, x2, c); drawHLine(cx-
x, cy-y, x2, c); };

                ++x;
                stopping_x+=two_b_square;
                ellipse_error+=x_change;
                x_change+=two_b_square;

                if((2 * ellipse_error + y_change) > 0)
                {
                        --y;
                        stopping_y-=two_a_square;
                        ellipse_error+=y_change;
                        y_change+=two_a_square;
                }
        }
}

void
dosadi::Aqua::Surface::drawQuarterCircle(const geom::gRect &r, byte_u 
quadrant, const Pixel &c)
{
        float radius = (r.Width() + r.Height()) / 4.0,
                  cx = r.xmin+radius,
                  cy = r.ymin+radius,
                  x = radius,
                  y = 0,
                  x_change = 1 - 2 * radius,
                  y_change = 1,
                  radius_error = 0;


        while(x>=y)
        {

                switch(quadrant)
                {
                        case CURVE_QUAD_UL:
                                putPixel(cx-x, cy+y, c);
                                putPixel(cx-y, cy+x, c);
                        break;

                        case CURVE_QUAD_LL:
                                putPixel(cx-x, cy-y, c);
                                putPixel(cx-y, cy-x, c);
                        break;

                        case CURVE_QUAD_UR:
                                putPixel(cx+x, cy+y, c);
                                putPixel(cx+y, cy+x, c);
                        break;

                        case CURVE_QUAD_LR:
                                putPixel(cx+x, cy-y, c);
                                putPixel(cx+y, cy-x, c);
                        break;
                }

                ++y;
                radius_error+=y_change;
                y_change+=2;
                if (2*radius_error + x_change > 0)
                {
                        --x;
                        radius_error+=x_change;
                        x_change+=2;
                }
        }

}


void
dosadi::Aqua::Surface::fillQuarterCircle(const geom::gRect &r, byte_u 
quadrant, const Pixel &c)
{
        float radius = (r.Width() + r.Height()) / 4.0,
                  cx = r.xmin+radius,
                  cy = r.ymin+radius,
                  x = radius,
                  y = 0,
                  x_change = 1 - 2 * radius,
                  y_change = 1,
                  radius_error = 0;


        while(x>=y)
        {
                switch(quadrant)
                {
                        case CURVE_QUAD_UL:
                                drawHLine(cx-x, cy+y, x, c);
                                drawHLine(cx-y, cy+x, y, c);
                        break;

                        case CURVE_QUAD_LL:
                                drawHLine(cx-x, cy-y, x, c);
                                drawHLine(cx-y, cy-x, y, c);
                        break;

                        case CURVE_QUAD_UR:
                                drawHLine(cx, cy+y, x, c);
                                drawHLine(cx, cy+x, y, c);
                        break;

                        case CURVE_QUAD_LR:
                                drawHLine(cx, cy-y, x, c);
                                drawHLine(cx, cy-x, y, c);
                        break;
                }

                ++y;
                radius_error+=y_change;
                y_change+=2;
                if (2*radius_error + x_change > 0)
                {
                        --x;
                        radius_error+=x_change;
                        x_change+=2;
                }
        }
}

void
dosadi::Aqua::Surface::drawQuarterEllipse(const geom::gRect &r, byte_u 
quadrant, const Pixel &c)
{
        float rx = r.Width() / 2.0,
                  ry = r.Height() / 2.0,
                  cx = r.xmin+rx,
                  cy = r.ymin+ry,
                  x = rx,
                  y = 0,
                  x_change = ry*ry*(1-2*rx),
                  y_change = rx*rx,
                  two_a_square = 2*rx*rx,
                  two_b_square = 2*ry*ry,
                  stopping_x = two_b_square * rx,
                  stopping_y = 0,
                  ellipse_error = 0;


        while(stopping_x >= stopping_y)
        {
                switch(quadrant)
                {
                        case CURVE_QUAD_UL:
                                putPixel(cx-x, cy+y, c);
                        break;

                        case CURVE_QUAD_LL:
                                putPixel(cx-x, cy-y, c);
                        break;

                        case CURVE_QUAD_UR:
                                putPixel(cx+x, cy+y, c);
                        break;

                        case CURVE_QUAD_LR:
                                putPixel(cx+x, cy-y, c);
                        break;
                }

                ++y;
                stopping_y+=two_a_square;
                ellipse_error+=y_change;
                y_change+=two_a_square;

                if ((2 * ellipse_error + x_change) > 0)
                {
                        --x;
                        stopping_x-=two_b_square;
                        ellipse_error+=x_change;
                        x_change+=two_b_square;
                }
        }


        x=0;
        y=ry;
        x_change = ry*ry;
        y_change = rx*rx*(1-2*ry);
        ellipse_error = 0;
        stopping_x = 0;
        stopping_y = two_a_square * ry;

        while(stopping_x <= stopping_y)
        {
                switch(quadrant)
                {
                        case CURVE_QUAD_UL:
                                putPixel(cx-x, cy+y, c);
                        break;

                        case CURVE_QUAD_LL:
                                putPixel(cx-x, cy-y, c);
                        break;

                        case CURVE_QUAD_UR:
                                putPixel(cx+x, cy+y, c);
                        break;

                        case CURVE_QUAD_LR:
                                putPixel(cx+x, cy-y, c);
                        break;
                }

                ++x;
                stopping_x+=two_b_square;
                ellipse_error+=x_change;
                x_change+=two_b_square;

                if((2 * ellipse_error + y_change) > 0)
                {
                        --y;
                        stopping_y-=two_a_square;
                        ellipse_error+=y_change;
                        y_change+=two_a_square;
                }
        }
}

void
dosadi::Aqua::Surface::fillQuarterEllipse(const geom::gRect &r, byte_u 
quadrant, const Pixel &c)
{
        float rx = r.Width() / 2.0,
                  ry = r.Height() / 2.0,
                  cx = r.xmin+rx,
                  cy = r.ymin+ry,
                  x = rx,
                  y = 0,
                  x_change = ry*ry*(1-2*rx),
                  y_change = rx*rx,
                  two_a_square = 2*rx*rx,
                  two_b_square = 2*ry*ry,
                  stopping_x = two_b_square * rx,
                  stopping_y = 0,
                  ellipse_error = 0;


        while(stopping_x >= stopping_y)
        {
                switch(quadrant)
                {
                        case CURVE_QUAD_UL:
                                drawHLine(cx-x, cy+y, x, c);
                        break;

                        case CURVE_QUAD_LL:
                                drawHLine(cx-x, cy-y, x, c);
                        break;

                        case CURVE_QUAD_UR:
                                drawHLine(cx, cy+y, x, c);
                        break;

                        case CURVE_QUAD_LR:
                                drawHLine(cx, cy-y, x, c);
                        break;
                }

                ++y;
                stopping_y+=two_a_square;
                ellipse_error+=y_change;
                y_change+=two_a_square;

                if ((2 * ellipse_error + x_change) > 0)
                {
                        --x;
                        stopping_x-=two_b_square;
                        ellipse_error+=x_change;
                        x_change+=two_b_square;
                }
        }


        x=0;
        y=ry;
        x_change = ry*ry;
        y_change = rx*rx*(1-2*ry);
        ellipse_error = 0;
        stopping_x = 0;
        stopping_y = two_a_square * ry;

        while(stopping_x <= stopping_y)
        {
                switch(quadrant)
                {
                        case CURVE_QUAD_UL:
                                drawHLine(cx-x, cy+y, x, c);
                        break;

                        case CURVE_QUAD_LL:
                                drawHLine(cx-x, cy-y, x, c);
                        break;

                        case CURVE_QUAD_UR:
                                drawHLine(cx, cy+y, x, c);
                        break;

                        case CURVE_QUAD_LR:
                                drawHLine(cx, cy-y, x, c);
                        break;
                }

                ++x;
                stopping_x+=two_b_square;
                ellipse_error+=x_change;
                x_change+=two_b_square;

                if((2 * ellipse_error + y_change) > 0)
                {
                        --y;
                        stopping_y-=two_a_square;
                        ellipse_error+=y_change;
                        y_change+=two_a_square;
                }
        }
}

void
dosadi::Aqua::Surface::blitSurface(Surface &s, const geom::gRect &src, const 
geom::gRect &dst)
{
        geom::gRect src_r(src),
                                dst_r(dst);


        src_r.intersect(s.getClip());
        dst_r.intersect(getClip());


        src_r.Minimum(dst_r);

        tetra_u src_x = (tetra_u)src_r.xmin,
                        dst_x = (tetra_u)dst_r.xmin,
                        src_y = (tetra_u)src_r.ymin,
                        dst_y = (tetra_u)dst_r.ymin,
                        line_w = (tetra_u)src_r.Width(),
                        rect_h = (tetra_u)src_r.Height(),
                        src_w = s.Width(),
                        dst_w = Width();

        tetra_u src_ofs = src_x + (src_y * src_w),
                    dst_ofs = dst_x + (dst_y * dst_w);


        for(tetra_u i = 0; i<rect_h; ++i)
        {
                            asm volatile ("cld\n"
                                                          "movl %0, %%edi\n"
                                                          "movl %1, %%esi\n"
                                                          "movl %2, %%ecx\n"
                                                          "repnz movsl\n"
                                                         :
                                                         : "rm" (surf), "rm" 
(s.surf), "rm" (line_w)
                                                         : "esi", "edi", "ecx",
 "flags");

                                src_ofs += src_w;
                                dst_ofs += dst_w;
        }
}

void
dosadi::Aqua::Surface::blitMaskedSurface(Surface &s, const geom::gRect &src, 
const geom::gRect &dst, const Pixel &c)
{
        geom::gRect src_r(src),
                                dst_r(dst);


        src_r.intersect(s.getClip());
        dst_r.intersect(getClip());


        src_r.Minimum(dst_r);

        tetra_u src_x = (tetra_u)src_r.xmin,
                        dst_x = (tetra_u)dst_r.xmin,
                        src_y = (tetra_u)src_r.ymin,
                        dst_y = (tetra_u)dst_r.ymin,
                        line_w = (tetra_u)src_r.Width(),
                        rect_h = (tetra_u)src_r.Height(),
                        src_w = s.Width(),
                        dst_w = Width();

        tetra_u src_ofs = src_x + (src_y * src_w),
                    dst_ofs = dst_x + (dst_y * dst_w);


        for(tetra_u i = 0; i<rect_h; ++i)
        {
                            asm volatile ("cld\n"
                                                          "movl %2, %%ecx\n"
                                                          "blit_move_repeat:\n"
                                                          "lodsl\n"
                                                          "cmp %%eax, %3\n"
                                                          "loope 
blit_move_repeat\n"
                                                          "jcxz 
blit_move_done\n"
                                                          "stosl\n"
                                                          "loop 
blit_move_repeat\n"
                                                          "blit_move_done:\n"
                                                         :
                                                         : "edi" (surf), "esi" 
(s.surf), "rm" (line_w), "rm" (c.t)
                                                         : "eax", "ecx", "flags
");

                                src_ofs += src_w;
                                dst_ofs += dst_w;
        }
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]