File : s-memmov.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- S Y S T E M . M E M O R Y _ M O V E --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2006-2014, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- --
19 -- --
20 -- --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
31
32 with Ada.Unchecked_Conversion;
33 with Interfaces.C; use Interfaces.C;
34
35 package body System.Memory_Move is
36
37 type IA is mod System.Memory_Size;
38 -- The type used to provide the actual desired operations
39
40 function To_IA is new Ada.Unchecked_Conversion (Address, IA);
41 -- The operations are implemented by unchecked conversion to type IA,
42 -- followed by doing the intrinsic operation on the IA values, followed
43 -- by converting the result back to type Address.
44
45 type Byte is mod 2 ** 8;
46 for Byte'Size use 8;
47 -- Byte is the storage unit
48
49 type Byte_Ptr is access Byte;
50 -- Access to a byte
51
52 function To_Byte_Ptr is new Ada.Unchecked_Conversion (IA, Byte_Ptr);
53 -- Conversion between an integer address and access to byte
54
55 Byte_Size : constant := 1;
56 -- Number of storage unit in a byte
57
58 type Word is mod 2 ** System.Word_Size;
59 for Word'Size use System.Word_Size;
60 -- Word is efficiently loaded and stored by the processor, but has
61 -- alignment constraints.
62
63 type Word_Ptr is access Word;
64 -- Access to a word.
65
66 function To_Word_Ptr is new Ada.Unchecked_Conversion (IA, Word_Ptr);
67 -- Conversion from an integer adddress to word access
68
69 Word_Size : constant := Word'Size / Storage_Unit;
70 -- Number of storage unit per word
71
72 -------------
73 -- memmove --
74 -------------
75
76 function memmove
77 (Dest : Address; Src : Address; N : size_t) return Address is
78 D : IA := To_IA (Dest);
79 S : IA := To_IA (Src);
80 C : IA := IA (N);
81 begin
82 -- Return immediately if no bytes to copy.
83
84 if N = 0 then
85 return Dest;
86 end if;
87
88 -- This function must handle overlapping memory regions
89 -- for the source and destination. If the Dest buffer is
90 -- located past the Src buffer then we use backward copying,
91 -- and forward copying otherwise.
92
93 if D > S and then D < S + C then
94 D := D + C;
95 S := S + C;
96 while C /= 0 loop
97 D := D - Byte_Size;
98 S := S - Byte_Size;
99 To_Byte_Ptr (D).all := To_Byte_Ptr (S).all;
100
101 C := C - Byte_Size;
102 end loop;
103 else
104 -- Try to copy per word, if alignment constraints are respected
105 if ((D or S) and (Word'Alignment - 1)) = 0 then
106 while C >= Word_Size loop
107 To_Word_Ptr (D).all := To_Word_Ptr (S).all;
108 D := D + Word_Size;
109 S := S + Word_Size;
110 C := C - Word_Size;
111 end loop;
112 end if;
113
114 -- Copy the remaining byte per byte
115 while C > 0 loop
116 To_Byte_Ptr (D).all := To_Byte_Ptr (S).all;
117 D := D + Byte_Size;
118 S := S + Byte_Size;
119 C := C - Byte_Size;
120 end loop;
121 end if;
122
123 return Dest;
124 end memmove;
125
126 end System.Memory_Move;