summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/codegen-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/codegen-ia32.cc')
-rw-r--r--deps/v8/src/ia32/codegen-ia32.cc467
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