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