~ubuntu-branches/ubuntu/hoary/gimp/hoary

« back to all changes in this revision

Viewing changes to app/composite/gimp-composite-mmx.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-04-04 14:51:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050404145123-9py049eeelfymur8
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c tab-width: 2; c-basic-indent: 2; indent-tabs-mode: nil -*-
 
2
 *
 
3
 * The GIMP -- an image manipulation program
 
4
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
5
 *
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
/* Much of the content of this file are derivative works of David
 
23
 * Monniaux which are Copyright (C) 1999, 2001 David Monniaux
 
24
 * Tip-o-the-hat to David for pioneering this effort.
 
25
 *
 
26
 * All of these functions use the mmx registers and expect them to
 
27
 * remain intact across multiple asm() constructs.  This may not work
 
28
 * in the future, if the compiler allocates mmx registers for it's own
 
29
 * use. XXX
 
30
 */
 
31
 
 
32
#include "config.h"
 
33
 
 
34
#include <stdio.h>
 
35
 
 
36
#include <glib-object.h>
 
37
 
 
38
#include "base/base-types.h"
 
39
#include "base/cpu-accel.h"
 
40
 
 
41
#include "gimp-composite.h"
 
42
#include "gimp-composite-mmx.h"
 
43
 
 
44
#ifdef COMPILE_MMX_IS_OKAY
 
45
 
 
46
#include "gimp-composite-x86.h"
 
47
 
 
48
#define pminub(src,dst,tmp)  "\tmovq %%" #dst ", %%" #tmp ";" "psubusb %%" #src ", %%" #tmp ";" "psubb %%" #tmp ", %%" #dst "\n"
 
49
#define pmaxub(a,b,tmp)      "\tmovq %%" #a ", %%" #tmp ";" "psubusb %%" #b ", %%" #tmp ";" "paddb %%" #tmp ", %%" #b "\n"
 
50
 
 
51
 
 
52
void
 
53
debug_display_mmx(void)
 
54
{
 
55
#define mask32(x) ((x)& (unsigned long long) 0xFFFFFFFF)
 
56
#define print64(reg) { unsigned long long reg; asm("movq %%" #reg ",%0" : "=m" (reg)); printf(#reg"=%08llx %08llx", mask32(reg>>32), mask32(reg)); }
 
57
  printf("--------------------------------------------\n");
 
58
  print64(mm0); printf("  "); print64(mm1); printf("\n");
 
59
  print64(mm2); printf("  "); print64(mm3); printf("\n");
 
60
  print64(mm4); printf("  "); print64(mm5); printf("\n");
 
61
  print64(mm6); printf("  "); print64(mm7); printf("\n");
 
62
  printf("--------------------------------------------\n");
 
63
}
 
64
 
 
65
const guint32 rgba8_alpha_mask_64[2] = { 0xFF000000, 0xFF000000 };
 
66
const guint32 rgba8_b1_64[2] =         { 0x01010101, 0x01010101 };
 
67
const guint32 rgba8_b255_64[2] =       { 0xFFFFFFFF, 0xFFFFFFFF };
 
68
const guint32 rgba8_w1_64[2] =         { 0x00010001, 0x00010001 };
 
69
const guint32 rgba8_w2_64[2] =         { 0x00020002, 0x00020002 };
 
70
const guint32 rgba8_w128_64[2] =       { 0x00800080, 0x00800080 };
 
71
const guint32 rgba8_w256_64[2] =       { 0x01000100, 0x01000100 };
 
72
const guint32 rgba8_w255_64[2] =       { 0X00FF00FF, 0X00FF00FF };
 
73
 
 
74
const guint32 va8_alpha_mask_64[2] =   { 0xFF00FF00, 0xFF00FF00 };
 
75
const guint32 va8_b255_64[2] =         { 0xFFFFFFFF, 0xFFFFFFFF };
 
76
const guint32 va8_w1_64[2] =           { 0x00010001, 0x00010001 };
 
77
const guint32 va8_w255_64[2] =         { 0x00FF00FF, 0x00FF00FF };
 
78
 
 
79
/*const static guint32 v8_alpha_mask[2] = { 0xFF00FF00, 0xFF00FF00};
 
80
  const static guint32 v8_mul_shift[2] = { 0x00800080, 0x00800080 };*/
 
81
 
 
82
 
 
83
/*
 
84
 *
 
85
 */
 
86
void
 
