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

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

Issue 371923006: Add mips64 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « src/mips64/regexp-macro-assembler-mips64.h ('k') | src/mips64/simulator-mips64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_MIPS 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/log.h" 10 #include "src/log.h"
11 #include "src/macro-assembler.h" 11 #include "src/macro-assembler.h"
12 #include "src/regexp-macro-assembler.h" 12 #include "src/regexp-macro-assembler.h"
13 #include "src/regexp-stack.h" 13 #include "src/regexp-stack.h"
14 #include "src/unicode.h" 14 #include "src/unicode.h"
15 15
16 #include "src/mips/regexp-macro-assembler-mips.h" 16 #include "src/mips64/regexp-macro-assembler-mips64.h"
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 20
21 #ifndef V8_INTERPRETED_REGEXP 21 #ifndef V8_INTERPRETED_REGEXP
22 /* 22 /*
23 * This assembler uses the following register assignment convention 23 * This assembler uses the following register assignment convention
24 * - t7 : Temporarily stores the index of capture start after a matching pass 24 * - t3 : Temporarily stores the index of capture start after a matching pass
25 * for a global regexp. 25 * for a global regexp.
26 * - t1 : Pointer to current code object (Code*) including heap object tag. 26 * - a5 : Pointer to current code object (Code*) including heap object tag.
27 * - t2 : Current position in input, as negative offset from end of string. 27 * - a6 : Current position in input, as negative offset from end of string.
28 * Please notice that this is the byte offset, not the character offset! 28 * Please notice that this is the byte offset, not the character offset!
29 * - t3 : Currently loaded character. Must be loaded using 29 * - a7 : Currently loaded character. Must be loaded using
30 * LoadCurrentCharacter before using any of the dispatch methods. 30 * LoadCurrentCharacter before using any of the dispatch methods.
31 * - t4 : Points to tip of backtrack stack 31 * - t0 : Points to tip of backtrack stack
32 * - t5 : Unused. 32 * - t1 : Unused.
33 * - t6 : End of input (points to byte after last character in input). 33 * - t2 : End of input (points to byte after last character in input).
34 * - fp : Frame pointer. Used to access arguments, local variables and 34 * - fp : Frame pointer. Used to access arguments, local variables and
35 * RegExp registers. 35 * RegExp registers.
36 * - sp : Points to tip of C stack. 36 * - sp : Points to tip of C stack.
37 * 37 *
38 * The remaining registers are free for computations. 38 * The remaining registers are free for computations.
39 * Each call to a public method should retain this convention. 39 * Each call to a public method should retain this convention.
40 * 40 *
41 * The stack will have the following structure: 41 * TODO(plind): O32 documented here with intent of having single 32/64 codebase
42 * in the future.
42 * 43 *
43 * - fp[64] Isolate* isolate (address of the current isolate) 44 * The O32 stack will have the following structure:
44 * - fp[60] direct_call (if 1, direct call from JavaScript code, 45 *
46 * - fp[76] Isolate* isolate (address of the current isolate)
47 * - fp[72] direct_call (if 1, direct call from JavaScript code,
45 * if 0, call through the runtime system). 48 * if 0, call through the runtime system).
46 * - fp[56] stack_area_base (High end of the memory area to use as 49 * - fp[68] stack_area_base (High end of the memory area to use as
47 * backtracking stack). 50 * backtracking stack).
48 * - fp[52] capture array size (may fit multiple sets of matches) 51 * - fp[64] capture array size (may fit multiple sets of matches)
49 * - fp[48] int* capture_array (int[num_saved_registers_], for output). 52 * - fp[60] int* capture_array (int[num_saved_registers_], for output).
50 * - fp[44] secondary link/return address used by native call. 53 * - fp[44..59] MIPS O32 four argument slots
54 * - fp[40] secondary link/return address used by native call.
51 * --- sp when called --- 55 * --- sp when called ---
52 * - fp[40] return address (lr). 56 * - fp[36] return address (lr).
53 * - fp[36] old frame pointer (r11). 57 * - fp[32] old frame pointer (r11).
54 * - fp[0..32] backup of registers s0..s7. 58 * - fp[0..31] backup of registers s0..s7.
55 * --- frame pointer ---- 59 * --- frame pointer ----
56 * - fp[-4] end of input (address of end of string). 60 * - fp[-4] end of input (address of end of string).
57 * - fp[-8] start of input (address of first character in string). 61 * - fp[-8] start of input (address of first character in string).
58 * - fp[-12] start index (character index of start). 62 * - fp[-12] start index (character index of start).
59 * - fp[-16] void* input_string (location of a handle containing the string). 63 * - fp[-16] void* input_string (location of a handle containing the string).
60 * - fp[-20] success counter (only for global regexps to count matches). 64 * - fp[-20] success counter (only for global regexps to count matches).
61 * - fp[-24] Offset of location before start of input (effectively character 65 * - fp[-24] Offset of location before start of input (effectively character
62 * position -1). Used to initialize capture registers to a 66 * position -1). Used to initialize capture registers to a
63 * non-position. 67 * non-position.
64 * - fp[-28] At start (if 1, we are starting at the start of the 68 * - fp[-28] At start (if 1, we are starting at the start of the
65 * string, otherwise 0) 69 * string, otherwise 0)
66 * - fp[-32] register 0 (Only positions must be stored in the first 70 * - fp[-32] register 0 (Only positions must be stored in the first
67 * - register 1 num_saved_registers_ registers) 71 * - register 1 num_saved_registers_ registers)
68 * - ... 72 * - ...
69 * - register num_registers-1 73 * - register num_registers-1
70 * --- sp --- 74 * --- sp ---
71 * 75 *
76 *
77 * The N64 stack will have the following structure:
78 *
79 * - fp[88] Isolate* isolate (address of the current isolate) kIsolate
80 * - fp[80] secondary link/return address used by exit frame on native call. kSecondaryReturnAddress
81 kStackFrameHeader
82 * --- sp when called ---
83 * - fp[72] ra Return from RegExp code (ra). kReturnAddress
84 * - fp[64] s9, old-fp Old fp, callee saved(s9).
85 * - fp[0..63] s0..s7 Callee-saved registers s0..s7.
86 * --- frame pointer ----
87 * - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall
88 * - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd
89 * - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters
90 * - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
91 * - fp[-40] end of input (address of end of string). kInputEnd
92 * - fp[-48] start of input (address of first character in string). kInputStart
93 * - fp[-56] start index (character index of start). kStartIndex
94 * - fp[-64] void* input_string (location of a handle containing the string). kInputString
95 * - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures
96 * - fp[-80] Offset of location before start of input (effectively character kInputStartMinusOne
97 * position -1). Used to initialize capture registers to a
98 * non-position.
99 * --------- The following output registers are 32-bit values. ---------
100 * - fp[-88] register 0 (Only positions must be stored in the first kRegisterZero
101 * - register 1 num_saved_registers_ registers)
102 * - ...
103 * - register num_registers-1
104 * --- sp ---
105 *
72 * The first num_saved_registers_ registers are initialized to point to 106 * The first num_saved_registers_ registers are initialized to point to
73 * "character -1" in the string (i.e., char_size() bytes before the first 107 * "character -1" in the string (i.e., char_size() bytes before the first
74 * character of the string). The remaining registers start out as garbage. 108 * character of the string). The remaining registers start out as garbage.
75 * 109 *
76 * The data up to the return address must be placed there by the calling 110 * The data up to the return address must be placed there by the calling
77 * code and the remaining arguments are passed in registers, e.g. by calling the 111 * code and the remaining arguments are passed in registers, e.g. by calling the
78 * code entry as cast to a function with the signature: 112 * code entry as cast to a function with the signature:
79 * int (*match)(String* input_string, 113 * int (*match)(String* input_string,
80 * int start_index, 114 * int start_index,
81 * Address start, 115 * Address start,
82 * Address end, 116 * Address end,
83 * Address secondary_return_address, // Only used by native call. 117 * Address secondary_return_address, // Only used by native call.
84 * int* capture_output_array, 118 * int* capture_output_array,
85 * byte* stack_area_base, 119 * byte* stack_area_base,
86 * bool direct_call = false) 120 * bool direct_call = false,
121 * void* return_address,
122 * Isolate* isolate);
87 * The call is performed by NativeRegExpMacroAssembler::Execute() 123 * The call is performed by NativeRegExpMacroAssembler::Execute()
88 * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro 124 * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
89 * in mips/simulator-mips.h. 125 * in mips/simulator-mips.h.
90 * When calling as a non-direct call (i.e., from C++ code), the return address 126 * When calling as a non-direct call (i.e., from C++ code), the return address
91 * area is overwritten with the ra register by the RegExp code. When doing a 127 * area is overwritten with the ra register by the RegExp code. When doing a
92 * direct call from generated code, the return address is placed there by 128 * direct call from generated code, the return address is placed there by
93 * the calling code, as in a normal exit frame. 129 * the calling code, as in a normal exit frame.
94 */ 130 */
95 131
96 #define __ ACCESS_MASM(masm_) 132 #define __ ACCESS_MASM(masm_)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 171 }
136 172
137 173
138 int RegExpMacroAssemblerMIPS::stack_limit_slack() { 174 int RegExpMacroAssemblerMIPS::stack_limit_slack() {
139 return RegExpStack::kStackLimitSlack; 175 return RegExpStack::kStackLimitSlack;
140 } 176 }
141 177
142 178
143 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { 179 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) {
144 if (by != 0) { 180 if (by != 0) {
145 __ Addu(current_input_offset(), 181 __ Daddu(current_input_offset(),
146 current_input_offset(), Operand(by * char_size())); 182 current_input_offset(), Operand(by * char_size()));
147 } 183 }
148 } 184 }
149 185
150 186
151 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { 187 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) {
152 ASSERT(reg >= 0); 188 ASSERT(reg >= 0);
153 ASSERT(reg < num_registers_); 189 ASSERT(reg < num_registers_);
154 if (by != 0) { 190 if (by != 0) {
155 __ lw(a0, register_location(reg)); 191 __ ld(a0, register_location(reg));
156 __ Addu(a0, a0, Operand(by)); 192 __ Daddu(a0, a0, Operand(by));
157 __ sw(a0, register_location(reg)); 193 __ sd(a0, register_location(reg));
158 } 194 }
159 } 195 }
160 196
161 197
162 void RegExpMacroAssemblerMIPS::Backtrack() { 198 void RegExpMacroAssemblerMIPS::Backtrack() {
163 CheckPreemption(); 199 CheckPreemption();
164 // Pop Code* offset from backtrack stack, add Code* and jump to location. 200 // Pop Code* offset from backtrack stack, add Code* and jump to location.
165 Pop(a0); 201 Pop(a0);
166 __ Addu(a0, a0, code_pointer()); 202 __ Daddu(a0, a0, code_pointer());
167 __ Jump(a0); 203 __ Jump(a0);
168 } 204 }
169 205
170 206
171 void RegExpMacroAssemblerMIPS::Bind(Label* label) { 207 void RegExpMacroAssemblerMIPS::Bind(Label* label) {
172 __ bind(label); 208 __ bind(label);
173 } 209 }
174 210
175 211
176 void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { 212 void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) {
177 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); 213 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c));
178 } 214 }
179 215
180 216
181 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { 217 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
182 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); 218 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit));
183 } 219 }
184 220
185 221
186 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { 222 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
187 Label not_at_start; 223 Label not_at_start;
188 // Did we start the match at the start of the string at all? 224 // Did we start the match at the start of the string at all?
189 __ lw(a0, MemOperand(frame_pointer(), kStartIndex)); 225 __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
190 BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg)); 226 BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg));
191 227
192 // If we did, are we still at the start of the input? 228 // If we did, are we still at the start of the input?
193 __ lw(a1, MemOperand(frame_pointer(), kInputStart)); 229 __ ld(a1, MemOperand(frame_pointer(), kInputStart));
194 __ Addu(a0, end_of_input_address(), Operand(current_input_offset())); 230 __ Daddu(a0, end_of_input_address(), Operand(current_input_offset()));
195 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); 231 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1));
196 __ bind(&not_at_start); 232 __ bind(&not_at_start);
197 } 233 }
198 234
199 235
200 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) { 236 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
201 // Did we start the match at the start of the string at all? 237 // Did we start the match at the start of the string at all?
202 __ lw(a0, MemOperand(frame_pointer(), kStartIndex)); 238 __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
203 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg)); 239 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg));
204 // If we did, are we still at the start of the input? 240 // If we did, are we still at the start of the input?
205 __ lw(a1, MemOperand(frame_pointer(), kInputStart)); 241 __ ld(a1, MemOperand(frame_pointer(), kInputStart));
206 __ Addu(a0, end_of_input_address(), Operand(current_input_offset())); 242 __ Daddu(a0, end_of_input_address(), Operand(current_input_offset()));
207 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); 243 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1));
208 } 244 }
209 245
210 246
211 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { 247 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) {
212 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); 248 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit));
213 } 249 }
214 250
215 251
216 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { 252 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
217 Label backtrack_non_equal; 253 Label backtrack_non_equal;
218 __ lw(a0, MemOperand(backtrack_stackpointer(), 0)); 254 __ lw(a0, MemOperand(backtrack_stackpointer(), 0));
219 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); 255 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
220 __ Addu(backtrack_stackpointer(), 256 __ Daddu(backtrack_stackpointer(),
221 backtrack_stackpointer(), 257 backtrack_stackpointer(),
222 Operand(kPointerSize)); 258 Operand(kIntSize));
223 __ bind(&backtrack_non_equal); 259 __ bind(&backtrack_non_equal);
224 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); 260 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
225 } 261 }
226 262
227 263
228 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( 264 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
229 int start_reg, 265 int start_reg,
230 Label* on_no_match) { 266 Label* on_no_match) {
231 Label fallthrough; 267 Label fallthrough;
232 __ lw(a0, register_location(start_reg)); // Index of start of capture. 268 __ ld(a0, register_location(start_reg)); // Index of start of capture.
233 __ lw(a1, register_location(start_reg + 1)); // Index of end of capture. 269 __ ld(a1, register_location(start_reg + 1)); // Index of end of capture.
234 __ Subu(a1, a1, a0); // Length of capture. 270 __ Dsubu(a1, a1, a0); // Length of capture.
235 271
236 // If length is zero, either the capture is empty or it is not participating. 272 // If length is zero, either the capture is empty or it is not participating.
237 // In either case succeed immediately. 273 // In either case succeed immediately.
238 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 274 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
239 275
240 __ Addu(t5, a1, current_input_offset()); 276 __ Daddu(t1, a1, current_input_offset());
241 // Check that there are enough characters left in the input. 277 // Check that there are enough characters left in the input.
242 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 278 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
243 279
244 if (mode_ == ASCII) { 280 if (mode_ == ASCII) {
245 Label success; 281 Label success;
246 Label fail; 282 Label fail;
247 Label loop_check; 283 Label loop_check;
248 284
249 // a0 - offset of start of capture. 285 // a0 - offset of start of capture.
250 // a1 - length of capture. 286 // a1 - length of capture.
251 __ Addu(a0, a0, Operand(end_of_input_address())); 287 __ Daddu(a0, a0, Operand(end_of_input_address()));
252 __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 288 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
253 __ Addu(a1, a0, Operand(a1)); 289 __ Daddu(a1, a0, Operand(a1));
254 290
255 // a0 - Address of start of capture. 291 // a0 - Address of start of capture.
256 // a1 - Address of end of capture. 292 // a1 - Address of end of capture.
257 // a2 - Address of current input position. 293 // a2 - Address of current input position.
258 294
259 Label loop; 295 Label loop;
260 __ bind(&loop); 296 __ bind(&loop);
261 __ lbu(a3, MemOperand(a0, 0)); 297 __ lbu(a3, MemOperand(a0, 0));
262 __ addiu(a0, a0, char_size()); 298 __ daddiu(a0, a0, char_size());
263 __ lbu(t0, MemOperand(a2, 0)); 299 __ lbu(a4, MemOperand(a2, 0));
264 __ addiu(a2, a2, char_size()); 300 __ daddiu(a2, a2, char_size());
265 301
266 __ Branch(&loop_check, eq, t0, Operand(a3)); 302 __ Branch(&loop_check, eq, a4, Operand(a3));
267 303
268 // Mismatch, try case-insensitive match (converting letters to lower-case). 304 // Mismatch, try case-insensitive match (converting letters to lower-case).
269 __ Or(a3, a3, Operand(0x20)); // Convert capture character to lower-case. 305 __ Or(a3, a3, Operand(0x20)); // Convert capture character to lower-case.
270 __ Or(t0, t0, Operand(0x20)); // Also convert input character. 306 __ Or(a4, a4, Operand(0x20)); // Also convert input character.
271 __ Branch(&fail, ne, t0, Operand(a3)); 307 __ Branch(&fail, ne, a4, Operand(a3));
272 __ Subu(a3, a3, Operand('a')); 308 __ Dsubu(a3, a3, Operand('a'));
273 __ Branch(&loop_check, ls, a3, Operand('z' - 'a')); 309 __ Branch(&loop_check, ls, a3, Operand('z' - 'a'));
274 // Latin-1: Check for values in range [224,254] but not 247. 310 // Latin-1: Check for values in range [224,254] but not 247.
275 __ Subu(a3, a3, Operand(224 - 'a')); 311 __ Dsubu(a3, a3, Operand(224 - 'a'));
276 // Weren't Latin-1 letters. 312 // Weren't Latin-1 letters.
277 __ Branch(&fail, hi, a3, Operand(254 - 224)); 313 __ Branch(&fail, hi, a3, Operand(254 - 224));
278 // Check for 247. 314 // Check for 247.
279 __ Branch(&fail, eq, a3, Operand(247 - 224)); 315 __ Branch(&fail, eq, a3, Operand(247 - 224));
280 316
281 __ bind(&loop_check); 317 __ bind(&loop_check);
282 __ Branch(&loop, lt, a0, Operand(a1)); 318 __ Branch(&loop, lt, a0, Operand(a1));
283 __ jmp(&success); 319 __ jmp(&success);
284 320
285 __ bind(&fail); 321 __ bind(&fail);
286 GoTo(on_no_match); 322 GoTo(on_no_match);
287 323
288 __ bind(&success); 324 __ bind(&success);
289 // Compute new value of character position after the matched part. 325 // Compute new value of character position after the matched part.
290 __ Subu(current_input_offset(), a2, end_of_input_address()); 326 __ Dsubu(current_input_offset(), a2, end_of_input_address());
291 } else { 327 } else {
292 ASSERT(mode_ == UC16); 328 ASSERT(mode_ == UC16);
293 // Put regexp engine registers on stack. 329 // Put regexp engine registers on stack.
294 RegList regexp_registers_to_retain = current_input_offset().bit() | 330 RegList regexp_registers_to_retain = current_input_offset().bit() |
295 current_character().bit() | backtrack_stackpointer().bit(); 331 current_character().bit() | backtrack_stackpointer().bit();
296 __ MultiPush(regexp_registers_to_retain); 332 __ MultiPush(regexp_registers_to_retain);
297 333
298 int argument_count = 4; 334 int argument_count = 4;
299 __ PrepareCallCFunction(argument_count, a2); 335 __ PrepareCallCFunction(argument_count, a2);
300 336
301 // a0 - offset of start of capture. 337 // a0 - offset of start of capture.
302 // a1 - length of capture. 338 // a1 - length of capture.
303 339
304 // Put arguments into arguments registers. 340 // Put arguments into arguments registers.
305 // Parameters are 341 // Parameters are
306 // a0: Address byte_offset1 - Address captured substring's start. 342 // a0: Address byte_offset1 - Address captured substring's start.
307 // a1: Address byte_offset2 - Address of current character position. 343 // a1: Address byte_offset2 - Address of current character position.
308 // a2: size_t byte_length - length of capture in bytes(!). 344 // a2: size_t byte_length - length of capture in bytes(!).
309 // a3: Isolate* isolate. 345 // a3: Isolate* isolate.
310 346
311 // Address of start of capture. 347 // Address of start of capture.
312 __ Addu(a0, a0, Operand(end_of_input_address())); 348 __ Daddu(a0, a0, Operand(end_of_input_address()));
313 // Length of capture. 349 // Length of capture.
314 __ mov(a2, a1); 350 __ mov(a2, a1);
315 // Save length in callee-save register for use on return. 351 // Save length in callee-save register for use on return.
316 __ mov(s3, a1); 352 __ mov(s3, a1);
317 // Address of current input position. 353 // Address of current input position.
318 __ Addu(a1, current_input_offset(), Operand(end_of_input_address())); 354 __ Daddu(a1, current_input_offset(), Operand(end_of_input_address()));
319 // Isolate. 355 // Isolate.
320 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); 356 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
321 357
322 { 358 {
323 AllowExternalCallThatCantCauseGC scope(masm_); 359 AllowExternalCallThatCantCauseGC scope(masm_);
324 ExternalReference function = 360 ExternalReference function =
325 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); 361 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
326 __ CallCFunction(function, argument_count); 362 __ CallCFunction(function, argument_count);
327 } 363 }
328 364
329 // Restore regexp engine registers. 365 // Restore regexp engine registers.
330 __ MultiPop(regexp_registers_to_retain); 366 __ MultiPop(regexp_registers_to_retain);
331 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 367 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
332 __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 368 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
333 369
334 // Check if function returned non-zero for success or zero for failure. 370 // Check if function returned non-zero for success or zero for failure.
335 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); 371 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg));
336 // On success, increment position by length of capture. 372 // On success, increment position by length of capture.
337 __ Addu(current_input_offset(), current_input_offset(), Operand(s3)); 373 __ Daddu(current_input_offset(), current_input_offset(), Operand(s3));
338 } 374 }
339 375
340 __ bind(&fallthrough); 376 __ bind(&fallthrough);
341 } 377 }
342 378
343 379
344 void RegExpMacroAssemblerMIPS::CheckNotBackReference( 380 void RegExpMacroAssemblerMIPS::CheckNotBackReference(
345 int start_reg, 381 int start_reg,
346 Label* on_no_match) { 382 Label* on_no_match) {
347 Label fallthrough; 383 Label fallthrough;
348 Label success; 384 Label success;
349 385
350 // Find length of back-referenced capture. 386 // Find length of back-referenced capture.
351 __ lw(a0, register_location(start_reg)); 387 __ ld(a0, register_location(start_reg));
352 __ lw(a1, register_location(start_reg + 1)); 388 __ ld(a1, register_location(start_reg + 1));
353 __ Subu(a1, a1, a0); // Length to check. 389 __ Dsubu(a1, a1, a0); // Length to check.
354 // Succeed on empty capture (including no capture). 390 // Succeed on empty capture (including no capture).
355 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 391 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
356 392
357 __ Addu(t5, a1, current_input_offset()); 393 __ Daddu(t1, a1, current_input_offset());
358 // Check that there are enough characters left in the input. 394 // Check that there are enough characters left in the input.
359 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 395 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
360 396
361 // Compute pointers to match string and capture string. 397 // Compute pointers to match string and capture string.
362 __ Addu(a0, a0, Operand(end_of_input_address())); 398 __ Daddu(a0, a0, Operand(end_of_input_address()));
363 __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 399 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
364 __ Addu(a1, a1, Operand(a0)); 400 __ Daddu(a1, a1, Operand(a0));
365 401
366 Label loop; 402 Label loop;
367 __ bind(&loop); 403 __ bind(&loop);
368 if (mode_ == ASCII) { 404 if (mode_ == ASCII) {
369 __ lbu(a3, MemOperand(a0, 0)); 405 __ lbu(a3, MemOperand(a0, 0));
370 __ addiu(a0, a0, char_size()); 406 __ daddiu(a0, a0, char_size());
371 __ lbu(t0, MemOperand(a2, 0)); 407 __ lbu(a4, MemOperand(a2, 0));
372 __ addiu(a2, a2, char_size()); 408 __ daddiu(a2, a2, char_size());
373 } else { 409 } else {
374 ASSERT(mode_ == UC16); 410 ASSERT(mode_ == UC16);
375 __ lhu(a3, MemOperand(a0, 0)); 411 __ lhu(a3, MemOperand(a0, 0));
376 __ addiu(a0, a0, char_size()); 412 __ daddiu(a0, a0, char_size());
377 __ lhu(t0, MemOperand(a2, 0)); 413 __ lhu(a4, MemOperand(a2, 0));
378 __ addiu(a2, a2, char_size()); 414 __ daddiu(a2, a2, char_size());
379 } 415 }
380 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0)); 416 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4));
381 __ Branch(&loop, lt, a0, Operand(a1)); 417 __ Branch(&loop, lt, a0, Operand(a1));
382 418
383 // Move current character position to position after match. 419 // Move current character position to position after match.
384 __ Subu(current_input_offset(), a2, end_of_input_address()); 420 __ Dsubu(current_input_offset(), a2, end_of_input_address());
385 __ bind(&fallthrough); 421 __ bind(&fallthrough);
386 } 422 }
387 423
388 424
389 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 425 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
390 Label* on_not_equal) { 426 Label* on_not_equal) {
391 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 427 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
392 } 428 }
393 429
394 430
(...skipping 14 matching lines...) Expand all
409 BranchOrBacktrack(on_not_equal, ne, a0, rhs); 445 BranchOrBacktrack(on_not_equal, ne, a0, rhs);
410 } 446 }
411 447
412 448
413 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( 449 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd(
414 uc16 c, 450 uc16 c,
415 uc16 minus, 451 uc16 minus,
416 uc16 mask, 452 uc16 mask,
417 Label* on_not_equal) { 453 Label* on_not_equal) {
418 ASSERT(minus < String::kMaxUtf16CodeUnit); 454 ASSERT(minus < String::kMaxUtf16CodeUnit);
419 __ Subu(a0, current_character(), Operand(minus)); 455 __ Dsubu(a0, current_character(), Operand(minus));
420 __ And(a0, a0, Operand(mask)); 456 __ And(a0, a0, Operand(mask));
421 BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); 457 BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
422 } 458 }
423 459
424 460
425 void RegExpMacroAssemblerMIPS::CheckCharacterInRange( 461 void RegExpMacroAssemblerMIPS::CheckCharacterInRange(
426 uc16 from, 462 uc16 from,
427 uc16 to, 463 uc16 to,
428 Label* on_in_range) { 464 Label* on_in_range) {
429 __ Subu(a0, current_character(), Operand(from)); 465 __ Dsubu(a0, current_character(), Operand(from));
430 // Unsigned lower-or-same condition. 466 // Unsigned lower-or-same condition.
431 BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from)); 467 BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from));
432 } 468 }
433 469
434 470
435 void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange( 471 void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
436 uc16 from, 472 uc16 from,
437 uc16 to, 473 uc16 to,
438 Label* on_not_in_range) { 474 Label* on_not_in_range) {
439 __ Subu(a0, current_character(), Operand(from)); 475 __ Dsubu(a0, current_character(), Operand(from));
440 // Unsigned higher condition. 476 // Unsigned higher condition.
441 BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from)); 477 BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from));
442 } 478 }
443 479
444 480
445 void RegExpMacroAssemblerMIPS::CheckBitInTable( 481 void RegExpMacroAssemblerMIPS::CheckBitInTable(
446 Handle<ByteArray> table, 482 Handle<ByteArray> table,
447 Label* on_bit_set) { 483 Label* on_bit_set) {
448 __ li(a0, Operand(table)); 484 __ li(a0, Operand(table));
449 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { 485 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) {
450 __ And(a1, current_character(), Operand(kTableSize - 1)); 486 __ And(a1, current_character(), Operand(kTableSize - 1));
451 __ Addu(a0, a0, a1); 487 __ Daddu(a0, a0, a1);
452 } else { 488 } else {
453 __ Addu(a0, a0, current_character()); 489 __ Daddu(a0, a0, current_character());
454 } 490 }
455 491
456 __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize)); 492 __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize));
457 BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg)); 493 BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg));
458 } 494 }
459 495
460 496
461 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, 497 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type,
462 Label* on_no_match) { 498 Label* on_no_match) {
463 // Range checks (c in min..max) are generally implemented by an unsigned 499 // Range checks (c in min..max) are generally implemented by an unsigned
464 // (c - min) <= (max - min) check. 500 // (c - min) <= (max - min) check.
465 switch (type) { 501 switch (type) {
466 case 's': 502 case 's':
467 // Match space-characters. 503 // Match space-characters.
468 if (mode_ == ASCII) { 504 if (mode_ == ASCII) {
469 // One byte space characters are '\t'..'\r', ' ' and \u00a0. 505 // One byte space characters are '\t'..'\r', ' ' and \u00a0.
470 Label success; 506 Label success;
471 __ Branch(&success, eq, current_character(), Operand(' ')); 507 __ Branch(&success, eq, current_character(), Operand(' '));
472 // Check range 0x09..0x0d. 508 // Check range 0x09..0x0d.
473 __ Subu(a0, current_character(), Operand('\t')); 509 __ Dsubu(a0, current_character(), Operand('\t'));
474 __ Branch(&success, ls, a0, Operand('\r' - '\t')); 510 __ Branch(&success, ls, a0, Operand('\r' - '\t'));
475 // \u00a0 (NBSP). 511 // \u00a0 (NBSP).
476 BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00a0 - '\t')); 512 BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00a0 - '\t'));
477 __ bind(&success); 513 __ bind(&success);
478 return true; 514 return true;
479 } 515 }
480 return false; 516 return false;
481 case 'S': 517 case 'S':
482 // The emitted code for generic character classes is good enough. 518 // The emitted code for generic character classes is good enough.
483 return false; 519 return false;
484 case 'd': 520 case 'd':
485 // Match ASCII digits ('0'..'9'). 521 // Match ASCII digits ('0'..'9').
486 __ Subu(a0, current_character(), Operand('0')); 522 __ Dsubu(a0, current_character(), Operand('0'));
487 BranchOrBacktrack(on_no_match, hi, a0, Operand('9' - '0')); 523 BranchOrBacktrack(on_no_match, hi, a0, Operand('9' - '0'));
488 return true; 524 return true;
489 case 'D': 525 case 'D':
490 // Match non ASCII-digits. 526 // Match non ASCII-digits.
491 __ Subu(a0, current_character(), Operand('0')); 527 __ Dsubu(a0, current_character(), Operand('0'));
492 BranchOrBacktrack(on_no_match, ls, a0, Operand('9' - '0')); 528 BranchOrBacktrack(on_no_match, ls, a0, Operand('9' - '0'));
493 return true; 529 return true;
494 case '.': { 530 case '.': {
495 // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029). 531 // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029).
496 __ Xor(a0, current_character(), Operand(0x01)); 532 __ Xor(a0, current_character(), Operand(0x01));
497 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c. 533 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c.
498 __ Subu(a0, a0, Operand(0x0b)); 534 __ Dsubu(a0, a0, Operand(0x0b));
499 BranchOrBacktrack(on_no_match, ls, a0, Operand(0x0c - 0x0b)); 535 BranchOrBacktrack(on_no_match, ls, a0, Operand(0x0c - 0x0b));
500 if (mode_ == UC16) { 536 if (mode_ == UC16) {
501 // Compare original value to 0x2028 and 0x2029, using the already 537 // Compare original value to 0x2028 and 0x2029, using the already
502 // computed (current_char ^ 0x01 - 0x0b). I.e., check for 538 // computed (current_char ^ 0x01 - 0x0b). I.e., check for
503 // 0x201d (0x2028 - 0x0b) or 0x201e. 539 // 0x201d (0x2028 - 0x0b) or 0x201e.
504 __ Subu(a0, a0, Operand(0x2028 - 0x0b)); 540 __ Dsubu(a0, a0, Operand(0x2028 - 0x0b));
505 BranchOrBacktrack(on_no_match, ls, a0, Operand(1)); 541 BranchOrBacktrack(on_no_match, ls, a0, Operand(1));
506 } 542 }
507 return true; 543 return true;
508 } 544 }
509 case 'n': { 545 case 'n': {
510 // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029). 546 // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029).
511 __ Xor(a0, current_character(), Operand(0x01)); 547 __ Xor(a0, current_character(), Operand(0x01));
512 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c. 548 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c.
513 __ Subu(a0, a0, Operand(0x0b)); 549 __ Dsubu(a0, a0, Operand(0x0b));
514 if (mode_ == ASCII) { 550 if (mode_ == ASCII) {
515 BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0c - 0x0b)); 551 BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0c - 0x0b));
516 } else { 552 } else {
517 Label done; 553 Label done;
518 BranchOrBacktrack(&done, ls, a0, Operand(0x0c - 0x0b)); 554 BranchOrBacktrack(&done, ls, a0, Operand(0x0c - 0x0b));
519 // Compare original value to 0x2028 and 0x2029, using the already 555 // Compare original value to 0x2028 and 0x2029, using the already
520 // computed (current_char ^ 0x01 - 0x0b). I.e., check for 556 // computed (current_char ^ 0x01 - 0x0b). I.e., check for
521 // 0x201d (0x2028 - 0x0b) or 0x201e. 557 // 0x201d (0x2028 - 0x0b) or 0x201e.
522 __ Subu(a0, a0, Operand(0x2028 - 0x0b)); 558 __ Dsubu(a0, a0, Operand(0x2028 - 0x0b));
523 BranchOrBacktrack(on_no_match, hi, a0, Operand(1)); 559 BranchOrBacktrack(on_no_match, hi, a0, Operand(1));
524 __ bind(&done); 560 __ bind(&done);
525 } 561 }
526 return true; 562 return true;
527 } 563 }
528 case 'w': { 564 case 'w': {
529 if (mode_ != ASCII) { 565 if (mode_ != ASCII) {
530 // Table is 128 entries, so all ASCII characters can be tested. 566 // Table is 128 entries, so all ASCII characters can be tested.
531 BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z')); 567 BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z'));
532 } 568 }
533 ExternalReference map = ExternalReference::re_word_character_map(); 569 ExternalReference map = ExternalReference::re_word_character_map();
534 __ li(a0, Operand(map)); 570 __ li(a0, Operand(map));
535 __ Addu(a0, a0, current_character()); 571 __ Daddu(a0, a0, current_character());
536 __ lbu(a0, MemOperand(a0, 0)); 572 __ lbu(a0, MemOperand(a0, 0));
537 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg)); 573 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg));
538 return true; 574 return true;
539 } 575 }
540 case 'W': { 576 case 'W': {
541 Label done; 577 Label done;
542 if (mode_ != ASCII) { 578 if (mode_ != ASCII) {
543 // Table is 128 entries, so all ASCII characters can be tested. 579 // Table is 128 entries, so all ASCII characters can be tested.
544 __ Branch(&done, hi, current_character(), Operand('z')); 580 __ Branch(&done, hi, current_character(), Operand('z'));
545 } 581 }
546 ExternalReference map = ExternalReference::re_word_character_map(); 582 ExternalReference map = ExternalReference::re_word_character_map();
547 __ li(a0, Operand(map)); 583 __ li(a0, Operand(map));
548 __ Addu(a0, a0, current_character()); 584 __ Daddu(a0, a0, current_character());
549 __ lbu(a0, MemOperand(a0, 0)); 585 __ lbu(a0, MemOperand(a0, 0));
550 BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg)); 586 BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg));
551 if (mode_ != ASCII) { 587 if (mode_ != ASCII) {
552 __ bind(&done); 588 __ bind(&done);
553 } 589 }
554 return true; 590 return true;
555 } 591 }
556 case '*': 592 case '*':
557 // Match any character. 593 // Match any character.
558 return true; 594 return true;
(...skipping 27 matching lines...) Expand all
586 // Tell the system that we have a stack frame. Because the type is MANUAL, 622 // Tell the system that we have a stack frame. Because the type is MANUAL,
587 // no is generated. 623 // no is generated.
588 FrameScope scope(masm_, StackFrame::MANUAL); 624 FrameScope scope(masm_, StackFrame::MANUAL);
589 625
590 // Actually emit code to start a new stack frame. 626 // Actually emit code to start a new stack frame.
591 // Push arguments 627 // Push arguments
592 // Save callee-save registers. 628 // Save callee-save registers.
593 // Start new stack frame. 629 // Start new stack frame.
594 // Store link register in existing stack-cell. 630 // Store link register in existing stack-cell.
595 // Order here should correspond to order of offset constants in header file. 631 // Order here should correspond to order of offset constants in header file.
632 // TODO(plind): we save s0..s7, but ONLY use s3 here - use the regs
633 // or dont save.
596 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() | 634 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() |
597 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit(); 635 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit();
598 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 636 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
637
638 if (kMipsAbi == kN64) {
639 // TODO(plind): Should probably alias a4-a7, for clarity.
640 argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit();
641 }
642
599 __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 643 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
600 // Set frame pointer in space for it if this is not a direct call 644 // Set frame pointer in space for it if this is not a direct call
601 // from generated code. 645 // from generated code.
602 __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize)); 646 // TODO(plind): this 8 is the # of argument regs, should have definition.
647 __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize));
603 __ mov(a0, zero_reg); 648 __ mov(a0, zero_reg);
604 __ push(a0); // Make room for success counter and initialize it to 0. 649 __ push(a0); // Make room for success counter and initialize it to 0.
605 __ push(a0); // Make room for "position - 1" constant (value irrelevant). 650 __ push(a0); // Make room for "position - 1" constant (value irrelevant).
606 651
607 // Check if we have space on the stack for registers. 652 // Check if we have space on the stack for registers.
608 Label stack_limit_hit; 653 Label stack_limit_hit;
609 Label stack_ok; 654 Label stack_ok;
610 655
611 ExternalReference stack_limit = 656 ExternalReference stack_limit =
612 ExternalReference::address_of_stack_limit(masm_->isolate()); 657 ExternalReference::address_of_stack_limit(masm_->isolate());
613 __ li(a0, Operand(stack_limit)); 658 __ li(a0, Operand(stack_limit));
614 __ lw(a0, MemOperand(a0)); 659 __ ld(a0, MemOperand(a0));
615 __ Subu(a0, sp, a0); 660 __ Dsubu(a0, sp, a0);
616 // Handle it if the stack pointer is already below the stack limit. 661 // Handle it if the stack pointer is already below the stack limit.
617 __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); 662 __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg));
618 // Check if there is room for the variable number of registers above 663 // Check if there is room for the variable number of registers above
619 // the stack limit. 664 // the stack limit.
620 __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); 665 __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize));
621 // Exit with OutOfMemory exception. There is not enough space on the stack 666 // Exit with OutOfMemory exception. There is not enough space on the stack
622 // for our working registers. 667 // for our working registers.
623 __ li(v0, Operand(EXCEPTION)); 668 __ li(v0, Operand(EXCEPTION));
624 __ jmp(&return_v0); 669 __ jmp(&return_v0);
625 670
626 __ bind(&stack_limit_hit); 671 __ bind(&stack_limit_hit);
627 CallCheckStackGuardState(a0); 672 CallCheckStackGuardState(a0);
628 // If returned value is non-zero, we exit with the returned value as result. 673 // If returned value is non-zero, we exit with the returned value as result.
629 __ Branch(&return_v0, ne, v0, Operand(zero_reg)); 674 __ Branch(&return_v0, ne, v0, Operand(zero_reg));
630 675
631 __ bind(&stack_ok); 676 __ bind(&stack_ok);
632 // Allocate space on stack for registers. 677 // Allocate space on stack for registers.
633 __ Subu(sp, sp, Operand(num_registers_ * kPointerSize)); 678 __ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize));
634 // Load string end. 679 // Load string end.
635 __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 680 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
636 // Load input start. 681 // Load input start.
637 __ lw(a0, MemOperand(frame_pointer(), kInputStart)); 682 __ ld(a0, MemOperand(frame_pointer(), kInputStart));
638 // Find negative length (offset of start relative to end). 683 // Find negative length (offset of start relative to end).
639 __ Subu(current_input_offset(), a0, end_of_input_address()); 684 __ Dsubu(current_input_offset(), a0, end_of_input_address());
640 // Set a0 to address of char before start of the input string 685 // Set a0 to address of char before start of the input string
641 // (effectively string position -1). 686 // (effectively string position -1).
642 __ lw(a1, MemOperand(frame_pointer(), kStartIndex)); 687 __ ld(a1, MemOperand(frame_pointer(), kStartIndex));
643 __ Subu(a0, current_input_offset(), Operand(char_size())); 688 __ Dsubu(a0, current_input_offset(), Operand(char_size()));
644 __ sll(t5, a1, (mode_ == UC16) ? 1 : 0); 689 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0);
645 __ Subu(a0, a0, t5); 690 __ Dsubu(a0, a0, t1);
646 // Store this value in a local variable, for use when clearing 691 // Store this value in a local variable, for use when clearing
647 // position registers. 692 // position registers.
648 __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 693 __ sd(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
649 694
650 // Initialize code pointer register 695 // Initialize code pointer register
651 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 696 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
652 697
653 Label load_char_start_regexp, start_regexp; 698 Label load_char_start_regexp, start_regexp;
654 // Load newline if index is at start, previous character otherwise. 699 // Load newline if index is at start, previous character otherwise.
655 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 700 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
656 __ li(current_character(), Operand('\n')); 701 __ li(current_character(), Operand('\n'));
657 __ jmp(&start_regexp); 702 __ jmp(&start_regexp);
658 703
659 // Global regexp restarts matching here. 704 // Global regexp restarts matching here.
660 __ bind(&load_char_start_regexp); 705 __ bind(&load_char_start_regexp);
661 // Load previous char as initial value of current character register. 706 // Load previous char as initial value of current character register.
662 LoadCurrentCharacterUnchecked(-1, 1); 707 LoadCurrentCharacterUnchecked(-1, 1);
663 __ bind(&start_regexp); 708 __ bind(&start_regexp);
664 709
665 // Initialize on-stack registers. 710 // Initialize on-stack registers.
666 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. 711 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
667 // Fill saved registers with initial value = start offset - 1. 712 // Fill saved registers with initial value = start offset - 1.
668 if (num_saved_registers_ > 8) { 713 if (num_saved_registers_ > 8) {
669 // Address of register 0. 714 // Address of register 0.
670 __ Addu(a1, frame_pointer(), Operand(kRegisterZero)); 715 __ Daddu(a1, frame_pointer(), Operand(kRegisterZero));
671 __ li(a2, Operand(num_saved_registers_)); 716 __ li(a2, Operand(num_saved_registers_));
672 Label init_loop; 717 Label init_loop;
673 __ bind(&init_loop); 718 __ bind(&init_loop);
674 __ sw(a0, MemOperand(a1)); 719 __ sd(a0, MemOperand(a1));
675 __ Addu(a1, a1, Operand(-kPointerSize)); 720 __ Daddu(a1, a1, Operand(-kPointerSize));
676 __ Subu(a2, a2, Operand(1)); 721 __ Dsubu(a2, a2, Operand(1));
677 __ Branch(&init_loop, ne, a2, Operand(zero_reg)); 722 __ Branch(&init_loop, ne, a2, Operand(zero_reg));
678 } else { 723 } else {
679 for (int i = 0; i < num_saved_registers_; i++) { 724 for (int i = 0; i < num_saved_registers_; i++) {
680 __ sw(a0, register_location(i)); 725 __ sd(a0, register_location(i));
681 } 726 }
682 } 727 }
683 } 728 }
684 729
685 // Initialize backtrack stack pointer. 730 // Initialize backtrack stack pointer.
686 __ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); 731 __ ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
687 732
688 __ jmp(&start_label_); 733 __ jmp(&start_label_);
689 734
690 735
691 // Exit code: 736 // Exit code:
692 if (success_label_.is_linked()) { 737 if (success_label_.is_linked()) {
693 // Save captures when successful. 738 // Save captures when successful.
694 __ bind(&success_label_); 739 __ bind(&success_label_);
695 if (num_saved_registers_ > 0) { 740 if (num_saved_registers_ > 0) {
696 // Copy captures to output. 741 // Copy captures to output.
697 __ lw(a1, MemOperand(frame_pointer(), kInputStart)); 742 __ ld(a1, MemOperand(frame_pointer(), kInputStart));
698 __ lw(a0, MemOperand(frame_pointer(), kRegisterOutput)); 743 __ ld(a0, MemOperand(frame_pointer(), kRegisterOutput));
699 __ lw(a2, MemOperand(frame_pointer(), kStartIndex)); 744 __ ld(a2, MemOperand(frame_pointer(), kStartIndex));
700 __ Subu(a1, end_of_input_address(), a1); 745 __ Dsubu(a1, end_of_input_address(), a1);
701 // a1 is length of input in bytes. 746 // a1 is length of input in bytes.
702 if (mode_ == UC16) { 747 if (mode_ == UC16) {
703 __ srl(a1, a1, 1); 748 __ dsrl(a1, a1, 1);
704 } 749 }
705 // a1 is length of input in characters. 750 // a1 is length of input in characters.
706 __ Addu(a1, a1, Operand(a2)); 751 __ Daddu(a1, a1, Operand(a2));
707 // a1 is length of string in characters. 752 // a1 is length of string in characters.
708 753
709 ASSERT_EQ(0, num_saved_registers_ % 2); 754 ASSERT_EQ(0, num_saved_registers_ % 2);
710 // Always an even number of capture registers. This allows us to 755 // Always an even number of capture registers. This allows us to
711 // unroll the loop once to add an operation between a load of a register 756 // unroll the loop once to add an operation between a load of a register
712 // and the following use of that register. 757 // and the following use of that register.
713 for (int i = 0; i < num_saved_registers_; i += 2) { 758 for (int i = 0; i < num_saved_registers_; i += 2) {
714 __ lw(a2, register_location(i)); 759 __ ld(a2, register_location(i));
715 __ lw(a3, register_location(i + 1)); 760 __ ld(a3, register_location(i + 1));
716 if (i == 0 && global_with_zero_length_check()) { 761 if (i == 0 && global_with_zero_length_check()) {
717 // Keep capture start in a4 for the zero-length check later. 762 // Keep capture start in a4 for the zero-length check later.
718 __ mov(t7, a2); 763 __ mov(t3, a2);
719 } 764 }
720 if (mode_ == UC16) { 765 if (mode_ == UC16) {
721 __ sra(a2, a2, 1); 766 __ dsra(a2, a2, 1);
722 __ Addu(a2, a2, a1); 767 __ Daddu(a2, a2, a1);
723 __ sra(a3, a3, 1); 768 __ dsra(a3, a3, 1);
724 __ Addu(a3, a3, a1); 769 __ Daddu(a3, a3, a1);
725 } else { 770 } else {
726 __ Addu(a2, a1, Operand(a2)); 771 __ Daddu(a2, a1, Operand(a2));
727 __ Addu(a3, a1, Operand(a3)); 772 __ Daddu(a3, a1, Operand(a3));
728 } 773 }
774 // V8 expects the output to be an int32_t array.
729 __ sw(a2, MemOperand(a0)); 775 __ sw(a2, MemOperand(a0));
730 __ Addu(a0, a0, kPointerSize); 776 __ Daddu(a0, a0, kIntSize);
731 __ sw(a3, MemOperand(a0)); 777 __ sw(a3, MemOperand(a0));
732 __ Addu(a0, a0, kPointerSize); 778 __ Daddu(a0, a0, kIntSize);
733 } 779 }
734 } 780 }
735 781
736 if (global()) { 782 if (global()) {
737 // Restart matching if the regular expression is flagged as global. 783 // Restart matching if the regular expression is flagged as global.
738 __ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 784 __ ld(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
739 __ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 785 __ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
740 __ lw(a2, MemOperand(frame_pointer(), kRegisterOutput)); 786 __ ld(a2, MemOperand(frame_pointer(), kRegisterOutput));
741 // Increment success counter. 787 // Increment success counter.
742 __ Addu(a0, a0, 1); 788 __ Daddu(a0, a0, 1);
743 __ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 789 __ sd(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
744 // Capture results have been stored, so the number of remaining global 790 // Capture results have been stored, so the number of remaining global
745 // output registers is reduced by the number of stored captures. 791 // output registers is reduced by the number of stored captures.
746 __ Subu(a1, a1, num_saved_registers_); 792 __ Dsubu(a1, a1, num_saved_registers_);
747 // Check whether we have enough room for another set of capture results. 793 // Check whether we have enough room for another set of capture results.
748 __ mov(v0, a0); 794 __ mov(v0, a0);
749 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 795 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
750 796
751 __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 797 __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
752 // Advance the location for output. 798 // Advance the location for output.
753 __ Addu(a2, a2, num_saved_registers_ * kPointerSize); 799 __ Daddu(a2, a2, num_saved_registers_ * kIntSize);
754 __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput)); 800 __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
755 801
756 // Prepare a0 to initialize registers with its value in the next run. 802 // Prepare a0 to initialize registers with its value in the next run.
757 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 803 __ ld(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
758 804
759 if (global_with_zero_length_check()) { 805 if (global_with_zero_length_check()) {
760 // Special case for zero-length matches. 806 // Special case for zero-length matches.
761 // t7: capture start index 807 // t3: capture start index
762 // Not a zero-length match, restart. 808 // Not a zero-length match, restart.
763 __ Branch( 809 __ Branch(
764 &load_char_start_regexp, ne, current_input_offset(), Operand(t7)); 810 &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
765 // Offset from the end is zero if we already reached the end. 811 // Offset from the end is zero if we already reached the end.
766 __ Branch(&exit_label_, eq, current_input_offset(), 812 __ Branch(&exit_label_, eq, current_input_offset(),
767 Operand(zero_reg)); 813 Operand(zero_reg));
768 // Advance current position after a zero-length match. 814 // Advance current position after a zero-length match.
769 __ Addu(current_input_offset(), 815 __ Daddu(current_input_offset(),
770 current_input_offset(), 816 current_input_offset(),
771 Operand((mode_ == UC16) ? 2 : 1)); 817 Operand((mode_ == UC16) ? 2 : 1));
772 } 818 }
773 819
774 __ Branch(&load_char_start_regexp); 820 __ Branch(&load_char_start_regexp);
775 } else { 821 } else {
776 __ li(v0, Operand(SUCCESS)); 822 __ li(v0, Operand(SUCCESS));
777 } 823 }
778 } 824 }
779 // Exit and return v0. 825 // Exit and return v0.
780 __ bind(&exit_label_); 826 __ bind(&exit_label_);
781 if (global()) { 827 if (global()) {
782 __ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 828 __ ld(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
783 } 829 }
784 830
785 __ bind(&return_v0); 831 __ bind(&return_v0);
786 // Skip sp past regexp registers and local variables.. 832 // Skip sp past regexp registers and local variables..
787 __ mov(sp, frame_pointer()); 833 __ mov(sp, frame_pointer());
788 // Restore registers s0..s7 and return (restoring ra to pc). 834 // Restore registers s0..s7 and return (restoring ra to pc).
789 __ MultiPop(registers_to_retain | ra.bit()); 835 __ MultiPop(registers_to_retain | ra.bit());
790 __ Ret(); 836 __ Ret();
791 837
792 // Backtrack code (branch target for conditional backtracks). 838 // Backtrack code (branch target for conditional backtracks).
(...skipping 11 matching lines...) Expand all
804 RegList regexp_registers_to_retain = current_input_offset().bit() | 850 RegList regexp_registers_to_retain = current_input_offset().bit() |
805 current_character().bit() | backtrack_stackpointer().bit(); 851 current_character().bit() | backtrack_stackpointer().bit();
806 __ MultiPush(regexp_registers_to_retain); 852 __ MultiPush(regexp_registers_to_retain);
807 CallCheckStackGuardState(a0); 853 CallCheckStackGuardState(a0);
808 __ MultiPop(regexp_registers_to_retain); 854 __ MultiPop(regexp_registers_to_retain);
809 // If returning non-zero, we should end execution with the given 855 // If returning non-zero, we should end execution with the given
810 // result as return value. 856 // result as return value.
811 __ Branch(&return_v0, ne, v0, Operand(zero_reg)); 857 __ Branch(&return_v0, ne, v0, Operand(zero_reg));
812 858
813 // String might have moved: Reload end of string from frame. 859 // String might have moved: Reload end of string from frame.
814 __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 860 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
815 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 861 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
816 SafeReturn(); 862 SafeReturn();
817 } 863 }
818 864
819 // Backtrack stack overflow code. 865 // Backtrack stack overflow code.
820 if (stack_overflow_label_.is_linked()) { 866 if (stack_overflow_label_.is_linked()) {
821 SafeCallTarget(&stack_overflow_label_); 867 SafeCallTarget(&stack_overflow_label_);
822 // Reached if the backtrack-stack limit has been hit. 868 // Reached if the backtrack-stack limit has been hit.
823 // Put regexp engine registers on stack first. 869 // Put regexp engine registers on stack first.
824 RegList regexp_registers = current_input_offset().bit() | 870 RegList regexp_registers = current_input_offset().bit() |
825 current_character().bit(); 871 current_character().bit();
826 __ MultiPush(regexp_registers); 872 __ MultiPush(regexp_registers);
827 Label grow_failed; 873 Label grow_failed;
828 // Call GrowStack(backtrack_stackpointer(), &stack_base) 874 // Call GrowStack(backtrack_stackpointer(), &stack_base)
829 static const int num_arguments = 3; 875 static const int num_arguments = 3;
830 __ PrepareCallCFunction(num_arguments, a0); 876 __ PrepareCallCFunction(num_arguments, a0);
831 __ mov(a0, backtrack_stackpointer()); 877 __ mov(a0, backtrack_stackpointer());
832 __ Addu(a1, frame_pointer(), Operand(kStackHighEnd)); 878 __ Daddu(a1, frame_pointer(), Operand(kStackHighEnd));
833 __ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate()))); 879 __ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
834 ExternalReference grow_stack = 880 ExternalReference grow_stack =
835 ExternalReference::re_grow_stack(masm_->isolate()); 881 ExternalReference::re_grow_stack(masm_->isolate());
836 __ CallCFunction(grow_stack, num_arguments); 882 __ CallCFunction(grow_stack, num_arguments);
837 // Restore regexp registers. 883 // Restore regexp registers.
838 __ MultiPop(regexp_registers); 884 __ MultiPop(regexp_registers);
839 // If return NULL, we have failed to grow the stack, and 885 // If return NULL, we have failed to grow the stack, and
840 // must exit with a stack-overflow exception. 886 // must exit with a stack-overflow exception.
841 __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); 887 __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg));
842 // Otherwise use return value as new stack pointer. 888 // Otherwise use return value as new stack pointer.
843 __ mov(backtrack_stackpointer(), v0); 889 __ mov(backtrack_stackpointer(), v0);
844 // Restore saved registers and continue. 890 // Restore saved registers and continue.
845 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 891 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
846 __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 892 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
847 SafeReturn(); 893 SafeReturn();
848 } 894 }
849 895
850 if (exit_with_exception.is_linked()) { 896 if (exit_with_exception.is_linked()) {
851 // If any of the code above needed to exit with an exception. 897 // If any of the code above needed to exit with an exception.
852 __ bind(&exit_with_exception); 898 __ bind(&exit_with_exception);
853 // Exit with Result EXCEPTION(-1) to signal thrown exception. 899 // Exit with Result EXCEPTION(-1) to signal thrown exception.
854 __ li(v0, Operand(EXCEPTION)); 900 __ li(v0, Operand(EXCEPTION));
855 __ jmp(&return_v0); 901 __ jmp(&return_v0);
856 } 902 }
(...skipping 14 matching lines...) Expand all
871 return; 917 return;
872 } 918 }
873 __ jmp(to); 919 __ jmp(to);
874 return; 920 return;
875 } 921 }
876 922
877 923
878 void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, 924 void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg,
879 int comparand, 925 int comparand,
880 Label* if_ge) { 926 Label* if_ge) {
881 __ lw(a0, register_location(reg)); 927 __ ld(a0, register_location(reg));
882 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); 928 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand));
883 } 929 }
884 930
885 931
886 void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, 932 void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg,
887 int comparand, 933 int comparand,
888 Label* if_lt) { 934 Label* if_lt) {
889 __ lw(a0, register_location(reg)); 935 __ ld(a0, register_location(reg));
890 BranchOrBacktrack(if_lt, lt, a0, Operand(comparand)); 936 BranchOrBacktrack(if_lt, lt, a0, Operand(comparand));
891 } 937 }
892 938
893 939
894 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, 940 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg,
895 Label* if_eq) { 941 Label* if_eq) {
896 __ lw(a0, register_location(reg)); 942 __ ld(a0, register_location(reg));
897 BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset())); 943 BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset()));
898 } 944 }
899 945
900 946
901 RegExpMacroAssembler::IrregexpImplementation 947 RegExpMacroAssembler::IrregexpImplementation
902 RegExpMacroAssemblerMIPS::Implementation() { 948 RegExpMacroAssemblerMIPS::Implementation() {
903 return kMIPSImplementation; 949 return kMIPSImplementation;
904 } 950 }
905 951
906 952
(...skipping 10 matching lines...) Expand all
917 } 963 }
918 964
919 965
920 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { 966 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
921 Pop(current_input_offset()); 967 Pop(current_input_offset());
922 } 968 }
923 969
924 970
925 void RegExpMacroAssemblerMIPS::PopRegister(int register_index) { 971 void RegExpMacroAssemblerMIPS::PopRegister(int register_index) {
926 Pop(a0); 972 Pop(a0);
927 __ sw(a0, register_location(register_index)); 973 __ sd(a0, register_location(register_index));
928 } 974 }
929 975
930 976
931 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { 977 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
932 if (label->is_bound()) { 978 if (label->is_bound()) {
933 int target = label->pos(); 979 int target = label->pos();
934 __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); 980 __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
935 } else { 981 } else {
936 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 982 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
937 Label after_constant; 983 Label after_constant;
938 __ Branch(&after_constant); 984 __ Branch(&after_constant);
939 int offset = masm_->pc_offset(); 985 int offset = masm_->pc_offset();
940 int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag; 986 int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag;
941 __ emit(0); 987 __ emit(0);
942 masm_->label_at_put(label, offset); 988 masm_->label_at_put(label, offset);
943 __ bind(&after_constant); 989 __ bind(&after_constant);
944 if (is_int16(cp_offset)) { 990 if (is_int16(cp_offset)) {
945 __ lw(a0, MemOperand(code_pointer(), cp_offset)); 991 __ lwu(a0, MemOperand(code_pointer(), cp_offset));
946 } else { 992 } else {
947 __ Addu(a0, code_pointer(), cp_offset); 993 __ Daddu(a0, code_pointer(), cp_offset);
948 __ lw(a0, MemOperand(a0, 0)); 994 __ lwu(a0, MemOperand(a0, 0));
949 } 995 }
950 } 996 }
951 Push(a0); 997 Push(a0);
952 CheckStackLimit(); 998 CheckStackLimit();
953 } 999 }
954 1000
955 1001
956 void RegExpMacroAssemblerMIPS::PushCurrentPosition() { 1002 void RegExpMacroAssemblerMIPS::PushCurrentPosition() {
957 Push(current_input_offset()); 1003 Push(current_input_offset());
958 } 1004 }
959 1005
960 1006
961 void RegExpMacroAssemblerMIPS::PushRegister(int register_index, 1007 void RegExpMacroAssemblerMIPS::PushRegister(int register_index,
962 StackCheckFlag check_stack_limit) { 1008 StackCheckFlag check_stack_limit) {
963 __ lw(a0, register_location(register_index)); 1009 __ ld(a0, register_location(register_index));
964 Push(a0); 1010 Push(a0);
965 if (check_stack_limit) CheckStackLimit(); 1011 if (check_stack_limit) CheckStackLimit();
966 } 1012 }
967 1013
968 1014
969 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { 1015 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) {
970 __ lw(current_input_offset(), register_location(reg)); 1016 __ ld(current_input_offset(), register_location(reg));
971 } 1017 }
972 1018
973 1019
974 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { 1020 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) {
975 __ lw(backtrack_stackpointer(), register_location(reg)); 1021 __ ld(backtrack_stackpointer(), register_location(reg));
976 __ lw(a0, MemOperand(frame_pointer(), kStackHighEnd)); 1022 __ ld(a0, MemOperand(frame_pointer(), kStackHighEnd));
977 __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); 1023 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
978 } 1024 }
979 1025
980 1026
981 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { 1027 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) {
982 Label after_position; 1028 Label after_position;
983 __ Branch(&after_position, 1029 __ Branch(&after_position,
984 ge, 1030 ge,
985 current_input_offset(), 1031 current_input_offset(),
986 Operand(-by * char_size())); 1032 Operand(-by * char_size()));
987 __ li(current_input_offset(), -by * char_size()); 1033 __ li(current_input_offset(), -by * char_size());
988 // On RegExp code entry (where this operation is used), the character before 1034 // On RegExp code entry (where this operation is used), the character before
989 // the current position is expected to be already loaded. 1035 // the current position is expected to be already loaded.
990 // We have advanced the position, so it's safe to read backwards. 1036 // We have advanced the position, so it's safe to read backwards.
991 LoadCurrentCharacterUnchecked(-1, 1); 1037 LoadCurrentCharacterUnchecked(-1, 1);
992 __ bind(&after_position); 1038 __ bind(&after_position);
993 } 1039 }
994 1040
995 1041
996 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { 1042 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) {
997 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 1043 ASSERT(register_index >= num_saved_registers_); // Reserved for positions!
998 __ li(a0, Operand(to)); 1044 __ li(a0, Operand(to));
999 __ sw(a0, register_location(register_index)); 1045 __ sd(a0, register_location(register_index));
1000 } 1046 }
1001 1047
1002 1048
1003 bool RegExpMacroAssemblerMIPS::Succeed() { 1049 bool RegExpMacroAssemblerMIPS::Succeed() {
1004 __ jmp(&success_label_); 1050 __ jmp(&success_label_);
1005 return global(); 1051 return global();
1006 } 1052 }
1007 1053
1008 1054
1009 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, 1055 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg,
1010 int cp_offset) { 1056 int cp_offset) {
1011 if (cp_offset == 0) { 1057 if (cp_offset == 0) {
1012 __ sw(current_input_offset(), register_location(reg)); 1058 __ sd(current_input_offset(), register_location(reg));
1013 } else { 1059 } else {
1014 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1060 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1015 __ sw(a0, register_location(reg)); 1061 __ sd(a0, register_location(reg));
1016 } 1062 }
1017 } 1063 }
1018 1064
1019 1065
1020 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1066 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
1021 ASSERT(reg_from <= reg_to); 1067 ASSERT(reg_from <= reg_to);
1022 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1068 __ ld(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
1023 for (int reg = reg_from; reg <= reg_to; reg++) { 1069 for (int reg = reg_from; reg <= reg_to; reg++) {
1024 __ sw(a0, register_location(reg)); 1070 __ sd(a0, register_location(reg));
1025 } 1071 }
1026 } 1072 }
1027 1073
1028 1074
1029 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1075 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
1030 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1076 __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd));
1031 __ Subu(a0, backtrack_stackpointer(), a1); 1077 __ Dsubu(a0, backtrack_stackpointer(), a1);
1032 __ sw(a0, register_location(reg)); 1078 __ sd(a0, register_location(reg));
1033 } 1079 }
1034 1080
1035 1081
1036 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { 1082 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
1037 return false; 1083 return false;
1038 } 1084 }
1039 1085
1040 1086
1041 // Private methods: 1087 // Private methods:
1042 1088
1043 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { 1089 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
1044 int stack_alignment = base::OS::ActivationFrameAlignment(); 1090 int stack_alignment = base::OS::ActivationFrameAlignment();
1045 1091
1046 // Align the stack pointer and save the original sp value on the stack. 1092 // Align the stack pointer and save the original sp value on the stack.
1047 __ mov(scratch, sp); 1093 __ mov(scratch, sp);
1048 __ Subu(sp, sp, Operand(kPointerSize)); 1094 __ Dsubu(sp, sp, Operand(kPointerSize));
1049 ASSERT(IsPowerOf2(stack_alignment)); 1095 ASSERT(IsPowerOf2(stack_alignment));
1050 __ And(sp, sp, Operand(-stack_alignment)); 1096 __ And(sp, sp, Operand(-stack_alignment));
1051 __ sw(scratch, MemOperand(sp)); 1097 __ sd(scratch, MemOperand(sp));
1052 1098
1053 __ mov(a2, frame_pointer()); 1099 __ mov(a2, frame_pointer());
1054 // Code* of self. 1100 // Code* of self.
1055 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); 1101 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE);
1056 1102
1057 // We need to make room for the return address on the stack. 1103 // We need to make room for the return address on the stack.
1058 ASSERT(IsAligned(stack_alignment, kPointerSize)); 1104 ASSERT(IsAligned(stack_alignment, kPointerSize));
1059 __ Subu(sp, sp, Operand(stack_alignment)); 1105 __ Dsubu(sp, sp, Operand(stack_alignment));
1060 1106
1061 // Stack pointer now points to cell where return address is to be written. 1107 // Stack pointer now points to cell where return address is to be written.
1062 // Arguments are in registers, meaning we teat the return address as 1108 // Arguments are in registers, meaning we teat the return address as
1063 // argument 5. Since DirectCEntryStub will handleallocating space for the C 1109 // argument 5. Since DirectCEntryStub will handleallocating space for the C
1064 // argument slots, we don't need to care about that here. This is how the 1110 // argument slots, we don't need to care about that here. This is how the
1065 // stack will look (sp meaning the value of sp at this moment): 1111 // stack will look (sp meaning the value of sp at this moment):
1066 // [sp + 3] - empty slot if needed for alignment. 1112 // [sp + 3] - empty slot if needed for alignment.
1067 // [sp + 2] - saved sp. 1113 // [sp + 2] - saved sp.
1068 // [sp + 1] - second word reserved for return value. 1114 // [sp + 1] - second word reserved for return value.
1069 // [sp + 0] - first word reserved for return value. 1115 // [sp + 0] - first word reserved for return value.
(...skipping 11 matching lines...) Expand all
1081 // drop them with the return address from the stack with loading saved sp. 1127 // drop them with the return address from the stack with loading saved sp.
1082 // At this point stack must look: 1128 // At this point stack must look:
1083 // [sp + 7] - empty slot if needed for alignment. 1129 // [sp + 7] - empty slot if needed for alignment.
1084 // [sp + 6] - saved sp. 1130 // [sp + 6] - saved sp.
1085 // [sp + 5] - second word reserved for return value. 1131 // [sp + 5] - second word reserved for return value.
1086 // [sp + 4] - first word reserved for return value. 1132 // [sp + 4] - first word reserved for return value.
1087 // [sp + 3] - C argument slot. 1133 // [sp + 3] - C argument slot.
1088 // [sp + 2] - C argument slot. 1134 // [sp + 2] - C argument slot.
1089 // [sp + 1] - C argument slot. 1135 // [sp + 1] - C argument slot.
1090 // [sp + 0] - C argument slot. 1136 // [sp + 0] - C argument slot.
1091 __ lw(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize)); 1137 __ ld(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize));
1092 1138
1093 __ li(code_pointer(), Operand(masm_->CodeObject())); 1139 __ li(code_pointer(), Operand(masm_->CodeObject()));
1094 } 1140 }
1095 1141
1096 1142
1097 // Helper function for reading a value out of a stack frame. 1143 // Helper function for reading a value out of a stack frame.
1098 template <typename T> 1144 template <typename T>
1099 static T& frame_entry(Address re_frame, int frame_offset) { 1145 static T& frame_entry(Address re_frame, int frame_offset) {
1100 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 1146 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
1101 } 1147 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 void RegExpMacroAssemblerMIPS::SafeCall(Label* to, 1287 void RegExpMacroAssemblerMIPS::SafeCall(Label* to,
1242 Condition cond, 1288 Condition cond,
1243 Register rs, 1289 Register rs,
1244 const Operand& rt) { 1290 const Operand& rt) {
1245 __ BranchAndLink(to, cond, rs, rt); 1291 __ BranchAndLink(to, cond, rs, rt);
1246 } 1292 }
1247 1293
1248 1294
1249 void RegExpMacroAssemblerMIPS::SafeReturn() { 1295 void RegExpMacroAssemblerMIPS::SafeReturn() {
1250 __ pop(ra); 1296 __ pop(ra);
1251 __ Addu(t5, ra, Operand(masm_->CodeObject())); 1297 __ Daddu(t1, ra, Operand(masm_->CodeObject()));
1252 __ Jump(t5); 1298 __ Jump(t1);
1253 } 1299 }
1254 1300
1255 1301
1256 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { 1302 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) {
1257 __ bind(name); 1303 __ bind(name);
1258 __ Subu(ra, ra, Operand(masm_->CodeObject())); 1304 __ Dsubu(ra, ra, Operand(masm_->CodeObject()));
1259 __ push(ra); 1305 __ push(ra);
1260 } 1306 }
1261 1307
1262 1308
1263 void RegExpMacroAssemblerMIPS::Push(Register source) { 1309 void RegExpMacroAssemblerMIPS::Push(Register source) {
1264 ASSERT(!source.is(backtrack_stackpointer())); 1310 ASSERT(!source.is(backtrack_stackpointer()));
1265 __ Addu(backtrack_stackpointer(), 1311 __ Daddu(backtrack_stackpointer(),
1266 backtrack_stackpointer(), 1312 backtrack_stackpointer(),
1267 Operand(-kPointerSize)); 1313 Operand(-kIntSize));
1268 __ sw(source, MemOperand(backtrack_stackpointer())); 1314 __ sw(source, MemOperand(backtrack_stackpointer()));
1269 } 1315 }
1270 1316
1271 1317
1272 void RegExpMacroAssemblerMIPS::Pop(Register target) { 1318 void RegExpMacroAssemblerMIPS::Pop(Register target) {
1273 ASSERT(!target.is(backtrack_stackpointer())); 1319 ASSERT(!target.is(backtrack_stackpointer()));
1274 __ lw(target, MemOperand(backtrack_stackpointer())); 1320 __ lw(target, MemOperand(backtrack_stackpointer()));
1275 __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), kPointerSize); 1321 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize);
1276 } 1322 }
1277 1323
1278 1324
1279 void RegExpMacroAssemblerMIPS::CheckPreemption() { 1325 void RegExpMacroAssemblerMIPS::CheckPreemption() {
1280 // Check for preemption. 1326 // Check for preemption.
1281 ExternalReference stack_limit = 1327 ExternalReference stack_limit =
1282 ExternalReference::address_of_stack_limit(masm_->isolate()); 1328 ExternalReference::address_of_stack_limit(masm_->isolate());
1283 __ li(a0, Operand(stack_limit)); 1329 __ li(a0, Operand(stack_limit));
1284 __ lw(a0, MemOperand(a0)); 1330 __ ld(a0, MemOperand(a0));
1285 SafeCall(&check_preempt_label_, ls, sp, Operand(a0)); 1331 SafeCall(&check_preempt_label_, ls, sp, Operand(a0));
1286 } 1332 }
1287 1333
1288 1334
1289 void RegExpMacroAssemblerMIPS::CheckStackLimit() { 1335 void RegExpMacroAssemblerMIPS::CheckStackLimit() {
1290 ExternalReference stack_limit = 1336 ExternalReference stack_limit =
1291 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); 1337 ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
1292 1338
1293 __ li(a0, Operand(stack_limit)); 1339 __ li(a0, Operand(stack_limit));
1294 __ lw(a0, MemOperand(a0)); 1340 __ ld(a0, MemOperand(a0));
1295 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0)); 1341 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0));
1296 } 1342 }
1297 1343
1298 1344
1299 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, 1345 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
1300 int characters) { 1346 int characters) {
1301 Register offset = current_input_offset(); 1347 Register offset = current_input_offset();
1302 if (cp_offset != 0) { 1348 if (cp_offset != 0) {
1303 // t7 is not being used to store the capture start index at this point. 1349 // t3 is not being used to store the capture start index at this point.
1304 __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size())); 1350 __ Daddu(t3, current_input_offset(), Operand(cp_offset * char_size()));
1305 offset = t7; 1351 offset = t3;
1306 } 1352 }
1307 // We assume that we cannot do unaligned loads on MIPS, so this function 1353 // We assume that we cannot do unaligned loads on MIPS, so this function
1308 // must only be used to load a single character at a time. 1354 // must only be used to load a single character at a time.
1309 ASSERT(characters == 1); 1355 ASSERT(characters == 1);
1310 __ Addu(t5, end_of_input_address(), Operand(offset)); 1356 __ Daddu(t1, end_of_input_address(), Operand(offset));
1311 if (mode_ == ASCII) { 1357 if (mode_ == ASCII) {
1312 __ lbu(current_character(), MemOperand(t5, 0)); 1358 __ lbu(current_character(), MemOperand(t1, 0));
1313 } else { 1359 } else {
1314 ASSERT(mode_ == UC16); 1360 ASSERT(mode_ == UC16);
1315 __ lhu(current_character(), MemOperand(t5, 0)); 1361 __ lhu(current_character(), MemOperand(t1, 0));
1316 } 1362 }
1317 } 1363 }
1318 1364
1319
1320 #undef __ 1365 #undef __
1321 1366
1322 #endif // V8_INTERPRETED_REGEXP 1367 #endif // V8_INTERPRETED_REGEXP
1323 1368
1324 }} // namespace v8::internal 1369 }} // namespace v8::internal
1325 1370
1326 #endif // V8_TARGET_ARCH_MIPS 1371 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/regexp-macro-assembler-mips64.h ('k') | src/mips64/simulator-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698