소스 검색

Add assembler implementation of Move.

git-svn-id: trunk@42155 -
Jeppe Johansen 6 년 전
부모
커밋
009c87156a
1개의 변경된 파일37개의 추가작업 그리고 31개의 파일을 삭제
  1. 37 31
      rtl/avr/avr.inc

+ 37 - 31
rtl/avr/avr.inc

@@ -32,37 +32,43 @@ procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif}
 
 
 {$define FPC_SYSTEM_HAS_MOVE}
-procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];
-var
-  pdest,psrc,pend : pbyte;
-begin
-  if (@dest=@source) or (count<=0) then
-    exit;
-  if (@dest<@source) or (@source+count<@dest) then
-    begin
-      { Forward Move }
-      psrc:=@source;
-      pdest:=@dest;
-      pend:=psrc+count;
-      while psrc<pend do
-        begin
-          pdest^:=psrc^;
-          inc(pdest);
-          inc(psrc);
-        end;
-    end
-  else
-    begin
-      { Backward Move }
-      psrc:=@source+count;
-      pdest:=@dest+count;
-      while psrc>@source do
-        begin
-          dec(pdest);
-          dec(psrc);
-          pdest^:=psrc^;
-        end;
-    end;
+procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE']; assembler; nostackframe;
+asm
+  push r28
+  push r29
+
+  movw r26, r24         // Src=X
+  movw r28, r22         // Dest=Y
+  movw r30, r20         // Count=Z
+  cp r1, r30
+  cpc r1, r31
+  brge .Lexit           // if 0 >= Count
+  cp  r28, r26
+  cpc r29, r27
+  breq .Lexit           // if dest = source
+  brlo .LForwardMove    // if dest < source
+
+  // Add count to both pointers
+  add r26, r30
+  adc r27, r31
+  add r28, r30
+  adc r29, r31
+.LBackwardMove:
+  ld r18, -X
+  st -Y, r18
+  sbiw Z, 1
+  brne .LBackwardMove
+  rjmp .Lexit
+
+.LForwardMove:
+  ld r18, X+
+  st Y+, r18
+  sbiw Z, 1
+  brne .LForwardMove
+.Lexit:
+
+  pop r29
+  pop r28
 end;