~ubuntu-branches/debian/lenny/fpc/lenny

« back to all changes in this revision

Viewing changes to fpcsrc/rtl/i386/fastmove.inc

  • Committer: Bazaar Package Importer
  • Author(s): Mazen Neifer, Torsten Werner, Mazen Neifer
  • Date: 2008-05-17 17:12:11 UTC
  • mfrom: (3.1.9 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080517171211-9qi33xhd9evfa0kg
Tags: 2.2.0-dfsg1-9
[ Torsten Werner ]
* Add Mazen Neifer to Uploaders field.

[ Mazen Neifer ]
* Moved FPC sources into a version dependent directory from /usr/share/fpcsrc
  to /usr/share/fpcsrc/${FPCVERSION}. This allow installing more than on FPC
  release.
* Fixed far call issue in compiler preventing building huge binearies.
  (closes: #477743)
* Updated building dependencies, recomennded and suggested packages.
* Moved fppkg to fp-utils as it is just a helper tool and is not required by
  compiler.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
{
 
2
  Copyright (c) 2004, John O'Harrow (john@almcrest.demon.co.uk)
 
3
 
 
4
This software is provided 'as-is', without any express or implied warranty.
 
5
In no event will the authors be held liable for any damages arising from the
 
6
use of this software.
 
7
 
 
8
Permission is granted to anyone to use this software for any purpose, including
 
9
commercial applications, and to alter it and redistribute it freely, subject to
 
10
the following restrictions:
 
11
 
 
12
1. The origin of this software must not be misrepresented; you must not claim
 
13
   that you wrote the original software. If you use this software in a product,
 
14
   an acknowledgment in the product documentation would be appreciated but is
 
15
   not required.
 
16
 
 
17
2. Altered source versions must be plainly marked as such, and must not be
 
18
   misrepresented as being the original software.
 
19
 
 
20
3. This notice may not be removed or altered from any source distribution.
 
21
 
 
22
-------------------------------------------------------------------------------
 
23
 
 
24
Version: 1.40 - 16-SEP-2004
 
25
}
 
26
 
 
27
{$ifdef USE_FASTMOVE}
 
28
 
 
29
{$ifndef FPC_SYSTEM_HAS_MOVE}
 
30
{$define FPC_SYSTEM_HAS_MOVE}
 
31
 
 
32
{$asmmode intel}
 
33
 
 
34
{-------------------------------------------------------------------------}
 
35
(*
 
36
{Just to show that a good Pascal algorithm can beat the default BASM}
 
37
procedure MoveJOH_PAS_3(const Source; var Dest; Count : Integer);
 
38
var
 
39
  S, D       : PtrUInt;
 
40
  Temp, C, I : PtrInt;
 
41
  L          : PPtrInt;
 
42
begin
 
43
  S := Cardinal(@Source);
 
44
  D := Cardinal(@Dest);
 
45
  if S = D then
 
46
    Exit;
 
47
  if Count <= 4 then
 
48
    case Count of
 
49
      1 : PByte(@Dest)^ := PByte(S)^;
 
50
      2 : PWord(@Dest)^ := PWord(S)^;
 
51
      3 : if D > S then
 
52
            begin
 
53
              PByte(Integer(@Dest)+2)^ := PByte(S+2)^;
 
54
              PWord(@Dest)^ := PWord(S)^;
 
55
            end
 
56
          else
 
57
            begin
 
58
              PWord(@Dest)^ := PWord(S)^;
 
59
              PByte(Integer(@Dest)+2)^ := PByte(S+2)^;
 
60
            end;
 
61
      4 : PInteger(@Dest)^ := PInteger(S)^
 
62
      else Exit; {Count <= 0}
 
63
    end
 
64
  else
 
65
    if D > S then
 
66
      begin
 
67
        Temp := PInteger(S)^;
 
68
        I := Integer(@Dest);
 
69
        C := Count - 4;
 
70
        L := PInteger(Integer(@Dest) + C);
 
71
        Inc(S, C);
 
72
        repeat
 
73
          L^ := PInteger(S)^;
 
74
          if Count <= 8 then
 
75
            Break;
 
76
          Dec(Count, 4);
 
77
          Dec(S, 4);
 
78
          Dec(L);
 
79
        until False;
 
80
        PInteger(I)^ := Temp;
 
81
      end
 
82
    else
 
83
      begin
 
84
        C := Count - 4;
 
85
        Temp := PInteger(S + Cardinal(C))^;
 
86
        I := Integer(@Dest) + C;
 
87
        L := @Dest;
 
88
        repeat
 
89
          L^ := PInteger(S)^;
 
90
          if Count <= 8 then
 
91
            Break;
 
92
          Dec(Count, 4);
 
93
          Inc(S, 4);
 
94
          Inc(L);
 
95
        until False;
 
96
        PInteger(I)^ := Temp;
 
97
      end;
 
98
end; {MoveJOH_PAS}
 
99
*)
 
100
 
 
101
const
 
102
  SMALLMOVESIZE = 36;
 
103
 
 
104
{-------------------------------------------------------------------------}
 
105
{Perform Forward Move of 0..36 Bytes}
 
106
{On Entry, ECX = Count, EAX = Source+Count, EDX = Dest+Count.  Destroys ECX}
 
107
procedure SmallForwardMove_3;assembler;nostackframe;
 
108
asm
 
109
  jmp     dword ptr @@FwdJumpTable[ecx*4]
 
110
  align   16
 
111
@@FwdJumpTable:
 
112
  dd      @@Done {Removes need to test for zero size move}
 
113
  dd      @@Fwd01,@@Fwd02,@@Fwd03,@@Fwd04,@@Fwd05,@@Fwd06,@@Fwd07,@@Fwd08
 
114
  dd      @@Fwd09,@@Fwd10,@@Fwd11,@@Fwd12,@@Fwd13,@@Fwd14,@@Fwd15,@@Fwd16
 
115
  dd      @@Fwd17,@@Fwd18,@@Fwd19,@@Fwd20,@@Fwd21,@@Fwd22,@@Fwd23,@@Fwd24
 
116
  dd      @@Fwd25,@@Fwd26,@@Fwd27,@@Fwd28,@@Fwd29,@@Fwd30,@@Fwd31,@@Fwd32
 
117
  dd      @@Fwd33,@@Fwd34,@@Fwd35,@@Fwd36
 
118
@@Fwd36:
 
119
  mov     ecx,[eax-36]
 
120
  mov     [edx-36],ecx
 
121
@@Fwd32:
 
122
  mov     ecx,[eax-32]
 
123
  mov     [edx-32],ecx
 
124
@@Fwd28:
 
125
  mov     ecx,[eax-28]
 
126
  mov     [edx-28],ecx
 
127
@@Fwd24:
 
128
  mov     ecx,[eax-24]
 
129
  mov     [edx-24],ecx
 
130
@@Fwd20:
 
131
  mov     ecx,[eax-20]
 
132
  mov     [edx-20],ecx
 
133
@@Fwd16:
 
134
  mov     ecx,[eax-16]
 
135
  mov     [edx-16],ecx
 
136
@@Fwd12:
 
137
  mov     ecx,[eax-12]
 
138
  mov     [edx-12],ecx
 
139
@@Fwd08:
 
140
  mov     ecx,[eax-8]
 
141
  mov     [edx-8],ecx
 
142
@@Fwd04:
 
143
  mov     ecx,[eax-4]
 
144
  mov     [edx-4],ecx
 
145
  ret
 
146
@@Fwd35:
 
147
  mov     ecx,[eax-35]
 
148
  mov     [edx-35],ecx
 
149
@@Fwd31:
 
150
  mov     ecx,[eax-31]
 
151
  mov     [edx-31],ecx
 
152
@@Fwd27:
 
153
  mov     ecx,[eax-27]
 
154
  mov     [edx-27],ecx
 
155
@@Fwd23:
 
156
  mov     ecx,[eax-23]
 
157
  mov     [edx-23],ecx
 
158
@@Fwd19:
 
159
  mov     ecx,[eax-19]
 
160
  mov     [edx-19],ecx
 
161
@@Fwd15:
 
162
  mov     ecx,[eax-15]
 
163
  mov     [edx-15],ecx
 
164
@@Fwd11:
 
165
  mov     ecx,[eax-11]
 
166
  mov     [edx-11],ecx
 
167
@@Fwd07:
 
168
  mov     ecx,[eax-7]
 
169
  mov     [edx-7],ecx
 
170
  mov     ecx,[eax-4]
 
171
  mov     [edx-4],ecx
 
172
  ret
 
173
@@Fwd03:
 
174
  movzx   ecx, word ptr [eax-3]
 
175
  mov     [edx-3],cx
 
176
  movzx   ecx, byte ptr [eax-1]
 
177
  mov     [edx-1],cl
 
178
  ret
 
179
@@Fwd34:
 
180
  mov     ecx,[eax-34]
 
181
  mov     [edx-34],ecx
 
182
@@Fwd30:
 
183
  mov     ecx,[eax-30]
 
184
  mov     [edx-30],ecx
 
185
@@Fwd26:
 
186
  mov     ecx,[eax-26]
 
187
  mov     [edx-26],ecx
 
188
@@Fwd22:
 
189
  mov     ecx,[eax-22]
 
190
  mov     [edx-22],ecx
 
191
@@Fwd18:
 
192
  mov     ecx,[eax-18]
 
193
  mov     [edx-18],ecx
 
194
@@Fwd14:
 
195
  mov     ecx,[eax-14]
 
196
  mov     [edx-14],ecx
 
197
@@Fwd10:
 
198
  mov     ecx,[eax-10]
 
199
  mov     [edx-10],ecx
 
200
@@Fwd06:
 
201
  mov     ecx,[eax-6]
 
202
  mov     [edx-6],ecx
 
203
@@Fwd02:
 
204
  movzx   ecx, word ptr [eax-2]
 
205
  mov     [edx-2],cx
 
206
  ret
 
207
@@Fwd33:
 
208
  mov     ecx,[eax-33]
 
209
  mov     [edx-33],ecx
 
210
@@Fwd29:
 
211
  mov     ecx,[eax-29]
 
212
  mov     [edx-29],ecx
 
213
@@Fwd25:
 
214
  mov     ecx,[eax-25]
 
215
  mov     [edx-25],ecx
 
216
@@Fwd21:
 
217
  mov     ecx,[eax-21]
 
218
  mov     [edx-21],ecx
 
219
@@Fwd17:
 
220
  mov     ecx,[eax-17]
 
221
  mov     [edx-17],ecx
 
222
@@Fwd13:
 
223
  mov     ecx,[eax-13]
 
224
  mov     [edx-13],ecx
 
225
@@Fwd09:
 
226
  mov     ecx,[eax-9]
 
227
  mov     [edx-9],ecx
 
228
@@Fwd05:
 
229
  mov     ecx,[eax-5]
 
230
  mov     [edx-5],ecx
 
231
@@Fwd01:
 
232
  movzx   ecx, byte ptr [eax-1]
 
233
  mov     [edx-1],cl
 
234
@@Done:
 
235
end; {SmallForwardMove}
 
236
 
 
237
{-------------------------------------------------------------------------}
 
238
{Perform Backward Move of 0..36 Bytes}
 
239
{On Entry, ECX = Count, EAX = Source, EDX = Dest.  Destroys ECX}
 
240
procedure SmallBackwardMove_3;assembler;nostackframe;
 
241
asm
 
242
  jmp     dword ptr @@BwdJumpTable[ecx*4]
 
243
  align   16
 
244
@@BwdJumpTable:
 
245
  dd      @@Done {Removes need to test for zero size move}
 
246
  dd      @@Bwd01,@@Bwd02,@@Bwd03,@@Bwd04,@@Bwd05,@@Bwd06,@@Bwd07,@@Bwd08
 
247
  dd      @@Bwd09,@@Bwd10,@@Bwd11,@@Bwd12,@@Bwd13,@@Bwd14,@@Bwd15,@@Bwd16
 
248
  dd      @@Bwd17,@@Bwd18,@@Bwd19,@@Bwd20,@@Bwd21,@@Bwd22,@@Bwd23,@@Bwd24
 
249
  dd      @@Bwd25,@@Bwd26,@@Bwd27,@@Bwd28,@@Bwd29,@@Bwd30,@@Bwd31,@@Bwd32
 
250
  dd      @@Bwd33,@@Bwd34,@@Bwd35,@@Bwd36
 
251
@@Bwd36:
 
252
  mov     ecx,[eax+32]
 
253
  mov     [edx+32],ecx
 
254
@@Bwd32:
 
255
  mov     ecx,[eax+28]
 
256
  mov     [edx+28],ecx
 
257
@@Bwd28:
 
258
  mov     ecx,[eax+24]
 
259
  mov     [edx+24],ecx
 
260
@@Bwd24:
 
261
  mov     ecx,[eax+20]
 
262
  mov     [edx+20],ecx
 
263
@@Bwd20:
 
264
  mov     ecx,[eax+16]
 
265
  mov     [edx+16],ecx
 
266
@@Bwd16:
 
267
  mov     ecx,[eax+12]
 
268
  mov     [edx+12],ecx
 
269
@@Bwd12:
 
270
  mov     ecx,[eax+8]
 
271
  mov     [edx+8],ecx
 
272
@@Bwd08:
 
273
  mov     ecx,[eax+4]
 
274
  mov     [edx+4],ecx
 
275
@@Bwd04:
 
276
  mov     ecx,[eax]
 
277
  mov     [edx],ecx
 
278
  ret
 
279
@@Bwd35:
 
280
  mov     ecx,[eax+31]
 
281
  mov     [edx+31],ecx
 
282
@@Bwd31:
 
283
  mov     ecx,[eax+27]
 
284
  mov     [edx+27],ecx
 
285
@@Bwd27:
 
286
  mov     ecx,[eax+23]
 
287
  mov     [edx+23],ecx
 
288
@@Bwd23:
 
289
  mov     ecx,[eax+19]
 
290
  mov     [edx+19],ecx
 
291
@@Bwd19:
 
292
  mov     ecx,[eax+15]
 
293
  mov     [edx+15],ecx
 
294
@@Bwd15:
 
295
  mov     ecx,[eax+11]
 
296
  mov     [edx+11],ecx
 
297
@@Bwd11:
 
298
  mov     ecx,[eax+7]
 
299
  mov     [edx+7],ecx
 
300
@@Bwd07:
 
301
  mov     ecx,[eax+3]
 
302
  mov     [edx+3],ecx
 
303
  mov     ecx,[eax]
 
304
  mov     [edx],ecx
 
305
  ret
 
306
@@Bwd03:
 
307
  movzx   ecx, word ptr [eax+1]
 
308
  mov     [edx+1],cx
 
309
  movzx   ecx, byte ptr [eax]
 
310
  mov     [edx],cl
 
311
  ret
 
312
@@Bwd34:
 
313
  mov     ecx,[eax+30]
 
314
  mov     [edx+30],ecx
 
315
@@Bwd30:
 
316
  mov     ecx,[eax+26]
 
317
  mov     [edx+26],ecx
 
318
@@Bwd26:
 
319
  mov     ecx,[eax+22]
 
320
  mov     [edx+22],ecx
 
321
@@Bwd22:
 
322
  mov     ecx,[eax+18]
 
323
  mov     [edx+18],ecx
 
324
@@Bwd18:
 
325
  mov     ecx,[eax+14]
 
326
  mov     [edx+14],ecx
 
327
@@Bwd14:
 
328
  mov     ecx,[eax+10]
 
329
  mov     [edx+10],ecx
 
330
@@Bwd10:
 
331
  mov     ecx,[eax+6]
 
332
  mov     [edx+6],ecx
 
333
@@Bwd06:
 
334
  mov     ecx,[eax+2]
 
335
  mov     [edx+2],ecx
 
336
@@Bwd02:
 
337
  movzx   ecx, word ptr [eax]
 
338
  mov     [edx],cx
 
339
  ret
 
340
@@Bwd33:
 
341
  mov     ecx,[eax+29]
 
342
  mov     [edx+29],ecx
 
343
@@Bwd29:
 
344
  mov     ecx,[eax+25]
 
345
  mov     [edx+25],ecx
 
346
@@Bwd25:
 
347
  mov     ecx,[eax+21]
 
348
  mov     [edx+21],ecx
 
349
@@Bwd21:
 
350
  mov     ecx,[eax+17]
 
351
  mov     [edx+17],ecx
 
352
@@Bwd17:
 
353
  mov     ecx,[eax+13]
 
354
  mov     [edx+13],ecx
 
355
@@Bwd13:
 
356
  mov     ecx,[eax+9]
 
357
  mov     [edx+9],ecx
 
358
@@Bwd09:
 
359
  mov     ecx,[eax+5]
 
360
  mov     [edx+5],ecx
 
361
@@Bwd05:
 
362
  mov     ecx,[eax+1]
 
363
  mov     [edx+1],ecx
 
364
@@Bwd01:
 
365
  movzx   ecx, byte ptr[eax]
 
366
  mov     [edx],cl
 
367
@@Done:
 
368
end; {SmallBackwardMove}
 
369
 
 
370
 
 
371
{ at least valgrind up to 3.3 has a bug which prevents the default code to
 
372
  work so we use a rather simple implementation here
 
373
}
 
374
procedure Forwards_Valgrind;assembler;nostackframe;
 
375
asm
 
376
  push    esi
 
377
  push    edi
 
378
  mov     esi,eax
 
379
  mov     edi,edx
 
380
  rep     movsb
 
381
  pop     edi
 
382
  pop     esi
 
383
end;
 
384
 
 
385
{ at least valgrind up to 3.3 has a bug which prevents the default code to
 
386
  work so we use a rather simple implementation here
 
387
}
 
388
procedure Backwards_Valgrind;assembler;nostackframe;
 
389
asm
 
390
  push    esi
 
391
  push    edi
 
392
  lea     esi,[eax+ecx-1]
 
393
  lea     edi,[edx+ecx-1]
 
394
@@repeat:
 
395
  mov     al,[esi]
 
396
  mov     [edi],al
 
397
  dec     esi
 
398
  dec     edi
 
399
  dec     ecx
 
400
  jnz     @@repeat
 
401
  pop     edi
 
402
  pop     esi
 
403
end;
 
404
 
 
405
{-------------------------------------------------------------------------}
 
406
{Move ECX Bytes from EAX to EDX, where EAX > EDX and ECX > 36 (SMALLMOVESIZE)}
 
407
procedure Forwards_IA32_3;assembler;nostackframe;
 
408
asm
 
409
  push    ebx
 
410
  mov     ebx,edx
 
411
  fild    qword ptr [eax]
 
412
  add     eax,ecx {QWORD Align Writes}
 
413
  add     ecx,edx
 
414
  add     edx,7
 
415
  and     edx,-8
 
416
  sub     ecx,edx
 
417
  add     edx,ecx {Now QWORD Aligned}
 
418
  sub     ecx,16
 
419
  neg     ecx
 
420
@FwdLoop:
 
421
  fild    qword ptr [eax+ecx-16]
 
422
  fistp   qword ptr [edx+ecx-16]
 
423
  fild    qword ptr [eax+ecx-8]
 
424
  fistp   qword ptr [edx+ecx-8]
 
425
  add     ecx,16
 
426
  jle     @FwdLoop
 
427
  fistp   qword ptr [ebx]
 
428
  neg     ecx
 
429
  add     ecx,16
 
430
  pop     ebx
 
431
  jmp     SmallForwardMove_3
 
432
end; {Forwards_IA32}
 
433
 
 
434
{-------------------------------------------------------------------------}
 
435
{Move ECX Bytes from EAX to EDX, where EAX < EDX and ECX > 36 (SMALLMOVESIZE)}
 
436
procedure Backwards_IA32_3;assembler;nostackframe;
 
437
asm
 
438
  push    ebx
 
439
  fild    qword ptr [eax+ecx-8]
 
440
  lea     ebx,[edx+ecx] {QWORD Align Writes}
 
441
  and     ebx,7
 
442
  sub     ecx,ebx
 
443
  add     ebx,ecx {Now QWORD Aligned, EBX = Original Length}
 
444
  sub     ecx,16
 
445
@BwdLoop:
 
446
  fild    qword ptr [eax+ecx]
 
447
  fild    qword ptr [eax+ecx+8]
 
448
  fistp   qword ptr [edx+ecx+8]
 
449
  fistp   qword ptr [edx+ecx]
 
450
  sub     ecx,16
 
451
  jge     @BwdLoop
 
452
  fistp   qword ptr [edx+ebx-8]
 
453
  add     ecx,16
 
454
  pop     ebx
 
455
  jmp     SmallBackwardMove_3
 
456
end; {Backwards_IA32}
 
457
 
 
458
{-------------------------------------------------------------------------}
 
459
{Move ECX Bytes from EAX to EDX, where EAX > EDX and ECX > 36 (SMALLMOVESIZE)}
 
460
procedure Forwards_MMX_3;assembler;nostackframe;
 
461
const
 
462
  LARGESIZE = 1024;
 
463
asm
 
464
  cmp     ecx,LARGESIZE
 
465
  jge     @FwdLargeMove
 
466
  cmp     ecx,72 {Size at which using MMX becomes worthwhile}
 
467
  jl      Forwards_IA32_3
 
468
  push    ebx
 
469
  mov     ebx,edx
 
470
  movq    mm0,[eax] {First 8 Characters}
 
471
  {QWORD Align Writes}
 
472
  add     eax,ecx
 
473
  add     ecx,edx
 
474
  add     edx,7
 
475
  and     edx,-8
 
476
  sub     ecx,edx
 
477
  add     edx,ecx
 
478
  {Now QWORD Aligned}
 
479
  sub     ecx,32
 
480
  neg     ecx
 
481
@FwdLoopMMX:
 
482
  movq    mm1,[eax+ecx-32]
 
483
  movq    mm2,[eax+ecx-24]
 
484
  movq    mm3,[eax+ecx-16]
 
485
  movq    mm4,[eax+ecx- 8]
 
486
  movq    [edx+ecx-32],mm1
 
487
  movq    [edx+ecx-24],mm2
 
488
  movq    [edx+ecx-16],mm3
 
489
  movq    [edx+ecx- 8],mm4
 
490
  add     ecx,32
 
491
  jle     @FwdLoopMMX
 
492
  movq    [ebx],mm0 {First 8 Characters}
 
493
  emms
 
494
  pop     ebx
 
495
  neg     ecx
 
496
  add     ecx,32
 
497
  jmp     SmallForwardMove_3
 
498
@FwdLargeMove:
 
499
  push    ebx
 
500
  mov     ebx,ecx
 
501
  test    edx,15
 
502
  jz      @FwdAligned
 
503
  {16 byte Align Destination}
 
504
  mov     ecx,edx
 
505
  add     ecx,15
 
506
  and     ecx,-16
 
507
  sub     ecx,edx
 
508
  add     eax,ecx
 
509
  add     edx,ecx
 
510
  sub     ebx,ecx
 
511
  {Destination now 16 Byte Aligned}
 
512
  call    SmallForwardMove_3
 
513
@FwdAligned:
 
514
  mov     ecx,ebx
 
515
  and     ecx,-16
 
516
  sub     ebx,ecx {EBX = Remainder}
 
517
  push    esi
 
518
  push    edi
 
519
  mov     esi,eax          {ESI = Source}
 
520
  mov     edi,edx          {EDI = Dest}
 
521
  mov     eax,ecx          {EAX = Count}
 
522
  and     eax,-64          {EAX = No of Bytes to Blocks Moves}
 
523
  and     ecx,$3F          {ECX = Remaining Bytes to Move (0..63)}
 
524
  add     esi,eax
 
525
  add     edi,eax
 
526
  shr     eax,3            {EAX = No of QWORD's to Block Move}
 
527
  neg     eax
 
528
@MMXcopyloop:
 
529
  movq    mm0,[esi+eax*8   ]
 
530
  movq    mm1,[esi+eax*8+ 8]
 
531
  movq    mm2,[esi+eax*8+16]
 
532
  movq    mm3,[esi+eax*8+24]
 
533
  movq    mm4,[esi+eax*8+32]
 
534
  movq    mm5,[esi+eax*8+40]
 
535
  movq    mm6,[esi+eax*8+48]
 
536
  movq    mm7,[esi+eax*8+56]
 
537
  movq    [edi+eax*8   ],mm0
 
538
  movq    [edi+eax*8+ 8],mm1
 
539
  movq    [edi+eax*8+16],mm2
 
540
  movq    [edi+eax*8+24],mm3
 
541
  movq    [edi+eax*8+32],mm4
 
542
  movq    [edi+eax*8+40],mm5
 
543
  movq    [edi+eax*8+48],mm6
 
544
  movq    [edi+eax*8+56],mm7
 
545
  add     eax,8
 
546
  jnz     @MMXcopyloop
 
547
  emms                   {Empty MMX State}
 
548
  add     ecx,ebx
 
549
  shr     ecx,2
 
550
  rep     movsd
 
551
  mov     ecx,ebx
 
552
  and     ecx,3
 
553
  rep     movsb
 
554
  pop     edi
 
555
  pop     esi
 
556
  pop     ebx
 
557
end; {Forwards_MMX}
 
558
 
 
559
{-------------------------------------------------------------------------}
 
560
{Move ECX Bytes from EAX to EDX, where EAX < EDX and ECX > 36 (SMALLMOVESIZE)}
 
561
procedure Backwards_MMX_3;assembler;nostackframe;
 
562
asm
 
563
  cmp     ecx,72 {Size at which using MMX becomes worthwhile}
 
564
  jl      Backwards_IA32_3
 
565
  push    ebx
 
566
  movq    mm0,[eax+ecx-8] {Get Last QWORD}
 
567
  {QWORD Align Writes}
 
568
  lea     ebx,[edx+ecx]
 
569
  and     ebx,7
 
570
  sub     ecx,ebx
 
571
  add     ebx,ecx
 
572
  {Now QWORD Aligned}
 
573
  sub     ecx,32
 
574
@BwdLoopMMX:
 
575
  movq    mm1,[eax+ecx   ]
 
576
  movq    mm2,[eax+ecx+ 8]
 
577
  movq    mm3,[eax+ecx+16]
 
578
  movq    mm4,[eax+ecx+24]
 
579
  movq    [edx+ecx+24],mm4
 
580
  movq    [edx+ecx+16],mm3
 
581
  movq    [edx+ecx+ 8],mm2
 
582
  movq    [edx+ecx   ],mm1
 
583
  sub     ecx,32
 
584
  jge     @BwdLoopMMX
 
585
  movq    [edx+ebx-8], mm0 {Last QWORD}
 
586
  emms
 
587
  add     ecx,32
 
588
  pop     ebx
 
589
  jmp     SmallBackwardMove_3
 
590
end; {Backwards_MMX}
 
591
 
 
592
{-------------------------------------------------------------------------}
 
593
{Dest MUST be 16-Byes Aligned, Count MUST be multiple of 16 }
 
594
procedure AlignedFwdMoveSSE_3(const Source; var Dest; Count: Integer);assembler;nostackframe;
 
595
const
 
596
  Prefetch = 512;
 
597
asm
 
598
  push    esi
 
599
  mov     esi,eax             {ESI = Source}
 
600
  mov     eax,ecx             {EAX = Count}
 
601
  and     eax,-128            {EAX = No of Bytes to Block Move}
 
602
  add     esi,eax
 
603
  add     edx,eax
 
604
  shr     eax,3               {EAX = No of QWORD's to Block Move}
 
605
  neg     eax
 
606
  cmp     eax, -(32*1024)     {Count > 256K}
 
607
  jl      @Large
 
608
@Small: {Count<=256K}
 
609
  test    esi,15              {Check if Both Source/Dest Aligned}
 
610
  jnz     @SmallUnaligned
 
611
@SmallAligned:                {Both Source and Dest 16-Byte Aligned}
 
612
@SmallAlignedLoop:
 
613
  movaps  xmm0,[esi+8*eax]
 
614
  movaps  xmm1,[esi+8*eax+16]
 
615
  movaps  xmm2,[esi+8*eax+32]
 
616
  movaps  xmm3,[esi+8*eax+48]
 
617
  movaps  [edx+8*eax],xmm0
 
618
  movaps  [edx+8*eax+16],xmm1
 
619
  movaps  [edx+8*eax+32],xmm2
 
620
  movaps  [edx+8*eax+48],xmm3
 
621
  movaps  xmm4,[esi+8*eax+64]
 
622
  movaps  xmm5,[esi+8*eax+80]
 
623
  movaps  xmm6,[esi+8*eax+96]
 
624
  movaps  xmm7,[esi+8*eax+112]
 
625
  movaps  [edx+8*eax+64],xmm4
 
626
  movaps  [edx+8*eax+80],xmm5
 
627
  movaps  [edx+8*eax+96],xmm6
 
628
  movaps  [edx+8*eax+112],xmm7
 
629
  add     eax,16
 
630
  js      @SmallAlignedLoop
 
631
  jmp     @Remainder
 
632
@SmallUnaligned:              {Source Not 16-Byte Aligned}
 
633
@SmallUnalignedLoop:
 
634
  movups  xmm0,[esi+8*eax]
 
635
  movups  xmm1,[esi+8*eax+16]
 
636
  movups  xmm2,[esi+8*eax+32]
 
637
  movups  xmm3,[esi+8*eax+48]
 
638
  movaps  [edx+8*eax],xmm0
 
639
  movaps  [edx+8*eax+16],xmm1
 
640
  movaps  [edx+8*eax+32],xmm2
 
641
  movaps  [edx+8*eax+48],xmm3
 
642
  movups  xmm4,[esi+8*eax+64]
 
643
  movups  xmm5,[esi+8*eax+80]
 
644
  movups  xmm6,[esi+8*eax+96]
 
645
  movups  xmm7,[esi+8*eax+112]
 
646
  movaps  [edx+8*eax+64],xmm4
 
647
  movaps  [edx+8*eax+80],xmm5
 
648
  movaps  [edx+8*eax+96],xmm6
 
649
  movaps  [edx+8*eax+112],xmm7
 
650
  add     eax,16
 
651
  js      @SmallUnalignedLoop
 
652
  jmp     @Remainder
 
653
@Large: {Count>256K}
 
654
  test    esi,15              {Check if Both Source/Dest Aligned}
 
655
  jnz     @LargeUnaligned
 
656
@LargeAligned:                {Both Source and Dest 16-Byte Aligned}
 
657
@LargeAlignedLoop:
 
658
  prefetchnta  [esi+8*eax+Prefetch]
 
659
  prefetchnta  [esi+8*eax+Prefetch+64]
 
660
  movaps  xmm0,[esi+8*eax]
 
661
  movaps  xmm1,[esi+8*eax+16]
 
662
  movaps  xmm2,[esi+8*eax+32]
 
663
  movaps  xmm3,[esi+8*eax+48]
 
664
  movntps [edx+8*eax],xmm0
 
665
  movntps [edx+8*eax+16],xmm1
 
666
  movntps [edx+8*eax+32],xmm2
 
667
  movntps [edx+8*eax+48],xmm3
 
668
  movaps  xmm4,[esi+8*eax+64]
 
669
  movaps  xmm5,[esi+8*eax+80]
 
670
  movaps  xmm6,[esi+8*eax+96]
 
671
  movaps  xmm7,[esi+8*eax+112]
 
672
  movntps [edx+8*eax+64],xmm4
 
673
  movntps [edx+8*eax+80],xmm5
 
674
  movntps [edx+8*eax+96],xmm6
 
675
  movntps [edx+8*eax+112],xmm7
 
676
  add     eax,16
 
677
  js      @LargeAlignedLoop
 
678
  sfence
 
679
  jmp     @Remainder
 
680
@LargeUnaligned:              {Source Not 16-Byte Aligned}
 
681
@LargeUnalignedLoop:
 
682
  prefetchnta  [esi+8*eax+Prefetch]
 
683
  prefetchnta  [esi+8*eax+Prefetch+64]
 
684
  movups  xmm0,[esi+8*eax]
 
685
  movups  xmm1,[esi+8*eax+16]
 
686
  movups  xmm2,[esi+8*eax+32]
 
687
  movups  xmm3,[esi+8*eax+48]
 
688
  movntps [edx+8*eax],xmm0
 
689
  movntps [edx+8*eax+16],xmm1
 
690
  movntps [edx+8*eax+32],xmm2
 
691
  movntps [edx+8*eax+48],xmm3
 
692
  movups  xmm4,[esi+8*eax+64]
 
693
  movups  xmm5,[esi+8*eax+80]
 
694
  movups  xmm6,[esi+8*eax+96]
 
695
  movups  xmm7,[esi+8*eax+112]
 
696
  movntps [edx+8*eax+64],xmm4
 
697
  movntps [edx+8*eax+80],xmm5
 
698
  movntps [edx+8*eax+96],xmm6
 
699
  movntps [edx+8*eax+112],xmm7
 
700
  add     eax,16
 
701
  js      @LargeUnalignedLoop
 
702
  sfence
 
703
@Remainder:
 
704
  and     ecx,$7F {ECX = Remainder (0..112 - Multiple of 16)}
 
705
  jz      @Done
 
706
  add     esi,ecx
 
707
  add     edx,ecx
 
708
  neg     ecx
 
709
@RemainderLoop:
 
710
  movups  xmm0,[esi+ecx]
 
711
  movaps  [edx+ecx],xmm0
 
712
  add     ecx,16
 
713
  jnz     @RemainderLoop
 
714
@Done:
 
715
  pop     esi
 
716
end; {AlignedFwdMoveSSE}
 
717
 
 
718
{-------------------------------------------------------------------------}
 
719
{Move ECX Bytes from EAX to EDX, where EAX > EDX and ECX > 36 (SMALLMOVESIZE)}
 
720
procedure Forwards_SSE_3;assembler;nostackframe;
 
721
const
 
722
  LARGESIZE = 2048;
 
723
asm
 
724
  cmp     ecx,LARGESIZE
 
725
  jge     @FwdLargeMove
 
726
  cmp     ecx,SMALLMOVESIZE+32
 
727
  movups  xmm0,[eax]
 
728
  jg      @FwdMoveSSE
 
729
  movups  xmm1,[eax+16]
 
730
  movups  [edx],xmm0
 
731
  movups  [edx+16],xmm1
 
732
  add     eax,ecx
 
733
  add     edx,ecx
 
734
  sub     ecx,32
 
735
  jmp     SmallForwardMove_3
 
736
@FwdMoveSSE:
 
737
  push    ebx
 
738
  mov     ebx,edx
 
739
  {Align Writes}
 
740
  add     eax,ecx
 
741
  add     ecx,edx
 
742
  add     edx,15
 
743
  and     edx,-16
 
744
  sub     ecx,edx
 
745
  add     edx,ecx
 
746
  {Now Aligned}
 
747
  sub     ecx,32
 
748
  neg     ecx
 
749
@FwdLoopSSE:
 
750
  movups  xmm1,[eax+ecx-32]
 
751
  movups  xmm2,[eax+ecx-16]
 
752
  movaps  [edx+ecx-32],xmm1
 
753
  movaps  [edx+ecx-16],xmm2
 
754
  add     ecx,32
 
755
  jle     @FwdLoopSSE
 
756
  movups  [ebx],xmm0 {First 16 Bytes}
 
757
  neg     ecx
 
758
  add     ecx,32
 
759
  pop     ebx
 
760
  jmp     SmallForwardMove_3
 
761
@FwdLargeMove:
 
762
  push    ebx
 
763
  mov     ebx,ecx
 
764
  test    edx,15
 
765
  jz      @FwdLargeAligned
 
766
  {16 byte Align Destination}
 
767
  mov     ecx,edx
 
768
  add     ecx,15
 
769
  and     ecx,-16
 
770
  sub     ecx,edx
 
771
  add     eax,ecx
 
772
  add     edx,ecx
 
773
  sub     ebx,ecx
 
774
  {Destination now 16 Byte Aligned}
 
775
  call    SmallForwardMove_3
 
776
  mov     ecx,ebx
 
777
@FwdLargeAligned:
 
778
  and     ecx,-16
 
779
  sub     ebx,ecx {EBX = Remainder}
 
780
  push    edx
 
781
  push    eax
 
782
  push    ecx
 
783
  call    AlignedFwdMoveSSE_3
 
784
  pop     ecx
 
785
  pop     eax
 
786
  pop     edx
 
787
  add     ecx,ebx
 
788
  add     eax,ecx
 
789
  add     edx,ecx
 
790
  mov     ecx,ebx
 
791
  pop     ebx
 
792
  jmp     SmallForwardMove_3
 
793
end; {Forwards_SSE}
 
794
 
 
795
{-------------------------------------------------------------------------}
 
796
{Move ECX Bytes from EAX to EDX, where EAX < EDX and ECX > 36 (SMALLMOVESIZE)}
 
797
procedure Backwards_SSE_3;assembler;nostackframe;
 
798
asm
 
799
  cmp     ecx,SMALLMOVESIZE+32
 
800
  jg      @BwdMoveSSE
 
801
  sub     ecx,32
 
802
  movups  xmm1,[eax+ecx]
 
803
  movups  xmm2,[eax+ecx+16]
 
804
  movups  [edx+ecx],xmm1
 
805
  movups  [edx+ecx+16],xmm2
 
806
  jmp     SmallBackwardMove_3
 
807
@BwdMoveSSE:
 
808
  push    ebx
 
809
  movups  xmm0,[eax+ecx-16] {Last 16 Bytes}
 
810
  {Align Writes}
 
811
  lea     ebx,[edx+ecx]
 
812
  and     ebx,15
 
813
  sub     ecx,ebx
 
814
  add     ebx,ecx
 
815
  {Now Aligned}
 
816
  sub     ecx,32
 
817
@BwdLoop:
 
818
  movups  xmm1,[eax+ecx]
 
819
  movups  xmm2,[eax+ecx+16]
 
820
  movaps  [edx+ecx],xmm1
 
821
  movaps  [edx+ecx+16],xmm2
 
822
  sub     ecx,32
 
823
  jge     @BwdLoop
 
824
  movups  [edx+ebx-16],xmm0  {Last 16 Bytes}
 
825
  add     ecx,32
 
826
  pop     ebx
 
827
  jmp     SmallBackwardMove_3
 
828
end; {Backwards_SSE}
 
829
 
 
830
const
 
831
   fastmoveproc_forward : pointer = @Forwards_IA32_3;
 
832
   fastmoveproc_backward : pointer = @Backwards_IA32_3;
 
833
 
 
834
{$ifndef INTERNALMOVEFILLCHAR}
 
835
procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];assembler;nostackframe;
 
836
asm
 
837
  cmp     ecx,SMALLMOVESIZE
 
838
  ja      @Large
 
839
  cmp     eax,edx
 
840
  lea     eax,[eax+ecx]
 
841
  jle     @SmallCheck
 
842
@SmallForward:
 
843
  add     edx,ecx
 
844
  jmp     SmallForwardMove_3
 
845
@SmallCheck:
 
846
  je      @Done {For Compatibility with Delphi's move for Source = Dest}
 
847
  sub     eax,ecx
 
848
  jmp     SmallBackwardMove_3
 
849
@Large:
 
850
  jng     @Done {For Compatibility with Delphi's move for Count < 0}
 
851
  cmp     eax,edx
 
852
  jg      @moveforward
 
853
  je      @Done {For Compatibility with Delphi's move for Source = Dest}
 
854
  push    eax
 
855
  add     eax,ecx
 
856
  cmp     eax,edx
 
857
  pop     eax
 
858
  jg      @movebackward
 
859
@moveforward:
 
860
  jmp     dword ptr fastmoveproc_forward
 
861
@movebackward:
 
862
  jmp     dword ptr fastmoveproc_backward {Source/Dest Overlap}
 
863
@Done:
 
864
end;
 
865
{$endif INTERNALMOVEFILLCHAR}
 
866
 
 
867
{$asmmode att}
 
868
{$ifdef FPC_HAS_VALGRINDBOOL}
 
869
var
 
870
  valgrind_used : boolean;external name '__fpc_valgrind';
 
871
{$endif FPC_HAS_VALGRINDBOOL}
 
872
 
 
873
procedure setup_fastmove;{$ifdef SYSTEMINLINE}inline;{$endif}
 
874
  begin
 
875
{$ifdef FPC_HAS_VALGRINDBOOL}
 
876
    { workaround valgrind bug }
 
877
    if valgrind_used then
 
878
      begin
 
879
        fastmoveproc_forward:=@Forwards_Valgrind;
 
880
        fastmoveproc_backward:=@Backwards_Valgrind;
 
881
      end
 
882
    else
 
883
{$endif FPC_HAS_VALGRINDBOOL}
 
884
 
 
885
    if has_sse_support then
 
886
      begin
 
887
        fastmoveproc_forward:=@Forwards_SSE_3;
 
888
        fastmoveproc_backward:=@Backwards_SSE_3;
 
889
      end
 
890
   else if has_mmx_support then
 
891
      begin
 
892
        fastmoveproc_forward:=@Forwards_MMX_3;
 
893
        fastmoveproc_backward:=@Backwards_MMX_3;
 
894
      end;
 
895
  end;
 
896
 
 
897
{$endif  FPC_SYSTEM_HAS_MOVE}
 
898
 
 
899
{$endif}