Repository navigation
Expand file tree
/
Copy pathStringLoadStoreOperations.h
More file actions
238 lines (168 loc) · 7.65 KB
/
Copy pathStringLoadStoreOperations.h
File metadata and controls
238 lines (168 loc) · 7.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*++
Copyright (c) 2016 Trent Nelson <trent@trent.me>
Module Name:
StringLoadStoreOperations.h
Abstract:
This module contains macros and inline routines implementing various
approaches for loading memory into XMM/YMM registers and storing XMM/YMM
register values into memory.
--*/
#pragma once
#include "stdafx.h"
#ifdef __cplusplus
extern "C" {
#endif
/*++
VOID
LoadSearchStringIntoXmmRegister_SEH(
_In_ STRING_SLOT Slot,
_In_ PSTRING String,
_In_ USHORT LengthVar
);
Routine Description:
Attempts an aligned 128-bit load of String->Buffer into Slot.CharXmm via
the _mm_stream_load_si128() intrinsic. The intrinsic is surrounded in a
__try/__except block that catches EXCEPTION_ACCESS_VIOLATION exceptions.
If such an exception is caught, the routine will check to see if the string
buffer's address will cross a page boundary if 16-bytes are loaded. If a
page boundary would be crossed, a __movsb() intrinsic is used to copy only
the bytes specified by String->Length, otherwise, an unaligned 128-bit load
is attemped via the _mm_loadu_si128() intrinsic.
Arguments:
Slot - Supplies the STRING_SLOT local variable name within the calling
function that will receive the results of the load operation.
String - Supplies the name of the PSTRING variable that is to be loaded
into the slot. This will usually be one of the function parameters.
LengthVar - Supplies the name of a USHORT local variable that will receive
the value of min(String->Length, 16).
Return Value:
None.
--*/
#define LoadSearchStringIntoXmmRegister_SEH(Slot, String, LengthVar) \
LengthVar = min(String->Length, 16); \
TRY_SSE42_ALIGNED { \
Slot.CharsXmm = _mm_load_si128((PXMMWORD)String->Buffer); \
} CATCH_EXCEPTION_ACCESS_VIOLATION { \
if (PointerToOffsetCrossesPageBoundary(String->Buffer, 16)) { \
__movsb(Slot.Char, String->Buffer, LengthVar); \
} else { \
Slot.CharsXmm = _mm_loadu_si128((PXMMWORD)String->Buffer); \
} \
}
/*++
VOID
LoadSearchStringIntoXmmRegister_AlignmentCheck(
_In_ STRING_SLOT Slot,
_In_ PSTRING String,
_In_ USHORT LengthVar
);
Routine Description:
This routine checks to see if a page boundary will be crossed if 16-bytes
are loaded from the address supplied by String->Buffer. If a page boundary
will be crossed, a __movsb() intrinsic is used to only copy String->Length
bytes into the given Slot.
If no page boundary will be crossed by a 128-bit load, the alignment of
the address supplied by String->Buffer is checked. If the alignment isn't
at least on a 16-byte boundary, an unaligned load will be issued via the
_mm_loadu_si128() intrinsic, otherwise, an _mm_stream_load_si128() will be
used.
Arguments:
Slot - Supplies the STRING_SLOT local variable name within the calling
function that will receive the results of the load operation.
String - Supplies the name of the PSTRING variable that is to be loaded
into the slot. This will usually be one of the function parameters.
LengthVar - Supplies the name of a USHORT local variable that will receive
the value of min(String->Length, 16).
Return Value:
None.
--*/
#define LoadSearchStringIntoXmmRegister_AlignmentCheck(Slot, String,LengthVar) \
LengthVar = min(String->Length, 16); \
if (PointerToOffsetCrossesPageBoundary(String->Buffer, 16)) { \
__movsb(Slot.Char, String->Buffer, LengthVar); \
} else if (GetAddressAlignment(String->Buffer) < 16) { \
Slot.CharsXmm = _mm_loadu_si128((PXMMWORD)String->Buffer); \
} else { \
Slot.CharsXmm = _mm_load_si128((PXMMWORD)String->Buffer); \
}
/*++
VOID
LoadSearchStringIntoXmmRegister_AlwaysUnaligned(
_In_ STRING_SLOT Slot,
_In_ PSTRING String,
_In_ USHORT LengthVar
);
Routine Description:
This routine performs an unaligned 128-bit load of the address supplied by
String->Buffer into the given Slot via the _mm_loadu_si128() intrinsic.
No checks are done regarding whether or not a page boundary will be crossed.
Arguments:
Slot - Supplies the STRING_SLOT local variable name within the calling
function that will receive the results of the load operation.
String - Supplies the name of the PSTRING variable that is to be loaded
into the slot. This will usually be one of the function parameters.
LengthVar - Supplies the name of a USHORT local variable that will receive
the value of min(String->Length, 16).
Return Value:
None.
--*/
#define LoadSearchStringIntoXmmRegister_Unaligned(Slot, String, LengthVar) \
LengthVar = min(String->Length, 16); \
if (PointerToOffsetCrossesPageBoundary(String->Buffer, 16)) { \
__movsb(Slot.Char, String->Buffer, LengthVar); \
} else if (GetAddressAlignment(String->Buffer) < 16) { \
Slot.CharsXmm = _mm_loadu_si128(String->Buffer); \
} else { \
Slot.CharsXmm = _mm_load_si128(String->Buffer); \
}
/*++
VOID
LoadSearchStringIntoXmmRegister_AlwaysMovsb(
_In_ STRING_SLOT Slot,
_In_ PSTRING String,
_In_ USHORT LengthVar
);
Routine Description:
This routine copies min(String->Length, 16) bytes from String->Buffer
into the given Slot via the __movsb() intrinsic. The memory referenced by
the Slot is not cleared first via SecureZeroMemory().
Arguments:
Slot - Supplies the STRING_SLOT local variable name within the calling
function that will receive the results of the load operation.
String - Supplies the name of the PSTRING variable that is to be loaded
into the slot. This will usually be one of the function parameters.
LengthVar - Supplies the name of a USHORT local variable that will receive
the value of min(String->Length, 16).
Return Value:
None.
--*/
#define LoadSearchStringIntoXmmRegister_AlwaysMovsb(Slot, String, LengthVar) \
LengthVar = min(String->Length, 16); \
__movsb(Slot.Char, String->Buffer, LengthVar);
//
// Define the appropriate target for the LoadSearchStringIntoXmmRegister macro
// based on the search string strategy defined.
//
#if LOAD_SEARCH_STRING_STRATEGY_SEH
#define LoadSearchStringIntoXmmRegister \
LoadSearchStringIntoXmmRegister_SEH
#elif LOAD_SEARCH_STRING_STRATEGY_ALIGNMENT_CHECK
#define LoadSearchStringIntoXmmRegister \
LoadSearchStringIntoXmmRegister_AlignmentCheck
#elif LOAD_SEARCH_STRING_STRATEGY_ALWAYS_UNALIGNED
#define LoadSearchStringIntoXmmRegister \
LoadSearchStringIntoXmmRegister_AlwaysUnaligned
#elif LOAD_SEARCH_STRING_STRATEGY_ALWAYS_MOVSB
#define LoadSearchStringIntoXmmRegister \
LoadSearchStringIntoXmmRegister_AlwaysMovsb
#else
//
// Default setting.
//
#define LoadSearchStringIntoXmmRegister \
LoadSearchStringIntoXmmRegister_AlignmentCheck
#endif
#ifdef __cplusplus
} // extern "C"
#endif
// vim:set ts=8 sw=4 sts=4 tw=80 expandtab :