5 #if V8_TARGET_ARCH_IA32 7 #include "src/codegen.h" 8 #include "src/heap/factory-inl.h" 9 #include "src/heap/heap.h" 10 #include "src/macro-assembler.h" 17 UnaryMathFunction CreateSqrtFunction() {
20 byte* buffer = AllocatePage(page_allocator,
22 if (buffer ==
nullptr)
return nullptr;
24 MacroAssembler masm(AssemblerOptions{}, buffer,
static_cast<int>(allocated));
29 __ movsd(xmm0, Operand(esp, 1 * kPointerSize));
30 __ sqrtsd(xmm0, xmm0);
31 __ movsd(Operand(esp, 1 * kPointerSize), xmm0);
33 __ fld_d(Operand(esp, 1 * kPointerSize));
38 masm.GetCode(
nullptr, &desc);
39 DCHECK(!RelocInfo::RequiresRelocationAfterCodegen(desc));
41 Assembler::FlushICache(buffer, allocated);
42 CHECK(SetPermissions(page_allocator, buffer, allocated,
43 PageAllocator::kReadExecute));
44 return FUNCTION_CAST<UnaryMathFunction>(buffer);
50 #define __ ACCESS_MASM(masm) 52 enum Direction { FORWARD, BACKWARD };
53 enum Alignment { MOVE_ALIGNED, MOVE_UNALIGNED };
60 void MemMoveEmitMainLoop(MacroAssembler* masm,
63 Alignment alignment) {
67 Register loop_count = edx;
68 Label loop, move_last_31, move_last_63;
69 __ cmp(loop_count, 0);
70 __ j(equal, &move_last_63);
73 if (direction == BACKWARD) __ sub(src, Immediate(0x40));
74 __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0x00));
75 __ movdq(alignment == MOVE_ALIGNED, xmm1, Operand(src, 0x10));
76 __ movdq(alignment == MOVE_ALIGNED, xmm2, Operand(src, 0x20));
77 __ movdq(alignment == MOVE_ALIGNED, xmm3, Operand(src, 0x30));
78 if (direction == FORWARD) __ add(src, Immediate(0x40));
79 if (direction == BACKWARD) __ sub(dst, Immediate(0x40));
80 __ movdqa(Operand(dst, 0x00), xmm0);
81 __ movdqa(Operand(dst, 0x10), xmm1);
82 __ movdqa(Operand(dst, 0x20), xmm2);
83 __ movdqa(Operand(dst, 0x30), xmm3);
84 if (direction == FORWARD) __ add(dst, Immediate(0x40));
86 __ j(not_zero, &loop);
88 __ bind(&move_last_63);
89 __ test(count, Immediate(0x20));
90 __ j(zero, &move_last_31);
91 if (direction == BACKWARD) __ sub(src, Immediate(0x20));
92 __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0x00));
93 __ movdq(alignment == MOVE_ALIGNED, xmm1, Operand(src, 0x10));
94 if (direction == FORWARD) __ add(src, Immediate(0x20));
95 if (direction == BACKWARD) __ sub(dst, Immediate(0x20));
96 __ movdqa(Operand(dst, 0x00), xmm0);
97 __ movdqa(Operand(dst, 0x10), xmm1);
98 if (direction == FORWARD) __ add(dst, Immediate(0x20));
100 __ bind(&move_last_31);
101 __ test(count, Immediate(0x10));
102 __ j(zero, move_last_15);
103 if (direction == BACKWARD) __ sub(src, Immediate(0x10));
104 __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0));
105 if (direction == FORWARD) __ add(src, Immediate(0x10));
106 if (direction == BACKWARD) __ sub(dst, Immediate(0x10));
107 __ movdqa(Operand(dst, 0), xmm0);
108 if (direction == FORWARD) __ add(dst, Immediate(0x10));
112 void MemMoveEmitPopAndReturn(MacroAssembler* masm) {
123 class LabelConverter {
125 explicit LabelConverter(byte* buffer) : buffer_(buffer) {}
126 int32_t address(Label* l)
const {
127 return reinterpret_cast<int32_t
>(buffer_) + l->pos();
133 MemMoveFunction CreateMemMoveFunction() {
135 size_t allocated = 0;
136 byte* buffer = AllocatePage(page_allocator,
138 if (buffer ==
nullptr)
return nullptr;
140 MacroAssembler masm(AssemblerOptions{}, buffer,
static_cast<int>(allocated));
141 LabelConverter conv(buffer);
155 const int kDestinationOffset = 1 * kPointerSize;
156 const int kSourceOffset = 2 * kPointerSize;
157 const int kSizeOffset = 3 * kPointerSize;
160 const size_t kSmallCopySize = 8;
162 const size_t kMediumCopySize = 63;
165 const size_t kMinMoveDistance = 16;
169 int stack_offset = 0;
171 Label backward, backward_much_overlap;
172 Label forward_much_overlap, small_size, medium_size, pop_and_return;
175 stack_offset += 2 * kPointerSize;
178 Register count = ecx;
179 Register loop_count = edx;
180 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
181 __ mov(src, Operand(esp, stack_offset + kSourceOffset));
182 __ mov(count, Operand(esp, stack_offset + kSizeOffset));
185 __ j(equal, &pop_and_return);
187 __ prefetch(Operand(src, 0), 1);
188 __ cmp(count, kSmallCopySize);
189 __ j(below_equal, &small_size);
190 __ cmp(count, kMediumCopySize);
191 __ j(below_equal, &medium_size);
193 __ j(above, &backward);
197 Label unaligned_source, move_last_15, skip_last_move;
200 __ cmp(eax, kMinMoveDistance);
201 __ j(below, &forward_much_overlap);
203 __ movdqu(xmm0, Operand(src, 0));
204 __ movdqu(Operand(dst, 0), xmm0);
209 __ add(edx, Immediate(16));
214 __ mov(loop_count, count);
215 __ shr(loop_count, 6);
217 __ test(src, Immediate(0xF));
218 __ j(not_zero, &unaligned_source);
220 MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, MOVE_ALIGNED);
222 __ bind(&move_last_15);
224 __ j(zero, &skip_last_move, Label::kNear);
225 __ movdqu(xmm0, Operand(src, count, times_1, -0x10));
226 __ movdqu(Operand(dst, count, times_1, -0x10), xmm0);
227 __ bind(&skip_last_move);
228 MemMoveEmitPopAndReturn(&masm);
231 __ bind(&unaligned_source);
232 MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, MOVE_UNALIGNED);
233 __ jmp(&move_last_15);
236 Label loop_until_aligned, last_15_much_overlap;
237 __ bind(&loop_until_aligned);
238 __ mov_b(eax, Operand(src, 0));
240 __ mov_b(Operand(dst, 0), eax);
243 __ bind(&forward_much_overlap);
244 __ test(dst, Immediate(0xF));
245 __ j(not_zero, &loop_until_aligned);
247 __ mov(loop_count, count);
248 __ shr(loop_count, 6);
249 MemMoveEmitMainLoop(&masm, &last_15_much_overlap,
250 FORWARD, MOVE_UNALIGNED);
251 __ bind(&last_15_much_overlap);
253 __ j(zero, &pop_and_return);
254 __ cmp(count, kSmallCopySize);
255 __ j(below_equal, &small_size);
256 __ jmp(&medium_size);
261 Label unaligned_source, move_first_15, skip_last_move;
268 __ cmp(eax, kMinMoveDistance);
269 __ j(below, &backward_much_overlap);
271 __ movdqu(xmm0, Operand(src, -0x10));
272 __ movdqu(Operand(dst, -0x10), xmm0);
280 __ mov(loop_count, count);
281 __ shr(loop_count, 6);
283 __ test(src, Immediate(0xF));
284 __ j(not_zero, &unaligned_source);
286 MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, MOVE_ALIGNED);
288 __ bind(&move_first_15);
290 __ j(zero, &skip_last_move, Label::kNear);
293 __ movdqu(xmm0, Operand(src, 0));
294 __ movdqu(Operand(dst, 0), xmm0);
295 __ bind(&skip_last_move);
296 MemMoveEmitPopAndReturn(&masm);
299 __ bind(&unaligned_source);
300 MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, MOVE_UNALIGNED);
301 __ jmp(&move_first_15);
304 Label loop_until_aligned, first_15_much_overlap;
305 __ bind(&loop_until_aligned);
308 __ mov_b(eax, Operand(src, 0));
309 __ mov_b(Operand(dst, 0), eax);
311 __ bind(&backward_much_overlap);
312 __ test(dst, Immediate(0xF));
313 __ j(not_zero, &loop_until_aligned);
315 __ mov(loop_count, count);
316 __ shr(loop_count, 6);
317 MemMoveEmitMainLoop(&masm, &first_15_much_overlap,
318 BACKWARD, MOVE_UNALIGNED);
319 __ bind(&first_15_much_overlap);
321 __ j(zero, &pop_and_return);
325 __ cmp(count, kSmallCopySize);
326 __ j(below_equal, &small_size);
327 __ jmp(&medium_size);
333 Label medium_handlers, f9_16, f17_32, f33_48, f49_63;
336 __ movsd(xmm0, Operand(src, 0));
337 __ movsd(xmm1, Operand(src, count, times_1, -8));
338 __ movsd(Operand(dst, 0), xmm0);
339 __ movsd(Operand(dst, count, times_1, -8), xmm1);
340 MemMoveEmitPopAndReturn(&masm);
343 __ movdqu(xmm0, Operand(src, 0));
344 __ movdqu(xmm1, Operand(src, count, times_1, -0x10));
345 __ movdqu(Operand(dst, 0x00), xmm0);
346 __ movdqu(Operand(dst, count, times_1, -0x10), xmm1);
347 MemMoveEmitPopAndReturn(&masm);
350 __ movdqu(xmm0, Operand(src, 0x00));
351 __ movdqu(xmm1, Operand(src, 0x10));
352 __ movdqu(xmm2, Operand(src, count, times_1, -0x10));
353 __ movdqu(Operand(dst, 0x00), xmm0);
354 __ movdqu(Operand(dst, 0x10), xmm1);
355 __ movdqu(Operand(dst, count, times_1, -0x10), xmm2);
356 MemMoveEmitPopAndReturn(&masm);
359 __ movdqu(xmm0, Operand(src, 0x00));
360 __ movdqu(xmm1, Operand(src, 0x10));
361 __ movdqu(xmm2, Operand(src, 0x20));
362 __ movdqu(xmm3, Operand(src, count, times_1, -0x10));
363 __ movdqu(Operand(dst, 0x00), xmm0);
364 __ movdqu(Operand(dst, 0x10), xmm1);
365 __ movdqu(Operand(dst, 0x20), xmm2);
366 __ movdqu(Operand(dst, count, times_1, -0x10), xmm3);
367 MemMoveEmitPopAndReturn(&masm);
369 __ bind(&medium_handlers);
370 __ dd(conv.address(&f9_16));
371 __ dd(conv.address(&f17_32));
372 __ dd(conv.address(&f33_48));
373 __ dd(conv.address(&f49_63));
375 __ bind(&medium_size);
379 if (FLAG_debug_code) {
382 __ j(below_equal, &ok);
386 __ mov(eax, Operand(eax, times_4, conv.address(&medium_handlers)));
391 Label small_handlers, f0, f1, f2, f3, f4, f5_8;
393 MemMoveEmitPopAndReturn(&masm);
396 __ mov_b(eax, Operand(src, 0));
397 __ mov_b(Operand(dst, 0), eax);
398 MemMoveEmitPopAndReturn(&masm);
401 __ mov_w(eax, Operand(src, 0));
402 __ mov_w(Operand(dst, 0), eax);
403 MemMoveEmitPopAndReturn(&masm);
406 __ mov_w(eax, Operand(src, 0));
407 __ mov_b(edx, Operand(src, 2));
408 __ mov_w(Operand(dst, 0), eax);
409 __ mov_b(Operand(dst, 2), edx);
410 MemMoveEmitPopAndReturn(&masm);
413 __ mov(eax, Operand(src, 0));
414 __ mov(Operand(dst, 0), eax);
415 MemMoveEmitPopAndReturn(&masm);
418 __ mov(eax, Operand(src, 0));
419 __ mov(edx, Operand(src, count, times_1, -4));
420 __ mov(Operand(dst, 0), eax);
421 __ mov(Operand(dst, count, times_1, -4), edx);
422 MemMoveEmitPopAndReturn(&masm);
424 __ bind(&small_handlers);
425 __ dd(conv.address(&f0));
426 __ dd(conv.address(&f1));
427 __ dd(conv.address(&f2));
428 __ dd(conv.address(&f3));
429 __ dd(conv.address(&f4));
430 __ dd(conv.address(&f5_8));
431 __ dd(conv.address(&f5_8));
432 __ dd(conv.address(&f5_8));
433 __ dd(conv.address(&f5_8));
435 __ bind(&small_size);
436 if (FLAG_debug_code) {
439 __ j(below_equal, &ok);
443 __ mov(eax, Operand(count, times_4, conv.address(&small_handlers)));
447 __ bind(&pop_and_return);
448 MemMoveEmitPopAndReturn(&masm);
451 masm.GetCode(
nullptr, &desc);
452 DCHECK(!RelocInfo::RequiresRelocationAfterCodegen(desc));
453 Assembler::FlushICache(buffer, allocated);
454 CHECK(SetPermissions(page_allocator, buffer, allocated,
455 PageAllocator::kReadExecute));
458 return FUNCTION_CAST<MemMoveFunction>(buffer);
467 #endif // V8_TARGET_ARCH_IA32
virtual void * GetRandomMmapAddr()=0