87
gimp_composite_addition_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
88
{
 
89
  uint64 *d = (uint64 *) _op->D;
 
90
  uint64 *a = (uint64 *) _op->A;
 
91
  uint64 *b = (uint64 *) _op->B;
 
92
  gulong n_pixels = _op->n_pixels;
 
93
 
 
94
  asm volatile ("movq    %0,%%mm0"
 
95
                : /* empty */
 
96
                : "m" (*rgba8_alpha_mask_64)
 
97
                : "%mm0");
 
98
 
 
99
  for (; n_pixels >= 2; n_pixels -= 2)
 
100
    {
 
101
      asm volatile ("  movq       %1, %%mm2\n"
 
102
                    "\tmovq       %2, %%mm3\n"
 
103
                    "\tmovq    %%mm2, %%mm4\n"
 
104
                    "\tpaddusb %%mm3, %%mm4\n"
 
105
                    "\tmovq    %%mm0, %%mm1\n"
 
106
                    "\tpandn   %%mm4, %%mm1\n"
 
107
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
108
                    "\tpand    %%mm0, %%mm2\n"
 
109
                    "\tpor     %%mm2, %%mm1\n"
 
110
                    "\tmovq    %%mm1, %0\n"
 
111
                    : "=m" (*d)
 
112
                    : "m" (*a), "m" (*b)
 
113
                    : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4");
 
114
      a++;
 
115
      b++;
 
116
      d++;
 
117
    }
 
118
 
 
119
  if (n_pixels > 0)
 
120
    {
 
121
      asm volatile ("  movd    %1, %%mm2\n"
 
122
                    "\tmovd    %2, %%mm3\n"
 
123
                    "\tmovq    %%mm2, %%mm4\n"
 
124
                    "\tpaddusb %%mm3, %%mm4\n"
 
125
                    "\tmovq    %%mm0, %%mm1\n"
 
126
                    "\tpandn   %%mm4, %%mm1\n"
 
127
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
128
                    "\tpand    %%mm0, %%mm2\n"
 
129
                    "\tpor     %%mm2, %%mm1\n"
 
130
                    "\tmovd    %%mm1, %0\n"
 
131
                    : "=m" (*d)
 
132
                    : "m" (*a), "m" (*b)
 
133
                    : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4");
 
134
    }
 
135
 
 
136
  asm("emms");
 
137
}
 
138
 
 
139
void
 
140
gimp_composite_burn_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
141
{
 
142
  uint64 *d = (uint64 *) _op->D;
 
143
  uint64 *a = (uint64 *) _op->A;
 
144
  uint64 *b = (uint64 *) _op->B;
 
145
  gulong n_pixels = _op->n_pixels;
 
146
 
 
147
  for (; n_pixels >= 2; n_pixels -= 2)
 
148
    {
 
149
      asm volatile ("  movq         %1,%%mm0\n"
 
150
                    "\tmovq         %2,%%mm1\n"
 
151
 
 
152
                    "\tmovq         %3,%%mm2\n"
 
153
                    "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
154
                    "\tpxor      %%mm4,%%mm4\n"
 
155
                    "\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
156
 
 
157
                    "\tmovq      %%mm1,%%mm3\n"
 
158
                    "\tpxor      %%mm5,%%mm5\n"
 
159
                    "\tpunpcklbw %%mm5,%%mm3\n"
 
160
                    "\tmovq         %4,%%mm5\n"
 
161
                    "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
162
 
 
163
                    "\t" pdivwqX(mm4,mm5,mm7) "\n"
 
164
 
 
165
                    "\tmovq         %3,%%mm2\n"
 
166
                    "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
167
                    "\tpxor      %%mm4,%%mm4\n"
 
168
                    "\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
169
 
 
170
                    "\tmovq      %%mm1,%%mm3\n"
 
171
                    "\tpxor      %%mm5,%%mm5\n"
 
172
                    "\tpunpckhbw %%mm5,%%mm3\n"
 
173
                    "\tmovq         %4,%%mm5\n"
 
174
                    "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
175
                    "\t" pdivwqX(mm4,mm5,mm6) "\n"
 
176
 
 
177
                    "\tmovq         %5,%%mm4\n"
 
178
                    "\tmovq      %%mm4,%%mm5\n"
 
179
                    "\tpsubusw   %%mm6,%%mm4\n"
 
180
                    "\tpsubusw   %%mm7,%%mm5\n"
 
181
 
 
182
                    "\tpackuswb  %%mm4,%%mm5\n"
 
183
 
 
184
                    "\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
 
185
 
 
186
                    "\tmovq         %6,%%mm7\n" /* mm6 = rgba8_alpha_mask_64 */
 
187
                    "\tpand      %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
 
188
 
 
189
                    "\tpandn     %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
 
190
                    "\tpor       %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
 
191
                    
 
192
                    "\tmovq      %%mm7,%0\n"
 
193
                    : "=m" (*d)
 
194
                    : "m" (*a), "m" (*b), "m" (*rgba8_b255_64), "m" (*rgba8_w1_64), "m" (*rgba8_w255_64), "m" (*rgba8_alpha_mask_64)
 
195
                    : pdivwqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
 
196
      d++;
 
197
      b++;
 
198
      a++;
 
199
    }
 
200
 
 
201
  if (n_pixels > 0)
 
202
    {
 
203
      asm volatile ("  movd         %1,%%mm0\n"
 
204
                    "\tmovd         %2,%%mm1\n"
 
205
 
 
206
                    "\tmovq         %3,%%mm2\n"
 
207
                    "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
208
                    "\tpxor      %%mm4,%%mm4\n"
 
209
                    "\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
210
 
 
211
                    "\tmovq      %%mm1,%%mm3\n"
 
212
                    "\tpxor      %%mm5,%%mm5\n"
 
213
                    "\tpunpcklbw %%mm5,%%mm3\n"
 
214
                    "\tmovq         %4,%%mm5\n"
 
215
                    "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
216
 
 
217
                    "\t" pdivwqX(mm4,mm5,mm7) "\n"
 
218
 
 
219
                    "\tmovq         %3,%%mm2\n"
 
220
                    "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
221
                    "\tpxor      %%mm4,%%mm4\n"
 
222
                    "\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
223
 
 
224
                    "\tmovq      %%mm1,%%mm3\n"
 
225
                    "\tpxor      %%mm5,%%mm5\n"
 
226
                    "\tpunpckhbw %%mm5,%%mm3\n"
 
227
                    "\tmovq         %4,%%mm5\n"
 
228
                    "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
229
                    "\t" pdivwqX(mm4,mm5,mm6) "\n"
 
230
 
 
231
                    "\tmovq         %5,%%mm4\n"
 
232
                    "\tmovq      %%mm4,%%mm5\n"
 
233
                    "\tpsubusw   %%mm6,%%mm4\n"
 
234
                    "\tpsubusw   %%mm7,%%mm5\n"
 
235
 
 
236
                    "\tpackuswb  %%mm4,%%mm5\n"
 
237
 
 
238
                    "\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
 
239
 
 
240
                    "\tmovq         %6,%%mm7\n"
 
241
                    "\tpand      %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
 
242
 
 
243
                    "\tpandn     %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
 
244
                    "\tpor       %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
 
245
 
 
246
                    "\tmovd      %%mm7,%0\n"
 
247
                    : "=m" (*d)
 
248
                    : "m" (*a), "m" (*b), "m" (*rgba8_b255_64), "m" (*rgba8_w1_64), "m" (*rgba8_w255_64), "m" (*rgba8_alpha_mask_64)
 
249
                    : pdivwqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
 
250
    }
 
251
 
 
252
  asm("emms");
 
253
}
 
254
 
 
255
 
 
256
void
 
257
gimp_composite_darken_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
258
{
 
259
  uint64 *d = (uint64 *) _op->D;
 
260
  uint64 *a = (uint64 *) _op->A;
 
261
  uint64 *b = (uint64 *) _op->B;
 
262
  gulong n_pixels = _op->n_pixels;
 
263
 
 
264
  for (; n_pixels >= 2; n_pixels -= 2)
 
265
    {
 
266
      asm volatile ("  movq    %1, %%mm2\n"
 
267
                    "\tmovq    %2, %%mm3\n"
 
268
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
269
                    "\tmovq    %%mm2, %0\n"
 
270
                    : "=m" (*d)
 
271
                    : "m" (*a), "m" (*b)
 
272
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
273
      a++;
 
274
      b++;
 
275
      d++;
 
276
    }
 
277
 
 
278
  if (n_pixels > 0)
 
279
    {
 
280
      asm volatile ("  movd    %1, %%mm2\n"
 
281
                    "\tmovd    %2, %%mm3\n"
 
282
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
283
                    "\tmovd    %%mm2, %0\n"
 
284
                    : "=m" (*d)
 
285
                    : "m" (*a), "m" (*b)
 
286
                    : "%mm2", "%mm3", "%mm4");
 
287
    }
 
288
 
 
289
  asm("emms");
 
290
}
 
291
 
 
292
void
 
293
gimp_composite_difference_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
294
{
 
295
  uint64 *d = (uint64 *) _op->D;
 
296
  uint64 *a = (uint64 *) _op->A;
 
297
  uint64 *b = (uint64 *) _op->B;
 
298
  gulong n_pixels = _op->n_pixels;
 
299
 
 
300
  asm volatile ("movq    %0,%%mm0"     :  : "m" (*rgba8_alpha_mask_64) : "%mm0");
 
301
 
 
302
  for (; n_pixels >= 2; n_pixels -= 2)
 
303
    {
 
304
      asm volatile ("  movq       %1, %%mm2\n"
 
305
                    "\tmovq       %2, %%mm3\n"
 
306
                    "\tmovq    %%mm2, %%mm4\n"
 
307
                    "\tmovq    %%mm3, %%mm5\n"
 
308
                    "\tpsubusb %%mm3, %%mm4\n"
 
309
                    "\tpsubusb %%mm2, %%mm5\n"
 
310
                    "\tpaddb   %%mm5, %%mm4\n"
 
311
                    "\tmovq    %%mm0, %%mm1\n"
 
312
                    "\tpandn   %%mm4, %%mm1\n"
 
313
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
314
                    "\tpand    %%mm0, %%mm2\n"
 
315
                    "\tpor     %%mm2, %%mm1\n"
 
316
                    "\tmovq    %%mm1, %0\n"
 
317
                    : "=m" (*d)
 
318
                    : "m" (*a), "m" (*b)
 
319
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
320
      a++;
 
321
      b++;
 
322
      d++;
 
323
    }
 
324
 
 
325
  if (n_pixels > 0)
 
326
    {
 
327
      asm volatile ("  movd       %1, %%mm2\n"
 
328
                    "\tmovd       %2, %%mm3\n"
 
329
                    "\tmovq    %%mm2, %%mm4\n"
 
330
                    "\tmovq    %%mm3, %%mm5\n"
 
331
                    "\tpsubusb %%mm3, %%mm4\n"
 
332
                    "\tpsubusb %%mm2, %%mm5\n"
 
333
                    "\tpaddb   %%mm5, %%mm4\n"
 
334
                    "\tmovq    %%mm0, %%mm1\n"
 
335
                    "\tpandn   %%mm4, %%mm1\n"
 
336
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
337
                    "\tpand    %%mm0, %%mm2\n"
 
338
                    "\tpor     %%mm2, %%mm1\n"
 
339
                    "\tmovd    %%mm1, %0\n"
 
340
                    : "=m" (*d)
 
341
                    : "m" (*a), "m" (*b)
 
342
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
343
    }
 
344
 
 
345
  asm("emms");
 
346
}
 
347
 
 
348
#if 0
 
349
void
 
350
xxxgimp_composite_divide_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
351
{
 
352
  uint64 *d = (uint64 *) _op->D;
 
353
  uint64 *a = (uint64 *) _op->A;
 
354
  uint64 *b = (uint64 *) _op->B;
 
355
  gulong n_pixels = _op->n_pixels;
 
356
 
 
357
  asm volatile ("  movq    %0, %%mm0\n"
 
358
                "\tmovq    %1, %%mm7\n"
 
359
                :
 
360
                : "m" (*rgba8_alpha_mask_64), "m" (*rgba8_w1_64)
 
361
                : "%mm0", "%mm7");
 
362
 
 
363
  for (; n_pixels >= 2; n_pixels -= 2)
 
364
    {
 
365
      asm volatile ("  movq         %1,%%mm0\n"
 
366
                    "\tmovq         %2,%%mm1\n"
 
367
                    "\tpxor      %%mm2,%%mm2\n"
 
368
                    "\tpunpcklbw %%mm0,%%mm2\n" /* mm2 = A*256 */
 
369
 
 
370
                    "\tmovq      %%mm1,%%mm3\n"
 
371
                    "\tpxor      %%mm5,%%mm5\n"
 
372
                    "\tpunpcklbw %%mm5,%%mm3\n"
 
373
                    "\tpaddw     %%mm7,%%mm3\n" /* mm3 = B+1 */
 
374
 
 
375
                    "\t" pdivwuqX(mm2,mm3,mm5) "\n" /* mm5 = (A*256)/(B+1) */
 
376
 
 
377
                    "\tpxor      %%mm2,%%mm2\n"
 
378
                    "\tpunpckhbw %%mm0,%%mm2\n" /* mm2 = A*256 */
 
379
 
 
380
                    "\tmovq      %%mm1,%%mm3\n"
 
381
                    "\tpxor      %%mm6,%%mm6\n"
 
382
                    "\tpunpckhbw %%mm6,%%mm3\n"
 
383
                    "\tpaddw     %%mm7,%%mm3\n" /* mm3 = B+1 */
 
384
 
 
385
                    "\t" pdivwuqX(mm2,mm3,mm4) "\n" /* mm4 = (A*256)/(B+1) */
 
386
 
 
387
                    "\tpackuswb  %%mm4,%%mm5\n" /* expects mm4 and mm5 to be signed values */
 
388
 
 
389
                    "\t" pminub(mm0,mm1,mm3) "\n"
 
390
                    "\tmovq         %3,%%mm3\n"
 
391
                    "\tmovq      %%mm3,%%mm2\n"
 
392
 
 
393
                    "\tpandn     %%mm5,%%mm3\n"
 
394
 
 
395
                    "\tpand      %%mm2,%%mm1\n"
 
396
                    "\tpor       %%mm1,%%mm3\n"
 
397
 
 
398
                    "\tmovq      %%mm3,%0\n"
 
399
                    : "=m" (*d)
 
400
                    : "m" (*a), "m" (*b), "m" (*rgba8_alpha_mask_64)
 
401
                    : pdivwuqX_clobber, "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
402
      a++;
 
403
      b++;
 
404
      d++;
 
405
    }
 
406
 
 
407
  if (n_pixels > 0)
 
408
    {
 
409
      asm volatile ("  movd         %1,%%mm0\n"
 
410
                    "\tmovd         %2,%%mm1\n"
 
411
                    "\tpxor      %%mm2,%%mm2\n"
 
412
                    "\tpunpcklbw %%mm0,%%mm2\n" /* mm2 = A*256 */
 
413
 
 
414
                    "\tmovq      %%mm1,%%mm3\n"
 
415
                    "\tpxor      %%mm5,%%mm5\n"
 
416
                    "\tpunpcklbw %%mm5,%%mm3\n"
 
417
                    "\tpaddw     %%mm7,%%mm3\n" /* mm3 = B+1 */
 
418
 
 
419
                    "\t" pdivwuqX(mm2,mm3,mm5) "\n" /* mm5 = (A*256)/(B+1) */
 
420
 
 
421
                    "\tpxor      %%mm2,%%mm2\n"
 
422
                    "\tpunpckhbw %%mm0,%%mm2\n" /* mm2 = A*256 */
 
423
 
 
424
                    "\tmovq      %%mm1,%%mm3\n"
 
425
                    "\tpxor      %%mm6,%%mm6\n"
 
426
                    "\tpunpckhbw %%mm6,%%mm3\n"
 
427
                    "\tpaddw     %%mm7,%%mm3\n" /* mm3 = B+1 */
 
428
 
 
429
                    "\t" pdivwuqX(mm2,mm3,mm4) "\n" /* mm4 = (A*256)/(B+1) */
 
430
 
 
431
                    "\tpackuswb  %%mm4,%%mm5\n" /* expects mm4 and mm5 to be signed values */
 
432
 
 
433
                    "\t" pminub(mm0,mm1,mm3) "\n"
 
434
                    "\tmovq         %3,%%mm3\n"
 
435
                    "\tmovq      %%mm3,%%mm2\n"
 
436
 
 
437
                    "\tpandn     %%mm5,%%mm3\n"
 
438
 
 
439
                    "\tpand      %%mm2,%%mm1\n"
 
440
                    "\tpor       %%mm1,%%mm3\n"
 
441
 
 
442
                    "\tmovd      %%mm3,%0\n"
 
443
                    : "=m" (*d)
 
444
                    : "m" (*a), "m" (*b), "m" (*rgba8_alpha_mask_64)
 
445
                    : pdivwuqX_clobber, "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
446
    }
 
447
 
 
448
  asm("emms");
 
449
}
 
450
#endif
 
451
 
 
452
#if 0
 
453
void
 
454
xxxgimp_composite_dodge_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
455
{
 
456
  uint64 *d = (uint64 *) _op->D;
 
457
  uint64 *a = (uint64 *) _op->A;
 
458
  uint64 *b = (uint64 *) _op->B;
 
459
  gulong n_pixels = _op->n_pixels;
 
460
 
 
461
  for (; n_pixels >= 2; n_pixels -= 2)
 
462
    {
 
463
      asm volatile ("  movq         %1,%%mm0\n"
 
464
                    "\tmovq         %2,%%mm1\n"
 
465
                    "\tmovq      %%mm1,%%mm3\n"
 
466
                    "\tpxor      %%mm2,%%mm2\n"
 
467
                    "\tpunpcklbw %%mm2,%%mm3\n"
 
468
                    "\tpunpcklbw %%mm0,%%mm2\n"
 
469
 
 
470
                    "\tmovq         %3,%%mm4\n"
 
471
                    "\tpsubw     %%mm3,%%mm4\n"
 
472
 
 
473
                    "\t" pdivwuqX(mm2,mm4,mm5) "\n"
 
474
 
 
475
                    "\tmovq      %%mm1,%%mm3\n"
 
476
                    "\tpxor      %%mm2,%%mm2\n"
 
477
                    "\tpunpckhbw %%mm2,%%mm3\n"
 
478
                    "\tpunpckhbw %%mm0,%%mm2\n"
 
479
 
 
480
                    "\tmovq         %3,%%mm4\n"
 
481
                    "\tpsubw     %%mm3,%%mm4\n"
 
482
 
 
483
                    "\t" pdivwuqX(mm2,mm4,mm6) "\n"
 
484
 
 
485
                    "\tpackuswb  %%mm6,%%mm5\n"
 
486
 
 
487
                    "\tmovq         %4,%%mm6\n"
 
488
                    "\tmovq      %%mm1,%%mm7\n"
 
489
                    "\t" pminub(mm0,mm7,mm2) "\n"
 
490
                    "\tpand      %%mm6,%%mm7\n"
 
491
                    "\tpandn     %%mm5,%%mm6\n"
 
492
 
 
493
                    "\tpor       %%mm6,%%mm7\n"
 
494
 
 
495
                    "\tmovq      %%mm7,%0\n"
 
496
                    : "=m" (*d)
 
497
                    : "m" (*a), "m" (*b), "m" (*rgba8_w256_64), "m" (*rgba8_alpha_mask_64)
 
498
                    : pdivwuqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
 
499
      a++;
 
500
      b++;
 
501
      d++;
 
502
    }
 
503
 
 
504
  if (n_pixels > 0)
 
505
    {
 
506
      asm volatile ("  movd         %0,%%mm0\n"
 
507
                    "\tmovq         %1,%%mm1\n"
 
508
                    "\tmovq      %%mm1,%%mm3\n"
 
509
                    "\tpxor      %%mm2,%%mm2\n"
 
510
                    "\tpunpcklbw %%mm2,%%mm3\n"
 
511
                    "\tpunpcklbw %%mm0,%%mm2\n"
 
512
 
 
513
                    "\tmovq         %3,%%mm4\n"
 
514
                    "\tpsubw     %%mm3,%%mm4\n"
 
515
 
 
516
                    "\t" pdivwuqX(mm2,mm4,mm5) "\n"
 
517
 
 
518
                    "\tmovq      %%mm1,%%mm3\n"
 
519
                    "\tpxor      %%mm2,%%mm2\n"
 
520
                    "\tpunpckhbw %%mm2,%%mm3\n"
 
521
                    "\tpunpckhbw %%mm0,%%mm2\n"
 
522
 
 
523
                    "\tmovq         %3,%%mm4\n"
 
524
                    "\tpsubw     %%mm3,%%mm4\n"
 
525
 
 
526
                    "\t" pdivwuqX(mm2,mm4,mm6) "\n"
 
527
 
 
528
                    "\tpackuswb  %%mm6,%%mm5\n"
 
529
 
 
530
                    "\tmovq         %4,%%mm6\n"
 
531
                    "\tmovq      %%mm1,%%mm7\n"
 
532
                    "\t" pminub(mm0,mm7,mm2) "\n"
 
533
                    "\tpand      %%mm6,%%mm7\n"
 
534
                    "\tpandn     %%mm5,%%mm6\n"
 
535
 
 
536
                    "\tpor       %%mm6,%%mm7\n"
 
537
 
 
538
                    "\tmovd      %%mm7,%2\n"
 
539
                    : /* empty */
 
540
                    : "m" (*a), "m" (*b), "m" (*d), "m" (*rgba8_w256_64), "m" (*rgba8_alpha_mask_64)
 
541
                    : pdivwuqX_clobber, "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
542
    }
 
543
 
 
544
  asm("emms");
 
545
}
 
546
#endif
 
547
 
 
548
void
 
549
gimp_composite_grain_extract_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
550
{
 
551
  uint64 *d = (uint64 *) _op->D;
 
552
  uint64 *a = (uint64 *) _op->A;
 
553
  uint64 *b = (uint64 *) _op->B;
 
554
  gulong n_pixels = _op->n_pixels;
 
555
 
 
556
  asm volatile ("movq       %0,%%mm0\n"
 
557
                "pxor    %%mm6,%%mm6\n"
 
558
                "movq       %1,%%mm7\n"
 
559
                : /* no outputs */
 
560
                : "m" (*rgba8_alpha_mask_64), "m" (*rgba8_w128_64)
 
561
                : "%mm0",  "%mm7", "%mm6");
 
562
 
 
563
  for (; n_pixels >= 2; n_pixels -= 2)
 
564
    {
 
565
      asm volatile ("  movq         %1,%%mm2\n"
 
566
                    "\tmovq         %2,%%mm3\n"
 
567
                    mmx_low_bytes_to_words(mm2,mm4,mm6)
 
568
                    mmx_low_bytes_to_words(mm3,mm5,mm6)
 
569
                    "\tpsubw     %%mm5,%%mm4\n"
 
570
                    "\tpaddw     %%mm7,%%mm4\n"
 
571
                    "\tmovq      %%mm4,%%mm1\n"
 
572
 
 
573
                    mmx_high_bytes_to_words(mm2,mm4,mm6)
 
574
                    mmx_high_bytes_to_words(mm3,mm5,mm6)
 
575
 
 
576
                    "\tpsubw     %%mm5,%%mm4\n"
 
577
                    "\tpaddw     %%mm7,%%mm4\n"
 
578
 
 
579
                    "\tpackuswb  %%mm4,%%mm1\n"
 
580
                    "\tmovq      %%mm1,%%mm4\n"
 
581
 
 
582
                    "\tmovq      %%mm0,%%mm1\n"
 
583
                    "\tpandn     %%mm4,%%mm1\n"
 
584
 
 
585
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
586
                    "\tpand      %%mm0,%%mm2\n"
 
587
 
 
588
                    "\tpor       %%mm2,%%mm1\n"
 
589
                    "\tmovq      %%mm1,%0\n"
 
590
                    : "=m" (*d)
 
591
                    : "m" (*a), "m" (*b)
 
592
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
593
      a++;
 
594
      b++;
 
595
      d++;
 
596
    }
 
597
 
 
598
  if (n_pixels > 0)
 
599
    {
 
600
      asm volatile ("  movd    %1, %%mm2\n"
 
601
                    "\tmovd    %2, %%mm3\n"
 
602
 
 
603
                    mmx_low_bytes_to_words(mm2,mm4,mm6)
 
604
                    mmx_low_bytes_to_words(mm3,mm5,mm6)
 
605
 
 
606
                    "\tpsubw     %%mm5, %%mm4\n"
 
607
                    "\tpaddw     %%mm7, %%mm4\n"
 
608
                    "\tmovq      %%mm4, %%mm1\n"
 
609
 
 
610
                    "\tpackuswb  %%mm6, %%mm1\n"
 
611
 
 
612
                    "\tmovq      %%mm1, %%mm4\n"
 
613
 
 
614
                    "\tmovq      %%mm0, %%mm1; pandn     %%mm4, %%mm1\n"
 
615
 
 
616
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
617
                    "\tpand      %%mm0, %%mm2\n"
 
618
 
 
619
                    "\tpor       %%mm2, %%mm1\n"
 
620
                    "\tmovd      %%mm1, %0\n"
 
621
                    : "=m" (*d)
 
622
                    : "m" (*a), "m" (*b)
 
623
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
624
    }
 
625
 
 
626
  asm("emms");
 
627
}
 
628
 
 
629
void
 
630
gimp_composite_grain_merge_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
631
{
 
632
  uint64 *d = (uint64 *) _op->D;
 
633
  uint64 *a = (uint64 *) _op->A;
 
634
  uint64 *b = (uint64 *) _op->B;
 
635
  gulong n_pixels = _op->n_pixels;
 
636
 
 
637
  asm volatile ("movq    %0, %%mm0\n"
 
638
                "pxor    %%mm6, %%mm6\n"
 
639
                "movq    %1, %%mm7\n"
 
640
                : /* empty */
 
641
                : "m" (*rgba8_alpha_mask_64), "m" (*rgba8_w128_64)
 
642
                : "%mm0", "%mm6", "%mm7");
 
643
 
 
644
  for (; n_pixels >= 2; n_pixels -= 2)
 
645
    {
 
646
      asm volatile ("  movq    %1, %%mm2\n"
 
647
                    "\tmovq    %2, %%mm3\n"
 
648
 
 
649
                    mmx_low_bytes_to_words(mm2,mm4,mm6)
 
650
                    mmx_low_bytes_to_words(mm3,mm5,mm6)
 
651
                    "\tpaddw     %%mm5, %%mm4\n"
 
652
                    "\tpsubw     %%mm7, %%mm4\n"
 
653
 
 
654
                    mmx_high_bytes_to_words(mm2,mm1,mm6)
 
655
                    mmx_high_bytes_to_words(mm3,mm5,mm6)
 
656
                    "\tpaddw     %%mm5, %%mm1\n"
 
657
                    "\tpsubw     %%mm7, %%mm1\n"
 
658
 
 
659
                    "\tpackuswb  %%mm1, %%mm4\n"
 
660
 
 
661
                    "\t" pminub(mm3,mm2,mm5) "\n"
 
662
                    "\tpand      %%mm0, %%mm2\n"
 
663
 
 
664
                    "\tmovq      %%mm0, %%mm1\n"
 
665
                    "\tpandn     %%mm4, %%mm1\n"
 
666
                    "\tpor       %%mm2, %%mm1\n"
 
667
                    "\tmovq      %%mm1, %0\n"
 
668
                    : "=m" (*d)
 
669
                    : "m" (*a), "m" (*b)
 
670
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
671
      a++;
 
672
      b++;
 
673
      d++;
 
674
    }
 
675
 
 
676
  if (n_pixels > 0)
 
677
    {
 
678
      asm volatile ("  movd    %1, %%mm2\n"
 
679
                    "\tmovd    %2, %%mm3\n"
 
680
 
 
681
                    mmx_low_bytes_to_words(mm2,mm4,mm6)
 
682
                    mmx_low_bytes_to_words(mm3,mm5,mm6)
 
683
 
 
684
                    "\tpaddw     %%mm5, %%mm4\n"
 
685
                    "\tpsubw     %%mm7, %%mm4\n"
 
686
                    "\tmovq      %%mm4, %%mm1\n"
 
687
                    "\tpackuswb  %%mm6, %%mm1\n"
 
688
 
 
689
                    "\tmovq      %%mm1, %%mm4\n"
 
690
 
 
691
                    "\tmovq      %%mm0, %%mm1; pandn     %%mm4, %%mm1\n"
 
692
 
 
693
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
694
                    "\tpand      %%mm0, %%mm2\n"
 
695
 
 
696
                    "\tpor       %%mm2, %%mm1\n"
 
697
                    "\tmovd      %%mm1, %0\n"
 
698
                    : "=m" (*d)
 
699
                    : "m" (*a), "m" (*b)
 
700
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
701
    }
 
702
 
 
703
  asm("emms");
 
704
}
 
705
 
 
706
void
 
707
gimp_composite_lighten_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
708
{
 
709
  uint64 *d = (uint64 *) _op->D;
 
710
  uint64 *a = (uint64 *) _op->A;
 
711
  uint64 *b = (uint64 *) _op->B;
 
712
  gulong n_pixels = _op->n_pixels;
 
713
 
 
714
  asm volatile ("movq    %0,%%mm0"     :  : "m" (*rgba8_alpha_mask_64) : "%mm0");
 
715
 
 
716
  for (; n_pixels >= 2; n_pixels -= 2)
 
717
    {
 
718
      asm volatile ("  movq       %1, %%mm2\n"
 
719
                    "\tmovq       %2, %%mm3\n"
 
720
                    "\tmovq    %%mm2, %%mm4\n"
 
721
                    "\t" pmaxub(mm3,mm4,mm5) "\n"
 
722
                    "\tmovq    %%mm0, %%mm1\n"
 
723
                    "\tpandn   %%mm4, %%mm1\n"
 
724
                    "\t" pminub(mm2,mm3,mm4) "\n"
 
725
                    "\tpand    %%mm0, %%mm3\n"
 
726
                    "\tpor     %%mm3, %%mm1\n"
 
727
                    "\tmovq    %%mm1, %0\n"
 
728
                    : "=m" (*d)
 
729
                    : "m" (*a), "m" (*b)
 
730
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
731
      a++;
 
732
      b++;
 
733
      d++;
 
734
    }
 
735
 
 
736
  if (n_pixels > 0)
 
737
    {
 
738
      asm volatile ("  movd       %1, %%mm2\n"
 
739
                    "\tmovd       %2, %%mm3\n"
 
740
                    "\tmovq    %%mm2, %%mm4\n"
 
741
                    "\t" pmaxub(mm3,mm4,mm5) "\n"
 
742
 
 
743
                    "\tmovq    %%mm0, %%mm1\n"
 
744
                    "\tpandn   %%mm4, %%mm1\n"
 
745
 
 
746
                    "\t" pminub(mm2,mm3,mm4) "\n"
 
747
 
 
748
                    "\tpand    %%mm0, %%mm3\n"
 
749
                    "\tpor     %%mm3, %%mm1\n"
 
750
                    "\tmovd    %%mm1, %0\n"
 
751
                    : "=m" (*d)
 
752
                    : "m" (*a), "m" (*b)
 
753
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
754
    }
 
755
 
 
756
  asm("emms");
 
757
}
 
758
 
 
759
void
 
760
gimp_composite_multiply_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
761
{
 
762
  uint64 *d = (uint64 *) _op->D;
 
763
  uint64 *a = (uint64 *) _op->A;
 
764
  uint64 *b = (uint64 *) _op->B;
 
765
  gulong n_pixels = _op->n_pixels;
 
766
 
 
767
  asm volatile (
 
768
                "movq    %0,%%mm0\n"
 
769
                "movq    %1,%%mm7\n"
 
770
                "pxor    %%mm6,%%mm6\n"
 
771
                : /* empty */
 
772
                : "m" (*rgba8_alpha_mask_64), "m" (*rgba8_w128_64)
 
773
                : "%mm6", "%mm7", "%mm0");
 
774
 
 
775
  for (; n_pixels >= 2; n_pixels -= 2)
 
776
    {
 
777
      asm volatile ("  movq        %1, %%mm2\n"
 
778
                    "\tmovq        %2, %%mm3\n"
 
779
 
 
780
                    mmx_low_bytes_to_words(mm2,mm1,mm6)
 
781
                    mmx_low_bytes_to_words(mm3,mm5,mm6)
 
782
                    mmx_int_mult(mm5,mm1,mm7)
 
783
 
 
784
                    mmx_high_bytes_to_words(mm2,mm4,mm6)
 
785
                    mmx_high_bytes_to_words(mm3,mm5,mm6)
 
786
                    mmx_int_mult(mm5,mm4,mm7)
 
787
 
 
788
                    "\tpackuswb  %%mm4, %%mm1\n"
 
789
 
 
790
                    "\tmovq      %%mm0, %%mm4\n"
 
791
                    "\tpandn     %%mm1, %%mm4\n"
 
792
                    "\tmovq      %%mm4, %%mm1\n"
 
793
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
794
                    "\tpand      %%mm0, %%mm2\n"
 
795
                    "\tpor       %%mm2, %%mm1\n"
 
796
 
 
797
                    "\tmovq      %%mm1, %0\n"
 
798
                    : "=m" (*d)
 
799
                    : "m" (*a), "m" (*b)
 
800
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
801
      a++;
 
802
      b++;
 
803
      d++;
 
804
  }
 
805
 
 
806
  if (n_pixels > 0)
 
807
    {
 
808
      asm volatile ("  movd     %1, %%mm2\n"
 
809
                    "\tmovd     %2, %%mm3\n"
 
810
 
 
811
                    mmx_low_bytes_to_words(mm2,mm1,mm6)
 
812
                    mmx_low_bytes_to_words(mm3,mm5,mm6)
 
813
                    pmulwX(mm5,mm1,mm7)
 
814
 
 
815
                    "\tpackuswb  %%mm6, %%mm1\n"
 
816
 
 
817
                    "\tmovq      %%mm0, %%mm4\n"
 
818
                    "\tpandn     %%mm1, %%mm4\n"
 
819
                    "\tmovq      %%mm4, %%mm1\n"
 
820
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
821
                    "\tpand      %%mm0, %%mm2\n"
 
822
                    "\tpor       %%mm2, %%mm1\n"
 
823
 
 
824
                    "\tmovd    %%mm1, %0\n"
 
825
                    : "=m" (*d)
 
826
                    : "m" (*a), "m" (*b)
 
827
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
828
  }
 
829
 
 
830
  asm("emms");
 
831
}
 
832
 
 
833
static void
 
834
mmx_op_overlay(void)
 
835
{
 
836
  asm volatile (
 
837
                /* low bytes */
 
838
                mmx_low_bytes_to_words(mm3,mm5,mm0)
 
839
                "\tpcmpeqb   %%mm4,%%mm4\n"
 
840
                "\tpsubb     %%mm2,%%mm4\n" /* mm4 = 255 - A */
 
841
                "\tpunpcklbw %%mm0,%%mm4\n" /* mm4 = (low bytes as word) mm4 */
 
842
                "\tmovq         %0,%%mm6\n"  /* mm6 = words of value 2 */
 
843
                "\tpmullw    %%mm5,%%mm6\n" /* mm6 = 2 * low bytes of B */
 
844
                mmx_int_mult(mm6,mm4,mm7)    /* mm4 = INT_MULT(mm6, mm4) */
 
845
 
 
846
                /* high bytes */
 
847
                mmx_high_bytes_to_words(mm3,mm5,mm0)
 
848
                "\tpcmpeqb   %%mm1,%%mm1\n"
 
849
                "\tpsubb     %%mm2,%%mm1\n" /* mm1 = 255 - A */
 
850
                "\tpunpckhbw %%mm0,%%mm1\n" /* mm1 = (high bytes as word) mm1 */
 
851
                "\tmovq         %0,%%mm6\n"  /* mm6 = words of value 2 */
 
852
                "\tpmullw    %%mm5,%%mm6\n" /* mm6 = 2 * high bytes of B */
 
853
                mmx_int_mult(mm6,mm1,mm7)    /* mm1 = INT_MULT(mm6, mm1) */
 
854
 
 
855
                "\tpackuswb  %%mm1,%%mm4\n"  /* mm4 = intermediate value */
 
856
 
 
857
                mmx_low_bytes_to_words(mm4,mm5,mm0)
 
858
                mmx_low_bytes_to_words(mm2,mm6,mm0)
 
859
                "\tpaddw     %%mm6,%%mm5\n"
 
860
                mmx_int_mult(mm6,mm5,mm7)   /* mm5 = INT_MULT(mm6, mm5) low bytes */
 
861
 
 
862
                mmx_high_bytes_to_words(mm4,mm1,mm0)
 
863
                mmx_high_bytes_to_words(mm2,mm6,mm0)
 
864
                "\tpaddw     %%mm6,%%mm1\n"
 
865
                mmx_int_mult(mm6,mm1,mm7)   /* mm1 = INT_MULT(mm6, mm1) high bytes */
 
866
 
 
867
                "\tpackuswb  %%mm1,%%mm5\n"
 
868
 
 
869
                "\tmovq         %1,%%mm0\n"
 
870
                "\tmovq      %%mm0,%%mm1\n"
 
871
                "\tpandn     %%mm5,%%mm1\n"
 
872
 
 
873
                "\t" pminub(mm2,mm3,mm4) "\n"
 
874
                "\tpand      %%mm0,%%mm3\n"
 
875
 
 
876
                "\tpor       %%mm3,%%mm1\n"
 
877
 
 
878
                : /* empty */
 
879
                : "m" (*rgba8_w2_64), "m" (*rgba8_alpha_mask_64)
 
880
                );
 
881
}
 
882
 
 
883
#if 0
 
884
void
 
885
xxxgimp_composite_overlay_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
886
{
 
887
  uint64 *d = (uint64 *) _op->D;
 
888
  uint64 *a = (uint64 *) _op->A;
 
889
  uint64 *b = (uint64 *) _op->B;
 
890
  gulong n_pixels = _op->n_pixels;
 
891
 
 
892
  asm volatile ("pxor    %%mm0,%%mm0\n"
 
893
                "movq       %0,%%mm7"
 
894
                : /* empty */
 
895
                : "m" (*rgba8_w128_64) : "%mm0");
 
896
 
 
897
  for (; n_pixels >= 2; n_pixels -= 2)
 
898
    {
 
899
      asm volatile ("  movq         %0,%%mm2\n"
 
900
                    "\tmovq         %1,%%mm3\n"
 
901
 
 
902
                    /* low bytes */
 
903
                    mmx_low_bytes_to_words(mm3,mm5,mm0)
 
904
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
905
                    "\tpsubb     %%mm2,%%mm4\n" /* mm4 = 255 - A */
 
906
                    "\tpunpcklbw %%mm0,%%mm4\n" /* mm4 = (low bytes as word) mm4 */
 
907
                    "\tmovq         %3,%%mm6\n"  /* mm6 = words of value 2 */
 
908
                    "\tpmullw    %%mm5,%%mm6\n" /* mm6 = 2 * low bytes of B */
 
909
                    mmx_int_mult(mm6,mm4,mm7)    /* mm4 = INT_MULT(mm6, mm4) */
 
910
 
 
911
                    /* high bytes */
 
912
                    mmx_high_bytes_to_words(mm3,mm5,mm0)
 
913
                    "\tpcmpeqb   %%mm1,%%mm1\n"
 
914
                    "\tpsubb     %%mm2,%%mm1\n" /* mm1 = 255 - A */
 
915
                    "\tpunpckhbw %%mm0,%%mm1\n" /* mm1 = (high bytes as word) mm1 */
 
916
                    "\tmovq         %3,%%mm6\n"  /* mm6 = words of value 2 */
 
917
                    "\tpmullw    %%mm5,%%mm6\n" /* mm6 = 2 * high bytes of B */
 
918
                    mmx_int_mult(mm6,mm1,mm7)    /* mm1 = INT_MULT(mm6, mm1) */
 
919
 
 
920
                    "\tpackuswb  %%mm1,%%mm4\n"  /* mm4 = intermediate value */
 
921
 
 
922
                    mmx_low_bytes_to_words(mm4,mm5,mm0)
 
923
                    mmx_low_bytes_to_words(mm2,mm6,mm0)
 
924
                    "\tpaddw     %%mm6,%%mm5\n"
 
925
                    mmx_int_mult(mm6,mm5,mm7)   /* mm5 = INT_MULT(mm6, mm5) low bytes */
 
926
 
 
927
                    mmx_high_bytes_to_words(mm4,mm1,mm0)
 
928
                    mmx_high_bytes_to_words(mm2,mm6,mm0)
 
929
                    "\tpaddw     %%mm6,%%mm1\n"
 
930
                    mmx_int_mult(mm6,mm1,mm7)   /* mm1 = INT_MULT(mm6, mm1) high bytes */
 
931
 
 
932
                    "\tpackuswb  %%mm1,%%mm5\n"
 
933
 
 
934
                    "\tmovq         %4,%%mm0\n"
 
935
                    "\tmovq      %%mm0,%%mm1\n"
 
936
                    "\tpandn     %%mm5,%%mm1\n"
 
937
 
 
938
                    "\t" pminub(mm2,mm3,mm4) "\n"
 
939
                    "\tpand      %%mm0,%%mm3\n"
 
940
 
 
941
                    "\tpor       %%mm3,%%mm1\n"
 
942
 
 
943
                    "\tmovq      %%mm1,%2\n"
 
944
                    : "+m" (*a), "+m" (*b), "+m" (*d)
 
945
                    : "m" (*rgba8_w2_64), "m" (*rgba8_alpha_mask_64)
 
946
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
947
      a++;
 
948
      b++;
 
949
      d++;
 
950
  }
 
951
 
 
952
  if (n_pixels > 0)
 
953
    {
 
954
      asm volatile ("  movd         %1,%%mm2\n"
 
955
                    "\tmovd         %2,%%mm3\n"
 
956
 
 
957
                    /* low bytes */
 
958
                    mmx_low_bytes_to_words(mm3,mm5,mm0)
 
959
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
960
                    "\tpsubb     %%mm2,%%mm4\n" /* mm4 = 255 - A */
 
961
                    "\tpunpcklbw %%mm0,%%mm4\n" /* mm4 = (low bytes as word) mm4 */
 
962
                    "\tmovq         %3,%%mm6\n"  /* mm6 = words of integer value 2 */
 
963
                    "\tpmullw    %%mm5,%%mm6\n" /* mm6 = 2 * low bytes of B */
 
964
                    mmx_int_mult(mm6,mm4,mm7)    /* mm4 = INT_MULT(mm6, mm4) */
 
965
 
 
966
                    /* high bytes */
 
967
                    mmx_high_bytes_to_words(mm3,mm5,mm0)
 
968
                    "\tpcmpeqb   %%mm1,%%mm1\n"
 
969
                    "\tpsubb     %%mm2,%%mm1\n" /* mm1 = 255 - A */
 
970
                    "\tpunpckhbw %%mm0,%%mm1\n" /* mm1 = (high bytes as word) mm1 */
 
971
                    "\tmovq         %3,%%mm6\n"  /* mm6 = words of integer value 2 */
 
972
                    "\tpmullw    %%mm5,%%mm6\n" /* mm6 = 2 * high bytes of B */
 
973
                    mmx_int_mult(mm6,mm1,mm7)    /* mm1 = INT_MULT(mm6, mm1) */
 
974
 
 
975
                    "\tpackuswb  %%mm1,%%mm4\n"  /* mm4 = intermediate value */
 
976
 
 
977
                    mmx_low_bytes_to_words(mm4,mm5,mm0)
 
978
                    mmx_low_bytes_to_words(mm2,mm6,mm0)
 
979
                    "\tpaddw     %%mm6,%%mm5\n"
 
980
                    mmx_int_mult(mm6,mm5,mm7)   /* mm5 = INT_MULT(mm6, mm5) low bytes */
 
981
 
 
982
                    mmx_high_bytes_to_words(mm4,mm1,mm0)
 
983
                    mmx_high_bytes_to_words(mm2,mm6,mm0)
 
984
                    "\tpaddw     %%mm6,%%mm1\n"
 
985
                    mmx_int_mult(mm6,mm1,mm7)   /* mm1 = INT_MULT(mm6, mm1) high bytes */
 
986
 
 
987
                    "\tpackuswb  %%mm1,%%mm5\n"
 
988
 
 
989
                    "\tmovq         %4,%%mm0\n"
 
990
                    "\tmovq      %%mm0,%%mm1\n"
 
991
                    "\tpandn     %%mm5,%%mm1\n"
 
992
 
 
993
                    "\t" pminub(mm2,mm3,mm4) "\n"
 
994
                    "\tpand      %%mm0,%%mm3\n"
 
995
 
 
996
                    "\tpor       %%mm3,%%mm1\n"
 
997
 
 
998
                    "\tmovd      %%mm1,%0\n"
 
999
                    : "=m" (*d)
 
1000
                    : "m" (*a), "m" (*b), "m" (*rgba8_w2_64), "m" (*rgba8_alpha_mask_64)
 
1001
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
1002
    }
 
1003
 
 
1004
  asm("emms");
 
1005
}
 
1006
#endif
 
1007
 
 
1008
void
 
1009
gimp_composite_scale_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
1010
{
 
1011
  uint64 *d = (uint64 *) _op->D;
 
1012
  uint64 *a = (uint64 *) _op->A;
 
1013
  gulong n_pixels = _op->n_pixels;
 
1014
 
 
1015
  asm volatile ("pxor    %%mm0,%%mm0\n"
 
1016
                "\tmovl     %0,%%eax\n"
 
1017
                "\tmovl  %%eax,%%ebx\n"
 
1018
                "\tshl     $16,%%ebx\n"
 
1019
                "\torl   %%ebx,%%eax\n"
 
1020
                "\tmovd  %%eax,%%mm5\n"
 
1021
                "\tmovd  %%eax,%%mm3\n"
 
1022
                "\tpsllq   $32,%%mm5\n"
 
1023
                "\tpor   %%mm5,%%mm3\n"
 
1024
                "\tmovq     %1,%%mm7\n"
 
1025
                : /* empty */
 
1026
                : "m" (_op->scale.scale), "m" (*rgba8_w128_64)
 
1027
                : "%eax", "%ebx", "%mm0", "%mm5", "%mm6", "%mm7");
 
1028
 
 
1029
  for (; n_pixels >= 2; n_pixels -= 2)
 
1030
    {
 
1031
      asm volatile ("movq           %1,%%mm2\n"
 
1032
                    "\tmovq      %%mm2,%%mm1\n"
 
1033
                    "\tpunpcklbw %%mm0,%%mm1\n"
 
1034
                    "\tmovq      %%mm3,%%mm5\n"
 
1035
 
 
1036
                    "\t" pmulwX(mm5,mm1,mm7) "\n"
 
1037
 
 
1038
                    "\tmovq      %%mm2,%%mm4\n"
 
1039
                    "\tpunpckhbw %%mm0,%%mm4\n"
 
1040
                    "\tmovq      %%mm3,%%mm5\n"
 
1041
 
 
1042
                    "\t" pmulwX(mm5,mm4,mm7) "\n"
 
1043
 
 
1044
                    "\tpackuswb  %%mm4,%%mm1\n"
 
1045
 
 
1046
                    "\tmovq      %%mm1,%0\n"
 
1047
                    : "=m" (*d)
 
1048
                    : "m" (*a)
 
1049
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
 
1050
      a++;
 
1051
      d++;
 
1052
    }
 
1053
 
 
1054
  if (n_pixels > 0)
 
1055
    {
 
1056
      asm volatile ("movd           %1,%%mm2\n"
 
1057
                    "\tmovq      %%mm2,%%mm1\n"
 
1058
                    "\tpunpcklbw %%mm0,%%mm1\n"
 
1059
                    "\tmovq      %%mm3,%%mm5\n"
 
1060
 
 
1061
                    "\t" pmulwX(mm5,mm1,mm7) "\n"
 
1062
 
 
1063
                    "\tpackuswb  %%mm0,%%mm1\n"
 
1064
                    "\tmovd      %%mm1,%0\n"
 
1065
                    : "=m" (*d)
 
1066
                    : "m" (*a)
 
1067
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
 
1068
  }
 
1069
 
 
1070
  asm("emms");
 
1071
}
 
1072
 
 
1073
void
 
1074
gimp_composite_screen_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
1075
{
 
1076
  uint64 *d = (uint64 *) _op->D;
 
1077
  uint64 *a = (uint64 *) _op->A;
 
1078
  uint64 *b = (uint64 *) _op->B;
 
1079
  gulong n_pixels = _op->n_pixels;
 
1080
 
 
1081
  asm volatile ("pxor    %%mm6,%%mm6\n"
 
1082
                "movq       %0,%%mm0\n"
 
1083
                "movq       %1,%%mm7\n"
 
1084
                : /* empty */
 
1085
                : "m" (*rgba8_alpha_mask_64), "m" (*rgba8_w128_64)
 
1086
                : "%mm0", "%mm6", "%mm7");
 
1087
 
 
1088
  for (; n_pixels >= 2; n_pixels -= 2)
 
1089
    {
 
1090
      asm volatile ("  movq         %1,%%mm2\n"
 
1091
                    "\tmovq         %2,%%mm3\n"
 
1092
 
 
1093
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
1094
                    "\tpsubb     %%mm2,%%mm4\n"
 
1095
                    "\tpcmpeqb   %%mm5,%%mm5\n"
 
1096
                    "\tpsubb     %%mm3,%%mm5\n"
 
1097
 
 
1098
                    "\tpunpcklbw %%mm6,%%mm4\n"
 
1099
                    "\tpunpcklbw %%mm6,%%mm5\n"
 
1100
                    "\tpmullw    %%mm4,%%mm5\n"
 
1101
                    "\tpaddw     %%mm7,%%mm5\n"
 
1102
                    "\tmovq      %%mm5,%%mm1\n"
 
1103
                    "\tpsrlw       $ 8,%%mm1\n"
 
1104
                    "\tpaddw     %%mm5,%%mm1\n"
 
1105
                    "\tpsrlw       $ 8,%%mm1\n"
 
1106
 
 
1107
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
1108
                    "\tpsubb     %%mm2,%%mm4\n"
 
1109
                    "\tpcmpeqb   %%mm5,%%mm5\n"
 
1110
                    "\tpsubb     %%mm3,%%mm5\n"
 
1111
 
 
1112
                    "\tpunpckhbw %%mm6,%%mm4\n"
 
1113
                    "\tpunpckhbw %%mm6,%%mm5\n"
 
1114
                    "\tpmullw    %%mm4,%%mm5\n"
 
1115
                    "\tpaddw     %%mm7,%%mm5\n"
 
1116
                    "\tmovq      %%mm5,%%mm4\n"
 
1117
                    "\tpsrlw       $ 8,%%mm4\n"
 
1118
                    "\tpaddw     %%mm5,%%mm4\n"
 
1119
                    "\tpsrlw       $ 8,%%mm4\n"
 
1120
 
 
1121
                    "\tpackuswb  %%mm4,%%mm1\n"
 
1122
 
 
1123
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
1124
                    "\tpsubb     %%mm1,%%mm4\n"
 
1125
 
 
1126
                    "\tmovq      %%mm0,%%mm1\n"
 
1127
                    "\tpandn     %%mm4,%%mm1\n"
 
1128
 
 
1129
                    "\t" pminub(mm2,mm3,mm4) "\n"
 
1130
                    "\tpand      %%mm0,%%mm3\n"
 
1131
 
 
1132
                    "\tpor       %%mm3,%%mm1\n"
 
1133
 
 
1134
                    "\tmovq      %%mm1,%0\n"
 
1135
                    : "=m" (*d)
 
1136
                    : "m" (*a), "m" (*b)
 
1137
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
1138
      a++;
 
1139
      b++;
 
1140
      d++;
 
1141
  }
 
1142
 
 
1143
  if (n_pixels > 0)
 
1144
    {
 
1145
      asm volatile ("  movd         %1,%%mm2\n"
 
1146
                    "\tmovd         %2,%%mm3\n"
 
1147
 
 
1148
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
1149
                    "\tpsubb     %%mm2,%%mm4\n"
 
1150
                    "\tpcmpeqb   %%mm5,%%mm5\n"
 
1151
                    "\tpsubb     %%mm3,%%mm5\n"
 
1152
 
 
1153
                    "\tpunpcklbw %%mm6,%%mm4\n"
 
1154
                    "\tpunpcklbw %%mm6,%%mm5\n"
 
1155
                    "\tpmullw    %%mm4,%%mm5\n"
 
1156
                    "\tpaddw     %%mm7,%%mm5\n"
 
1157
                    "\tmovq      %%mm5,%%mm1\n"
 
1158
                    "\tpsrlw       $ 8,%%mm1\n"
 
1159
                    "\tpaddw     %%mm5,%%mm1\n"
 
1160
                    "\tpsrlw       $ 8,%%mm1\n"
 
1161
 
 
1162
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
1163
                    "\tpsubb     %%mm2,%%mm4\n"
 
1164
                    "\tpcmpeqb   %%mm5,%%mm5\n"
 
1165
                    "\tpsubb     %%mm3,%%mm5\n"
 
1166
 
 
1167
                    "\tpunpckhbw %%mm6,%%mm4\n"
 
1168
                    "\tpunpckhbw %%mm6,%%mm5\n"
 
1169
                    "\tpmullw    %%mm4,%%mm5\n"
 
1170
                    "\tpaddw     %%mm7,%%mm5\n"
 
1171
                    "\tmovq      %%mm5,%%mm4\n"
 
1172
                    "\tpsrlw       $ 8,%%mm4\n"
 
1173
                    "\tpaddw     %%mm5,%%mm4\n"
 
1174
                    "\tpsrlw       $ 8,%%mm4\n"
 
1175
 
 
1176
                    "\tpackuswb  %%mm4,%%mm1\n"
 
1177
 
 
1178
                    "\tpcmpeqb   %%mm4,%%mm4\n"
 
1179
                    "\tpsubb     %%mm1,%%mm4\n"
 
1180
 
 
1181
                    "\tmovq      %%mm0,%%mm1\n"
 
1182
                    "\tpandn     %%mm4,%%mm1\n"
 
1183
 
 
1184
                    "\t" pminub(mm2,mm3,mm4) "\n"
 
1185
                    "\tpand      %%mm0,%%mm3\n"
 
1186
 
 
1187
                    "\tpor       %%mm3,%%mm1\n"
 
1188
                    
 
1189
                    "\tmovd      %%mm1,%0\n"
 
1190
                    : "=m" (*d)
 
1191
                    : "m" (*a), "m" (*b)
 
1192
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
1193
    }
 
1194
 
 
1195
  asm volatile ("emms");
 
1196
}
 
1197
 
 
1198
 
 
1199
void
 
1200
gimp_composite_subtract_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
1201
{
 
1202
  uint64 *d = (uint64 *) _op->D;
 
1203
  uint64 *a = (uint64 *) _op->A;
 
1204
  uint64 *b = (uint64 *) _op->B;
 
1205
  gulong n_pixels = _op->n_pixels;
 
1206
 
 
1207
  asm volatile ("movq    %0,%%mm0"     :  : "m" (*rgba8_alpha_mask_64) : "%mm0");
 
1208
 
 
1209
  for (; n_pixels >= 2; n_pixels -= 2)
 
1210
    {
 
1211
      asm volatile ("  movq       %1,%%mm2\n"
 
1212
                    "\tmovq       %2,%%mm3\n"
 
1213
 
 
1214
                    "\tmovq    %%mm2,%%mm4\n"
 
1215
                    "\tpsubusb %%mm3,%%mm4\n"
 
1216
 
 
1217
                    "\tmovq    %%mm0,%%mm1\n"
 
1218
                    "\tpandn   %%mm4,%%mm1\n"
 
1219
 
 
1220
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
1221
 
 
1222
                    "\tpand    %%mm0,%%mm2\n"
 
1223
                    "\tpor     %%mm2,%%mm1\n"
 
1224
                    "\tmovq    %%mm1,%0\n"
 
1225
                    : "=m" (*d)
 
1226
                    : "m" (*a), "m" (*b)
 
1227
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
1228
      a++;
 
1229
      b++;
 
1230
      d++;
 
1231
    }
 
1232
 
 
1233
  if (n_pixels > 0)
 
1234
    {
 
1235
      asm volatile ("  movd       %1,%%mm2\n"
 
1236
                    "\tmovd       %2,%%mm3\n"
 
1237
 
 
1238
                    "\tmovq    %%mm2,%%mm4\n"
 
1239
                    "\tpsubusb %%mm3,%%mm4\n"
 
1240
 
 
1241
                    "\tmovq    %%mm0,%%mm1\n"
 
1242
                    "\tpandn   %%mm4,%%mm1\n"
 
1243
 
 
1244
                    "\t" pminub(mm3,mm2,mm4) "\n"
 
1245
 
 
1246
                    "\tpand    %%mm0,%%mm2\n"
 
1247
                    "\tpor     %%mm2,%%mm1\n"
 
1248
                    "\tmovd    %%mm1,%0\n"
 
1249
                    : "=m" (*d)
 
1250
                    : "m" (*a), "m" (*b)
 
1251
                    : "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
 
1252
    }
 
1253
 
 
1254
  asm volatile ("emms");
 
1255
}
 
1256
 
 
1257
void
 
1258
gimp_composite_swap_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
 
1259
{
 
1260
  uint64 *a = (uint64 *) _op->A;
 
1261
  uint64 *b = (uint64 *) _op->B;
 
1262
  gulong n_pixels = _op->n_pixels;
 
1263
 
 
1264
  for (; n_pixels >= 2; n_pixels -= 2)
 
1265
    {
 
1266
      asm volatile ("  movq       %0,%%mm2\n"
 
1267
                    "\tmovq       %1,%%mm3\n"
 
1268
                    "\tmovq    %%mm3,%0\n"
 
1269
                    "\tmovq    %%mm2,%1\n"
 
1270
                    : "+m" (*a), "+m" (*b)
 
1271
                    : 
 
1272
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
1273
      a++;
 
1274
      b++;
 
1275
    }
 
1276
 
 
1277
  if (n_pixels > 0)
 
1278
    {
 
1279
      asm volatile ("  movd       %0,%%mm2\n"
 
1280
                    "\tmovd       %1,%%mm3\n"
 
1281
                    "\tmovd    %%mm3,%0\n"
 
1282
                    "\tmovd    %%mm2,%1\n"
 
1283
                    : "+m" (*a), "+m" (*b)
 
1284
                    :
 
1285
                    : "%mm1", "%mm2", "%mm3", "%mm4");
 
1286
    }
 
1287
 
 
1288
  asm("emms");
 
1289
}
 
1290
 
 
1291
 
 
1292
#if 0
 
1293
void
 
1294
gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1295
{
 
1296
  uint64 *d = (uint64 *) _op->D;
 
1297
  uint64 *a = (uint64 *) _op->A;
 
1298
  uint64 *b = (uint64 *) _op->B;
 
1299
  gulong n_pixels = _op->n_pixels;
 
1300
 
 
1301
  asm volatile ("movq    %0,%%mm0"
 
1302
                : 
 
1303
                : "m" (*va8_alpha_mask_64)
 
1304
                : "%mm0");
 
1305
 
 
1306
  for (; n_pixels >= 4; n_pixels -= 4)
 
1307
    {
 
1308
      asm volatile ("  movq       %1, %%mm2\n"
 
1309
                    "\tmovq       %2, %%mm3\n"
 
1310
                    "\tmovq    %%mm2, %%mm4\n"
 
1311
                    "\tpaddusb %%mm3, %%mm4\n"
 
1312
                    "\tmovq    %%mm0, %%mm1\n"
 
1313
                    "\tpandn   %%mm4, %%mm1\n"
 
1314
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
1315
                    "\tpand    %%mm0, %%mm2\n"
 
1316
                    "\tpor     %%mm2, %%mm1\n"
 
1317
#if 0
 
1318
                    "\tmovq    %%mm1, %0\n"
 
1319
#else
 
1320
                    "\tmovntq  %%mm1, %0\n"
 
1321
#endif
 
1322
                    : "=m" (*d)
 
1323
                    : "m" (*a), "m" (*b)
 
1324
                    : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4");
 
1325
      a++;
 
1326
      b++;
 
1327
      d++;
 
1328
    }
 
1329
 
 
1330
  uint32 *a32 = (uint32 *) a;
 
1331
  uint32 *b32 = (uint32 *) b;
 
1332
  uint32 *d32 = (uint32 *) d;
 
1333
 
 
1334
  for (; n_pixels >= 2; n_pixels -= 2)
 
1335
    {
 
1336
      asm volatile ("  movd    %1, %%mm2\n"
 
1337
                    "\tmovd    %2, %%mm3\n"
 
1338
                    "\tmovq    %%mm2, %%mm4\n"
 
1339
                    "\tpaddusb %%mm3, %%mm4\n"
 
1340
                    "\tmovq    %%mm0, %%mm1\n"
 
1341
                    "\tpandn   %%mm4, %%mm1\n"
 
1342
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
1343
                    "\tpand    %%mm0, %%mm2\n"
 
1344
                    "\tpor     %%mm2, %%mm1\n"
 
1345
                    "\tmovd    %%mm1, %0\n"
 
1346
                    : "=m" (*d32)
 
1347
                    : "m" (*a32), "m" (*b32)
 
1348
                    : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4");
 
1349
      a32++;
 
1350
      b32++;
 
1351
      d32++;
 
1352
    }
 
1353
  
 
1354
  uint16 *a16 = (uint16 *) a32;
 
1355
  uint16 *b16 = (uint16 *) b32;
 
1356
  uint16 *d16 = (uint16 *) d32;
 
1357
 
 
1358
  for (; n_pixels >= 1; n_pixels -= 1)
 
1359
    {
 
1360
      asm volatile ("  movw    %1, %%ax ; movd    %%eax, %%mm2\n"
 
1361
                    "\tmovw    %2, %%ax ; movd    %%eax, %%mm3\n"
 
1362
                    "\tmovq    %%mm2, %%mm4\n"
 
1363
                    "\tpaddusb %%mm3, %%mm4\n"
 
1364
                    "\tmovq    %%mm0, %%mm1\n"
 
1365
                    "\tpandn   %%mm4, %%mm1\n"
 
1366
                    "\t" pminub(mm3, mm2, mm4) "\n"
 
1367
                    "\tpand    %%mm0, %%mm2\n"
 
1368
                    "\tpor     %%mm2, %%mm1\n"
 
1369
                    "\tmovd    %%mm1, %%eax\n"
 
1370
                    "\tmovw    %%ax, %0\n"
 
1371
                    : "=m" (*d16)
 
1372
                    : "m" (*a16), "m" (*b16)
 
1373
                    : "%eax", "%mm0", "%mm1", "%mm2", "%mm3", "%mm4");
 
1374
 
 
1375
      a16++;
 
1376
      b16++;
 
1377
      d16++;
 
1378
    }
 
1379
  
 
1380
  asm("emms");
 
1381
}
 
1382
#endif
 
1383
 
 
1384
#if 0
 
1385
void
 
1386
gimp_composite_burn_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1387
{
 
1388
  GimpCompositeContext op = *_op;
 
1389
 
 
1390
  asm("movq   %0,%%mm1"
 
1391
      :
 
1392
      : "m" (*va8_alpha_mask)
 
1393
      : "%mm1");
 
1394
 
 
1395
  for (; op.n_pixels >= 4; op.n_pixels -= 4)
 
1396
    {
 
1397
    asm volatile ("  movq         %0,%%mm0\n"
 
1398
                  "\tmovq         %1,%%mm1\n"
 
1399
 
 
1400
                  "\tmovq         %3,%%mm2\n"
 
1401
                  "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
1402
                  "\tpxor      %%mm4,%%mm4\n"
 
1403
                  "\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
1404
 
 
1405
                  "\tmovq      %%mm1,%%mm3\n"
 
1406
                  "\tpxor      %%mm5,%%mm5\n"
 
1407
                  "\tpunpcklbw %%mm5,%%mm3\n"
 
1408
                  "\tmovq         %4,%%mm5\n"
 
1409
                  "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
1410
 
 
1411
                  "\t" pdivwqX(mm4,mm5,mm7) "\n"
 
1412
 
 
1413
                  "\tmovq         %3,%%mm2\n"
 
1414
                  "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
1415
                  "\tpxor      %%mm4,%%mm4\n"
 
1416
                  "\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
1417
 
 
1418
                  "\tmovq      %%mm1,%%mm3\n"
 
1419
                  "\tpxor      %%mm5,%%mm5\n"
 
1420
                  "\tpunpckhbw %%mm5,%%mm3\n"
 
1421
                  "\tmovq         %4,%%mm5\n"
 
1422
                  "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
1423
                  "\t" pdivwqX(mm4,mm5,mm6) "\n"
 
1424
 
 
1425
                  "\tmovq         %5,%%mm4\n"
 
1426
                  "\tmovq      %%mm4,%%mm5\n"
 
1427
                  "\tpsubusw   %%mm6,%%mm4\n"
 
1428
                  "\tpsubusw   %%mm7,%%mm5\n"
 
1429
 
 
1430
                  "\tpackuswb  %%mm4,%%mm5\n"
 
1431
 
 
1432
                  "\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
 
1433
 
 
1434
                  "\tmovq         %6,%%mm7\n"
 
1435
                  "\tpand      %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
 
1436
 
 
1437
                  "\tpandn     %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
 
1438
                  "\tpor       %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
 
1439
 
 
1440
                  "\tmovq      %%mm7,%2\n"
 
1441
                  : /* empty */
 
1442
                  : "+m" (*op.A), "+m" (*op.B), "+m" (*op.D), "m" (*va8_b255), "m" (*va8_w1), "m" (*va8_w255_64), "m" (*va8_alpha_mask)
 
1443
                  : "%mm1", "%mm2", "%mm3", "%mm4");
 
1444
      op.A += 8;
 
1445
      op.B += 8;
 
1446
      op.D += 8;
 
1447
  }
 
1448
 
 
1449
  if (op.n_pixels)
 
1450
    {
 
1451
    asm volatile ("  movd         %0,%%mm0\n"
 
1452
                  "\tmovd         %1,%%mm1\n"
 
1453
                  "\tmovq         %3,%%mm2\n"
 
1454
                  "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
1455
                  "\tpxor      %%mm4,%%mm4\n"
 
1456
                  "\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
1457
 
 
1458
                  "\tmovq      %%mm1,%%mm3\n"
 
1459
                  "\tpxor      %%mm5,%%mm5\n"
 
1460
                  "\tpunpcklbw %%mm5,%%mm3\n"
 
1461
                  "\tmovq         %4,%%mm5\n"
 
1462
                  "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
1463
 
 
1464
                  "\t" pdivwqX(mm4,mm5,mm7) "\n"
 
1465
 
 
1466
                  "\tmovq         %3,%%mm2\n"
 
1467
                  "\tpsubb     %%mm0,%%mm2\n" /* mm2 = 255 - A */
 
1468
                  "\tpxor      %%mm4,%%mm4\n"
 
1469
                  "\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256  */
 
1470
 
 
1471
                  "\tmovq      %%mm1,%%mm3\n"
 
1472
                  "\tpxor      %%mm5,%%mm5\n"
 
1473
                  "\tpunpckhbw %%mm5,%%mm3\n"
 
1474
                  "\tmovq         %4,%%mm5\n"
 
1475
                  "\tpaddusw   %%mm3,%%mm5\n" /* mm5 = B + 1 */
 
1476
                  "\t" pdivwqX(mm4,mm5,mm6) "\n"
 
1477
 
 
1478
                  "\tmovq         %5,%%mm4\n"
 
1479
                  "\tmovq      %%mm4,%%mm5\n"
 
1480
                  "\tpsubusw   %%mm6,%%mm4\n"
 
1481
                  "\tpsubusw   %%mm7,%%mm5\n"
 
1482
 
 
1483
                  "\tpackuswb  %%mm4,%%mm5\n"
 
1484
 
 
1485
                  "\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
 
1486
 
 
1487
                  "\tmovq         %6,%%mm7\n"
 
1488
                  "\tpand      %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
 
1489
 
 
1490
                  "\tpandn     %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
 
1491
                  "\tpor       %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
 
1492
 
 
1493
                  "\tmovd      %%mm7,%2\n"
 
1494
                  : /* empty */
 
1495
                  : "m" (*op.A), "m" (*op.B), "m" (*op.D), "m" (*va8_b255), "m" (*va8_w1), "m" (*va8_w255_64), "m" (*va8_alpha_mask)
 
1496
                  : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
 
1497
  }
 
1498
 
 
1499
  asm("emms");
 
1500
}
 
1501
 
 
1502
void
 
1503
xxxgimp_composite_coloronly_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1504
{
 
1505
  GimpCompositeContext op = *_op;
 
1506
 
 
1507
}
 
1508
 
 
1509
void
 
1510
xxxgimp_composite_darken_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1511
{
 
1512
  GimpCompositeContext op = *_op;
 
1513
 
 
1514
  asm("pushl %edi");
 
1515
  asm("pushl %ebx");
 
1516
  asm("movl 12(%esp), %edi");
 
1517
  asm("movq v8_alpha_mask, %mm0");
 
1518
  asm("subl $ 4, %ecx");
 
1519
  asm("jl .darken_pixels_1a_1a_last3");
 
1520
  asm("movl $ 8, %ebx");
 
1521
  asm(".darken_pixels_1a_1a_loop:");
 
1522
  asm("movq (%eax), %mm2");
 
1523
  asm("movq (%edx), %mm3");
 
1524
 
 
1525
  asm("movq %mm2, %mm4");
 
1526
  asm("psubusb %mm3, %mm4");
 
1527
  asm("psubb %mm4, %mm2");
 
1528
  asm("movq %mm2, %mm1");
 
1529
  asm("movq %mm1, (%edi)");
 
1530
  asm("addl %ebx, %eax");
 
1531
  asm("addl %ebx, %edx");
 
1532
  asm("addl %ebx, %edi");
 
1533
  asm("subl $ 4, %ecx");
 
1534
  asm("jge .darken_pixels_1a_1a_loop");
 
1535
 
 
1536
  asm(".darken_pixels_1a_1a_last3:");
 
1537
  asm("test $ 2, %ecx");
 
1538
  asm("jz .darken_pixels_1a_1a_last1");
 
1539
  asm("movd (%eax), %mm2");
 
1540
  asm("movd (%edx), %mm3");
 
1541
 
 
1542
  asm("movq %mm2, %mm4");
 
1543
  asm("psubusb %mm3, %mm4");
 
1544
  asm("psubb %mm4, %mm2");
 
1545
  asm("movq %mm2, %mm1");
 
1546
  asm("addl $ 4, %eax");
 
1547
  asm("addl $ 4, %edx");
 
1548
  asm("addl $ 4, %edi");
 
1549
 
 
1550
  asm(".darken_pixels_1a_1a_last1:");
 
1551
  asm("test $ 1, %ecx");
 
1552
  asm("jz .darken_pixels_1a_1a_end");
 
1553
 
 
1554
  asm("movw (%eax), %bx");
 
1555
  asm("movd %ebx, %mm2");
 
1556
  asm("movw (%edx), %bx");
 
1557
  asm("movd %ebx, %mm3");
 
1558
 
 
1559
  asm("movq %mm2, %mm4");
 
1560
  asm("psubusb %mm3, %mm4");
 
1561
  asm("psubb %mm4, %mm2");
 
1562
  asm("movq %mm2, %mm1");
 
1563
  asm("movd %mm1, %ebx");
 
1564
  asm("movw %bx, (%edi)");
 
1565
 
 
1566
  asm(".darken_pixels_1a_1a_end:");
 
1567
 
 
1568
  asm("emms");
 
1569
  asm("popl %ebx");
 
1570
  asm("popl %edi");
 
1571
}
 
1572
 
 
1573
void
 
1574
xxxgimp_composite_difference_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1575
{
 
1576
  GimpCompositeContext op = *_op;
 
1577
 
 
1578
  asm("pushl %edi");
 
1579
  asm("pushl %ebx");
 
1580
  asm("movl 12(%esp), %edi");
 
1581
  asm("movq v8_alpha_mask, %mm0");
 
1582
  asm("subl $ 4, %ecx");
 
1583
  asm("jl .difference_pixels_1a_1a_last3");
 
1584
  asm("movl $ 8, %ebx");
 
1585
  asm(".difference_pixels_1a_1a_loop:");
 
1586
  asm("movq (%eax), %mm2");
 
1587
  asm("movq (%edx), %mm3");
 
1588
 
 
1589
  asm("movq %mm2, %mm4");
 
1590
  asm("movq %mm3, %mm5");
 
1591
  asm("psubusb %mm3, %mm4");
 
1592
  asm("psubusb %mm2, %mm5");
 
1593
  asm("movq %mm0, %mm1");
 
1594
  asm("paddb %mm5, %mm4");
 
1595
  asm("pandn %mm4, %mm1");
 
1596
  asm("psubb %mm4, %mm2");
 
1597
  asm("pand %mm0, %mm2");
 
1598
  asm("por %mm2, %mm1");
 
1599
  asm("movq %mm1, (%edi)");
 
1600
  asm("addl %ebx, %eax");
 
1601
  asm("addl %ebx, %edx");
 
1602
  asm("addl %ebx, %edi");
 
1603
  asm("subl $ 4, %ecx");
 
1604
  asm("jge .difference_pixels_1a_1a_loop");
 
1605
 
 
1606
  asm(".difference_pixels_1a_1a_last3:");
 
1607
  asm("test $ 2, %ecx");
 
1608
  asm("jz .difference_pixels_1a_1a_last1");
 
1609
  asm("movd (%eax), %mm2");
 
1610
  asm("movd (%edx), %mm3");
 
1611
 
 
1612
  asm("movq %mm2, %mm4");
 
1613
  asm("movq %mm3, %mm5");
 
1614
  asm("psubusb %mm3, %mm4");
 
1615
  asm("psubusb %mm2, %mm5");
 
1616
  asm("movq %mm0, %mm1");
 
1617
  asm("paddb %mm5, %mm4");
 
1618
  asm("pandn %mm4, %mm1");
 
1619
  asm("psubb %mm4, %mm2");
 
1620
  asm("pand %mm0, %mm2");
 
1621
  asm("por %mm2, %mm1");
 
1622
  asm("addl $ 4, %eax");
 
1623
  asm("addl $ 4, %edx");
 
1624
  asm("addl $ 4, %edi");
 
1625
 
 
1626
  asm(".difference_pixels_1a_1a_last1:");
 
1627
  asm("test $ 1, %ecx");
 
1628
  asm("jz .difference_pixels_1a_1a_end");
 
1629
 
 
1630
  asm("movw (%eax), %bx");
 
1631
  asm("movd %ebx, %mm2");
 
1632
  asm("movw (%edx), %bx");
 
1633
  asm("movd %ebx, %mm3");
 
1634
 
 
1635
  asm("movq %mm2, %mm4");
 
1636
  asm("movq %mm3, %mm5");
 
1637
  asm("psubusb %mm3, %mm4");
 
1638
  asm("psubusb %mm2, %mm5");
 
1639
  asm("movq %mm0, %mm1");
 
1640
  asm("paddb %mm5, %mm4");
 
1641
  asm("pandn %mm4, %mm1");
 
1642
  asm("psubb %mm4, %mm2");
 
1643
  asm("pand %mm0, %mm2");
 
1644
  asm("por %mm2, %mm1");
 
1645
  asm("movd %mm1, %ebx");
 
1646
  asm("movw %bx, (%edi)");
 
1647
 
 
1648
  asm(".difference_pixels_1a_1a_end:");
 
1649
 
 
1650
  asm("emms");
 
1651
  asm("popl %ebx");
 
1652
  asm("popl %edi");
 
1653
}
 
1654
 
 
1655
void
 
1656
xxxgimp_composite_dissolve_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1657
{
 
1658
  GimpCompositeContext op = *_op;
 
1659
 
 
1660
}
 
1661
 
 
1662
void
 
1663
xxxgimp_composite_divide_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1664
{
 
1665
  GimpCompositeContext op = *_op;
 
1666
 
 
1667
}
 
1668
 
 
1669
void
 
1670
xxxgimp_composite_dodge_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1671
{
 
1672
  GimpCompositeContext op = *_op;
 
1673
 
 
1674
}
 
1675
 
 
1676
void
 
1677
xxxgimp_composite_grain_extract_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1678
{
 
1679
  GimpCompositeContext op = *_op;
 
1680
 
 
1681
}
 
1682
 
 
1683
void
 
1684
xxxgimp_composite_grain_merge_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1685
{
 
1686
  GimpCompositeContext op = *_op;
 
1687
 
 
1688
}
 
1689
 
 
1690
void
 
1691
xxxgimp_composite_hardlight_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1692
{
 
1693
  GimpCompositeContext op = *_op;
 
1694
 
 
1695
}
 
1696
 
 
1697
void
 
1698
xxxgimp_composite_hueonly_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1699
{
 
1700
  GimpCompositeContext op = *_op;
 
1701
 
 
1702
}
 
1703
 
 
1704
void
 
1705
xxxgimp_composite_lighten_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1706
{
 
1707
  GimpCompositeContext op = *_op;
 
1708
 
 
1709
  asm("pushl %edi");
 
1710
  asm("pushl %ebx");
 
1711
  asm("movl 12(%esp), %edi");
 
1712
  asm("movq v8_alpha_mask, %mm0");
 
1713
  asm("subl $ 4, %ecx");
 
1714
  asm("jl .lighten_pixels_1a_1a_last3");
 
1715
  asm("movl $ 8, %ebx");
 
1716
  asm(".lighten_pixels_1a_1a_loop:");
 
1717
  asm("movq (%eax), %mm2");
 
1718
  asm("movq (%edx), %mm3");
 
1719
 
 
1720
  asm("movq %mm2, %mm4");
 
1721
  asm("psubusb %mm3, %mm4");
 
1722
  asm("paddb %mm4, %mm3");
 
1723
  asm("movq %mm0, %mm1");
 
1724
  asm("pandn %mm3, %mm1");
 
1725
 
 
1726
  asm("psubb %mm4, %mm2");
 
1727
  asm("pand %mm0, %mm2");
 
1728
  asm("por %mm2, %mm1");
 
1729
  asm("movq %mm1, (%edi)");
 
1730
  asm("addl %ebx, %eax");
 
1731
  asm("addl %ebx, %edx");
 
1732
  asm("addl %ebx, %edi");
 
1733
  asm("subl $ 4, %ecx");
 
1734
  asm("jge .lighten_pixels_1a_1a_loop");
 
1735
 
 
1736
  asm(".lighten_pixels_1a_1a_last3:");
 
1737
  asm("test $ 2, %ecx");
 
1738
  asm("jz .lighten_pixels_1a_1a_last1");
 
1739
  asm("movd (%eax), %mm2");
 
1740
  asm("movd (%edx), %mm3");
 
1741
 
 
1742
  asm("movq %mm2, %mm4");
 
1743
  asm("psubusb %mm3, %mm4");
 
1744
  asm("paddb %mm4, %mm3");
 
1745
  asm("movq %mm0, %mm1");
 
1746
  asm("pandn %mm3, %mm1");
 
1747
 
 
1748
  asm("psubb %mm4, %mm2");
 
1749
  asm("pand %mm0, %mm2");
 
1750
  asm("por %mm2, %mm1");
 
1751
  asm("addl $ 4, %eax");
 
1752
  asm("addl $ 4, %edx");
 
1753
  asm("addl $ 4, %edi");
 
1754
 
 
1755
  asm(".lighten_pixels_1a_1a_last1:");
 
1756
  asm("test $ 1, %ecx");
 
1757
  asm("jz .lighten_pixels_1a_1a_end");
 
1758
 
 
1759
  asm("movw (%eax), %bx");
 
1760
  asm("movd %ebx, %mm2");
 
1761
  asm("movw (%edx), %bx");
 
1762
  asm("movd %ebx, %mm3");
 
1763
 
 
1764
  asm("movq %mm2, %mm4");
 
1765
  asm("psubusb %mm3, %mm4");
 
1766
  asm("paddb %mm4, %mm3");
 
1767
  asm("movq %mm0, %mm1");
 
1768
  asm("pandn %mm3, %mm1");
 
1769
 
 
1770
  asm("psubb %mm4, %mm2");
 
1771
  asm("pand %mm0, %mm2");
 
1772
  asm("por %mm2, %mm1");
 
1773
  asm("movd %mm1, %ebx");
 
1774
  asm("movw %bx, (%edi)");
 
1775
 
 
1776
  asm(".lighten_pixels_1a_1a_end:");
 
1777
 
 
1778
  asm("emms");
 
1779
  asm("popl %ebx");
 
1780
  asm("popl %edi");
 
1781
}
 
1782
 
 
1783
void
 
1784
xxxgimp_composite_multiply_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1785
{
 
1786
  GimpCompositeContext op = *_op;
 
1787
 
 
1788
  asm("pushl %edi");
 
1789
  asm("pushl %ebx");
 
1790
  asm("movl 12(%esp), %edi");
 
1791
  asm("movq v8_alpha_mask, %mm0");
 
1792
  asm("subl $ 4, %ecx");
 
1793
  asm("jl .multiply_pixels_1a_1a_last3");
 
1794
  asm("movl $ 8, %ebx");
 
1795
  asm(".multiply_pixels_1a_1a_loop:");
 
1796
  asm("movq (%eax), %mm2");
 
1797
  asm("movq (%edx), %mm3");
 
1798
 
 
1799
 
 
1800
  asm("movq %mm2, %mm1");
 
1801
  asm("punpcklbw %mm6, %mm1");
 
1802
  asm("movq %mm3, %mm5");
 
1803
  asm("punpcklbw %mm6, %mm5");
 
1804
  asm("pmullw %mm5, %mm1");
 
1805
  asm("paddw %mm7, %mm1");
 
1806
  asm("movq %mm1, %mm5");
 
1807
  asm("psrlw $ 8, %mm5");
 
1808
  asm("paddw %mm5, %mm1");
 
1809
  asm("psrlw $ 8, %mm1");
 
1810
 
 
1811
  asm("movq %mm2, %mm4");
 
1812
  asm("punpckhbw %mm6, %mm4");
 
1813
  asm("movq %mm3, %mm5");
 
1814
  asm("punpckhbw %mm6, %mm5");
 
1815
  asm("pmullw %mm5, %mm4");
 
1816
  asm("paddw %mm7, %mm4");
 
1817
  asm("movq %mm4, %mm5");
 
1818
  asm("psrlw $ 8, %mm5");
 
1819
  asm("paddw %mm5, %mm4");
 
1820
  asm("psrlw $ 8, %mm4");
 
1821
 
 
1822
  asm("packuswb %mm4, %mm1");
 
1823
 
 
1824
  asm("movq %mm0, %mm4");
 
1825
  asm("pandn %mm1, %mm4");
 
1826
  asm("movq %mm4, %mm1");
 
1827
 
 
1828
  asm("movq %mm2, %mm4");
 
1829
  asm("psubusb %mm3, %mm4");
 
1830
  asm("psubb %mm4, %mm2");
 
1831
  asm("pand %mm0, %mm2");
 
1832
  asm("por %mm2, %mm1");
 
1833
  asm("movq %mm1, (%edi)");
 
1834
  asm("addl %ebx, %eax");
 
1835
  asm("addl %ebx, %edx");
 
1836
  asm("addl %ebx, %edi");
 
1837
  asm("subl $ 4, %ecx");
 
1838
  asm("jge .multiply_pixels_1a_1a_loop");
 
1839
 
 
1840
  asm(".multiply_pixels_1a_1a_last3:");
 
1841
  asm("test $ 2, %ecx");
 
1842
  asm("jz .multiply_pixels_1a_1a_last1");
 
1843
  asm("movd (%eax), %mm2");
 
1844
  asm("movd (%edx), %mm3");
 
1845
 
 
1846
 
 
1847
  asm("movq %mm2, %mm1");
 
1848
  asm("punpcklbw %mm6, %mm1");
 
1849
  asm("movq %mm3, %mm5");
 
1850
  asm("punpcklbw %mm6, %mm5");
 
1851
  asm("pmullw %mm5, %mm1");
 
1852
  asm("paddw %mm7, %mm1");
 
1853
  asm("movq %mm1, %mm5");
 
1854
  asm("psrlw $ 8, %mm5");
 
1855
  asm("paddw %mm5, %mm1");
 
1856
  asm("psrlw $ 8, %mm1");
 
1857
 
 
1858
  asm("movq %mm2, %mm4");
 
1859
  asm("punpckhbw %mm6, %mm4");
 
1860
  asm("movq %mm3, %mm5");
 
1861
  asm("punpckhbw %mm6, %mm5");
 
1862
  asm("pmullw %mm5, %mm4");
 
1863
  asm("paddw %mm7, %mm4");
 
1864
  asm("movq %mm4, %mm5");
 
1865
  asm("psrlw $ 8, %mm5");
 
1866
  asm("paddw %mm5, %mm4");
 
1867
  asm("psrlw $ 8, %mm4");
 
1868
 
 
1869
  asm("packuswb %mm4, %mm1");
 
1870
 
 
1871
  asm("movq %mm0, %mm4");
 
1872
  asm("pandn %mm1, %mm4");
 
1873
  asm("movq %mm4, %mm1");
 
1874
 
 
1875
  asm("movq %mm2, %mm4");
 
1876
  asm("psubusb %mm3, %mm4");
 
1877
  asm("psubb %mm4, %mm2");
 
1878
  asm("pand %mm0, %mm2");
 
1879
  asm("por %mm2, %mm1");
 
1880
  asm("addl $ 4, %eax");
 
1881
  asm("addl $ 4, %edx");
 
1882
  asm("addl $ 4, %edi");
 
1883
 
 
1884
  asm(".multiply_pixels_1a_1a_last1:");
 
1885
  asm("test $ 1, %ecx");
 
1886
  asm("jz .multiply_pixels_1a_1a_end");
 
1887
 
 
1888
  asm("movw (%eax), %bx");
 
1889
  asm("movd %ebx, %mm2");
 
1890
  asm("movw (%edx), %bx");
 
1891
  asm("movd %ebx, %mm3");
 
1892
 
 
1893
 
 
1894
  asm("movq %mm2, %mm1");
 
1895
  asm("punpcklbw %mm6, %mm1");
 
1896
  asm("movq %mm3, %mm5");
 
1897
  asm("punpcklbw %mm6, %mm5");
 
1898
  asm("pmullw %mm5, %mm1");
 
1899
  asm("paddw %mm7, %mm1");
 
1900
  asm("movq %mm1, %mm5");
 
1901
  asm("psrlw $ 8, %mm5");
 
1902
  asm("paddw %mm5, %mm1");
 
1903
  asm("psrlw $ 8, %mm1");
 
1904
 
 
1905
  asm("movq %mm2, %mm4");
 
1906
  asm("punpckhbw %mm6, %mm4");
 
1907
  asm("movq %mm3, %mm5");
 
1908
  asm("punpckhbw %mm6, %mm5");
 
1909
  asm("pmullw %mm5, %mm4");
 
1910
  asm("paddw %mm7, %mm4");
 
1911
  asm("movq %mm4, %mm5");
 
1912
  asm("psrlw $ 8, %mm5");
 
1913
  asm("paddw %mm5, %mm4");
 
1914
  asm("psrlw $ 8, %mm4");
 
1915
 
 
1916
  asm("packuswb %mm4, %mm1");
 
1917
 
 
1918
  asm("movq %mm0, %mm4");
 
1919
  asm("pandn %mm1, %mm4");
 
1920
  asm("movq %mm4, %mm1");
 
1921
 
 
1922
  asm("movq %mm2, %mm4");
 
1923
  asm("psubusb %mm3, %mm4");
 
1924
  asm("psubb %mm4, %mm2");
 
1925
  asm("pand %mm0, %mm2");
 
1926
  asm("por %mm2, %mm1");
 
1927
  asm("movd %mm1, %ebx");
 
1928
  asm("movw %bx, (%edi)");
 
1929
 
 
1930
  asm(".multiply_pixels_1a_1a_end:");
 
1931
 
 
1932
  asm("emms");
 
1933
  asm("popl %ebx");
 
1934
  asm("popl %edi");
 
1935
}
 
1936
 
 
1937
void
 
1938
xxxgimp_composite_overlay_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1939
{
 
1940
  GimpCompositeContext op = *_op;
 
1941
 
 
1942
  asm("pushl %edi");
 
1943
  asm("pushl %ebx");
 
1944
  asm("movl 12(%esp), %edi");
 
1945
  asm("movq v8_alpha_mask, %mm0");
 
1946
  asm("subl $ 4, %ecx");
 
1947
  asm("jl .overlay_pixels_1a_1a_last3");
 
1948
  asm("movl $ 8, %ebx");
 
1949
  asm(".overlay_pixels_1a_1a_loop:");
 
1950
  asm("movq (%eax), %mm2");
 
1951
  asm("movq (%edx), %mm3");
 
1952
  asm("call op_overlay");
 
1953
  asm("movq %mm1, (%edi)");
 
1954
  asm("addl %ebx, %eax");
 
1955
  asm("addl %ebx, %edx");
 
1956
  asm("addl %ebx, %edi");
 
1957
  asm("subl $ 4, %ecx");
 
1958
  asm("jge .overlay_pixels_1a_1a_loop");
 
1959
 
 
1960
  asm(".overlay_pixels_1a_1a_last3:");
 
1961
  asm("test $ 2, %ecx");
 
1962
  asm("jz .overlay_pixels_1a_1a_last1");
 
1963
  asm("movd (%eax), %mm2");
 
1964
  asm("movd (%edx), %mm3");
 
1965
  asm("call op_overlay");
 
1966
  asm("addl $ 4, %eax");
 
1967
  asm("addl $ 4, %edx");
 
1968
  asm("addl $ 4, %edi");
 
1969
 
 
1970
  asm(".overlay_pixels_1a_1a_last1:");
 
1971
  asm("test $ 1, %ecx");
 
1972
  asm("jz .overlay_pixels_1a_1a_end");
 
1973
 
 
1974
  asm("movw (%eax), %bx");
 
1975
  asm("movd %ebx, %mm2");
 
1976
  asm("movw (%edx), %bx");
 
1977
  asm("movd %ebx, %mm3");
 
1978
  asm("call op_overlay");
 
1979
  asm("movd %mm1, %ebx");
 
1980
  asm("movw %bx, (%edi)");
 
1981
 
 
1982
  asm(".overlay_pixels_1a_1a_end:");
 
1983
 
 
1984
  asm("emms");
 
1985
  asm("popl %ebx");
 
1986
  asm("popl %edi");
 
1987
}
 
1988
 
 
1989
void
 
1990
xxxgimp_composite_replace_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1991
{
 
1992
  GimpCompositeContext op = *_op;
 
1993
 
 
1994
}
 
1995
 
 
1996
void
 
1997
xxxgimp_composite_saturationonly_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
1998
{
 
1999
  GimpCompositeContext op = *_op;
 
2000
 
 
2001
}
 
2002
 
 
2003
void
 
2004
xxxgimp_composite_screen_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
2005
{
 
2006
  GimpCompositeContext op = *_op;
 
2007
 
 
2008
  asm("pushl %edi");
 
2009
  asm("pushl %ebx");
 
2010
  asm("movl 12(%esp), %edi");
 
2011
  asm("movq v8_alpha_mask, %mm0");
 
2012
  asm("subl $ 4, %ecx");
 
2013
  asm("jl .screen_pixels_1a_1a_last3");
 
2014
  asm("movl $ 8, %ebx");
 
2015
  asm(".screen_pixels_1a_1a_loop:");
 
2016
  asm("movq (%eax), %mm2");
 
2017
  asm("movq (%edx), %mm3");
 
2018
 
 
2019
 
 
2020
  asm("pcmpeqb %mm4, %mm4");
 
2021
  asm("psubb %mm2, %mm4");
 
2022
  asm("pcmpeqb %mm5, %mm5");
 
2023
  asm("psubb %mm3, %mm5");
 
2024
 
 
2025
  asm("movq %mm4, %mm1");
 
2026
  asm("punpcklbw %mm6, %mm1");
 
2027
  asm("movq %mm5, %mm3");
 
2028
  asm("punpcklbw %mm6, %mm3");
 
2029
  asm("pmullw %mm3, %mm1");
 
2030
  asm("paddw %mm7, %mm1");
 
2031
  asm("movq %mm1, %mm3");
 
2032
  asm("psrlw $ 8, %mm3");
 
2033
  asm("paddw %mm3, %mm1");
 
2034
  asm("psrlw $ 8, %mm1");
 
2035
 
 
2036
  asm("movq %mm4, %mm2");
 
2037
  asm("punpckhbw %mm6, %mm2");
 
2038
  asm("movq %mm5, %mm3");
 
2039
  asm("punpckhbw %mm6, %mm3");
 
2040
  asm("pmullw %mm3, %mm2");
 
2041
  asm("paddw %mm7, %mm2");
 
2042
  asm("movq %mm2, %mm3");
 
2043
  asm("psrlw $ 8, %mm3");
 
2044
  asm("paddw %mm3, %mm2");
 
2045
  asm("psrlw $ 8, %mm2");
 
2046
 
 
2047
  asm("packuswb %mm2, %mm1");
 
2048
 
 
2049
  asm("pcmpeqb %mm3, %mm3");
 
2050
  asm("psubb %mm1, %mm3");
 
2051
 
 
2052
  asm("movq %mm0, %mm1");
 
2053
  asm("pandn %mm3, %mm1");
 
2054
 
 
2055
  asm("movq %mm2, %mm4");
 
2056
  asm("psubusb %mm5, %mm2");
 
2057
  asm("paddb %mm2, %mm5");
 
2058
  asm("pcmpeqb %mm3, %mm3");
 
2059
  asm("psubb %mm5, %mm3");
 
2060
 
 
2061
  asm("pand %mm0, %mm3");
 
2062
  asm("por %mm3, %mm1");
 
2063
  asm("movq %mm1, (%edi)");
 
2064
  asm("addl %ebx, %eax");
 
2065
  asm("addl %ebx, %edx");
 
2066
  asm("addl %ebx, %edi");
 
2067
  asm("subl $ 4, %ecx");
 
2068
  asm("jge .screen_pixels_1a_1a_loop");
 
2069
 
 
2070
  asm(".screen_pixels_1a_1a_last3:");
 
2071
  asm("test $ 2, %ecx");
 
2072
  asm("jz .screen_pixels_1a_1a_last1");
 
2073
  asm("movd (%eax), %mm2");
 
2074
  asm("movd (%edx), %mm3");
 
2075
 
 
2076
 
 
2077
  asm("pcmpeqb %mm4, %mm4");
 
2078
  asm("psubb %mm2, %mm4");
 
2079
  asm("pcmpeqb %mm5, %mm5");
 
2080
  asm("psubb %mm3, %mm5");
 
2081
 
 
2082
  asm("movq %mm4, %mm1");
 
2083
  asm("punpcklbw %mm6, %mm1");
 
2084
  asm("movq %mm5, %mm3");
 
2085
  asm("punpcklbw %mm6, %mm3");
 
2086
  asm("pmullw %mm3, %mm1");
 
2087
  asm("paddw %mm7, %mm1");
 
2088
  asm("movq %mm1, %mm3");
 
2089
  asm("psrlw $ 8, %mm3");
 
2090
  asm("paddw %mm3, %mm1");
 
2091
  asm("psrlw $ 8, %mm1");
 
2092
 
 
2093
  asm("movq %mm4, %mm2");
 
2094
  asm("punpckhbw %mm6, %mm2");
 
2095
  asm("movq %mm5, %mm3");
 
2096
  asm("punpckhbw %mm6, %mm3");
 
2097
  asm("pmullw %mm3, %mm2");
 
2098
  asm("paddw %mm7, %mm2");
 
2099
  asm("movq %mm2, %mm3");
 
2100
  asm("psrlw $ 8, %mm3");
 
2101
  asm("paddw %mm3, %mm2");
 
2102
  asm("psrlw $ 8, %mm2");
 
2103
 
 
2104
  asm("packuswb %mm2, %mm1");
 
2105
 
 
2106
  asm("pcmpeqb %mm3, %mm3");
 
2107
  asm("psubb %mm1, %mm3");
 
2108
 
 
2109
  asm("movq %mm0, %mm1");
 
2110
  asm("pandn %mm3, %mm1");
 
2111
 
 
2112
  asm("movq %mm2, %mm4");
 
2113
  asm("psubusb %mm5, %mm2");
 
2114
  asm("paddb %mm2, %mm5");
 
2115
  asm("pcmpeqb %mm3, %mm3");
 
2116
  asm("psubb %mm5, %mm3");
 
2117
 
 
2118
  asm("pand %mm0, %mm3");
 
2119
  asm("por %mm3, %mm1");
 
2120
  asm("addl $ 4, %eax");
 
2121
  asm("addl $ 4, %edx");
 
2122
  asm("addl $ 4, %edi");
 
2123
 
 
2124
  asm(".screen_pixels_1a_1a_last1:");
 
2125
  asm("test $ 1, %ecx");
 
2126
  asm("jz .screen_pixels_1a_1a_end");
 
2127
 
 
2128
  asm("movw (%eax), %bx");
 
2129
  asm("movd %ebx, %mm2");
 
2130
  asm("movw (%edx), %bx");
 
2131
  asm("movd %ebx, %mm3");
 
2132
 
 
2133
 
 
2134
  asm("pcmpeqb %mm4, %mm4");
 
2135
  asm("psubb %mm2, %mm4");
 
2136
  asm("pcmpeqb %mm5, %mm5");
 
2137
  asm("psubb %mm3, %mm5");
 
2138
 
 
2139
  asm("movq %mm4, %mm1");
 
2140
  asm("punpcklbw %mm6, %mm1");
 
2141
  asm("movq %mm5, %mm3");
 
2142
  asm("punpcklbw %mm6, %mm3");
 
2143
  asm("pmullw %mm3, %mm1");
 
2144
  asm("paddw %mm7, %mm1");
 
2145
  asm("movq %mm1, %mm3");
 
2146
  asm("psrlw $ 8, %mm3");
 
2147
  asm("paddw %mm3, %mm1");
 
2148
  asm("psrlw $ 8, %mm1");
 
2149
 
 
2150
  asm("movq %mm4, %mm2");
 
2151
  asm("punpckhbw %mm6, %mm2");
 
2152
  asm("movq %mm5, %mm3");
 
2153
  asm("punpckhbw %mm6, %mm3");
 
2154
  asm("pmullw %mm3, %mm2");
 
2155
  asm("paddw %mm7, %mm2");
 
2156
  asm("movq %mm2, %mm3");
 
2157
  asm("psrlw $ 8, %mm3");
 
2158
  asm("paddw %mm3, %mm2");
 
2159
  asm("psrlw $ 8, %mm2");
 
2160
 
 
2161
  asm("packuswb %mm2, %mm1");
 
2162
 
 
2163
  asm("pcmpeqb %mm3, %mm3");
 
2164
  asm("psubb %mm1, %mm3");
 
2165
 
 
2166
  asm("movq %mm0, %mm1");
 
2167
  asm("pandn %mm3, %mm1");
 
2168
 
 
2169
  asm("movq %mm2, %mm4");
 
2170
  asm("psubusb %mm5, %mm2");
 
2171
  asm("paddb %mm2, %mm5");
 
2172
  asm("pcmpeqb %mm3, %mm3");
 
2173
  asm("psubb %mm5, %mm3");
 
2174
 
 
2175
  asm("pand %mm0, %mm3");
 
2176
  asm("por %mm3, %mm1");
 
2177
  asm("movd %mm1, %ebx");
 
2178
  asm("movw %bx, (%edi)");
 
2179
 
 
2180
  asm(".screen_pixels_1a_1a_end:");
 
2181
 
 
2182
  asm("emms");
 
2183
  asm("popl %ebx");
 
2184
  asm("popl %edi");
 
2185
}
 
2186
 
 
2187
void
 
2188
xxxgimp_composite_softlight_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
2189
{
 
2190
  GimpCompositeContext op = *_op;
 
2191
 
 
2192
}
 
2193
 
 
2194
void
 
2195
xxxgimp_composite_subtract_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
2196
{
 
2197
  GimpCompositeContext op = *_op;
 
2198
 
 
2199
  asm("pushl %edi");
 
2200
  asm("pushl %ebx");
 
2201
  asm("movl 12(%esp), %edi");
 
2202
  asm("movq v8_alpha_mask, %mm0");
 
2203
  asm("subl $ 4, %ecx");
 
2204
  asm("jl .substract_pixels_1a_1a_last3");
 
2205
  asm("movl $ 8, %ebx");
 
2206
  asm(".substract_pixels_1a_1a_loop:");
 
2207
  asm("movq (%eax), %mm2");
 
2208
  asm("movq (%edx), %mm3");
 
2209
 
 
2210
  asm("movq %mm2, %mm4");
 
2211
  asm("psubusb %mm3, %mm4");
 
2212
  asm("movq %mm0, %mm1");
 
2213
  asm("pandn %mm4, %mm1");
 
2214
  asm("psubb %mm4, %mm2");
 
2215
  asm("pand %mm0, %mm2");
 
2216
  asm("por %mm2, %mm1");
 
2217
  asm("movq %mm1, (%edi)");
 
2218
  asm("addl %ebx, %eax");
 
2219
  asm("addl %ebx, %edx");
 
2220
  asm("addl %ebx, %edi");
 
2221
  asm("subl $ 4, %ecx");
 
2222
  asm("jge .substract_pixels_1a_1a_loop");
 
2223
 
 
2224
  asm(".substract_pixels_1a_1a_last3:");
 
2225
  asm("test $ 2, %ecx");
 
2226
  asm("jz .substract_pixels_1a_1a_last1");
 
2227
  asm("movd (%eax), %mm2");
 
2228
  asm("movd (%edx), %mm3");
 
2229
 
 
2230
  asm("movq %mm2, %mm4");
 
2231
  asm("psubusb %mm3, %mm4");
 
2232
  asm("movq %mm0, %mm1");
 
2233
  asm("pandn %mm4, %mm1");
 
2234
  asm("psubb %mm4, %mm2");
 
2235
  asm("pand %mm0, %mm2");
 
2236
  asm("por %mm2, %mm1");
 
2237
  asm("addl $ 4, %eax");
 
2238
  asm("addl $ 4, %edx");
 
2239
  asm("addl $ 4, %edi");
 
2240
 
 
2241
  asm(".substract_pixels_1a_1a_last1:");
 
2242
  asm("test $ 1, %ecx");
 
2243
  asm("jz .substract_pixels_1a_1a_end");
 
2244
 
 
2245
  asm("movw (%eax), %bx");
 
2246
  asm("movd %ebx, %mm2");
 
2247
  asm("movw (%edx), %bx");
 
2248
  asm("movd %ebx, %mm3");
 
2249
 
 
2250
  asm("movq %mm2, %mm4");
 
2251
  asm("psubusb %mm3, %mm4");
 
2252
  asm("movq %mm0, %mm1");
 
2253
  asm("pandn %mm4, %mm1");
 
2254
  asm("psubb %mm4, %mm2");
 
2255
  asm("pand %mm0, %mm2");
 
2256
  asm("por %mm2, %mm1");
 
2257
  asm("movd %mm1, %ebx");
 
2258
  asm("movw %bx, (%edi)");
 
2259
 
 
2260
  asm(".substract_pixels_1a_1a_end:");
 
2261
  asm("emms");
 
2262
  asm("popl %ebx");
 
2263
  asm("popl %edi");
 
2264
}
 
2265
 
 
2266
void
 
2267
xxxgimp_composite_swap_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
2268
{
 
2269
  GimpCompositeContext op = *_op;
 
2270
 
 
2271
}
 
2272
 
 
2273
void
 
2274
xxxgimp_composite_valueonly_va8_va8_va8_mmx (GimpCompositeContext *_op)
 
2275
{
 
2276
  GimpCompositeContext op = *_op;
 
2277
 
 
2278
}
 
2279
#endif
 
2280
 
 
2281
#endif /* COMPILE_IS_OKAY */
 
2282
 
 
2283
gboolean
 
2284
gimp_composite_mmx_init (void)
 
2285
{
 
2286
#ifdef COMPILE_MMX_IS_OKAY
 
2287
  if (cpu_accel () & CPU_ACCEL_X86_MMX)
 
2288
    {
 
2289
      return (TRUE);
 
2290
    }
 
2291
#endif
 
2292
  return (FALSE);
 
2293
}