assembler-ia32.cc revision 3e5fa29ddb82551500b118e9bf37af3966277b70
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 39f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#if defined(V8_TARGET_ARCH_IA32) 40f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "disassembler.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h" 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "serialize.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of CpuFeatures 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Safe default is no features. 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuint64_t CpuFeatures::supported_ = 0; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuint64_t CpuFeatures::enabled_ = 0; 54d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockuint64_t CpuFeatures::found_by_runtime_probing_ = 0; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The Probe method needs executable memory, so it uses Heap::CreateCode. 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Allocation failure is silent and leads to safe default. 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CpuFeatures::Probe() { 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Heap::HasBeenSetup()); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(supported_ == 0); 62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (Serializer::enabled()) { 63d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block supported_ |= OS::CpuFeaturesImpliedByPlatform(); 64d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; // No features if we might serialize. 65d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler assm(NULL, 0); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label cpuid, done; 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm. 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save old esp, since we are going to modify the stack. 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(ebp); 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pushfd(); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(ecx); 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(ebx); 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(ebp, Operand(esp)); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pushfd(); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(eax); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(edx, Operand(eax)); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(eax, 0x200000); // Flip bit 21. 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ push(eax); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ popfd(); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pushfd(); 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(eax); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(eax, Operand(edx)); // Different if CPUID is supported. 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ j(not_zero, &cpuid); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPUID not supported. Clear the supported features in edx:eax. 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(eax, Operand(eax)); 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ xor_(edx, Operand(edx)); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ jmp(&done); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke CPUID with 1 in eax to get feature information in 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ecx:edx. Temporarily enable CPUID support because we know it's 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // safe here. 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&cpuid); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, 1); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block supported_ = (1 << CPUID); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { Scope fscope(CPUID); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ cpuid(); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block supported_ = 0; 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move the result from ecx:edx to edx:eax and make sure to mark the 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPUID feature as supported. 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, Operand(edx)); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ or_(eax, 1 << CPUID); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(edx, Operand(ecx)); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Done. 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&done); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(esp, Operand(ebp)); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(ebx); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(ecx); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ popfd(); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ pop(ebp); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef __ 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 1235913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 1245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* code; 1255913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck { MaybeObject* maybe_code = Heap::CreateCode(desc, 1265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::ComputeFlags(Code::STUB), 1275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Code>::null()); 1285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe_code->ToObject(&code)) return; 1295913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!code->IsCode()) return; 1315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, 1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Code::cast(code), "CpuFeatures::Probe")); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef uint64_t (*F0)(); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block supported_ = probe(); 137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block found_by_runtime_probing_ = supported_; 138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); 139d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block supported_ |= os_guarantees; 140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block found_by_runtime_probing_ &= ~os_guarantees; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Displacement 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Displacement::init(Label* L, Type type) { 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!L->is_bound()); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int next = 0; 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_linked()) { 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next = L->pos(); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(next > 0); // Displacements must be at positions > 0 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ensure that we _never_ overflow the next field. 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize)); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block data_ = NextField::encode(next) | TypeField::encode(type); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of RelocInfo 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int RelocInfo::kApplyMask = 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 166bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE | 167bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1 << RelocInfo::DEBUG_BREAK_SLOT; 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkebool RelocInfo::IsCodedSpecially() { 171f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // The deserializer needs to know whether a pointer is specially coded. Being 172f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // specially coded on IA32 means that it is a relative address, as used by 173f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // branch instructions. These are also the ones that need changing when a 174f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // code object moves. 175f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return (1 << rmode_) & kApplyMask; 176f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 177f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 178f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) { 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code at the current address with the supplied instructions. 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < instruction_count; i++) { 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *(pc_ + i) = *(instructions + i); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicate that code has changed. 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CPU::FlushICache(pc_, instruction_count); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Patch the code at the current PC with a call to the target address. 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Additional guard int3 instructions can be added if required. 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call instruction takes up 5 bytes and int3 takes up one byte. 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kCallCodeSize = 5; 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int code_size = kCallCodeSize + guard_bytes; 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a code patcher. 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodePatcher patcher(pc_, code_size); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add a label for checking the size of the code used for returning. 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label check_codesize; 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->bind(&check_codesize); 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code. 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->call(target, RelocInfo::NONE); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the size of the code generated is as expected. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(kCallCodeSize, 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add the requested number of int3 instructions after the call. 2147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT_GE(guard_bytes, 0); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < guard_bytes; i++) { 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->int3(); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Operand 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) { 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base] 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, base); 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (base.is(esp)) set_sib(times_1, esp, base); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_int8(disp) && rmode == RelocInfo::NONE) { 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp8] 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(1, base); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (base.is(esp)) set_sib(times_1, esp, base); 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_disp8(disp); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(2, base); 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (base.is(esp)) set_sib(times_1, esp, base); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register base, 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp, 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode) { 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!index.is(esp)); // illegal addressing mode 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) { 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale] 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, esp); 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, base); 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_int8(disp) && rmode == RelocInfo::NONE) { 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp8] 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(1, esp); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, base); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_disp8(disp); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(2, esp); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, base); 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register index, 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp, 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode) { 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!index.is(esp)); // illegal addressing mode 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [index*scale + disp/r] 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, esp); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_sib(scale, index, ebp); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Operand::is_reg(Register reg) const { 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block && ((buf_[0] & 0x07) == reg.code()); // register codes match. 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 2873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Implementation of Assembler. 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Emit a single byte. Must always be inlined. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define EMIT(x) \ 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *pc_++ = (x) 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitCoverageLog(); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Spare buffer. 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbyte* Assembler::spare_buffer_ = NULL; 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3013e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui ZhuAssembler::Assembler(void* buffer, int buffer_size) 3023e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu : positions_recorder_(this) { 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer == NULL) { 3043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Do our own buffer management. 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_size <= kMinimalBufferSize) { 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size = kMinimalBufferSize; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_buffer_ != NULL) { 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer = spare_buffer_; 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_buffer_ = NULL; 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer == NULL) { 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = NewArray<byte>(buffer_size); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = static_cast<byte*>(buffer); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size_ = buffer_size; 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block own_buffer_ = true; 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Use externally provided buffer instead. 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(buffer_size > 0); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = static_cast<byte*>(buffer); 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size_ = buffer_size; 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block own_buffer_ = false; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the buffer in debug mode unless it was provided by the 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // caller in which case we can't be sure it's okay to overwrite 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // existing code in it; see CodePatcher::CodePatcher(...). 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (own_buffer_) { 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memset(buffer_, 0xCC, buffer_size); // int3 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Setup buffer pointers. 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(buffer_ != NULL); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ = buffer_; 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitCoverageLog(); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAssembler::~Assembler() { 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (own_buffer_) { 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_buffer_ = buffer_; 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(buffer_); 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::GetCode(CodeDesc* desc) { 3613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Finalize code (at this point overflow() may be true, but the gap ensures 3623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // that we are still not overlapping instructions and relocation info). 3633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. 3643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Setup code descriptor. 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->buffer = buffer_; 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->buffer_size = buffer_size_; 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->instr_size = pc_offset(); 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc->origin = this; 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::reloc_info_size.Increment(desc->reloc_size); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::Align(int m) { 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsPowerOf2(m)); 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((pc_offset() & (m - 1)) != 0) { 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nop(); 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid Assembler::CodeTargetAlign() { 3849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen Align(16); // Preferred alignment of jump targets on ia32. 3859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 3869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 3879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cpuid() { 389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CPUID)); 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA2); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pushad() { 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x60); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::popad() { 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x61); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pushfd() { 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9C); 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::popfd() { 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9D); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::push(const Immediate& x) { 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x.is_int8()) { 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x6a); 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(x.x_); 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x68); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::push(Register src) { 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x50 | src.code()); 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::push(const Operand& src) { 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(esi, src); 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pop(Register dst) { 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_info_writer.last_pc() != NULL); 455f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) { 4563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // (last_pc_ != NULL) is rolled into the above check. 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If a last_pc_ is set, we need to make sure that there has not been any 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information generated between the last instruction and this 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pop instruction. 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte instr = last_pc_[0]; 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & ~0x7) == 0x50) { 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int push_reg_code = instr & 0x7; 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (push_reg_code == dst.code()) { 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ = last_pc_; 465f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (same reg) eliminated\n", pc_offset()); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convert 'push src; pop dst' to 'mov dst, src'. 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x8b; 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src = { push_reg_code }; 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, Operand(src)); 474f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset()); 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (instr == 0xff) { // push of an operand, convert to a move 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte op1 = last_pc_[1]; 4823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check if the operation is really a push. 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((op1 & 0x38) == (6 << 3)) { 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3); 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x8b; 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[1] = op1; 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 488f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (op->reg) eliminated\n", pc_offset()); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if ((instr == 0x89) && 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (last_pc_[1] == 0x04) && 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (last_pc_[2] == 0x24)) { 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x71283c 396 890424 mov [esp],eax 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x71283f 399 58 pop eax 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(eax)) { 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x710fac 216 83c404 add esp,0x4 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x83; 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[1] = 0xc4; 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[2] = 0x04; 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 505f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset()); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte imm8 = last_pc_[1]; 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 0) { 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 6a00 push 0x0 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58 pop eax 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0x31; 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[1] = 0xc0; 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 31c0 xor eax,eax 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 520f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 6a00 push 0xXX 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58 pop eax 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0xb8; 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((imm8 & 0x80) != 0) { 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xff); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xff); 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xff); 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // b8XXffffff mov eax,0xffffffXX 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x00); 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x00); 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x00); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // b8XX000000 mov eax,0x000000XX 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 543f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 68XXXXXXXX push 0xXXXXXXXX 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58 pop eax 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_[0] = 0xb8; 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // change to 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // b8XXXXXXXX mov eax,0xXXXXXXXX 555f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Other potential patterns for peephole: 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x712716 102 890424 mov [esp], eax 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0x712719 105 8b1424 mov edx, [esp] 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x58 | dst.code()); 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::pop(const Operand& dst) { 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8F); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::enter(const Immediate& size) { 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC8); 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_w(size); 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::leave() { 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC9); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_b(Register dst, const Operand& src) { 596e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(dst.code() < 4); 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8A); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_b(const Operand& dst, int8_t imm8) { 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC6); 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_b(const Operand& dst, Register src) { 614e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(src.code() < 4); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x88); 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_w(Register dst, const Operand& src) { 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8B); 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov_w(const Operand& dst, Register src) { 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x89); 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, int32_t imm32) { 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB8 | dst.code()); 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm32); 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, const Immediate& x) { 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB8 | dst.code()); 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, Handle<Object> handle) { 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB8 | dst.code()); 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(handle); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, const Operand& src) { 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8B); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(Register dst, Register src) { 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x89); 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | src.code() << 3 | dst.code()); 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(const Operand& dst, const Immediate& x) { 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC7); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(const Operand& dst, Handle<Object> handle) { 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC7); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(handle); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mov(const Operand& dst, Register src) { 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x89); 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsx_b(Register dst, const Operand& src) { 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xBE); 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsx_w(Register dst, const Operand& src) { 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xBF); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movzx_b(Register dst, const Operand& src) { 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB6); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movzx_w(Register dst, const Operand& src) { 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xB7); 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmov(Condition cc, Register dst, int32_t imm32) { 743d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CMOV)); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(cc); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(dst); 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(imm32); 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmov(Condition cc, Register dst, Handle<Object> handle) { 754d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CMOV)); 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(cc); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(dst); 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(handle); 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmov(Condition cc, Register dst, const Operand& src) { 765d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(CMOV)); 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 7683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Opcode: 0f 40 + cc /r. 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x40 + cc); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7756ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::cld() { 7766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 7776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 7786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xFC); 7796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 7806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 782e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::rep_movs() { 783e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 784e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 785e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xF3); 786e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xA5); 787e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 788e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 789e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 7906ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::rep_stos() { 7916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 7926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 7936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xF3); 7946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xAB); 7956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 7966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 798f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid Assembler::stos() { 799f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke EnsureSpace ensure_space(this); 800f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke last_pc_ = pc_; 801f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke EMIT(0xAB); 802f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 803f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 804f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xchg(Register dst, Register src) { 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 8083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x87); 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | src.code() << 3 | dst.code()); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::adc(Register dst, int32_t imm32) { 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(2, Operand(dst), Immediate(imm32)); 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::adc(Register dst, const Operand& src) { 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x13); 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::add(Register dst, const Operand& src) { 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x03); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::add(const Operand& dst, const Immediate& x) { 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_info_writer.last_pc() != NULL); 842f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) { 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte instr = last_pc_[0]; 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & 0xf8) == 0x50) { 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Last instruction was a push. Check whether this is a pop without a 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // result. 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((dst.is_reg(esp)) && 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) { 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ = last_pc_; 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 851f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (FLAG_print_peephole_optimization) { 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%d push/pop(noreg) eliminated\n", pc_offset()); 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(0, dst, x); 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(Register dst, int32_t imm32) { 86559151504615d929945dc59db37bf1166937748c6Steve Block and_(dst, Immediate(imm32)); 86659151504615d929945dc59db37bf1166937748c6Steve Block} 86759151504615d929945dc59db37bf1166937748c6Steve Block 86859151504615d929945dc59db37bf1166937748c6Steve Block 86959151504615d929945dc59db37bf1166937748c6Steve Blockvoid Assembler::and_(Register dst, const Immediate& x) { 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 87259151504615d929945dc59db37bf1166937748c6Steve Block emit_arith(4, Operand(dst), x); 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(Register dst, const Operand& src) { 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x23); 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(const Operand& dst, const Immediate& x) { 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(4, dst, x); 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::and_(const Operand& dst, Register src) { 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x21); 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpb(const Operand& op, int8_t imm8) { 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80); 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edi, op); // edi == 7 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 908d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Assembler::cmpb(const Operand& dst, Register src) { 909d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(src.is_byte_register()); 910d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnsureSpace ensure_space(this); 911d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke last_pc_ = pc_; 912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EMIT(0x38); 913d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke emit_operand(src, dst); 914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 915d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 916d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 917d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Assembler::cmpb(Register dst, const Operand& src) { 918d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(dst.is_byte_register()); 919d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnsureSpace ensure_space(this); 920d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke last_pc_ = pc_; 921d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EMIT(0x3A); 922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke emit_operand(dst, src); 923d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpw(const Operand& op, Immediate imm16) { 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(imm16.is_int16()); 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x81); 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edi, op); 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_w(imm16); 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(Register reg, int32_t imm32) { 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, Operand(reg), Immediate(imm32)); 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(Register reg, Handle<Object> handle) { 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, Operand(reg), Immediate(handle)); 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(Register reg, const Operand& op) { 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x3B); 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg, op); 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(const Operand& op, const Immediate& imm) { 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, op, imm); 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmp(const Operand& op, Handle<Object> handle) { 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(7, op, Immediate(handle)); 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpb_al(const Operand& op) { 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x38); // CMP r/m8, r8 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, op); // eax has same code as register al. 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cmpw_ax(const Operand& op) { 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x66); 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x39); // CMP r/m16, r16 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, op); // eax has same code as register ax. 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dec_b(Register dst) { 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFE); 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC8 | dst.code()); 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9980d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::dec_b(const Operand& dst) { 9990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 10000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 10010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0xFE); 10020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen emit_operand(ecx, dst); 10030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 10040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 10050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dec(Register dst) { 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x48 | dst.code()); 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dec(const Operand& dst) { 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ecx, dst); 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cdq() { 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x99); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::idiv(Register src) { 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | src.code()); 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::imul(Register reg) { 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8 | reg.code()); 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::imul(Register dst, const Operand& src) { 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xAF); 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::imul(Register dst, Register src, int32_t imm32) { 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_int8(imm32)) { 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x6B); 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm32); 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x69); 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm32); 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::inc(Register dst) { 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x40 | dst.code()); 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::inc(const Operand& dst) { 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, dst); 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::lea(Register dst, const Operand& src) { 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x8D); 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mul(Register src) { 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | src.code()); 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::neg(Register dst) { 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD8 | dst.code()); 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::not_(Register dst) { 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD0 | dst.code()); 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(Register dst, int32_t imm32) { 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(1, Operand(dst), Immediate(imm32)); 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(Register dst, const Operand& src) { 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0B); 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(const Operand& dst, const Immediate& x) { 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(1, dst, x); 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::or_(const Operand& dst, Register src) { 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x09); 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::rcl(Register dst, uint8_t imm8) { 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 1) { 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD1); 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD0 | dst.code()); 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC1); 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD0 | dst.code()); 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1160756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid Assembler::rcr(Register dst, uint8_t imm8) { 1161756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick EnsureSpace ensure_space(this); 1162756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick last_pc_ = pc_; 1163756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(is_uint5(imm8)); // illegal shift count 1164756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (imm8 == 1) { 1165756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick EMIT(0xD1); 1166756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick EMIT(0xD8 | dst.code()); 1167756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else { 1168756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick EMIT(0xC1); 1169756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick EMIT(0xD8 | dst.code()); 1170756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick EMIT(imm8); 1171756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1172756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 1173756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1174756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sar(Register dst, uint8_t imm8) { 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 1) { 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD1); 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | dst.code()); 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC1); 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | dst.code()); 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Assembler::sar_cl(Register dst) { 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD3); 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8 | dst.code()); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sbb(Register dst, const Operand& src) { 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x1B); 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shld(Register dst, const Operand& src) { 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA5); 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shl(Register dst, uint8_t imm8) { 1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm8 == 1) { 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD1); 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | dst.code()); 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC1); 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | dst.code()); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1230d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Assembler::shl_cl(Register dst) { 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD3); 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0 | dst.code()); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shrd(Register dst, const Operand& src) { 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xAD); 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shr(Register dst, uint8_t imm8) { 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint5(imm8)); // illegal shift count 1251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (imm8 == 1) { 1252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xD1); 1253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xE8 | dst.code()); 1254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } else { 1255d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xC1); 1256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xE8 | dst.code()); 1257d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(imm8); 1258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::shr_cl(Register dst) { 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1265d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block EMIT(0xD3); 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8 | dst.code()); 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::subb(const Operand& op, int8_t imm8) { 12713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnsureSpace ensure_space(this); 12723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_pc_ = pc_; 12733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (op.is_reg(eax)) { 12743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0x2c); 12753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 12763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0x80); 12773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block emit_operand(ebp, op); // ebp == 5 12783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 12793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(imm8); 12803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 12813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sub(const Operand& dst, const Immediate& x) { 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(5, dst, x); 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sub(Register dst, const Operand& src) { 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2B); 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1298e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::subb(Register dst, const Operand& src) { 1299e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(dst.code() < 4); 1300e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 1301e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 1302e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x2A); 1303e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_operand(dst, src); 1304e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1305e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1306e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sub(const Operand& dst, Register src) { 1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x29); 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::test(Register reg, const Immediate& imm) { 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only use test against byte for registers that have a byte 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // variant: eax, ebx, ecx, and edx. 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm.rmode_ == RelocInfo::NONE && is_uint8(imm.x_) && reg.code() < 4) { 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint8_t imm8 = imm.x_; 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (reg.is(eax)) { 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA8); 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith_b(0xF6, 0xC0, reg, imm8); 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is not using emit_arith because test doesn't support 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sign-extension of 8-bit operands. 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (reg.is(eax)) { 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA9); 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | reg.code()); 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm); 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::test(Register reg, const Operand& op) { 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x85); 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg, op); 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1350e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::test_b(Register reg, const Operand& op) { 1351e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 1352e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 1353e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x84); 1354e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_operand(reg, op); 1355e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1356e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1357e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::test(const Operand& op, const Immediate& imm) { 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, op); 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(imm); 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Assembler::test_b(const Operand& op, uint8_t imm8) { 13687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EnsureSpace ensure_space(this); 13697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch last_pc_ = pc_; 13707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0xF6); 13717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch emit_operand(eax, op); 13727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(imm8); 13737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 13747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 13757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(Register dst, int32_t imm32) { 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(6, Operand(dst), Immediate(imm32)); 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(Register dst, const Operand& src) { 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x33); 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(const Operand& src, Register dst) { 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x31); 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::xor_(const Operand& dst, const Immediate& x) { 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_arith(6, dst, x); 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bt(const Operand& dst, Register src) { 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xA3); 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bts(const Operand& dst, Register src) { 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xAB); 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(src, dst); 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::hlt() { 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF4); 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::int3() { 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xCC); 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::nop() { 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x90); 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::rdtsc() { 1446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(RDTSC)); 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x31); 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::ret(int imm16) { 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint16(imm16)); 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (imm16 == 0) { 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC3); 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC2); 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm16 & 0xFF); 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((imm16 >> 8) & 0xFF); 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Labels refer to positions in the (to be) generated code. 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// There are bound, linked, and unused labels. 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Bound labels refer to known positions in the already 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// generated code. pos() is the position the label refers to. 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Linked labels refer to unknown positions in the code 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to be generated; pos() is the position of the 32bit 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Displacement of the last instruction using the label. 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::print(Label* L) { 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_unused()) { 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("unused label\n"); 1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (L->is_bound()) { 1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("bound label to %d\n", L->pos()); 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (L->is_linked()) { 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label l = *L; 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("unbound label"); 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (l.is_linked()) { 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp = disp_at(&l); 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("@ %d ", l.pos()); 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.print(); 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("\n"); 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.next(&l); 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bind_to(Label* L, int pos) { 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (L->is_linked()) { 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp = disp_at(L); 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int fixup_pos = L->pos(); 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp.type() == Displacement::CODE_RELATIVE) { 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Relative to Code* heap object pointer. 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 15143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Relative address, relative to point after address. 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long_at_put(fixup_pos, imm32); 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disp.next(L); 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block L->bind_to(pos); 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::bind(Label* L) { 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = NULL; 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!L->is_bound()); // label can only be bound once 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind_to(L, pc_offset()); 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15320d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::bind(NearLabel* L) { 15330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(!L->is_bound()); 15340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = NULL; 15350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen while (L->unresolved_branches_ > 0) { 15360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; 15370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int disp = pc_offset() - branch_pos; 15380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(is_int8(disp)); 15390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen set_byte_at(branch_pos - sizeof(int8_t), disp); 15400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen L->unresolved_branches_--; 15410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 15420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen L->bind_to(pc_offset()); 15430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 15440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(Label* L) { 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_bound()) { 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int long_size = 5; 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offs = L->pos() - pc_offset(); 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offs <= 0); 15523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1000 #32-bit disp. 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(offs - long_size); 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 15563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1000 #32-bit disp. 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(L, Displacement::OTHER); 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(byte* entry, RelocInfo::Mode rmode) { 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(entry - (pc_ + sizeof(int32_t)), rmode); 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(const Operand& adr) { 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edx, adr); 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { 15813e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu positions_recorder()->WriteRecordedPositions(); 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(RelocInfo::IsCodeTarget(rmode)); 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(code.location()), rmode); 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(Label* L) { 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_bound()) { 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int short_size = 2; 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int long_size = 5; 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offs = L->pos() - pc_offset(); 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offs <= 0); 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_int8(offs - short_size)) { 15993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1011 #8-bit disp. 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xEB); 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((offs - short_size) & 0xFF); 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 16033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1001 #32-bit disp. 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(offs - long_size); 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 16083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 1110 1001 #32-bit disp. 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(entry - (pc_ + sizeof(int32_t)), rmode); 1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(const Operand& adr) { 1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(esp, adr); 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(RelocInfo::IsCodeTarget(rmode)); 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(code.location()), rmode); 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16410d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::jmp(NearLabel* L) { 16420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 16430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 16440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (L->is_bound()) { 16450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const int short_size = 2; 16460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int offs = L->pos() - pc_offset(); 16470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(offs <= 0); 16480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(is_int8(offs - short_size)); 16490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // 1110 1011 #8-bit disp. 16500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0xEB); 16510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT((offs - short_size) & 0xFF); 16520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 16530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0xEB); 16540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x00); // The displacement will be resolved later. 16550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen L->link_to(pc_offset()); 16560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 16570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 16580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::j(Condition cc, Label* L, Hint hint) { 1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= cc && cc < 16); 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (L->is_bound()) { 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int short_size = 2; 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int long_size = 6; 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offs = L->pos() - pc_offset(); 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offs <= 0); 1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_int8(offs - short_size)) { 1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0111 tttn #8-bit disp 1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x70 | cc); 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((offs - short_size) & 0xFF); 1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0000 1111 1000 tttn #32-bit disp 1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(offs - long_size); 1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0000 1111 1000 tttn #32-bit disp 1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: could eliminate cond. jumps to this jump if condition 1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is the same however, seems to be rather unlikely case. 1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(L, Displacement::OTHER); 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint) { 1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((0 <= cc) && (cc < 16)); 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 16963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 0000 1111 1000 tttn #32-bit disp. 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(entry - (pc_ + sizeof(int32_t)), rmode); 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::j(Condition cc, Handle<Code> code, Hint hint) { 1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0000 1111 1000 tttn #32-bit disp 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x80 | cc); 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(code.location()), RelocInfo::CODE_TARGET); 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17140d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::j(Condition cc, NearLabel* L, Hint hint) { 17150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 17160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 17170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(0 <= cc && cc < 16); 17180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 17190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (L->is_bound()) { 17200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const int short_size = 2; 17210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int offs = L->pos() - pc_offset(); 17220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(offs <= 0); 17230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(is_int8(offs - short_size)); 17240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // 0111 tttn #8-bit disp 17250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x70 | cc); 17260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT((offs - short_size) & 0xFF); 17270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 17280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x70 | cc); 17290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x00); // The displacement will be resolved later. 17300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen L->link_to(pc_offset()); 17310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 17320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 17330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 17340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 17353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// FPU instructions. 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld(int i) { 1738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xD9, 0xC0, i); 1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1744402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Assembler::fstp(int i) { 1745402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EnsureSpace ensure_space(this); 1746402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_pc_ = pc_; 1747402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu emit_farith(0xDD, 0xD8, i); 1748402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1749402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1750402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld1() { 1752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE8); 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1759402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Assembler::fldpi() { 1760402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EnsureSpace ensure_space(this); 1761402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_pc_ = pc_; 1762402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EMIT(0xD9); 1763402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EMIT(0xEB); 1764402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1765402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1766402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fldz() { 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xEE); 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld_s(const Operand& adr) { 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, adr); 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fld_d(const Operand& adr) { 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDD); 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, adr); 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fstp_s(const Operand& adr) { 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebx, adr); 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fstp_d(const Operand& adr) { 1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDD); 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebx, adr); 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1807402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Assembler::fst_d(const Operand& adr) { 1808402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EnsureSpace ensure_space(this); 1809402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_pc_ = pc_; 1810402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu EMIT(0xDD); 1811402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu emit_operand(edx, adr); 1812402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1813402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1814402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fild_s(const Operand& adr) { 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(eax, adr); 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fild_d(const Operand& adr) { 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDF); 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebp, adr); 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fistp_s(const Operand& adr) { 1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ebx, adr); 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fisttp_s(const Operand& adr) { 1840d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE3)); 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ecx, adr); 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1848e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::fisttp_d(const Operand& adr) { 1849e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE3)); 1850e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 1851e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 1852e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xDD); 1853e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_operand(ecx, adr); 1854e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1855e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1856e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fist_s(const Operand& adr) { 1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edx, adr); 1862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fistp_d(const Operand& adr) { 1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDF); 1869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(edi, adr); 1870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fabs() { 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE1); 1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fchs() { 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0); 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fcos() { 1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFF); 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsin() { 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFE); 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fadd(int i) { 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xC0, i); 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsub(int i) { 1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xE8, i); 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fisub_s(const Operand& adr) { 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDA); 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(esp, adr); 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fmul(int i) { 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xC8, i); 1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fdiv(int i) { 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDC, 0xF8, i); 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::faddp(int i) { 1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xC0, i); 1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsubp(int i) { 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xE8, i); 1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fsubrp(int i) { 1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xE0, i); 1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fmulp(int i) { 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xC8, i); 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fdivp(int i) { 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDE, 0xF8, i); 1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fprem() { 1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF8); 1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fprem1() { 1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF5); 1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fxch(int i) { 1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xD9, 0xC8, i); 1996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fincstp() { 2000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 2003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF7); 2004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::ffree(int i) { 2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDD, 0xC0, i); 2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::ftst() { 2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE4); 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fucomp(int i) { 2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_farith(0xDD, 0xE8, i); 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fucompp() { 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDA); 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE9); 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::fucomi(int i) { 20383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnsureSpace ensure_space(this); 20393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_pc_ = pc_; 20403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xDB); 20413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xE8 + i); 20423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 20433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::fucomip() { 20463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnsureSpace ensure_space(this); 20473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_pc_ = pc_; 20483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xDF); 20493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EMIT(0xE9); 20503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 20513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fcompp() { 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDE); 2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fnstsw_ax() { 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDF); 2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE0); 2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fwait() { 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9B); 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::frndint() { 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xD9); 2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xFC); 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::fnclex() { 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xDB); 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xE2); 2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::sahf() { 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x9E); 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::setcc(Condition cc, Register reg) { 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reg.is_byte_register()); 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x90 | cc); 2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | reg.code()); 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cvttss2si(Register dst, const Operand& src) { 2110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF3); 2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2C); 2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cvttsd2si(Register dst, const Operand& src) { 2121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2C); 2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(dst, src); 2128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) { 2132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x2A); 2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { 21436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 21446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 21456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 21466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xF3); 21476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 21486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x5A); 21496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 21506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 21516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 21526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::addsd(XMMRegister dst, XMMRegister src) { 2154d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x58); 2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::mulsd(XMMRegister dst, XMMRegister src) { 2165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x59); 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::subsd(XMMRegister dst, XMMRegister src) { 2176d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x5C); 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::divsd(XMMRegister dst, XMMRegister src) { 2187d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x5E); 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2197e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::xorpd(XMMRegister dst, XMMRegister src) { 2198e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2199e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2200e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2201e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x66); 2202e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2203e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x57); 2204e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(dst, src); 2205e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 22086ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { 22096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 22106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 22116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xF2); 22126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 22136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x51); 22146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 22156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 22166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 22176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 22180d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::andpd(XMMRegister dst, XMMRegister src) { 22190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 22200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 22210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x66); 22220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x0F); 22230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x54); 22240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen emit_sse_operand(dst, src); 22250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 22260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 22270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 22286ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::ucomisd(XMMRegister dst, XMMRegister src) { 22296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 22306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 22316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 22326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x66); 22336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 22346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x2E); 22356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 22366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 22376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 22386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 22396ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::movmskpd(Register dst, XMMRegister src) { 22406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 22416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 22426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 22436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x66); 22446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 22456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x50); 22466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 22476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 22486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 22496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 22500d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::cmpltsd(XMMRegister dst, XMMRegister src) { 22510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(CpuFeatures::IsEnabled(SSE2)); 22520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 22530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 22540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0xF2); 22550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x0F); 22560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0xC2); 22570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen emit_sse_operand(dst, src); 22580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(1); // LT == 1 22590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 22600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 22610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 22620d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::movaps(XMMRegister dst, XMMRegister src) { 22630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(CpuFeatures::IsEnabled(SSE2)); 22640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 22650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 22660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x0F); 22670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x28); 22680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen emit_sse_operand(dst, src); 22690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 22700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 22710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 22720d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::movdqa(const Operand& dst, XMMRegister src) { 2273e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2274e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2275e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2276e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x66); 2277e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2278e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x7F); 2279e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(src, dst); 2280e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2281e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2282e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2283e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqa(XMMRegister dst, const Operand& src) { 2284e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2285e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2286e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2287e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x66); 2288e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2289e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x6F); 2290e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(dst, src); 2291e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2292e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2293e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2294e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqu(const Operand& dst, XMMRegister src ) { 2295e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2296e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2297e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2298e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xF3); 2299e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2300e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x7F); 2301e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(src, dst); 2302e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2303e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2304e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2305e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Assembler::movdqu(XMMRegister dst, const Operand& src) { 2306e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(CpuFeatures::IsEnabled(SSE2)); 2307e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EnsureSpace ensure_space(this); 2308e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke last_pc_ = pc_; 2309e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0xF3); 2310e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x0F); 2311e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EMIT(0x6F); 2312e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke emit_sse_operand(dst, src); 2313e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2314e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2315e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 23167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Assembler::movntdqa(XMMRegister dst, const Operand& src) { 23177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(CpuFeatures::IsEnabled(SSE4_1)); 23187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EnsureSpace ensure_space(this); 23197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch last_pc_ = pc_; 23207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x66); 23217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x0F); 23227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x38); 23237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x2A); 23247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch emit_sse_operand(dst, src); 23257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 23267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 23277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 23287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Assembler::movntdq(const Operand& dst, XMMRegister src) { 23297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(CpuFeatures::IsEnabled(SSE2)); 23307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EnsureSpace ensure_space(this); 23317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch last_pc_ = pc_; 23327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x66); 23337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x0F); 23347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0xE7); 23357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch emit_sse_operand(src, dst); 23367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 23377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 23387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 23397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Assembler::prefetch(const Operand& src, int level) { 23407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(is_uint2(level)); 23417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EnsureSpace ensure_space(this); 23427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch last_pc_ = pc_; 23437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x0F); 23447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EMIT(0x18); 23457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch XMMRegister code = { level }; // Emit hint number in Reg position of RegR/M. 23467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch emit_sse_operand(code, src); 23477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 23487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 23497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movdbl(XMMRegister dst, const Operand& src) { 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movsd(dst, src); 2354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movdbl(const Operand& dst, XMMRegister src) { 2358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movsd(dst, src); 2361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsd(const Operand& dst, XMMRegister src ) { 2365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); // double 2369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x11); // store 2371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(src, dst); 2372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::movsd(XMMRegister dst, const Operand& src) { 2376d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 2377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc_; 2379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xF2); // double 2380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x0F); 2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x10); // load 2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_sse_operand(dst, src); 2383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23856ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::movsd(XMMRegister dst, XMMRegister src) { 23866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 23876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 23886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 23896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xF2); 23906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 23916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x10); 23926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 23936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 23946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 23956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 23966ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::movd(XMMRegister dst, const Operand& src) { 23976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 23986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 23996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 24006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x66); 24016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 24026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x6E); 24036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 24046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 24056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24076ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::pxor(XMMRegister dst, XMMRegister src) { 24086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(CpuFeatures::IsEnabled(SSE2)); 24096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 24106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 24116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x66); 24126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 24136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xEF); 24146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 24156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 24166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24186ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::ptest(XMMRegister dst, XMMRegister src) { 2419f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(CpuFeatures::IsEnabled(SSE4_1)); 24206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EnsureSpace ensure_space(this); 24216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block last_pc_ = pc_; 24226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x66); 24236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x0F); 24246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x38); 24256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0x17); 24266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit_sse_operand(dst, src); 24276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 24286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 24300d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid Assembler::psllq(XMMRegister reg, int8_t imm8) { 24310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(CpuFeatures::IsEnabled(SSE2)); 24320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EnsureSpace ensure_space(this); 24330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen last_pc_ = pc_; 24340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x66); 24350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x0F); 24360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(0x73); 24370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen emit_sse_operand(esi, reg); // esi == 6 24380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EMIT(imm8); 24390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 24400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 24410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 2442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register ireg = { reg.code() }; 2444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ireg, adr); 2445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 2450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24536ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_sse_operand(Register dst, XMMRegister src) { 24546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block EMIT(0xC0 | dst.code() << 3 | src.code()); 24556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 24566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::Print() { 2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Disassembler::Decode(stdout, buffer_, pc_); 2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordJSReturn() { 24643e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu positions_recorder()->WriteRecordedPositions(); 2465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(RelocInfo::JS_RETURN); 2467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Assembler::RecordDebugBreakSlot() { 24713e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu positions_recorder()->WriteRecordedPositions(); 24727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EnsureSpace ensure_space(this); 24737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 24747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 24757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 24767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordComment(const char* msg) { 2478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_debug_code) { 2479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 2481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::GrowBuffer() { 24863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(overflow()); 2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!own_buffer_) FATAL("external code buffer is too small"); 2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Compute new buffer size. 2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; // the new buffer 2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_size_ < 4*KB) { 2492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.buffer_size = 4*KB; 2493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.buffer_size = 2*buffer_size_; 2495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Some internal data structures overflow for very large buffers, 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // they must ensure that kMaximalBufferSize is not too large. 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((desc.buffer_size > kMaximalBufferSize) || 24993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block (desc.buffer_size > Heap::MaxOldGenerationSize())) { 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Setup new buffer. 2504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.buffer = NewArray<byte>(desc.buffer_size); 2505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.instr_size = pc_offset(); 2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the buffer in debug mode. Use 'int3' instructions to make 2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sure to get into problems if we ever run uninitialized code. 2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memset(desc.buffer, 0xCC, desc.buffer_size); 2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Copy the data. 2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pc_delta = desc.buffer - buffer_; 2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memmove(desc.buffer, buffer_, desc.instr_size); 2518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memmove(rc_delta + reloc_info_writer.pos(), 2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.pos(), desc.reloc_size); 2520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Switch buffers. 2522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 2523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_buffer_ = buffer_; 2524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(buffer_); 2526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = desc.buffer; 2528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_size_ = desc.buffer_size; 2529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += pc_delta; 2530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (last_pc_ != NULL) { 2531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ += pc_delta; 2532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.last_pc() + pc_delta); 2535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Relocate runtime entries. 2537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (RelocIterator it(desc); !it.done(); it.next()) { 2538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode = it.rinfo()->rmode(); 2539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rmode == RelocInfo::RUNTIME_ENTRY) { 2540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p -= pc_delta; // relocate entry 2542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (rmode == RelocInfo::INTERNAL_REFERENCE) { 2543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*p != 0) { // 0 means uninitialized. 2545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p += pc_delta; 2546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!overflow()); 2551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 2555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode 2556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint8(imm8)); 2557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((op1 & 0x01) == 0); // should be 8bit operation 2558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(op1); 2559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(op2 | dst.code()); 2560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(imm8); 2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 2565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((0 <= sel) && (sel <= 7)); 2566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register ireg = { sel }; 2567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x.is_int8()) { 2568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x83); // using a sign-extended 8-bit immediate. 2569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ireg, dst); 2570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(x.x_ & 0xFF); 2571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (dst.is_reg(eax)) { 2572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT((sel << 3) | 0x05); // short form if the destination is eax. 2573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 2574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(0x81); // using a literal 32-bit immediate. 2576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(ireg, dst); 2577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 2578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_operand(Register reg, const Operand& adr) { 2583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const unsigned length = adr.len_; 2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(length > 0); 2585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit updated ModRM byte containing the given register. 2587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3); 2588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the rest of the encoded operand. 2590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 2591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += length; 2592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit relocation information if necessary. 2594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length >= sizeof(int32_t) && adr.rmode_ != RelocInfo::NONE) { 2595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 2596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordRelocInfo(adr.rmode_); 2597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(int32_t); 2598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_farith(int b1, int b2, int i) { 2603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode 2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= i && i < 8); // illegal stack offset 2605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(b1); 2606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMIT(b2 + i); 2607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::dd(uint32_t data, RelocInfo::Mode reloc_info) { 2611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnsureSpace ensure_space(this); 2612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(data, reloc_info); 2613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode != RelocInfo::NONE); 2618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't record external references unless the heap will be serialized. 2619d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 2620d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef DEBUG 2621d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Serializer::enabled()) { 2622d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Serializer::TooLateToEnableNow(); 2623d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2624d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 2625d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Serializer::enabled() && !FLAG_debug_code) { 2626d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 2627d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo rinfo(pc_, rmode, data); 2630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_info_writer.Write(&rinfo); 2631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 2635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic FILE* coverage_log = NULL; 2636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitCoverageLog() { 2639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (file_name != NULL) { 2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block coverage_log = fopen(file_name, "aw+"); 2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogGeneratedCodeCoverage(const char* file_line) { 2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* return_address = (&file_line)[-1]; 2648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* push_insn = const_cast<char*>(return_address - 12); 2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block push_insn[0] = 0xeb; // Relative branch insn. 2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block push_insn[1] = 13; // Skip over coverage insns. 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (coverage_log != NULL) { 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fprintf(coverage_log, "%s\n", file_line); 2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fflush(coverage_log); 2654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 2660f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2661f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_IA32 2662