Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: regexp2000/src/regexp-macro-assembler-ia32.cc

Issue 10942: Start IA32 implemenetation of regexp2k (Closed)
Patch Set: Addressed review comments Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « regexp2000/src/regexp-macro-assembler-ia32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29 #include "regexp-macro-assembler-ia32.h"
30
31 namespace v8 { namespace internal {
32
33 /*
34 * This assembler uses the following register assignment convention
35 * - edx : current character, or kEndOfInput if current position is not
36 * inside string. The kEndOfInput value is greater than 0xffff,
37 * so any tests that don't check whether the current position
38 * is inside the correct range should retain bits above the
39 * 15th in their computations, and fail if the value is too
40 * great.
41 * - edi : current position in input.
42 * - esi : end of input (points to byte after last character in input).
43 * - ebp : points to the location above the registers on the stack,
44 * as if by the "enter <register_count>" opcode.
45 * - esp : points to tip of backtracking stack.
46 *
47 * The registers eax, ebx and eax are free to use for computations.
48 *
49 * Each call to a public method should retain this convention.
50 * The stack is expected to have the following structure (tentative):
51 *
52 * - pointer to array where captures can be stored
53 * - end of input
54 * - start of input
55 * - return address
56 * ebp-> - old ebp
57 * - register 0 ebp[-4]
58 * - register 1 ebp[-8]
59 * - ...
60 *
61 * The data before ebp must be placed there by the calling code.
62 */
63
64 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32()
65 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
66 constants_(kRegExpConstantsSize),
67 num_registers_(0),
68 ignore_case(false) {}
69
70
71 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() {
72 delete masm_;
73 }
74
75
76 #define __ masm_->
77
78 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
79 __ add(edi, by * sizeof(SubjectChar));
80 __ cmp(edi, esi);
81 Label inside_string;
82 Backtrack();
83
84 __ bind(&inside_string);
85 ReadChar(edx, 0);
86 }
87
88
89 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) {
90 ASSERT(reg >= 0);
91 ASSERT(reg < num_registers);
92 __ add(register_location(reg), by);
93 }
94
95
96 void RegExpMacroAssemblerIA32::Backtrack() {
97 __ ret();
98 }
99
100
101 void RegExpMacroAssemblerIA32::Bind(Label* label) {
102 __ bind(label);
103 }
104
105
106 void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
107 Label* bitmap,
108 Label* on_zero) {
109 ReadCurrentChar(eax);
110 __ sub(eax, start);
111 __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits.
112 BranchOrBacktrack(greater_equal, on_zero);
113 __ mov(ebx, eax);
114 __ shr(ebx, 3);
115 // TODO: Where is the bitmap stored? Pass the bitmap as argument instead.
116 // __ mov(ecx, position_of_bitmap);
117 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0));
118 __ and_(eax, (1<<3)-1);
119 __ bt(ebx, eax);
120 __ j(greater_equal, on_zero); // Aka. jump on carry set.
121 }
122
123
124 void RegExpMacroAssemblerIA32::CheckCharacterClass(RegExpCharacterClass *cclass,
125 Label* on_failure) {
126 UNREACHABLE(); // Not implemented.
127 }
128
129
130 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<uc16> str,
131 Label* on_failure) {
132 if (sizeof(SubjectChar) == 1) {
133 for (int i = 0; i < str.length(); i++) {
134 if (str[i] > String::kMaxAsciiCharCode) {
135 __ jmp(on_failure);
136 return;
137 }
138 }
139 }
140 int byte_length = str.length() * sizeof(SubjectChar);
141 __ mov(ebx, edi);
142 __ add(ebx, byte_length);
143 __ cmp(ebx, esi);
144 BranchOrBacktrack(greater_equal, on_failure);
145
146 if (str.length() <= kMaxInlineStringTests || ignore_case()) {
147 // TODO: make proper loop if str.length is large but ignore_case is true;
148 for(int i = 0; i < str.length(); i++) {
149 ReadChar(eax, i);
150 if (ignore_case()) {
151 Canonicalize(eax);
152 }
153 __ cmp(eax, str[i]);
154 BranchOrBacktrack(not_equal, on_failure);
155 }
156 add(edi, byte_length);
157 } else {
158 int offset;
159 ArraySlice<SubjectChar> constant_buffer =
160 constants_.GetBuffer<SubjectChar>(str.length());
161 for (int i = 0; i < str.length(); i++) {
162 constant_buffer[i] = str[i];
163 }
164 __ mov(ebx, esi);
165 LoadConstantBufferAddress(esi, constant_buffer);
166 __ mov(ecx, str.length());
167 if (sizeof(SubjectChar) == 1) {
168 __ rep_cmpsb();
169 } else {
170 ASSERT(sizeof(SubjectChar)==2);
171 __ rep_cmpsw();
172 }
173 __ mov(esi, ebx);
174 BranchOrBacktrack(not_equal, on_failure);
175 }
176 };
177
178
179 void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index,
180 Label* on_equal) {
181 __ cmp(register_location(register_index), edi);
182 BranchOrBacktrack(equal, on_equal);
183 }
184
185
186 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
187 uc16 start,
188 Label* half_nibble_map,
189 const Vector<Label*>& destinations) {
190
191 if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
192 return;
193 }
194
195 Label fallthrough;
196
197 ReadCurrentChar(eax);
198 __ sub(eax, start);
199 __ cmp(eax, 64); // FIXME: 64 = size of map in bytes. Found somehow??
200 __ j(greater_equal, &fallthrough);
201
202 __ mov(ebx, eax);
203 __ shr(eax, 2);
204 __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx holds address of map
205 Label got_nybble;
206 Label high_bits;
207 __ and_(ebx, 0x03);
208 __ shr(eax, ebx);
209
210 Label second_bit_set, case_3, case_1;
211 __ test(eax, 2);
212 __ j(not_equal, &second_bit_set);
213 __ test(eax, 1);
214 __ j(not_equal, &case_1);
215 // Case 0:
216 __ jmp(&destinations[0]);
217 __ bind(&case_1);
218 // Case 1:
219 __ jmp(&destinations[1]);
220 __ bind(&second_bit_set);
221 __ test(eax, 1);
222 __ j(not_equal, &case_3);
223 // Case 2
224 __ jmp(&destinations[2]);
225 __ bind(&case_3);
226 // Case 3:
227 __ jmp(&destinations[3]);
228
229 __ bind(&fallthrough);
230 }
231
232
233 void RegExpMacroAssemblerIA32::DispatchByteMap(
234 uc16 start,
235 Label* byte_map,
236 const Vector<Label*>& destinations) {
237
238 if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
239 return;
240 }
241
242 Label fallthrough;
243
244 ReadCurrentChar(eax);
245 __ sub(eax, start);
246 __ cmp(eax, 64); // FIXME: 64 = size of map. Found somehow??
247 __ j(greater_equal, &fallthrough);
248
249 __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx must hold address of map
250 // jump table: jump to destinations[eax];
251
252 __ bind(&fallthrough);
253 }
254
255 void RegExpMacroAssemblerIA32::DispatchHighByteMap(
256 byte start,
257 Label* byte_map,
258 const Vector<Label*>& destinations) {
259 Label fallthrough;
260 ReadCurrentChar(eax);
261 __ shr(eax, 8);
262 __ sub(eax, start);
263 __ cmp(eax, destinations.length() - start);
264 __ j(greater_equal, &fallthrough);
265
266 // TODO jumptable: jump to destinations[eax]
267 __ bind(&fallthrough);
268 }
269
270
271 void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
272 UNREACHABLE(); // Has no use.
273 }
274
275
276 void RegExpMacroAssemblerIA32::Fail() {
277 Exit(false);
278 }
279
280 Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
281 // something
282 return Handle();
283 }
284
285
286 void RegExpMacroAssemblerIA32::GoTo(Label &to) {
287 __ jmp(to);
288 }
289
290
291 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
292 int comparand,
293 Label* if_ge) {
294 __ cmp(register_location(reg), comparand);
295 BranchOrBacktrack(greater_equal, if_ge);
296 }
297
298
299 void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
300 int comparand,
301 Label* if_lt) {
302 __ cmp(register_location(reg), comparand);
303 BranchOrBacktrack(less, if_lt);
304 }
305
306
307 Re2kImplementation RegExpMacroAssemblerIA32::Implementation() {
308 return kIA32Implementation;
309 }
310
311
312 void RegExpMacroAssemblerIA32::PopCurrentPosition() {
313 __ pop(edi);
314 ReadChar(edx, 0);
315 }
316
317
318 void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
319 __ pop(register_location(register_index));
320 }
321
322
323 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) {
324 Label cont;
325 __ call(&cont);
326 __ jmp(label);
327 __ bind(&cont);
328 }
329
330
331 void RegExpMacroAssemblerIA32::PushCurrentPosition() {
332 __ push(edi);
333 }
334
335
336 void RegExpMacroAssemblerIA32::PushRegister(int register_index) {
337 __ push(register_location(register_index));
338 }
339
340
341 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
342 __ mov(register_location(register_index), to);
343 }
344
345
346 void RegExpMacroAssemblerIA32::Succeed() {
347 Exit(true);
348 }
349
350 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister() {
351 __ mov(register_location(register_index), edi);
352 }
353
354 // Custom :
355
356 void RegExpMacroAssemblerIA32::Initialize(int num_registers, bool ignore_case) {
357 num_registers_ = num_registers;
358 ignore_case_ = ignore_case;
359 __ enter(num_registers * sizeof(uint32_t));
360 }
361
362
363 Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
364 ASSERT(register_index < (1<<30));
365 return Operand(ebp, -((register_index + 1) * sizeof(uint32_t)));
366 }
367
368
369 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
370 Label* to) {
371 if (condition < 0) { // No condition
372 if (to == NULL) {
373 Backtrack();
374 return;
375 }
376 __ jmp(to);
377 return;
378 } else if (to == NULL) {
379 Label skip;
380 __ j(NegateCondition(condition), &skip);
381 Backtrack();
382 __ bind(&skip);
383 return;
384 }
385 __ j(condition, to);
386 }
387
388
389 void RegExpMacroAssemblerIA32::Canonicalize(Register reg) {
390 if (sizeof(SubjectChar) == 1) {
391 Label end;
392 __ cmp(reg, 'a');
393 __ j(below, &end);
394 __ cmp(reg, 'z');
395 __ j(above, &end);
396 __ sub(reg, 'a' - 'A');
397 __ bind(&end);
398 return;
399 }
400 ASSERT(sizeof(SubjectChar) == 2);
401 // TODO: Use some tables.
402 }
403
404
405 void RegExpMacroAssemblerIA32::Exit(bool success) {
406 if (success) {
407 // Copy captures to output capture array.
408 }
409 __ leave();
410 __ mov(eax, success ? 1 : 0);
411 __ ret();
412 }
413
414
415 void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) {
416 if (sizeof(SubjectChar) == 1) {
417 __ movzx_b(destination, Operand(edi, offset));
418 return;
419 }
420 ASSERT(sizeof(SubjectChar) == 2);
421 __ movzx_w(destination, Operand(edi, offset * 2));
422 }
423
424
425 void RegExpMacroAssemblerIA32::ReadCurrentChar(Register destination) {
426 mov(destination, edx);
427 }
428
429
430 template <typename T>
431 void LoadConstantBufferAddress(Register reg, ArraySlice<T>& buffer) {
432 __ mov(reg, buffer.array());
433 __ add(reg, buffer.base_offset());
434 }
435
436 #undef __
437 }}
OLDNEW
« no previous file with comments | « regexp2000/src/regexp-macro-assembler-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698