assembler-ia32.cc revision 402d937239b0e2fd11bf2f4fe972ad78aa9fd481
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved. 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice, 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// distribution. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THE POSSIBILITY OF SUCH DAMAGE. 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been modified 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// significantly by Google Inc. 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "disassembler.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "serialize.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of CpuFeatures 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Safe default is no features. 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuint64_t CpuFeatures::supported_ = 0; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuint64_t CpuFeatures::enabled_ = 0; 52d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockuint64_t CpuFeatures::found_by_runtime_probing_ = 0; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The Probe method needs executable memory, so it uses Heap::CreateCode. 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Allocation failure is silent and leads to safe default. 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CpuFeatures::Probe() { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Heap::HasBeenSetup()); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(supported_ == 0); 60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (Serializer::enabled()) { 61d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block supported_ |= OS::CpuFeaturesImpliedByPlatform(); 62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; // No features if we might serialize. 63d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler assm(NULL, 0); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label cpuid, done; 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm. 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save old esp, since we are going to modify the stack. 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(ebp); 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pushfd(); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(ecx); 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(ebx); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(ebp, Operand(esp)); 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pushfd(); 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(eax); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(edx, Operand(eax)); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(eax, 0x200000); // Flip bit 21. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(eax); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ popfd(); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pushfd(); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(eax); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(eax, Operand(edx)); // Different if CPUID is supported. 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ j(not_zero, &cpuid); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPUID not supported. Clear the supported features in edx:eax. 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(eax, Operand(eax)); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(edx, Operand(edx)); 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ jmp(&done); 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke CPUID with 1 in eax to get feature information in 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ecx:edx. Temporarily enable CPUID support because we know it's 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // safe here. 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&cpuid); 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, 1); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block supported_ = (1 << CPUID); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { Scope fscope(CPUID); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ cpuid(); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block supported_ = 0; 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move the result from ecx:edx to edx:eax and make sure to mark the 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPUID feature as supported. 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, Operand(edx)); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ or_(eax, 1 << CPUID); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(edx, Operand(ecx)); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Done. 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&done); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(esp, Operand(ebp)); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(ebx); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(ecx); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ popfd(); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(ebp); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef __ 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* code = Heap::CreateCode(desc, 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeFlags(Code::STUB), 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code>::null()); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!code->IsCode()) return; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LOG(CodeCreateEvent(Logger::BUILTIN_TAG, 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::cast(code), "CpuFeatures::Probe")); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef uint64_t (*F0)(); 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block supported_ = probe(); 131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block found_by_runtime_probing_ = supported_; 132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); 133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block supported_ |= os_guarantees; 134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block found_by_runtime_probing_ &= ~os_guarantees; 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Displacement 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Displacement::init(Label* L, Type type) { 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!L->is_bound()); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int next = 0; 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_linked()) { 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next = L->pos(); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(next > 0); // Displacements must be at positions > 0 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ensure that we _never_ overflow the next field. 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize)); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block data_ = NextField::encode(next) | TypeField::encode(type); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of RelocInfo 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int RelocInfo::kApplyMask = 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE; 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code at the current address with the supplied instructions. 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < instruction_count; i++) { 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *(pc_ + i) = *(instructions + i); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicate that code has changed. 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CPU::FlushICache(pc_, instruction_count); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Patch the code at the current PC with a call to the target address. 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Additional guard int3 instructions can be added if required. 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call instruction takes up 5 bytes and int3 takes up one byte. 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kCallCodeSize = 5; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int code_size = kCallCodeSize + guard_bytes; 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a code patcher. 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodePatcher patcher(pc_, code_size); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add a label for checking the size of the code used for returning. 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label check_codesize; 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->bind(&check_codesize); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code. 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->call(target, RelocInfo::NONE); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the size of the code generated is as expected. 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(kCallCodeSize, 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add the requested number of int3 instructions after the call. 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < guard_bytes; i++) { 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->int3(); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Operand 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) { 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base] 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, base); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (base.is(esp)) set_sib(times_1, esp, base); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_int8(disp) && rmode == RelocInfo::NONE) { 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp8] 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(1, base); 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (base.is(esp)) set_sib(times_1, esp, base); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_disp8(disp); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(2, base); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (base.is(esp)) set_sib(times_1, esp, base); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register base, 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp, 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode) { 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!index.is(esp)); // illegal addressing mode 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) { 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale] 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, esp); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, base); 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_int8(disp) && rmode == RelocInfo::NONE) { 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp8] 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(1, esp); 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, base); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_disp8(disp); 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(2, esp); 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, base); 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register index, 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp, 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode) { 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!index.is(esp)); // illegal addressing mode 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [index*scale + disp/r] 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, esp); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, ebp); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Operand::is_reg(Register reg) const { 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block && ((buf_[0] & 0x07) == reg.code()); // register codes match. 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 2703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Implementation of Assembler. 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Emit a single byte. Must always be inlined. 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define EMIT(x) \ 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *pc_++ = (x) 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitCoverageLog(); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Spare buffer. 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbyte* Assembler::spare_buffer_ = NULL; 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAssembler::Assembler(void* buffer, int buffer_size) { 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer == NULL) { 2863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Do our own buffer management. 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_size <= kMinimalBufferSize) { 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size = kMinimalBufferSize; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_buffer_ != NULL) { 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer = spare_buffer_; 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_buffer_ = NULL; 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer == NULL) { 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = NewArray<byte>(buffer_size); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = static_cast<byte*>(buffer); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size_ = buffer_size; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block own_buffer_ = true; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Use externally provided buffer instead. 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(buffer_size > 0); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = static_cast<byte*>(buffer); 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size_ = buffer_size; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block own_buffer_ = false; 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the buffer in debug mode unless it was provided by the 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // caller in which case we can't be sure it's okay to overwrite 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // existing code in it; see CodePatcher::CodePatcher(...). 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (own_buffer_) { 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memset(buffer_, 0xCC, buffer_size); // int3 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Setup buffer pointers. 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(buffer_ != NULL); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ = buffer_; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_statement_position_ = RelocInfo::kNoPosition; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_position_ = RelocInfo::kNoPosition; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block written_statement_position_ = current_statement_position_; 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block written_position_ = current_position_; 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitCoverageLog(); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAssembler::~Assembler() { 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (own_buffer_) { 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_buffer_ = buffer_; 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(buffer_); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::GetCode(CodeDesc* desc) { 3473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Finalize code (at this point overflow() may be true, but the gap ensures 3483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // that we are still not overlapping instructions and relocation info). 3493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. 3503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Setup code descriptor. 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->buffer = buffer_; 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->buffer_size = buffer_size_; 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->instr_size = pc_offset(); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->origin = this; 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::reloc_info_size.Increment(desc->reloc_size); 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::Align(int m) { 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsPowerOf2(m)); 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((pc_offset() & (m - 1)) != 0) { 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nop(); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cpuid() { 370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CPUID)); 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA2); 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pushad() { 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x60); 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::popad() { 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x61); 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pushfd() { 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9C); 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::popfd() { 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9D); 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::push(const Immediate& x) { 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x.is_int8()) { 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x6a); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(x.x_); 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x68); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::push(Register src) { 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x50 | src.code()); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::push(const Operand& src) { 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(esi, src); 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pop(Register dst) { 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_info_writer.last_pc() != NULL); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { 4373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // (last_pc_ != NULL) is rolled into the above check. 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If a last_pc_ is set, we need to make sure that there has not been any 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information generated between the last instruction and this 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pop instruction. 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte instr = last_pc_[0]; 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & ~0x7) == 0x50) { 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int push_reg_code = instr & 0x7; 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (push_reg_code == dst.code()) { 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ = last_pc_; 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (same reg) eliminated\n", pc_offset()); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convert 'push src; pop dst' to 'mov dst, src'. 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x8b; 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src = { push_reg_code }; 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, Operand(src)); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset()); 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (instr == 0xff) { // push of an operand, convert to a move 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte op1 = last_pc_[1]; 4633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check if the operation is really a push. 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((op1 & 0x38) == (6 << 3)) { 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3); 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x8b; 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[1] = op1; 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (op->reg) eliminated\n", pc_offset()); 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if ((instr == 0x89) && 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (last_pc_[1] == 0x04) && 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (last_pc_[2] == 0x24)) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x71283c 396 890424 mov [esp],eax 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x71283f 399 58 pop eax 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(eax)) { 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x710fac 216 83c404 add esp,0x4 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x83; 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[1] = 0xc4; 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[2] = 0x04; 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset()); 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte imm8 = last_pc_[1]; 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 0) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 6a00 push 0x0 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58 pop eax 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x31; 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[1] = 0xc0; 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 31c0 xor eax,eax 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 6a00 push 0xXX 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58 pop eax 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0xb8; 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((imm8 & 0x80) != 0) { 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xff); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xff); 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xff); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // b8XXffffff mov eax,0xffffffXX 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x00); 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x00); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x00); 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // b8XX000000 mov eax,0x000000XX 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 68XXXXXXXX push 0xXXXXXXXX 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58 pop eax 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0xb8; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // b8XXXXXXXX mov eax,0xXXXXXXXX 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Other potential patterns for peephole: 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x712716 102 890424 mov [esp], eax 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x712719 105 8b1424 mov edx, [esp] 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x58 | dst.code()); 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pop(const Operand& dst) { 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8F); 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::enter(const Immediate& size) { 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC8); 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_w(size); 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0); 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::leave() { 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC9); 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_b(Register dst, const Operand& src) { 577e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(dst.code() < 4); 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8A); 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_b(const Operand& dst, int8_t imm8) { 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC6); 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_b(const Operand& dst, Register src) { 595e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(src.code() < 4); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x88); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_w(Register dst, const Operand& src) { 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8B); 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_w(const Operand& dst, Register src) { 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x89); 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, int32_t imm32) { 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB8 | dst.code()); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm32); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, const Immediate& x) { 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB8 | dst.code()); 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, Handle<Object> handle) { 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB8 | dst.code()); 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(handle); 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, const Operand& src) { 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8B); 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, Register src) { 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x89); 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | src.code() << 3 | dst.code()); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(const Operand& dst, const Immediate& x) { 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC7); 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(const Operand& dst, Handle<Object> handle) { 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC7); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(handle); 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(const Operand& dst, Register src) { 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x89); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsx_b(Register dst, const Operand& src) { 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xBE); 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsx_w(Register dst, const Operand& src) { 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xBF); 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movzx_b(Register dst, const Operand& src) { 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB6); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movzx_w(Register dst, const Operand& src) { 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB7); 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmov(Condition cc, Register dst, int32_t imm32) { 724d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CMOV)); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(cc); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(dst); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(imm32); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmov(Condition cc, Register dst, Handle<Object> handle) { 735d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CMOV)); 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(cc); 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(dst); 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(handle); 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmov(Condition cc, Register dst, const Operand& src) { 746d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CMOV)); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 7493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Opcode: 0f 40 + cc /r. 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x40 + cc); 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 756e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::rep_movs() { 757e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 758e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 759e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xF3); 760e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xA5); 761e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 762e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 763e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xchg(Register dst, Register src) { 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 7673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x87); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | src.code() << 3 | dst.code()); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::adc(Register dst, int32_t imm32) { 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(2, Operand(dst), Immediate(imm32)); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::adc(Register dst, const Operand& src) { 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x13); 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::add(Register dst, const Operand& src) { 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x03); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::add(const Operand& dst, const Immediate& x) { 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_info_writer.last_pc() != NULL); 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte instr = last_pc_[0]; 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & 0xf8) == 0x50) { 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Last instruction was a push. Check whether this is a pop without a 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // result. 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((dst.is_reg(esp)) && 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) { 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ = last_pc_; 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_print_push_pop_elimination) { 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop(noreg) eliminated\n", pc_offset()); 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(0, dst, x); 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(Register dst, int32_t imm32) { 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(4, Operand(dst), Immediate(imm32)); 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(Register dst, const Operand& src) { 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x23); 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(const Operand& dst, const Immediate& x) { 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(4, dst, x); 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(const Operand& dst, Register src) { 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x21); 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpb(const Operand& op, int8_t imm8) { 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80); 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edi, op); // edi == 7 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 862d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Assembler::cmpb(const Operand& dst, Register src) { 863d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(src.is_byte_register()); 864d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnsureSpace ensure_space(this); 865d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke last_pc_ = pc_; 866d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EMIT(0x38); 867d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke emit_operand(src, dst); 868d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 869d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 870d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 871d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Assembler::cmpb(Register dst, const Operand& src) { 872d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(dst.is_byte_register()); 873d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnsureSpace ensure_space(this); 874d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke last_pc_ = pc_; 875d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EMIT(0x3A); 876d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke emit_operand(dst, src); 877d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 878d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 879d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpw(const Operand& op, Immediate imm16) { 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(imm16.is_int16()); 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x81); 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edi, op); 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_w(imm16); 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(Register reg, int32_t imm32) { 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, Operand(reg), Immediate(imm32)); 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(Register reg, Handle<Object> handle) { 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, Operand(reg), Immediate(handle)); 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(Register reg, const Operand& op) { 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x3B); 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg, op); 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(const Operand& op, const Immediate& imm) { 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, op, imm); 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(const Operand& op, Handle<Object> handle) { 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, op, Immediate(handle)); 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpb_al(const Operand& op) { 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x38); // CMP r/m8, r8 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, op); // eax has same code as register al. 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpw_ax(const Operand& op) { 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x39); // CMP r/m16, r16 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, op); // eax has same code as register ax. 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dec_b(Register dst) { 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFE); 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC8 | dst.code()); 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dec(Register dst) { 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x48 | dst.code()); 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dec(const Operand& dst) { 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ecx, dst); 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cdq() { 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x99); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::idiv(Register src) { 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | src.code()); 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::imul(Register reg) { 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8 | reg.code()); 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::imul(Register dst, const Operand& src) { 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xAF); 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::imul(Register dst, Register src, int32_t imm32) { 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_int8(imm32)) { 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x6B); 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm32); 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x69); 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm32); 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::inc(Register dst) { 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x40 | dst.code()); 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::inc(const Operand& dst) { 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::lea(Register dst, const Operand& src) { 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8D); 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mul(Register src) { 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | src.code()); 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::neg(Register dst) { 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD8 | dst.code()); 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::not_(Register dst) { 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD0 | dst.code()); 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(Register dst, int32_t imm32) { 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(1, Operand(dst), Immediate(imm32)); 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(Register dst, const Operand& src) { 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0B); 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(const Operand& dst, const Immediate& x) { 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(1, dst, x); 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(const Operand& dst, Register src) { 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x09); 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::rcl(Register dst, uint8_t imm8) { 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 1) { 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD1); 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD0 | dst.code()); 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC1); 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD0 | dst.code()); 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sar(Register dst, uint8_t imm8) { 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 1) { 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD1); 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | dst.code()); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC1); 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | dst.code()); 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Assembler::sar_cl(Register dst) { 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD3); 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | dst.code()); 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sbb(Register dst, const Operand& src) { 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x1B); 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shld(Register dst, const Operand& src) { 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA5); 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shl(Register dst, uint8_t imm8) { 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 1) { 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD1); 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | dst.code()); 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC1); 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | dst.code()); 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Assembler::shl_cl(Register dst) { 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD3); 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | dst.code()); 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shrd(Register dst, const Operand& src) { 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xAD); 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shr(Register dst, uint8_t imm8) { 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1182d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (imm8 == 1) { 1183d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xD1); 1184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xE8 | dst.code()); 1185d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } else { 1186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xC1); 1187d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xE8 | dst.code()); 1188d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(imm8); 1189d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shr_cl(Register dst) { 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xD3); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8 | dst.code()); 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::subb(const Operand& op, int8_t imm8) { 12023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnsureSpace ensure_space(this); 12033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_pc_ = pc_; 12043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (op.is_reg(eax)) { 12053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0x2c); 12063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 12073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0x80); 12083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block emit_operand(ebp, op); // ebp == 5 12093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 12103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(imm8); 12113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 12123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sub(const Operand& dst, const Immediate& x) { 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(5, dst, x); 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sub(Register dst, const Operand& src) { 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2B); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1229e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::subb(Register dst, const Operand& src) { 1230e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(dst.code() < 4); 1231e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 1232e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 1233e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x2A); 1234e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_operand(dst, src); 1235e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1236e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1237e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sub(const Operand& dst, Register src) { 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x29); 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::test(Register reg, const Immediate& imm) { 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only use test against byte for registers that have a byte 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // variant: eax, ebx, ecx, and edx. 1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm.rmode_ == RelocInfo::NONE && is_uint8(imm.x_) && reg.code() < 4) { 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint8_t imm8 = imm.x_; 1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (reg.is(eax)) { 1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA8); 1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith_b(0xF6, 0xC0, reg, imm8); 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is not using emit_arith because test doesn't support 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sign-extension of 8-bit operands. 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (reg.is(eax)) { 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA9); 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | reg.code()); 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm); 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::test(Register reg, const Operand& op) { 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x85); 1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg, op); 1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1281e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::test_b(Register reg, const Operand& op) { 1282e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 1283e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 1284e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x84); 1285e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_operand(reg, op); 1286e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1287e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1288e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::test(const Operand& op, const Immediate& imm) { 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, op); 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm); 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(Register dst, int32_t imm32) { 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(6, Operand(dst), Immediate(imm32)); 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(Register dst, const Operand& src) { 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x33); 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(const Operand& src, Register dst) { 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x31); 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(const Operand& dst, const Immediate& x) { 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(6, dst, x); 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bt(const Operand& dst, Register src) { 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA3); 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bts(const Operand& dst, Register src) { 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xAB); 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::hlt() { 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF4); 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::int3() { 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xCC); 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::nop() { 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x90); 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::rdtsc() { 1368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(RDTSC)); 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x31); 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::ret(int imm16) { 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint16(imm16)); 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm16 == 0) { 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC3); 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC2); 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm16 & 0xFF); 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((imm16 >> 8) & 0xFF); 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Labels refer to positions in the (to be) generated code. 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// There are bound, linked, and unused labels. 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Bound labels refer to known positions in the already 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// generated code. pos() is the position the label refers to. 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Linked labels refer to unknown positions in the code 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to be generated; pos() is the position of the 32bit 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Displacement of the last instruction using the label. 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::print(Label* L) { 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_unused()) { 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("unused label\n"); 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (L->is_bound()) { 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("bound label to %d\n", L->pos()); 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (L->is_linked()) { 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label l = *L; 1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("unbound label"); 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (l.is_linked()) { 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp = disp_at(&l); 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("@ %d ", l.pos()); 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.print(); 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("\n"); 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.next(&l); 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bind_to(Label* L, int pos) { 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (L->is_linked()) { 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp = disp_at(L); 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int fixup_pos = L->pos(); 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp.type() == Displacement::CODE_RELATIVE) { 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Relative to Code* heap object pointer. 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 14363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Relative address, relative to point after address. 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long_at_put(fixup_pos, imm32); 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.next(L); 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block L->bind_to(pos); 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::link_to(Label* L, Label* appendix) { 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (appendix->is_linked()) { 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_linked()) { 14513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Append appendix to L's list. 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label p; 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label q = *L; 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block p = q; 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp = disp_at(&q); 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.next(&q); 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (q.is_linked()); 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp = disp_at(&p); 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.link_to(appendix); 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp_at_put(&p, disp); 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block p.Unuse(); // to avoid assertion failure in ~Label 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 14643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // L is empty, simply use appendix. 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *L = *appendix; 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block appendix->Unuse(); // appendix should not be used anymore 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bind(Label* L) { 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!L->is_bound()); // label can only be bound once 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind_to(L, pc_offset()); 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(Label* L) { 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_bound()) { 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int long_size = 5; 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offs = L->pos() - pc_offset(); 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offs <= 0); 14873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1000 #32-bit disp. 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(offs - long_size); 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 14913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1000 #32-bit disp. 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(L, Displacement::OTHER); 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(byte* entry, RelocInfo::Mode rmode) { 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(entry - (pc_ + sizeof(int32_t)), rmode); 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(const Operand& adr) { 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edx, adr); 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WriteRecordedPositions(); 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(RelocInfo::IsCodeTarget(rmode)); 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(code.location()), rmode); 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(Label* L) { 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_bound()) { 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int short_size = 2; 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int long_size = 5; 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offs = L->pos() - pc_offset(); 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offs <= 0); 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_int8(offs - short_size)) { 15343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1011 #8-bit disp. 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xEB); 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((offs - short_size) & 0xFF); 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 15383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1001 #32-bit disp. 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(offs - long_size); 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 15433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1001 #32-bit disp. 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(entry - (pc_ + sizeof(int32_t)), rmode); 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(const Operand& adr) { 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(esp, adr); 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(RelocInfo::IsCodeTarget(rmode)); 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(code.location()), rmode); 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::j(Condition cc, Label* L, Hint hint) { 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= cc && cc < 16); 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_bound()) { 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int short_size = 2; 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int long_size = 6; 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offs = L->pos() - pc_offset(); 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offs <= 0); 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_int8(offs - short_size)) { 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0111 tttn #8-bit disp 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x70 | cc); 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((offs - short_size) & 0xFF); 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0000 1111 1000 tttn #32-bit disp 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(offs - long_size); 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0000 1111 1000 tttn #32-bit disp 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: could eliminate cond. jumps to this jump if condition 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is the same however, seems to be rather unlikely case. 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(L, Displacement::OTHER); 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint) { 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((0 <= cc) && (cc < 16)); 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 16133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 0000 1111 1000 tttn #32-bit disp. 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(entry - (pc_ + sizeof(int32_t)), rmode); 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::j(Condition cc, Handle<Code> code, Hint hint) { 1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0000 1111 1000 tttn #32-bit disp 1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(code.location()), RelocInfo::CODE_TARGET); 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// FPU instructions. 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld(int i) { 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xD9, 0xC0, i); 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1640402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Assembler::fstp(int i) { 1641402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EnsureSpace ensure_space(this); 1642402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_pc_ = pc_; 1643402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu emit_farith(0xDD, 0xD8, i); 1644402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1645402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1646402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld1() { 1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1655402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Assembler::fldpi() { 1656402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EnsureSpace ensure_space(this); 1657402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_pc_ = pc_; 1658402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EMIT(0xD9); 1659402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EMIT(0xEB); 1660402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1661402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1662402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fldz() { 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xEE); 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld_s(const Operand& adr) { 1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, adr); 1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld_d(const Operand& adr) { 1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDD); 1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, adr); 1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fstp_s(const Operand& adr) { 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebx, adr); 1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fstp_d(const Operand& adr) { 1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDD); 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebx, adr); 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1703402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Assembler::fst_d(const Operand& adr) { 1704402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EnsureSpace ensure_space(this); 1705402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_pc_ = pc_; 1706402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EMIT(0xDD); 1707402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu emit_operand(edx, adr); 1708402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1709402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1710402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fild_s(const Operand& adr) { 1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, adr); 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fild_d(const Operand& adr) { 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDF); 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebp, adr); 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fistp_s(const Operand& adr) { 1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebx, adr); 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fisttp_s(const Operand& adr) { 1736d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE3)); 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ecx, adr); 1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1744e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::fisttp_d(const Operand& adr) { 1745e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE3)); 1746e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 1747e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 1748e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xDD); 1749e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_operand(ecx, adr); 1750e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1751e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1752e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fist_s(const Operand& adr) { 1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edx, adr); 1758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fistp_d(const Operand& adr) { 1762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDF); 1765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edi, adr); 1766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fabs() { 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE1); 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fchs() { 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0); 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fcos() { 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsin() { 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFE); 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fadd(int i) { 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xC0, i); 1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsub(int i) { 1809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xE8, i); 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fisub_s(const Operand& adr) { 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDA); 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(esp, adr); 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fmul(int i) { 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xC8, i); 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fdiv(int i) { 1831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xF8, i); 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::faddp(int i) { 1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xC0, i); 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsubp(int i) { 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xE8, i); 1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsubrp(int i) { 1852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xE0, i); 1855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fmulp(int i) { 1859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xC8, i); 1862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fdivp(int i) { 1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xF8, i); 1869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fprem() { 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8); 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fprem1() { 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF5); 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fxch(int i) { 1889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xD9, 0xC8, i); 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fincstp() { 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::ffree(int i) { 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDD, 0xC0, i); 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::ftst() { 1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE4); 1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fucomp(int i) { 1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDD, 0xE8, i); 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fucompp() { 1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDA); 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::fucomi(int i) { 19343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnsureSpace ensure_space(this); 19353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_pc_ = pc_; 19363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xDB); 19373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xE8 + i); 19383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 19393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::fucomip() { 19423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnsureSpace ensure_space(this); 19433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_pc_ = pc_; 19443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xDF); 19453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xE9); 19463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 19473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fcompp() { 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDE); 1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fnstsw_ax() { 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDF); 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0); 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fwait() { 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9B); 1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::frndint() { 1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFC); 1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fnclex() { 1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE2); 1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sahf() { 1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9E); 1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::setcc(Condition cc, Register reg) { 1996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reg.is_byte_register()); 1997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x90 | cc); 2001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | reg.code()); 2002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cvttss2si(Register dst, const Operand& src) { 2006d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF3); 2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2C); 2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cvttsd2si(Register dst, const Operand& src) { 2017d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2C); 2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) { 2028d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2A); 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::addsd(XMMRegister dst, XMMRegister src) { 2039d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x58); 2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mulsd(XMMRegister dst, XMMRegister src) { 2050d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x59); 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::subsd(XMMRegister dst, XMMRegister src) { 2061d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x5C); 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::divsd(XMMRegister dst, XMMRegister src) { 2072d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x5E); 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2082e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::xorpd(XMMRegister dst, XMMRegister src) { 2083e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2084e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2085e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2086e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x66); 2087e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2088e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x57); 2089e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(dst, src); 2090e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2091e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2092e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::comisd(XMMRegister dst, XMMRegister src) { 2094d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2F); 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2104e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqa(const Operand& dst, XMMRegister src ) { 2105e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x66); 2109e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2110e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x7F); 2111e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(src, dst); 2112e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2113e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2114e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2115e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqa(XMMRegister dst, const Operand& src) { 2116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2119e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x66); 2120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x6F); 2122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(dst, src); 2123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2126e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqu(const Operand& dst, XMMRegister src ) { 2127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2128e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2129e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xF3); 2131e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x7F); 2133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(src, dst); 2134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqu(XMMRegister dst, const Operand& src) { 2138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xF3); 2142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x6F); 2144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(dst, src); 2145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movdbl(XMMRegister dst, const Operand& src) { 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movsd(dst, src); 2152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movdbl(const Operand& dst, XMMRegister src) { 2156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movsd(dst, src); 2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsd(const Operand& dst, XMMRegister src ) { 2163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); // double 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x11); // store 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(src, dst); 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsd(XMMRegister dst, const Operand& src) { 2174d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); // double 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x10); // load 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register ireg = { reg.code() }; 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ireg, adr); 2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::Print() { 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Disassembler::Decode(stdout, buffer_, pc_); 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordJSReturn() { 2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WriteRecordedPositions(); 2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(RelocInfo::JS_RETURN); 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordComment(const char* msg) { 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_debug_code) { 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordPosition(int pos) { 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos != RelocInfo::kNoPosition); 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos >= 0); 2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_position_ = pos; 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordStatementPosition(int pos) { 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos != RelocInfo::kNoPosition); 2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos >= 0); 2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_statement_position_ = pos; 2226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::WriteRecordedPositions() { 2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Write the statement position if it is different from what was written last 2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // time. 2232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current_statement_position_ != written_statement_position_) { 2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_); 2235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block written_statement_position_ = current_statement_position_; 2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Write the position if it is different from what was written last time and 2239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // also different from the written statement position. 2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current_position_ != written_position_ && 2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_position_ != written_statement_position_) { 2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(RelocInfo::POSITION, current_position_); 2244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block written_position_ = current_position_; 2245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::GrowBuffer() { 22503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(overflow()); 2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!own_buffer_) FATAL("external code buffer is too small"); 2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Compute new buffer size. 2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; // the new buffer 2255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_size_ < 4*KB) { 2256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.buffer_size = 4*KB; 2257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.buffer_size = 2*buffer_size_; 2259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Some internal data structures overflow for very large buffers, 2261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // they must ensure that kMaximalBufferSize is not too large. 2262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((desc.buffer_size > kMaximalBufferSize) || 22633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block (desc.buffer_size > Heap::MaxOldGenerationSize())) { 2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Setup new buffer. 2268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.buffer = NewArray<byte>(desc.buffer_size); 2269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.instr_size = pc_offset(); 2270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 2271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the buffer in debug mode. Use 'int3' instructions to make 2273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sure to get into problems if we ever run uninitialized code. 2274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memset(desc.buffer, 0xCC, desc.buffer_size); 2276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Copy the data. 2279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pc_delta = desc.buffer - buffer_; 2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memmove(desc.buffer, buffer_, desc.instr_size); 2282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memmove(rc_delta + reloc_info_writer.pos(), 2283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.pos(), desc.reloc_size); 2284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Switch buffers. 2286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 2287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_buffer_ = buffer_; 2288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(buffer_); 2290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = desc.buffer; 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size_ = desc.buffer_size; 2293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += pc_delta; 2294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (last_pc_ != NULL) { 2295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ += pc_delta; 2296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.last_pc() + pc_delta); 2299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Relocate runtime entries. 2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (RelocIterator it(desc); !it.done(); it.next()) { 2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode = it.rinfo()->rmode(); 2303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rmode == RelocInfo::RUNTIME_ENTRY) { 2304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p -= pc_delta; // relocate entry 2306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (rmode == RelocInfo::INTERNAL_REFERENCE) { 2307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*p != 0) { // 0 means uninitialized. 2309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p += pc_delta; 2310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!overflow()); 2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 2319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode 2320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint8(imm8)); 2321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((op1 & 0x01) == 0); // should be 8bit operation 2322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(op1); 2323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(op2 | dst.code()); 2324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 2325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 2329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((0 <= sel) && (sel <= 7)); 2330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register ireg = { sel }; 2331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x.is_int8()) { 2332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x83); // using a sign-extended 8-bit immediate. 2333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ireg, dst); 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(x.x_ & 0xFF); 2335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (dst.is_reg(eax)) { 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((sel << 3) | 0x05); // short form if the destination is eax. 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x81); // using a literal 32-bit immediate. 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ireg, dst); 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_operand(Register reg, const Operand& adr) { 2347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const unsigned length = adr.len_; 2348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(length > 0); 2349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit updated ModRM byte containing the given register. 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3); 2352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the rest of the encoded operand. 2354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += length; 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit relocation information if necessary. 2358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length >= sizeof(int32_t) && adr.rmode_ != RelocInfo::NONE) { 2359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 2360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(adr.rmode_); 2361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(int32_t); 2362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_farith(int b1, int b2, int i) { 2367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode 2368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= i && i < 8); // illegal stack offset 2369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(b1); 2370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(b2 + i); 2371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dd(uint32_t data, RelocInfo::Mode reloc_info) { 2375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(data, reloc_info); 2377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode != RelocInfo::NONE); 2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't record external references unless the heap will be serialized. 2383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 2384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef DEBUG 2385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Serializer::enabled()) { 2386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Serializer::TooLateToEnableNow(); 2387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 2389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Serializer::enabled() && !FLAG_debug_code) { 2390d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 2391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo rinfo(pc_, rmode, data); 2394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.Write(&rinfo); 2395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 2399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic FILE* coverage_log = NULL; 2400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitCoverageLog() { 2403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 2404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (file_name != NULL) { 2405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block coverage_log = fopen(file_name, "aw+"); 2406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogGeneratedCodeCoverage(const char* file_line) { 2411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* return_address = (&file_line)[-1]; 2412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* push_insn = const_cast<char*>(return_address - 12); 2413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block push_insn[0] = 0xeb; // Relative branch insn. 2414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block push_insn[1] = 13; // Skip over coverage insns. 2415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (coverage_log != NULL) { 2416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fprintf(coverage_log, "%s\n", file_line); 2417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fflush(coverage_log); 2418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 2424