/[pcsx2_0.9.7]/trunk/common/include/Utilities/lnx_memzero.h
ViewVC logotype

Annotation of /trunk/common/include/Utilities/lnx_memzero.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 4025 byte(s)
committing r3113 initial commit again...
1 william 31 /* PCSX2 - PS2 Emulator for PCs
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16     #ifndef _LNX_MEMZERO_H_
17     #define _LNX_MEMZERO_H_
18    
19     // This header contains non-optimized implementation of memzero_ptr and memset8,
20     // memset16, etc.
21    
22     template< u32 data, typename T >
23     static __forceinline void memset32( T& obj )
24     {
25     // this function works on 32-bit aligned lengths of data only.
26     // If the data length is not a factor of 32 bits, the C++ optimizing compiler will
27     // probably just generate mysteriously broken code in Release builds. ;)
28    
29     jASSUME( (sizeof(T) & 0x3) == 0 );
30    
31     u32* dest = (u32*)&obj;
32     for( int i=sizeof(T)>>2; i; --i, ++dest )
33     *dest = data;
34     }
35    
36     template< uint size >
37     static __forceinline void memzero_ptr( void* dest )
38     {
39     memset( dest, 0, size );
40     }
41    
42     template< typename T >
43     static __forceinline void memzero( T& obj )
44     {
45     memset( &obj, 0, sizeof( T ) );
46     }
47    
48     template< u8 data, typename T >
49     static __forceinline void memset8( T& obj )
50     {
51     // Aligned sizes use the optimized 32 bit inline memset. Unaligned sizes use memset.
52     if( (sizeof(T) & 0x3) != 0 )
53     memset( &obj, data, sizeof( T ) );
54     else
55     memset32<data + (data<<8) + (data<<16) + (data<<24)>( obj );
56     }
57    
58     template< u16 data, typename T >
59     static __forceinline void memset16( T& obj )
60     {
61     if( (sizeof(T) & 0x3) != 0 )
62     _memset16_unaligned( &obj, data, sizeof( T ) );
63     else
64     memset32<data + (data<<16)>( obj );
65     }
66    
67    
68     // An optimized memset for 8 bit destination data.
69     template< u8 data, size_t bytes >
70     static __forceinline void memset_8( void *dest )
71     {
72     if( bytes == 0 ) return;
73    
74     if( (bytes & 0x3) != 0 )
75     {
76     // unaligned data length. No point in doing an optimized inline version (too complicated!)
77     // So fall back on the compiler implementation:
78    
79     memset( dest, data, bytes );
80     return;
81     }
82    
83     // This function only works on 32-bit alignments of data copied.
84     jASSUME( (bytes & 0x3) == 0 );
85    
86     enum
87     {
88     remdat = bytes>>2,
89     data32 = data + (data<<8) + (data<<16) + (data<<24)
90     };
91    
92     // macro to execute the x86/32 "stosd" copies.
93     switch( remdat )
94     {
95     case 1:
96     *(u32*)dest = data32;
97     return;
98    
99     case 2:
100     ((u32*)dest)[0] = data32;
101     ((u32*)dest)[1] = data32;
102     return;
103    
104     case 3:
105     __asm__ volatile
106     (
107     ".intel_syntax noprefix\n"
108     "cld\n"
109     // "mov edi, %[dest]\n"
110     // "mov eax, %[data32]\n"
111     "stosd\n"
112     "stosd\n"
113     "stosd\n"
114     ".att_syntax\n"
115     :
116     // Input specifiers: D - edi, a -- eax, c ecx
117     : [dest]"D"(dest), [data32]"a"(data32)
118     : "memory"
119     );
120     return;
121    
122     case 4:
123     __asm__ volatile
124     (
125     ".intel_syntax noprefix\n"
126     "cld\n"
127     // "mov edi, %[dest]\n"
128     // "mov eax, %[data32]\n"
129     "stosd\n"
130     "stosd\n"
131     "stosd\n"
132     "stosd\n"
133     ".att_syntax\n"
134     :
135     : [dest]"D"(dest), [data32]"a"(data32)
136     : "memory"
137    
138     );
139     return;
140    
141     case 5:
142     __asm__ volatile
143     (
144     ".intel_syntax noprefix\n"
145     "cld\n"
146     // "mov edi, %[dest]\n"
147     // "mov eax, %[data32]\n"
148     "stosd\n"
149     "stosd\n"
150     "stosd\n"
151     "stosd\n"
152     "stosd\n"
153     ".att_syntax\n"
154     :
155     : [dest]"D"(dest), [data32]"a"(data32)
156     : "memory"
157    
158     );
159     return;
160    
161     default:
162     __asm__ volatile
163     (
164     ".intel_syntax noprefix\n"
165     "cld\n"
166     // "mov ecx, %[remdat]\n"
167     // "mov edi, %[dest]\n"
168     // "mov eax, %\[data32]n"
169     "rep stosd\n"
170     ".att_syntax\n"
171     :
172     : [remdat]"c"(remdat), [dest]"D"(dest), [data32]"a"(data32)
173     : "memory"
174     );
175     return;
176     }
177     }
178    
179     #endif

  ViewVC Help
Powered by ViewVC 1.1.22