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

Side by Side Diff: src/mips/codegen-mips.cc

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/mips/code-stubs-mips.cc ('k') | src/mips/constants-mips.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 // 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
(...skipping 19 matching lines...) Expand all
30 #if V8_TARGET_ARCH_MIPS 30 #if V8_TARGET_ARCH_MIPS
31 31
32 #include "codegen.h" 32 #include "codegen.h"
33 #include "macro-assembler.h" 33 #include "macro-assembler.h"
34 #include "simulator-mips.h" 34 #include "simulator-mips.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
41 switch (type) {
42 case TranscendentalCache::LOG: return &log;
43 default: UNIMPLEMENTED();
44 }
45 return NULL;
46 }
47
48
49 #define __ masm. 40 #define __ masm.
50 41
51 42
52 #if defined(USE_SIMULATOR) 43 #if defined(USE_SIMULATOR)
53 byte* fast_exp_mips_machine_code = NULL; 44 byte* fast_exp_mips_machine_code = NULL;
54 double fast_exp_simulator(double x) { 45 double fast_exp_simulator(double x) {
55 return Simulator::current(Isolate::Current())->CallFP( 46 return Simulator::current(Isolate::Current())->CallFP(
56 fast_exp_mips_machine_code, x, 0); 47 fast_exp_mips_machine_code, x, 0);
57 } 48 }
58 #endif 49 #endif
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 94
104 #if !defined(USE_SIMULATOR) 95 #if !defined(USE_SIMULATOR)
105 return FUNCTION_CAST<UnaryMathFunction>(buffer); 96 return FUNCTION_CAST<UnaryMathFunction>(buffer);
106 #else 97 #else
107 fast_exp_mips_machine_code = buffer; 98 fast_exp_mips_machine_code = buffer;
108 return &fast_exp_simulator; 99 return &fast_exp_simulator;
109 #endif 100 #endif
110 } 101 }
111 102
112 103
104 #if defined(V8_HOST_ARCH_MIPS)
105 OS::MemCopyUint8Function CreateMemCopyUint8Function(
106 OS::MemCopyUint8Function stub) {
107 #if defined(USE_SIMULATOR)
108 return stub;
109 #else
110 if (Serializer::enabled()) {
111 return stub;
112 }
113
114 size_t actual_size;
115 byte* buffer = static_cast<byte*>(OS::Allocate(3 * KB, &actual_size, true));
116 if (buffer == NULL) return stub;
117
118 // This code assumes that cache lines are 32 bytes and if the cache line is
119 // larger it will not work correctly.
120 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
121
122 {
123 Label lastb, unaligned, aligned, chkw,
124 loop16w, chk1w, wordCopy_loop, skip_pref, lastbloop,
125 leave, ua_chk16w, ua_loop16w, ua_skip_pref, ua_chkw,
126 ua_chk1w, ua_wordCopy_loop, ua_smallCopy, ua_smallCopy_loop;
127
128 // The size of each prefetch.
129 uint32_t pref_chunk = 32;
130 // The maximum size of a prefetch, it must not be less then pref_chunk.
131 // If the real size of a prefetch is greater then max_pref_size and
132 // the kPrefHintPrepareForStore hint is used, the code will not work
133 // correctly.
134 uint32_t max_pref_size = 128;
135 ASSERT(pref_chunk < max_pref_size);
136
137 // pref_limit is set based on the fact that we never use an offset
138 // greater then 5 on a store pref and that a single pref can
139 // never be larger then max_pref_size.
140 uint32_t pref_limit = (5 * pref_chunk) + max_pref_size;
141 int32_t pref_hint_load = kPrefHintLoadStreamed;
142 int32_t pref_hint_store = kPrefHintPrepareForStore;
143 uint32_t loadstore_chunk = 4;
144
145 // The initial prefetches may fetch bytes that are before the buffer being
146 // copied. Start copies with an offset of 4 so avoid this situation when
147 // using kPrefHintPrepareForStore.
148 ASSERT(pref_hint_store != kPrefHintPrepareForStore ||
149 pref_chunk * 4 >= max_pref_size);
150
151 // If the size is less than 8, go to lastb. Regardless of size,
152 // copy dst pointer to v0 for the retuen value.
153 __ slti(t2, a2, 2 * loadstore_chunk);
154 __ bne(t2, zero_reg, &lastb);
155 __ mov(v0, a0); // In delay slot.
156
157 // If src and dst have different alignments, go to unaligned, if they
158 // have the same alignment (but are not actually aligned) do a partial
159 // load/store to make them aligned. If they are both already aligned
160 // we can start copying at aligned.
161 __ xor_(t8, a1, a0);
162 __ andi(t8, t8, loadstore_chunk - 1); // t8 is a0/a1 word-displacement.
163 __ bne(t8, zero_reg, &unaligned);
164 __ subu(a3, zero_reg, a0); // In delay slot.
165
166 __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1.
167 __ beq(a3, zero_reg, &aligned); // Already aligned.
168 __ subu(a2, a2, a3); // In delay slot. a2 is the remining bytes count.
169
170 __ lwr(t8, MemOperand(a1));
171 __ addu(a1, a1, a3);
172 __ swr(t8, MemOperand(a0));
173 __ addu(a0, a0, a3);
174
175 // Now dst/src are both aligned to (word) aligned addresses. Set a2 to
176 // count how many bytes we have to copy after all the 64 byte chunks are
177 // copied and a3 to the dst pointer after all the 64 byte chunks have been
178 // copied. We will loop, incrementing a0 and a1 until a0 equals a3.
179 __ bind(&aligned);
180 __ andi(t8, a2, 0x3f);
181 __ beq(a2, t8, &chkw); // Less than 64?
182 __ subu(a3, a2, t8); // In delay slot.
183 __ addu(a3, a0, a3); // Now a3 is the final dst after loop.
184
185 // When in the loop we prefetch with kPrefHintPrepareForStore hint,
186 // in this case the a0+x should be past the "t0-32" address. This means:
187 // for x=128 the last "safe" a0 address is "t0-160". Alternatively, for
188 // x=64 the last "safe" a0 address is "t0-96". In the current version we
189 // will use "pref hint, 128(a0)", so "t0-160" is the limit.
190 if (pref_hint_store == kPrefHintPrepareForStore) {
191 __ addu(t0, a0, a2); // t0 is the "past the end" address.
192 __ Subu(t9, t0, pref_limit); // t9 is the "last safe pref" address.
193 }
194
195 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
196 __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
197 __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
198 __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
199
200 if (pref_hint_store != kPrefHintPrepareForStore) {
201 __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
202 __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
203 __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
204 }
205 __ bind(&loop16w);
206 __ lw(t0, MemOperand(a1));
207
208 if (pref_hint_store == kPrefHintPrepareForStore) {
209 __ sltu(v1, t9, a0); // If a0 > t9, don't use next prefetch.
210 __ Branch(USE_DELAY_SLOT, &skip_pref, gt, v1, Operand(zero_reg));
211 }
212 __ lw(t1, MemOperand(a1, 1, loadstore_chunk)); // Maybe in delay slot.
213
214 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
215 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
216
217 __ bind(&skip_pref);
218 __ lw(t2, MemOperand(a1, 2, loadstore_chunk));
219 __ lw(t3, MemOperand(a1, 3, loadstore_chunk));
220 __ lw(t4, MemOperand(a1, 4, loadstore_chunk));
221 __ lw(t5, MemOperand(a1, 5, loadstore_chunk));
222 __ lw(t6, MemOperand(a1, 6, loadstore_chunk));
223 __ lw(t7, MemOperand(a1, 7, loadstore_chunk));
224 __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
225
226 __ sw(t0, MemOperand(a0));
227 __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
228 __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
229 __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
230 __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
231 __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
232 __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
233 __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
234
235 __ lw(t0, MemOperand(a1, 8, loadstore_chunk));
236 __ lw(t1, MemOperand(a1, 9, loadstore_chunk));
237 __ lw(t2, MemOperand(a1, 10, loadstore_chunk));
238 __ lw(t3, MemOperand(a1, 11, loadstore_chunk));
239 __ lw(t4, MemOperand(a1, 12, loadstore_chunk));
240 __ lw(t5, MemOperand(a1, 13, loadstore_chunk));
241 __ lw(t6, MemOperand(a1, 14, loadstore_chunk));
242 __ lw(t7, MemOperand(a1, 15, loadstore_chunk));
243 __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
244
245 __ sw(t0, MemOperand(a0, 8, loadstore_chunk));
246 __ sw(t1, MemOperand(a0, 9, loadstore_chunk));
247 __ sw(t2, MemOperand(a0, 10, loadstore_chunk));
248 __ sw(t3, MemOperand(a0, 11, loadstore_chunk));
249 __ sw(t4, MemOperand(a0, 12, loadstore_chunk));
250 __ sw(t5, MemOperand(a0, 13, loadstore_chunk));
251 __ sw(t6, MemOperand(a0, 14, loadstore_chunk));
252 __ sw(t7, MemOperand(a0, 15, loadstore_chunk));
253 __ addiu(a0, a0, 16 * loadstore_chunk);
254 __ bne(a0, a3, &loop16w);
255 __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot.
256 __ mov(a2, t8);
257
258 // Here we have src and dest word-aligned but less than 64-bytes to go.
259 // Check for a 32 bytes chunk and copy if there is one. Otherwise jump
260 // down to chk1w to handle the tail end of the copy.
261 __ bind(&chkw);
262 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
263 __ andi(t8, a2, 0x1f);
264 __ beq(a2, t8, &chk1w); // Less than 32?
265 __ nop(); // In delay slot.
266 __ lw(t0, MemOperand(a1));
267 __ lw(t1, MemOperand(a1, 1, loadstore_chunk));
268 __ lw(t2, MemOperand(a1, 2, loadstore_chunk));
269 __ lw(t3, MemOperand(a1, 3, loadstore_chunk));
270 __ lw(t4, MemOperand(a1, 4, loadstore_chunk));
271 __ lw(t5, MemOperand(a1, 5, loadstore_chunk));
272 __ lw(t6, MemOperand(a1, 6, loadstore_chunk));
273 __ lw(t7, MemOperand(a1, 7, loadstore_chunk));
274 __ addiu(a1, a1, 8 * loadstore_chunk);
275 __ sw(t0, MemOperand(a0));
276 __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
277 __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
278 __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
279 __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
280 __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
281 __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
282 __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
283 __ addiu(a0, a0, 8 * loadstore_chunk);
284
285 // Here we have less than 32 bytes to copy. Set up for a loop to copy
286 // one word at a time. Set a2 to count how many bytes we have to copy
287 // after all the word chunks are copied and a3 to the dst pointer after
288 // all the word chunks have been copied. We will loop, incrementing a0
289 // and a1 untill a0 equals a3.
290 __ bind(&chk1w);
291 __ andi(a2, t8, loadstore_chunk - 1);
292 __ beq(a2, t8, &lastb);
293 __ subu(a3, t8, a2); // In delay slot.
294 __ addu(a3, a0, a3);
295
296 __ bind(&wordCopy_loop);
297 __ lw(t3, MemOperand(a1));
298 __ addiu(a0, a0, loadstore_chunk);
299 __ addiu(a1, a1, loadstore_chunk);
300 __ bne(a0, a3, &wordCopy_loop);
301 __ sw(t3, MemOperand(a0, -1, loadstore_chunk)); // In delay slot.
302
303 __ bind(&lastb);
304 __ Branch(&leave, le, a2, Operand(zero_reg));
305 __ addu(a3, a0, a2);
306
307 __ bind(&lastbloop);
308 __ lb(v1, MemOperand(a1));
309 __ addiu(a0, a0, 1);
310 __ addiu(a1, a1, 1);
311 __ bne(a0, a3, &lastbloop);
312 __ sb(v1, MemOperand(a0, -1)); // In delay slot.
313
314 __ bind(&leave);
315 __ jr(ra);
316 __ nop();
317
318 // Unaligned case. Only the dst gets aligned so we need to do partial
319 // loads of the source followed by normal stores to the dst (once we
320 // have aligned the destination).
321 __ bind(&unaligned);
322 __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1.
323 __ beq(a3, zero_reg, &ua_chk16w);
324 __ subu(a2, a2, a3); // In delay slot.
325
326 __ lwr(v1, MemOperand(a1));
327 __ lwl(v1,
328 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
329 __ addu(a1, a1, a3);
330 __ swr(v1, MemOperand(a0));
331 __ addu(a0, a0, a3);
332
333 // Now the dst (but not the source) is aligned. Set a2 to count how many
334 // bytes we have to copy after all the 64 byte chunks are copied and a3 to
335 // the dst pointer after all the 64 byte chunks have been copied. We will
336 // loop, incrementing a0 and a1 until a0 equals a3.
337 __ bind(&ua_chk16w);
338 __ andi(t8, a2, 0x3f);
339 __ beq(a2, t8, &ua_chkw);
340 __ subu(a3, a2, t8); // In delay slot.
341 __ addu(a3, a0, a3);
342
343 if (pref_hint_store == kPrefHintPrepareForStore) {
344 __ addu(t0, a0, a2);
345 __ Subu(t9, t0, pref_limit);
346 }
347
348 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
349 __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
350 __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
351
352 if (pref_hint_store != kPrefHintPrepareForStore) {
353 __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
354 __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
355 __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
356 }
357
358 __ bind(&ua_loop16w);
359 __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
360 __ lwr(t0, MemOperand(a1));
361 __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
362 __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
363
364 if (pref_hint_store == kPrefHintPrepareForStore) {
365 __ sltu(v1, t9, a0);
366 __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
367 }
368 __ lwr(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
369
370 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
371 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
372
373 __ bind(&ua_skip_pref);
374 __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
375 __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
376 __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
377 __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
378 __ lwl(t0,
379 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
380 __ lwl(t1,
381 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
382 __ lwl(t2,
383 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
384 __ lwl(t3,
385 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
386 __ lwl(t4,
387 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
388 __ lwl(t5,
389 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
390 __ lwl(t6,
391 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
392 __ lwl(t7,
393 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
394 __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
395 __ sw(t0, MemOperand(a0));
396 __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
397 __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
398 __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
399 __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
400 __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
401 __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
402 __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
403 __ lwr(t0, MemOperand(a1, 8, loadstore_chunk));
404 __ lwr(t1, MemOperand(a1, 9, loadstore_chunk));
405 __ lwr(t2, MemOperand(a1, 10, loadstore_chunk));
406 __ lwr(t3, MemOperand(a1, 11, loadstore_chunk));
407 __ lwr(t4, MemOperand(a1, 12, loadstore_chunk));
408 __ lwr(t5, MemOperand(a1, 13, loadstore_chunk));
409 __ lwr(t6, MemOperand(a1, 14, loadstore_chunk));
410 __ lwr(t7, MemOperand(a1, 15, loadstore_chunk));
411 __ lwl(t0,
412 MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
413 __ lwl(t1,
414 MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
415 __ lwl(t2,
416 MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
417 __ lwl(t3,
418 MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
419 __ lwl(t4,
420 MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
421 __ lwl(t5,
422 MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
423 __ lwl(t6,
424 MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
425 __ lwl(t7,
426 MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
427 __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
428 __ sw(t0, MemOperand(a0, 8, loadstore_chunk));
429 __ sw(t1, MemOperand(a0, 9, loadstore_chunk));
430 __ sw(t2, MemOperand(a0, 10, loadstore_chunk));
431 __ sw(t3, MemOperand(a0, 11, loadstore_chunk));
432 __ sw(t4, MemOperand(a0, 12, loadstore_chunk));
433 __ sw(t5, MemOperand(a0, 13, loadstore_chunk));
434 __ sw(t6, MemOperand(a0, 14, loadstore_chunk));
435 __ sw(t7, MemOperand(a0, 15, loadstore_chunk));
436 __ addiu(a0, a0, 16 * loadstore_chunk);
437 __ bne(a0, a3, &ua_loop16w);
438 __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot.
439 __ mov(a2, t8);
440
441 // Here less than 64-bytes. Check for
442 // a 32 byte chunk and copy if there is one. Otherwise jump down to
443 // ua_chk1w to handle the tail end of the copy.
444 __ bind(&ua_chkw);
445 __ Pref(pref_hint_load, MemOperand(a1));
446 __ andi(t8, a2, 0x1f);
447
448 __ beq(a2, t8, &ua_chk1w);
449 __ nop(); // In delay slot.
450 __ lwr(t0, MemOperand(a1));
451 __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
452 __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
453 __ lwr(t3, MemOperand(a1, 3, loadstore_chunk));
454 __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
455 __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
456 __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
457 __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
458 __ lwl(t0,
459 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
460 __ lwl(t1,
461 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
462 __ lwl(t2,
463 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
464 __ lwl(t3,
465 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
466 __ lwl(t4,
467 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
468 __ lwl(t5,
469 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
470 __ lwl(t6,
471 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
472 __ lwl(t7,
473 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
474 __ addiu(a1, a1, 8 * loadstore_chunk);
475 __ sw(t0, MemOperand(a0));
476 __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
477 __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
478 __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
479 __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
480 __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
481 __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
482 __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
483 __ addiu(a0, a0, 8 * loadstore_chunk);
484
485 // Less than 32 bytes to copy. Set up for a loop to
486 // copy one word at a time.
487 __ bind(&ua_chk1w);
488 __ andi(a2, t8, loadstore_chunk - 1);
489 __ beq(a2, t8, &ua_smallCopy);
490 __ subu(a3, t8, a2); // In delay slot.
491 __ addu(a3, a0, a3);
492
493 __ bind(&ua_wordCopy_loop);
494 __ lwr(v1, MemOperand(a1));
495 __ lwl(v1,
496 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
497 __ addiu(a0, a0, loadstore_chunk);
498 __ addiu(a1, a1, loadstore_chunk);
499 __ bne(a0, a3, &ua_wordCopy_loop);
500 __ sw(v1, MemOperand(a0, -1, loadstore_chunk)); // In delay slot.
501
502 // Copy the last 8 bytes.
503 __ bind(&ua_smallCopy);
504 __ beq(a2, zero_reg, &leave);
505 __ addu(a3, a0, a2); // In delay slot.
506
507 __ bind(&ua_smallCopy_loop);
508 __ lb(v1, MemOperand(a1));
509 __ addiu(a0, a0, 1);
510 __ addiu(a1, a1, 1);
511 __ bne(a0, a3, &ua_smallCopy_loop);
512 __ sb(v1, MemOperand(a0, -1)); // In delay slot.
513
514 __ jr(ra);
515 __ nop();
516 }
517 CodeDesc desc;
518 masm.GetCode(&desc);
519 ASSERT(!RelocInfo::RequiresRelocation(desc));
520
521 CPU::FlushICache(buffer, actual_size);
522 OS::ProtectCode(buffer, actual_size);
523 return FUNCTION_CAST<OS::MemCopyUint8Function>(buffer);
524 #endif
525 }
526 #endif
527
113 #undef __ 528 #undef __
114 529
115 530
116 UnaryMathFunction CreateSqrtFunction() { 531 UnaryMathFunction CreateSqrtFunction() {
117 return &sqrt; 532 return &sqrt;
118 } 533 }
119 534
120 535
121 // ------------------------------------------------------------------------- 536 // -------------------------------------------------------------------------
122 // Platform-specific RuntimeCallHelper functions. 537 // Platform-specific RuntimeCallHelper functions.
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 __ bind(&zero); 1008 __ bind(&zero);
594 __ Move(result, kDoubleRegZero); 1009 __ Move(result, kDoubleRegZero);
595 __ Branch(&done); 1010 __ Branch(&done);
596 1011
597 __ bind(&infinity); 1012 __ bind(&infinity);
598 __ ldc1(result, ExpConstant(2, temp3)); 1013 __ ldc1(result, ExpConstant(2, temp3));
599 1014
600 __ bind(&done); 1015 __ bind(&done);
601 } 1016 }
602 1017
603 1018 #ifdef DEBUG
604 // nop(CODE_AGE_MARKER_NOP) 1019 // nop(CODE_AGE_MARKER_NOP)
605 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180; 1020 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
1021 #endif
606 1022
607 static byte* GetNoCodeAgeSequence(uint32_t* length) { 1023 static byte* GetNoCodeAgeSequence(uint32_t* length) {
608 // The sequence of instructions that is patched out for aging code is the 1024 // The sequence of instructions that is patched out for aging code is the
609 // following boilerplate stack-building prologue that is found in FUNCTIONS 1025 // following boilerplate stack-building prologue that is found in FUNCTIONS
610 static bool initialized = false; 1026 static bool initialized = false;
611 static uint32_t sequence[kNoCodeAgeSequenceLength]; 1027 static uint32_t sequence[kNoCodeAgeSequenceLength];
612 byte* byte_sequence = reinterpret_cast<byte*>(sequence); 1028 byte* byte_sequence = reinterpret_cast<byte*>(sequence);
613 *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize; 1029 *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize;
614 if (!initialized) { 1030 if (!initialized) {
615 CodePatcher patcher(byte_sequence, kNoCodeAgeSequenceLength); 1031 CodePatcher patcher(byte_sequence, kNoCodeAgeSequenceLength);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 patcher.masm()->nop(); // Pad the empty space. 1089 patcher.masm()->nop(); // Pad the empty space.
674 } 1090 }
675 } 1091 }
676 1092
677 1093
678 #undef __ 1094 #undef __
679 1095
680 } } // namespace v8::internal 1096 } } // namespace v8::internal
681 1097
682 #endif // V8_TARGET_ARCH_MIPS 1098 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips/constants-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698