diff options
Diffstat (limited to 'deps/v8/src/ia32/codegen-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/codegen-ia32.cc | 467 |
1 files changed, 0 insertions, 467 deletions
diff --git a/deps/v8/src/ia32/codegen-ia32.cc b/deps/v8/src/ia32/codegen-ia32.cc deleted file mode 100644 index 78790b75d0..0000000000 --- a/deps/v8/src/ia32/codegen-ia32.cc +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_IA32 - -#include "src/codegen.h" -#include "src/heap/factory-inl.h" -#include "src/heap/heap.h" -#include "src/macro-assembler.h" - -namespace v8 { -namespace internal { - -#define __ masm. - -UnaryMathFunction CreateSqrtFunction() { - v8::PageAllocator* page_allocator = GetPlatformPageAllocator(); - size_t allocated = 0; - byte* buffer = AllocatePage(page_allocator, - page_allocator->GetRandomMmapAddr(), &allocated); - if (buffer == nullptr) return nullptr; - - MacroAssembler masm(AssemblerOptions{}, buffer, static_cast<int>(allocated)); - // esp[1 * kPointerSize]: raw double input - // esp[0 * kPointerSize]: return address - // Move double input into registers. - { - __ movsd(xmm0, Operand(esp, 1 * kPointerSize)); - __ sqrtsd(xmm0, xmm0); - __ movsd(Operand(esp, 1 * kPointerSize), xmm0); - // Load result into floating point register as return value. - __ fld_d(Operand(esp, 1 * kPointerSize)); - __ Ret(); - } - - CodeDesc desc; - masm.GetCode(nullptr, &desc); - DCHECK(!RelocInfo::RequiresRelocationAfterCodegen(desc)); - - Assembler::FlushICache(buffer, allocated); - CHECK(SetPermissions(page_allocator, buffer, allocated, - PageAllocator::kReadExecute)); - return FUNCTION_CAST<UnaryMathFunction>(buffer); -} - - -// Helper functions for CreateMemMoveFunction. -#undef __ -#define __ ACCESS_MASM(masm) - -enum Direction { FORWARD, BACKWARD }; -enum Alignment { MOVE_ALIGNED, MOVE_UNALIGNED }; - -// Expects registers: -// esi - source, aligned if alignment == ALIGNED -// edi - destination, always aligned -// ecx - count (copy size in bytes) -// edx - loop count (number of 64 byte chunks) -void MemMoveEmitMainLoop(MacroAssembler* masm, - Label* move_last_15, - Direction direction, - Alignment alignment) { - Register src = esi; - Register dst = edi; - Register count = ecx; - Register loop_count = edx; - Label loop, move_last_31, move_last_63; - __ cmp(loop_count, 0); - __ j(equal, &move_last_63); - __ bind(&loop); - // Main loop. Copy in 64 byte chunks. - if (direction == BACKWARD) __ sub(src, Immediate(0x40)); - __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0x00)); - __ movdq(alignment == MOVE_ALIGNED, xmm1, Operand(src, 0x10)); - __ movdq(alignment == MOVE_ALIGNED, xmm2, Operand(src, 0x20)); - __ movdq(alignment == MOVE_ALIGNED, xmm3, Operand(src, 0x30)); - if (direction == FORWARD) __ add(src, Immediate(0x40)); - if (direction == BACKWARD) __ sub(dst, Immediate(0x40)); - __ movdqa(Operand(dst, 0x00), xmm0); - __ movdqa(Operand(dst, 0x10), xmm1); - __ movdqa(Operand(dst, 0x20), xmm2); - __ movdqa(Operand(dst, 0x30), xmm3); - if (direction == FORWARD) __ add(dst, Immediate(0x40)); - __ dec(loop_count); - __ j(not_zero, &loop); - // At most 63 bytes left to copy. - __ bind(&move_last_63); - __ test(count, Immediate(0x20)); - __ j(zero, &move_last_31); - if (direction == BACKWARD) __ sub(src, Immediate(0x20)); - __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0x00)); - __ movdq(alignment == MOVE_ALIGNED, xmm1, Operand(src, 0x10)); - if (direction == FORWARD) __ add(src, Immediate(0x20)); - if (direction == BACKWARD) __ sub(dst, Immediate(0x20)); - __ movdqa(Operand(dst, 0x00), xmm0); - __ movdqa(Operand(dst, 0x10), xmm1); - if (direction == FORWARD) __ add(dst, Immediate(0x20)); - // At most 31 bytes left to copy. - __ bind(&move_last_31); - __ test(count, Immediate(0x10)); - __ j(zero, move_last_15); - if (direction == BACKWARD) __ sub(src, Immediate(0x10)); - __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0)); - if (direction == FORWARD) __ add(src, Immediate(0x10)); - if (direction == BACKWARD) __ sub(dst, Immediate(0x10)); - __ movdqa(Operand(dst, 0), xmm0); - if (direction == FORWARD) __ add(dst, Immediate(0x10)); -} - - -void MemMoveEmitPopAndReturn(MacroAssembler* masm) { - __ pop(esi); - __ pop(edi); - __ ret(0); -} - - -#undef __ -#define __ masm. - - -class LabelConverter { - public: - explicit LabelConverter(byte* buffer) : buffer_(buffer) {} - int32_t address(Label* l) const { - return reinterpret_cast<int32_t>(buffer_) + l->pos(); - } - private: - byte* buffer_; -}; - -MemMoveFunction CreateMemMoveFunction() { - v8::PageAllocator* page_allocator = GetPlatformPageAllocator(); - size_t allocated = 0; - byte* buffer = AllocatePage(page_allocator, - page_allocator->GetRandomMmapAddr(), &allocated); - if (buffer == nullptr) return nullptr; - - MacroAssembler masm(AssemblerOptions{}, buffer, static_cast<int>(allocated)); - LabelConverter conv(buffer); - - // Generated code is put into a fixed, unmovable buffer, and not into - // the V8 heap. We can't, and don't, refer to any relocatable addresses - // (e.g. the JavaScript nan-object). - - // 32-bit C declaration function calls pass arguments on stack. - - // Stack layout: - // esp[12]: Third argument, size. - // esp[8]: Second argument, source pointer. - // esp[4]: First argument, destination pointer. - // esp[0]: return address - - const int kDestinationOffset = 1 * kPointerSize; - const int kSourceOffset = 2 * kPointerSize; - const int kSizeOffset = 3 * kPointerSize; - - // When copying up to this many bytes, use special "small" handlers. - const size_t kSmallCopySize = 8; - // When copying up to this many bytes, use special "medium" handlers. - const size_t kMediumCopySize = 63; - // When non-overlapping region of src and dst is less than this, - // use a more careful implementation (slightly slower). - const size_t kMinMoveDistance = 16; - // Note that these values are dictated by the implementation below, - // do not just change them and hope things will work! - - int stack_offset = 0; // Update if we change the stack height. - - Label backward, backward_much_overlap; - Label forward_much_overlap, small_size, medium_size, pop_and_return; - __ push(edi); - __ push(esi); - stack_offset += 2 * kPointerSize; - Register dst = edi; - Register src = esi; - Register count = ecx; - Register loop_count = edx; - __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); - __ mov(src, Operand(esp, stack_offset + kSourceOffset)); - __ mov(count, Operand(esp, stack_offset + kSizeOffset)); - - __ cmp(dst, src); - __ j(equal, &pop_and_return); - - __ prefetch(Operand(src, 0), 1); - __ cmp(count, kSmallCopySize); - __ j(below_equal, &small_size); - __ cmp(count, kMediumCopySize); - __ j(below_equal, &medium_size); - __ cmp(dst, src); - __ j(above, &backward); - - { - // |dst| is a lower address than |src|. Copy front-to-back. - Label unaligned_source, move_last_15, skip_last_move; - __ mov(eax, src); - __ sub(eax, dst); - __ cmp(eax, kMinMoveDistance); - __ j(below, &forward_much_overlap); - // Copy first 16 bytes. - __ movdqu(xmm0, Operand(src, 0)); - __ movdqu(Operand(dst, 0), xmm0); - // Determine distance to alignment: 16 - (dst & 0xF). - __ mov(edx, dst); - __ and_(edx, 0xF); - __ neg(edx); - __ add(edx, Immediate(16)); - __ add(dst, edx); - __ add(src, edx); - __ sub(count, edx); - // dst is now aligned. Main copy loop. - __ mov(loop_count, count); - __ shr(loop_count, 6); - // Check if src is also aligned. - __ test(src, Immediate(0xF)); - __ j(not_zero, &unaligned_source); - // Copy loop for aligned source and destination. - MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, MOVE_ALIGNED); - // At most 15 bytes to copy. Copy 16 bytes at end of string. - __ bind(&move_last_15); - __ and_(count, 0xF); - __ j(zero, &skip_last_move, Label::kNear); - __ movdqu(xmm0, Operand(src, count, times_1, -0x10)); - __ movdqu(Operand(dst, count, times_1, -0x10), xmm0); - __ bind(&skip_last_move); - MemMoveEmitPopAndReturn(&masm); - - // Copy loop for unaligned source and aligned destination. - __ bind(&unaligned_source); - MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, MOVE_UNALIGNED); - __ jmp(&move_last_15); - - // Less than kMinMoveDistance offset between dst and src. - Label loop_until_aligned, last_15_much_overlap; - __ bind(&loop_until_aligned); - __ mov_b(eax, Operand(src, 0)); - __ inc(src); - __ mov_b(Operand(dst, 0), eax); - __ inc(dst); - __ dec(count); - __ bind(&forward_much_overlap); // Entry point into this block. - __ test(dst, Immediate(0xF)); - __ j(not_zero, &loop_until_aligned); - // dst is now aligned, src can't be. Main copy loop. - __ mov(loop_count, count); - __ shr(loop_count, 6); - MemMoveEmitMainLoop(&masm, &last_15_much_overlap, - FORWARD, MOVE_UNALIGNED); - __ bind(&last_15_much_overlap); - __ and_(count, 0xF); - __ j(zero, &pop_and_return); - __ cmp(count, kSmallCopySize); - __ j(below_equal, &small_size); - __ jmp(&medium_size); - } - - { - // |dst| is a higher address than |src|. Copy backwards. - Label unaligned_source, move_first_15, skip_last_move; - __ bind(&backward); - // |dst| and |src| always point to the end of what's left to copy. - __ add(dst, count); - __ add(src, count); - __ mov(eax, dst); - __ sub(eax, src); - __ cmp(eax, kMinMoveDistance); - __ j(below, &backward_much_overlap); - // Copy last 16 bytes. - __ movdqu(xmm0, Operand(src, -0x10)); - __ movdqu(Operand(dst, -0x10), xmm0); - // Find distance to alignment: dst & 0xF - __ mov(edx, dst); - __ and_(edx, 0xF); - __ sub(dst, edx); - __ sub(src, edx); - __ sub(count, edx); - // dst is now aligned. Main copy loop. - __ mov(loop_count, count); - __ shr(loop_count, 6); - // Check if src is also aligned. - __ test(src, Immediate(0xF)); - __ j(not_zero, &unaligned_source); - // Copy loop for aligned source and destination. - MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, MOVE_ALIGNED); - // At most 15 bytes to copy. Copy 16 bytes at beginning of string. - __ bind(&move_first_15); - __ and_(count, 0xF); - __ j(zero, &skip_last_move, Label::kNear); - __ sub(src, count); - __ sub(dst, count); - __ movdqu(xmm0, Operand(src, 0)); - __ movdqu(Operand(dst, 0), xmm0); - __ bind(&skip_last_move); - MemMoveEmitPopAndReturn(&masm); - - // Copy loop for unaligned source and aligned destination. - __ bind(&unaligned_source); - MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, MOVE_UNALIGNED); - __ jmp(&move_first_15); - - // Less than kMinMoveDistance offset between dst and src. - Label loop_until_aligned, first_15_much_overlap; - __ bind(&loop_until_aligned); - __ dec(src); - __ dec(dst); - __ mov_b(eax, Operand(src, 0)); - __ mov_b(Operand(dst, 0), eax); - __ dec(count); - __ bind(&backward_much_overlap); // Entry point into this block. - __ test(dst, Immediate(0xF)); - __ j(not_zero, &loop_until_aligned); - // dst is now aligned, src can't be. Main copy loop. - __ mov(loop_count, count); - __ shr(loop_count, 6); - MemMoveEmitMainLoop(&masm, &first_15_much_overlap, - BACKWARD, MOVE_UNALIGNED); - __ bind(&first_15_much_overlap); - __ and_(count, 0xF); - __ j(zero, &pop_and_return); - // Small/medium handlers expect dst/src to point to the beginning. - __ sub(dst, count); - __ sub(src, count); - __ cmp(count, kSmallCopySize); - __ j(below_equal, &small_size); - __ jmp(&medium_size); - } - { - // Special handlers for 9 <= copy_size < 64. No assumptions about - // alignment or move distance, so all reads must be unaligned and - // must happen before any writes. - Label medium_handlers, f9_16, f17_32, f33_48, f49_63; - - __ bind(&f9_16); - __ movsd(xmm0, Operand(src, 0)); - __ movsd(xmm1, Operand(src, count, times_1, -8)); - __ movsd(Operand(dst, 0), xmm0); - __ movsd(Operand(dst, count, times_1, -8), xmm1); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f17_32); - __ movdqu(xmm0, Operand(src, 0)); - __ movdqu(xmm1, Operand(src, count, times_1, -0x10)); - __ movdqu(Operand(dst, 0x00), xmm0); - __ movdqu(Operand(dst, count, times_1, -0x10), xmm1); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f33_48); - __ movdqu(xmm0, Operand(src, 0x00)); - __ movdqu(xmm1, Operand(src, 0x10)); - __ movdqu(xmm2, Operand(src, count, times_1, -0x10)); - __ movdqu(Operand(dst, 0x00), xmm0); - __ movdqu(Operand(dst, 0x10), xmm1); - __ movdqu(Operand(dst, count, times_1, -0x10), xmm2); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f49_63); - __ movdqu(xmm0, Operand(src, 0x00)); - __ movdqu(xmm1, Operand(src, 0x10)); - __ movdqu(xmm2, Operand(src, 0x20)); - __ movdqu(xmm3, Operand(src, count, times_1, -0x10)); - __ movdqu(Operand(dst, 0x00), xmm0); - __ movdqu(Operand(dst, 0x10), xmm1); - __ movdqu(Operand(dst, 0x20), xmm2); - __ movdqu(Operand(dst, count, times_1, -0x10), xmm3); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&medium_handlers); - __ dd(conv.address(&f9_16)); - __ dd(conv.address(&f17_32)); - __ dd(conv.address(&f33_48)); - __ dd(conv.address(&f49_63)); - - __ bind(&medium_size); // Entry point into this block. - __ mov(eax, count); - __ dec(eax); - __ shr(eax, 4); - if (FLAG_debug_code) { - Label ok; - __ cmp(eax, 3); - __ j(below_equal, &ok); - __ int3(); - __ bind(&ok); - } - __ mov(eax, Operand(eax, times_4, conv.address(&medium_handlers))); - __ jmp(eax); - } - { - // Specialized copiers for copy_size <= 8 bytes. - Label small_handlers, f0, f1, f2, f3, f4, f5_8; - __ bind(&f0); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f1); - __ mov_b(eax, Operand(src, 0)); - __ mov_b(Operand(dst, 0), eax); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f2); - __ mov_w(eax, Operand(src, 0)); - __ mov_w(Operand(dst, 0), eax); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f3); - __ mov_w(eax, Operand(src, 0)); - __ mov_b(edx, Operand(src, 2)); - __ mov_w(Operand(dst, 0), eax); - __ mov_b(Operand(dst, 2), edx); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f4); - __ mov(eax, Operand(src, 0)); - __ mov(Operand(dst, 0), eax); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&f5_8); - __ mov(eax, Operand(src, 0)); - __ mov(edx, Operand(src, count, times_1, -4)); - __ mov(Operand(dst, 0), eax); - __ mov(Operand(dst, count, times_1, -4), edx); - MemMoveEmitPopAndReturn(&masm); - - __ bind(&small_handlers); - __ dd(conv.address(&f0)); - __ dd(conv.address(&f1)); - __ dd(conv.address(&f2)); - __ dd(conv.address(&f3)); - __ dd(conv.address(&f4)); - __ dd(conv.address(&f5_8)); - __ dd(conv.address(&f5_8)); - __ dd(conv.address(&f5_8)); - __ dd(conv.address(&f5_8)); - - __ bind(&small_size); // Entry point into this block. - if (FLAG_debug_code) { - Label ok; - __ cmp(count, 8); - __ j(below_equal, &ok); - __ int3(); - __ bind(&ok); - } - __ mov(eax, Operand(count, times_4, conv.address(&small_handlers))); - __ jmp(eax); - } - - __ bind(&pop_and_return); - MemMoveEmitPopAndReturn(&masm); - - CodeDesc desc; - masm.GetCode(nullptr, &desc); - DCHECK(!RelocInfo::RequiresRelocationAfterCodegen(desc)); - Assembler::FlushICache(buffer, allocated); - CHECK(SetPermissions(page_allocator, buffer, allocated, - PageAllocator::kReadExecute)); - // TODO(jkummerow): It would be nice to register this code creation event - // with the PROFILE / GDBJIT system. - return FUNCTION_CAST<MemMoveFunction>(buffer); -} - - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_IA32 |