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

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

Issue 11271: Building on regexp-ia32. (Closed)
Patch Set: Made it compile correctly. 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
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 #include "log.h"
30 #include "ast.h"
31 #include "macro-assembler.h"
29 #include "regexp-macro-assembler-ia32.h" 32 #include "regexp-macro-assembler-ia32.h"
30 33
31 namespace v8 { namespace internal { 34 namespace v8 { namespace internal {
32 35
33 /* 36 /*
34 * This assembler uses the following register assignment convention 37 * This assembler uses the following register assignment convention
35 * - edx : current character, or kEndOfInput if current position is not 38 * - edx : current character, or kEndOfInput if current position is not
36 * inside string. The kEndOfInput value is greater than 0xffff, 39 * inside string. The kEndOfInput value is greater than 0xffff,
37 * so any tests that don't check whether the current position 40 * so any tests that don't check whether the current position
38 * is inside the correct range should retain bits above the 41 * is inside the correct range should retain bits above the
39 * 15th in their computations, and fail if the value is too 42 * 15th in their computations, and fail if the value is too
40 * great. 43 * great.
41 * - edi : current position in input. 44 * - edi : current position in input, as negative offset from end of string.
42 * - esi : end of input (points to byte after last character in input). 45 * - esi : end of input (points to byte after last character in input).
43 * - ebp : points to the location above the registers on the stack, 46 * - ebp : points to the location above the registers on the stack,
44 * as if by the "enter <register_count>" opcode. 47 * as if by the "enter <register_count>" opcode.
45 * - esp : points to tip of backtracking stack. 48 * - esp : points to tip of backtracking stack.
46 * 49 *
47 * The registers eax, ebx and eax are free to use for computations. 50 * The registers eax, ebx and ecx are free to use for computations.
48 * 51 *
49 * Each call to a public method should retain this convention. 52 * Each call to a public method should retain this convention.
50 * The stack is expected to have the following structure (tentative): 53 * The stack is expected to have the following structure (tentative):
Erik Corry 2008/11/21 13:03:04 Be bold, not tentative! :-)
Lasse Reichstein 2008/11/24 08:32:33 Done!
51 * 54 * - int* capture_array (int[num_saved_registers_], for output).
52 * - pointer to array where captures can be stored 55 * - end of input (index of end of string, relative to *string_base)
53 * - end of input 56 * - start of input (index of first character in string, relative
54 * - start of input 57 * to *string_base)
58 * - void** string_base (location of a handle containing the string)
55 * - return address 59 * - return address
60 * - backup of esi
61 * - backup of edi
56 * ebp-> - old ebp 62 * ebp-> - old ebp
57 * - register 0 ebp[-4] 63 * - register 0 ebp[-4]
58 * - register 1 ebp[-8] 64 * - register 1 ebp[-8]
59 * - ... 65 * - ...
60 * 66 *
61 * The data before ebp must be placed there by the calling code. 67 * The data before ebp must be placed there by the calling code, e.g.,
68 * by calling the code as cast to:
69 * bool (*match)(void** string_base,
70 * int start_offset,
71 * int end_offset,
72 * int* capture_array)
62 */ 73 */
63 74
64 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32() 75 #define __ masm_->
76
77
78 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
79 Mode mode,
80 int registers_to_save,
81 bool ignore_case)
65 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), 82 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
66 constants_(kRegExpConstantsSize), 83 constants_(kRegExpConstantsSize),
67 num_registers_(0), 84 mode_(mode),
68 ignore_case(false) {} 85 num_registers_(registers_to_save),
86 num_saved_registers_(registers_to_save),
87 ignore_case_(ignore_case),
88 entry_label_(),
89 start_label_(),
90 success_label_(),
91 exit_label_(),
92 self_() {
93 __ jmp(&entry_label_); // We'll write the entry code later.
94 __ bind(&start_label_); // And then continue from here.
95 }
96
69 97
70 98
71 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { 99 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() {
72 delete masm_; 100 delete masm_;
73 } 101 }
74 102
75 103
76 #define __ masm_->
77 104
78 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { 105 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
79 __ add(edi, by * sizeof(SubjectChar)); 106 ASSERT(by > 0);
80 __ cmp(edi, esi);
81 Label inside_string; 107 Label inside_string;
108 __ add(Operand(edi), Immediate(by * char_size()));
109 __ j(below, &inside_string);
82 Backtrack(); 110 Backtrack();
83 111
84 __ bind(&inside_string); 112 __ bind(&inside_string);
85 ReadChar(edx, 0);
86 } 113 }
87 114
88 115
116
89 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { 117 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) {
90 ASSERT(reg >= 0); 118 ASSERT(reg >= 0);
91 ASSERT(reg < num_registers); 119 ASSERT(reg < num_registers_);
92 __ add(register_location(reg), by); 120 __ add(register_location(reg), Immediate(by));
93 } 121 }
94 122
95 123
124
96 void RegExpMacroAssemblerIA32::Backtrack() { 125 void RegExpMacroAssemblerIA32::Backtrack() {
97 __ ret(); 126 __ pop(ecx);
127 __ add(Operand(ecx), Immediate(self_));
128 __ jmp(Operand(ecx));
98 } 129 }
99 130
100 131
132
101 void RegExpMacroAssemblerIA32::Bind(Label* label) { 133 void RegExpMacroAssemblerIA32::Bind(Label* label) {
102 __ bind(label); 134 __ bind(label);
103 } 135 }
104 136
105 137
138
106 void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start, 139 void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
107 Label* bitmap, 140 Label* bitmap,
108 Label* on_zero) { 141 Label* on_zero) {
109 ReadCurrentChar(eax); 142 ReadCurrentChar(eax);
110 __ sub(eax, start); 143 __ sub(Operand(eax), Immediate(start));
111 __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits. 144 __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits.
112 BranchOrBacktrack(greater_equal, on_zero); 145 BranchOrBacktrack(greater_equal, on_zero);
113 __ mov(ebx, eax); 146 __ mov(ebx, eax);
114 __ shr(ebx, 3); 147 __ shr(ebx, 3);
115 // TODO(lrn): Where is the bitmap stored? Pass the bitmap as argument instead. 148 // TODO(lrn): Where is the bitmap stored? Pass the bitmap as argument instead.
116 // __ mov(ecx, position_of_bitmap); 149 // __ mov(ecx, position_of_bitmap);
117 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0)); 150 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0));
118 __ and_(eax, (1<<3)-1); 151 __ and_(eax, (1<<3)-1);
119 __ bt(ebx, eax); 152 __ bt(Operand(ebx), eax);
120 __ j(greater_equal, on_zero); // Aka. jump on carry set. 153 __ j(carry, on_zero);
121 } 154 }
122 155
123 156
124 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, 157 void RegExpMacroAssemblerIA32::CheckCharacter(uc16 c, Label* on_equal) {
125 Label* on_end_of_input) { 158 __ cmp(edx, c);
126 UNREACHABLE(); // Not implemented. 159 BranchOrBacktrack(equal, on_equal);
160 }
161
162
163 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) {
164 __ cmp(edx, limit);
165 BranchOrBacktrack(greater, on_greater);
127 } 166 }
128 167
129 168
130 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { 169 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) {
131 UNREACHABLE(); // Not implemented. 170 __ cmp(edx, limit);
171 BranchOrBacktrack(less, on_less);
132 } 172 }
133 173
134 174
135 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { 175 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str,
136 UNREACHABLE(); // Not implemented. 176 int cp_offset,
137 } 177 Label* on_failure) {
178 int byte_length = str.length() * char_size();
179 int start_offset = cp_offset * char_size();
180 __ mov(ebx, edi);
181 __ add(Operand(ebx), Immediate(start_offset + byte_length));
182 BranchOrBacktrack(greater_equal, on_failure);
138 183
139 184 ArraySlice constant_buffer = constants_.GetBuffer(str.length(), char_size());
140 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<uc16> str, 185 for (int i = 0; i < str.length(); i++) {
141 Label* on_failure) { 186 if (mode_ == ASCII) {
142 if (sizeof(SubjectChar) == 1) { 187 constant_buffer.at<char>(i) = static_cast<char>(str[i]);
143 for (int i = 0; i < str.length(); i++) { 188 } else {
144 if (str[i] > String::kMaxAsciiCharCode) { 189 constant_buffer.at<uc16>(i) = str[i];
145 __ jmp(on_failure);
146 return;
147 }
148 } 190 }
149 } 191 }
150 int byte_length = str.length() * sizeof(SubjectChar);
151 __ mov(ebx, edi);
152 __ add(ebx, byte_length);
153 __ cmp(ebx, esi);
154 BranchOrBacktrack(greater_equal, on_failure);
155 192
156 if (str.length() <= kMaxInlineStringTests || ignore_case()) { 193 __ mov(eax, edi);
157 // TODO(lrn): make loop if str.length is large but ignore_case is true; 194 __ mov(ebx, esi);
158 for (int i = 0; i < str.length(); i++) { 195 __ lea(edi, Operand(esi, edi, times_1, start_offset));
159 ReadChar(eax, i); 196 LoadConstantBufferAddress(esi, &constant_buffer);
160 if (ignore_case()) { 197 __ mov(ecx, str.length());
161 Canonicalize(eax); 198 if (mode_ == ASCII) {
162 } 199 __ rep_cmpsb();
163 __ cmp(eax, str[i]);
164 BranchOrBacktrack(not_equal, on_failure);
165 }
166 add(edi, byte_length);
167 } else { 200 } else {
168 int offset; 201 ASSERT(mode_ == UC16);
169 ArraySlice<SubjectChar> constant_buffer = 202 __ rep_cmpsw();
170 constants_.GetBuffer<SubjectChar>(str.length());
171 for (int i = 0; i < str.length(); i++) {
172 constant_buffer[i] = str[i];
173 }
174 __ mov(ebx, esi);
175 LoadConstantBufferAddress(esi, constant_buffer);
176 __ mov(ecx, str.length());
177 if (sizeof(SubjectChar) == 1) {
178 __ rep_cmpsb();
179 } else {
180 ASSERT(sizeof(SubjectChar) == 2);
181 __ rep_cmpsw();
182 }
183 __ mov(esi, ebx);
184 BranchOrBacktrack(not_equal, on_failure);
185 } 203 }
186 }; 204 __ mov(esi, ebx);
205 __ mov(edi, eax);
206 BranchOrBacktrack(not_equal, on_failure);
207 }
187 208
188 209
189 void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index, 210 void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index,
190 Label* on_equal) { 211 Label* on_equal) {
191 __ cmp(register_location(register_index), edi); 212 __ cmp(edi, register_location(register_index));
192 BranchOrBacktrack(equal, on_equal); 213 BranchOrBacktrack(equal, on_equal);
193 } 214 }
194 215
195 216
217 void RegExpMacroAssemblerIA32::CheckNotCharacter(uc16 c, Label* on_not_equal) {
218 __ cmp(edx, c);
219 BranchOrBacktrack(not_equal, on_not_equal);
220 }
221
222
196 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap( 223 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
197 uc16 start, 224 uc16 start,
198 Label* half_nibble_map, 225 Label* half_nibble_map,
199 const Vector<Label*>& destinations) { 226 const Vector<Label*>& destinations) {
227 ReadCurrentChar(eax);
228 __ sub(Operand(eax), Immediate(start));
200 229
201 if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) { 230 __ mov(ecx, eax);
202 return;
203 }
204
205 Label fallthrough;
206
207 ReadCurrentChar(eax);
208 __ sub(eax, start);
209 __ cmp(eax, 64); // FIXME: 64 = size of map in bytes. Found somehow??
210 __ j(greater_equal, &fallthrough);
211
212 __ mov(ebx, eax);
213 __ shr(eax, 2); 231 __ shr(eax, 2);
214 __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx holds address of map 232 // FIXME: ecx must hold address of map
233 __ movzx_b(eax, Operand(ecx, eax, times_1, 0));
215 Label got_nybble; 234 Label got_nybble;
216 Label high_bits; 235 Label high_bits;
217 __ and_(ebx, 0x03); 236 __ and_(ecx, 0x03);
218 __ shr(eax, ebx); 237 __ add(ecx, Operand(ecx));
238 __ shr(eax); // Shift right cl times
219 239
220 Label second_bit_set, case_3, case_1; 240 Label second_bit_set, case_3, case_1;
221 __ test(eax, 2); 241 __ test(eax, Immediate(0x02));
222 __ j(not_equal, &second_bit_set); 242 __ j(not_zero, &second_bit_set);
223 __ test(eax, 1); 243 __ test(eax, Immediate(0x01));
224 __ j(not_equal, &case_1); 244 __ j(not_zero, &case_1);
225 // Case 0: 245 // Case 0:
226 __ jmp(&destinations[0]); 246 __ jmp(destinations[0]);
227 __ bind(&case_1); 247 __ bind(&case_1);
228 // Case 1: 248 // Case 1:
229 __ jmp(&destinations[1]); 249 __ jmp(destinations[1]);
230 __ bind(&second_bit_set); 250 __ bind(&second_bit_set);
231 __ test(eax, 1); 251 __ test(eax, Immediate(0x01));
232 __ j(not_equal, &case_3); 252 __ j(not_zero, &case_3);
233 // Case 2 253 // Case 2
234 __ jmp(&destinations[2]); 254 __ jmp(destinations[2]);
235 __ bind(&case_3); 255 __ bind(&case_3);
236 // Case 3: 256 // Case 3:
237 __ jmp(&destinations[3]); 257 __ jmp(destinations[3]);
238
239 __ bind(&fallthrough);
240 } 258 }
241 259
242 260
243 void RegExpMacroAssemblerIA32::DispatchByteMap( 261 void RegExpMacroAssemblerIA32::DispatchByteMap(
244 uc16 start, 262 uc16 start,
245 Label* byte_map, 263 Label* byte_map,
246 const Vector<Label*>& destinations) { 264 const Vector<Label*>& destinations) {
247 265
248 if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
249 return;
250 }
251
252 Label fallthrough; 266 Label fallthrough;
253 267
254 ReadCurrentChar(eax); 268 ReadCurrentChar(eax);
255 __ sub(eax, start); 269 __ sub(Operand(eax), Immediate(start));
256 __ cmp(eax, 64); // FIXME: 64 = size of map. Found somehow?? 270 __ cmp(eax, 64); // FIXME: 64 = size of map. Found somehow??
257 __ j(greater_equal, &fallthrough); 271 __ j(greater_equal, &fallthrough);
258 272 // FIXME: ecx must hold address of map
259 __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx must hold address of map 273 __ movzx_b(eax, Operand(ecx, eax, times_1, 0));
260 // jump table: jump to destinations[eax]; 274 // jump table: jump to destinations[eax];
261 275
262 __ bind(&fallthrough); 276 __ bind(&fallthrough);
263 } 277 }
264 278
279
280
265 void RegExpMacroAssemblerIA32::DispatchHighByteMap( 281 void RegExpMacroAssemblerIA32::DispatchHighByteMap(
266 byte start, 282 byte start,
267 Label* byte_map, 283 Label* byte_map,
268 const Vector<Label*>& destinations) { 284 const Vector<Label*>& destinations) {
269 Label fallthrough; 285 Label fallthrough;
270 ReadCurrentChar(eax); 286 ReadCurrentChar(eax);
271 __ shr(eax, 8); 287 __ shr(eax, 8);
272 __ sub(eax, start); 288 __ sub(Operand(eax), Immediate(start));
273 __ cmp(eax, destinations.length() - start); 289 __ cmp(eax, destinations.length() - start);
274 __ j(greater_equal, &fallthrough); 290 __ j(greater_equal, &fallthrough);
275 291
276 // TODO(lrn) jumptable: jump to destinations[eax] 292 // TODO(lrn) jumptable: jump to destinations[eax]
277 __ bind(&fallthrough); 293 __ bind(&fallthrough);
278 } 294 }
279 295
280 296
281 void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) { 297 void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
282 UNREACHABLE(); // Has no use. 298 UNREACHABLE(); // Has no use.
283 } 299 }
284 300
285 301
286 void RegExpMacroAssemblerIA32::Fail() { 302 void RegExpMacroAssemblerIA32::Fail() {
287 Exit(false); 303 __ mov(eax, 0);
288 } 304 __ jmp(&exit_label_);
289
290 Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
291 // something
292 return Handle();
293 } 305 }
294 306
295 307
308 Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
309 // Finalize code - write the entry point code now we know how many
310 // registers we need.
311
312 // Entry code:
313 __ bind(&entry_label_);
314 __ push(esi);
315 __ push(edi);
316 __ enter(Immediate(num_registers_ * sizeof(uint32_t)));
317 __ mov(esi, Operand(ebp, kInputEndOffset));
318 __ mov(edi, Operand(ebp, kInputStartOffset));
319 __ sub(edi, Operand(esi));
320 __ mov(edx, Operand(ebp, kInputBuffer));
321 __ mov(edx, Operand(edx, 0));
322 __ add(esi, Operand(edx));
323 __ jmp(&start_label_);
324
325 // Exit code:
326 __ bind(&success_label_);
327 __ mov(ebx, Operand(ebp, kRegisterOutput));
328 __ mov(ecx, Operand(ebp, kInputEndOffset));
329 __ sub(ecx, Operand(ebp, kInputStartOffset));
330 for (int i = 0; i < num_saved_registers_; i++) {
331 __ mov(eax, register_location(i));
332 __ sub(eax, Operand(ecx)); // Convert to index from start, not end.
333 __ mov(Operand(ebx, i * sizeof(int32_t)), eax);
334 }
335 // copy captures to output
336 __ mov(eax, Immediate(1));
337
338 __ bind(&exit_label_);
339 __ leave();
340 __ pop(edi);
341 __ pop(esi);
342 __ ret(0);
343
344 CodeDesc code_desc;
345 masm_->GetCode(&code_desc);
346 Handle<Code> code = Factory::NewCode(code_desc,
347 NULL,
Erik Corry 2008/11/21 13:03:04 Indentation!
Lasse Reichstein 2008/11/24 08:32:33 Done.
348 Code::ComputeFlags(Code::REGEXP));
349 LOG(CodeCreateEvent("RegExp", *code, "(Compiled RegExp)"));
350 return Handle<Object>::cast(code);
351 }
352
353
296 void RegExpMacroAssemblerIA32::GoTo(Label* to) { 354 void RegExpMacroAssemblerIA32::GoTo(Label* to) {
297 __ jmp(to); 355 __ jmp(to);
298 } 356 }
299 357
300 358
359
301 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg, 360 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
302 int comparand, 361 int comparand,
303 Label* if_ge) { 362 Label* if_ge) {
304 __ cmp(register_location(reg), comparand); 363 __ cmp(register_location(reg), Immediate(comparand));
305 BranchOrBacktrack(greater_equal, if_ge); 364 BranchOrBacktrack(greater_equal, if_ge);
306 } 365 }
307 366
308 367
368
309 void RegExpMacroAssemblerIA32::IfRegisterLT(int reg, 369 void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
310 int comparand, 370 int comparand,
311 Label* if_lt) { 371 Label* if_lt) {
312 __ cmp(register_location(reg), comparand); 372 __ cmp(register_location(reg), Immediate(comparand));
313 BranchOrBacktrack(less, if_lt); 373 BranchOrBacktrack(less, if_lt);
314 } 374 }
315 375
316 376
317 Re2kImplementation RegExpMacroAssemblerIA32::Implementation() { 377
378 RegExpMacroAssembler::Re2kImplementation
379 RegExpMacroAssemblerIA32::Implementation() {
318 return kIA32Implementation; 380 return kIA32Implementation;
319 } 381 }
320 382
321 383
384
385 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
386 Label* on_end_of_input) {
387 ASSERT(cp_offset >= 0);
388 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
389 __ cmp(edi, -cp_offset);
390 BranchOrBacktrack(less_equal, on_end_of_input);
391 ReadChar(edx, cp_offset);
392 }
393
394
322 void RegExpMacroAssemblerIA32::PopCurrentPosition() { 395 void RegExpMacroAssemblerIA32::PopCurrentPosition() {
323 __ pop(edi); 396 __ pop(edi);
324 ReadChar(edx, 0);
325 } 397 }
326 398
327 399
328 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { 400 void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
401 RecordRegister(register_index);
329 __ pop(register_location(register_index)); 402 __ pop(register_location(register_index));
330 } 403 }
331 404
332 405
333 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) { 406 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) {
407 // Check for preemption first.
408 Label no_preempt;
409 Label retry_preempt;
410 // Check for preemption.
411 ExternalReference stack_limit =
412 ExternalReference::address_of_stack_guard_limit();
413 __ cmp(esp, Operand::StaticVariable(stack_limit));
414 __ j(above, &no_preempt);
Erik Corry 2008/11/21 13:03:04 We don't have to fix this now, but this needs movi
415
416 __ push(edi); // Current position.
417 __ push(edx); // Current character.
418 // Restore original edi, esi.
419 __ mov(edi, Operand(ebp, kBackup_edi));
420 __ mov(esi, Operand(ebp, kBackup_esi));
421
422 __ bind(&retry_preempt);
423 // simulate stack for Runtime call.
424 __ push(0); // Dummy receiver
425 __ CallRuntime(Runtime::kStackGuard, 0);
426 __ cmp(esp, Operand::StaticVariable(stack_limit));
427 __ j(below_equal, &retry_preempt);
428
429 __ pop(edx);
430 __ pop(edi);
431 __ mov(esi, Operand(ebp, kInputBuffer));
432 __ mov(esi, Operand(esi, 0));
433 __ add(esi, Operand(ebp, kInputEndOffset));
434
435 __ bind(&no_preempt);
436
334 Label cont; 437 Label cont;
335 __ call(&cont); 438 __ push(label);
336 __ jmp(label);
337 __ bind(&cont);
338 } 439 }
339 440
340 441
341 void RegExpMacroAssemblerIA32::PushCurrentPosition() { 442 void RegExpMacroAssemblerIA32::PushCurrentPosition() {
342 __ push(edi); 443 __ push(edi);
343 } 444 }
344 445
345 446
346 void RegExpMacroAssemblerIA32::PushRegister(int register_index) { 447 void RegExpMacroAssemblerIA32::PushRegister(int register_index) {
347 __ push(register_location(register_index)); 448 __ push(register_location(register_index));
348 } 449 }
349 450
350 451
452 void RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(int reg) {
453 __ mov(edi, register_location(reg));
454 }
455
456
457 void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) {
458 __ mov(esp, register_location(reg));
459 }
460
461
351 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) { 462 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
352 __ mov(register_location(register_index), to); 463 RecordRegister(register_index);
464 __ mov(register_location(register_index), Immediate(to));
353 } 465 }
354 466
355 467
356 void RegExpMacroAssemblerIA32::Succeed() { 468 void RegExpMacroAssemblerIA32::Succeed() {
357 Exit(true); 469 __ jmp(&success_label_);
Erik Corry 2008/11/21 13:03:04 Do we need to set eax here?
Lasse Reichstein 2008/11/24 08:32:33 No. The code at success_lable_ sets eax and runs i
358 } 470 }
359 471
360 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister() { 472
473 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(
474 int register_index) {
361 __ mov(register_location(register_index), edi); 475 __ mov(register_location(register_index), edi);
362 } 476 }
363 477
364 // Custom : 478 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
365 479 __ mov(register_location(reg), esp);
366 void RegExpMacroAssemblerIA32::Initialize(int num_registers, bool ignore_case) {
367 num_registers_ = num_registers;
368 ignore_case_ = ignore_case;
369 __ enter(num_registers * sizeof(uint32_t));
370 } 480 }
371 481
372 482
373 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { 483 // Private methods:
484
485 Operand RegExpMacroAssemblerIA32::register_location(
486 int register_index) {
374 ASSERT(register_index < (1<<30)); 487 ASSERT(register_index < (1<<30));
375 return Operand(ebp, -((register_index + 1) * sizeof(uint32_t))); 488 return Operand(ebp, -((register_index + 1) * sizeof(uint32_t)));
376 } 489 }
377 490
378 491
492 size_t RegExpMacroAssemblerIA32::char_size() {
493 return static_cast<size_t>(mode_);
494 }
495
496
379 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, 497 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
380 Label* to) { 498 Label* to) {
381 if (condition < 0) { // No condition 499 if (condition < 0) { // No condition
382 if (to == NULL) { 500 if (to == NULL) {
383 Backtrack(); 501 Backtrack();
384 return; 502 return;
385 } 503 }
386 __ jmp(to); 504 __ jmp(to);
387 return; 505 return;
388 } else if (to == NULL) { 506 } else if (to == NULL) {
389 Label skip; 507 Label skip;
390 __ j(NegateCondition(condition), &skip); 508 __ j(NegateCondition(condition), &skip);
391 Backtrack(); 509 Backtrack();
392 __ bind(&skip); 510 __ bind(&skip);
393 return; 511 return;
394 } 512 }
395 __ j(condition, to); 513 __ j(condition, to);
396 } 514 }
397 515
398 516
399 void RegExpMacroAssemblerIA32::Canonicalize(Register reg) { 517 void RegExpMacroAssemblerIA32::Canonicalize(Register reg) {
400 if (sizeof(SubjectChar) == 1) { 518 if (mode_ == ASCII) {
401 Label end; 519 Label end;
402 __ cmp(reg, 'a'); 520 __ cmp(Operand(reg), Immediate('a'));
403 __ j(below, &end); 521 __ j(below, &end);
404 __ cmp(reg, 'z'); 522 __ cmp(Operand(reg), Immediate('z'));
405 __ j(above, &end); 523 __ j(above, &end);
406 __ sub(reg, 'a' - 'A'); 524 __ sub(Operand(reg), Immediate('a' - 'A'));
407 __ bind(&end); 525 __ bind(&end);
408 return; 526 return;
409 } 527 }
410 ASSERT(sizeof(SubjectChar) == 2); 528 ASSERT(mode_ == UC16);
411 // TODO(lrn): Use some tables. 529 // TODO(lrn): Use some tables.
412 } 530 }
413 531
414 532
415 void RegExpMacroAssemblerIA32::Exit(bool success) { 533 void RegExpMacroAssemblerIA32::RecordRegister(int register_index) {
416 if (success) { 534 if (register_index >= num_registers_) {
417 // Copy captures to output capture array. 535 num_registers_ = register_index + 1;
418 } 536 }
419 __ leave();
420 __ mov(eax, success ? 1 : 0);
421 __ ret();
422 } 537 }
423 538
424 539
425 void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) { 540 void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) {
426 if (sizeof(SubjectChar) == 1) { 541 if (mode_ == ASCII) {
427 __ movzx_b(destination, Operand(edi, offset)); 542 __ movzx_b(destination, Operand(esi, edi, times_1, offset));
428 return; 543 return;
429 } 544 }
430 ASSERT(sizeof(SubjectChar) == 2); 545 ASSERT(mode_ == UC16);
431 __ movzx_w(destination, Operand(edi, offset * 2)); 546 __ movzx_w(destination, Operand(esi, edi, times_1, offset * 2));
432 } 547 }
433 548
434 549
435 void RegExpMacroAssemblerIA32::ReadCurrentChar(Register destination) { 550 void RegExpMacroAssemblerIA32::ReadCurrentChar(Register destination) {
436 mov(destination, edx); 551 __ mov(destination, edx);
437 } 552 }
438 553
439 554
440 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress( 555 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg,
441 Register reg, ArraySlice<T>* buffer) { 556 ArraySlice* buffer) {
442 __ mov(reg, buffer->array()); 557 __ mov(reg, buffer->array());
443 __ add(reg, buffer->base_offset()); 558 __ add(Operand(reg), Immediate(buffer->base_offset()));
444 } 559 }
445 560
446 #undef __ 561 #undef __
447 }} 562 }}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698