assembler-ia32.cc revision 0d5e116f6aee03185f237311a943491bb079a768
1a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// All Rights Reserved. 3a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// 4a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// Redistribution and use in source and binary forms, with or without 5a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// modification, are permitted provided that the following conditions 6a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// are met: 7a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// 8a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// - Redistributions of source code must retain the above copyright notice, 9a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// this list of conditions and the following disclaimer. 10a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// 11a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// - Redistribution in binary form must reproduce the above copyright 12a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// notice, this list of conditions and the following disclaimer in the 13a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// documentation and/or other materials provided with the 14a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// distribution. 15a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// 16a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// - Neither the name of Sun Microsystems or the names of contributors may 17a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// be used to endorse or promote products derived from this software without 18a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// specific prior written permission. 19a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// 20a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// OF THE POSSIBILITY OF SUCH DAMAGE. 32a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 33a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// The original source code covered by the above license above has been modified 34a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// significantly by Google Inc. 35c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// Copyright 2006-2008 the V8 project authors. All rights reserved. 36a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 37a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include "v8.h" 38a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 39a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#if defined(V8_TARGET_ARCH_IA32) 40a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 41a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include "disassembler.h" 42a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include "macro-assembler.h" 43a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include "serialize.h" 44a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 45a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMnamespace v8 { 46a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMnamespace internal { 47a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 48a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// ----------------------------------------------------------------------------- 49a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// Implementation of CpuFeatures 50a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 51a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// Safe default is no features. 52a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMuint64_t CpuFeatures::supported_ = 0; 53a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMuint64_t CpuFeatures::enabled_ = 0; 54a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMuint64_t CpuFeatures::found_by_runtime_probing_ = 0; 55a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 56a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 57a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// The Probe method needs executable memory, so it uses Heap::CreateCode. 58a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM// Allocation failure is silent and leads to safe default. 59a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMvoid CpuFeatures::Probe() { 60a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM ASSERT(Heap::HasBeenSetup()); 61a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM ASSERT(supported_ == 0); 62a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM if (Serializer::enabled()) { 63a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM supported_ |= OS::CpuFeaturesImpliedByPlatform(); 64a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM return; // No features if we might serialize. 65a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM } 66a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 67a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM Assembler assm(NULL, 0); 68a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM Label cpuid, done; 69a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#define __ assm. 70a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM // Save old esp, since we are going to modify the stack. 71a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM __ push(ebp); 72a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM __ pushfd(); 73a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM __ push(ecx); 74a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM __ push(ebx); 75a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM __ mov(ebp, Operand(esp)); 76a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 77a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. 78a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM __ pushfd(); 7927c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ pop(eax); 8027c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ mov(edx, Operand(eax)); 8127c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ xor_(eax, 0x200000); // Flip bit 21. 8227c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ push(eax); 8327c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ popfd(); 8427c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ pushfd(); 8527c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ pop(eax); 8627c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ xor_(eax, Operand(edx)); // Different if CPUID is supported. 8727c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ j(not_zero, &cpuid); 8827c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner 8927c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // CPUID not supported. Clear the supported features in edx:eax. 9027c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ xor_(eax, Operand(eax)); 9127c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ xor_(edx, Operand(edx)); 9227c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ jmp(&done); 9327c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner 9427c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // Invoke CPUID with 1 in eax to get feature information in 9527c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // ecx:edx. Temporarily enable CPUID support because we know it's 9627c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // safe here. 9727c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner __ bind(&cpuid); 98b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ mov(eax, 1); 99b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball supported_ = (1 << CPUID); 100b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball { Scope fscope(CPUID); 101b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ cpuid(); 102b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball } 103b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball supported_ = 0; 104b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 105b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Move the result from ecx:edx to edx:eax and make sure to mark the 106b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // CPUID feature as supported. 107b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ mov(eax, Operand(edx)); 108b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ or_(eax, 1 << CPUID); 109b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ mov(edx, Operand(ecx)); 110b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 111b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Done. 112b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ bind(&done); 113b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ mov(esp, Operand(ebp)); 114b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ pop(ebx); 115b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ pop(ecx); 116b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ popfd(); 117b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ pop(ebp); 118b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball __ ret(0); 119b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball#undef __ 120b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 121b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball CodeDesc desc; 122b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball assm.GetCode(&desc); 123b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball Object* code = Heap::CreateCode(desc, 124b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball Code::ComputeFlags(Code::STUB), 125b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball Handle<Code>::null()); 126b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball if (!code->IsCode()) return; 127b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, 128b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball Code::cast(code), "CpuFeatures::Probe")); 129b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball typedef uint64_t (*F0)(); 130b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); 131b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball supported_ = probe(); 132b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball found_by_runtime_probing_ = supported_; 133b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); 134b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball supported_ |= os_guarantees; 135b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball found_by_runtime_probing_ &= ~os_guarantees; 136b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball} 137b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 1388ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball 1398ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball// ----------------------------------------------------------------------------- 140b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball// Implementation of Displacement 141b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 142b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballvoid Displacement::init(Label* L, Type type) { 143b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball ASSERT(!L->is_bound()); 144b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball int next = 0; 145b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball if (L->is_linked()) { 146b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball next = L->pos(); 147b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball ASSERT(next > 0); // Displacements must be at positions > 0 148b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball } 149b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Ensure that we _never_ overflow the next field. 150b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize)); 151b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball data_ = NextField::encode(next) | TypeField::encode(type); 152b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball} 153b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 154b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 155b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball// ----------------------------------------------------------------------------- 156b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball// Implementation of RelocInfo 157b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 158b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 159b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballconst int RelocInfo::kApplyMask = 160b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 161b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE | 162b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 1 << RelocInfo::DEBUG_BREAK_SLOT; 163b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 164b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 165b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballbool RelocInfo::IsCodedSpecially() { 1668ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball // The deserializer needs to know whether a pointer is specially coded. Being 1678ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball // specially coded on IA32 means that it is a relative address, as used by 168b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // branch instructions. These are also the ones that need changing when a 169b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // code object moves. 170b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball return (1 << rmode_) & kApplyMask; 171b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball} 172b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 173b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 174b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) { 175b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Patch the code at the current address with the supplied instructions. 176b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball for (int i = 0; i < instruction_count; i++) { 177b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball *(pc_ + i) = *(instructions + i); 178b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball } 179b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 180b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Indicate that code has changed. 181b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball CPU::FlushICache(pc_, instruction_count); 182b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball} 183b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 184b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 185b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball// Patch the code at the current PC with a call to the target address. 186b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball// Additional guard int3 instructions can be added if required. 187b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 188b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Call instruction takes up 5 bytes and int3 takes up one byte. 189b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball static const int kCallCodeSize = 5; 190b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball int code_size = kCallCodeSize + guard_bytes; 191b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 192b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Create a code patcher. 193b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball CodePatcher patcher(pc_, code_size); 194b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 195b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball // Add a label for checking the size of the code used for returning. 196b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das#ifdef DEBUG 197b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das Label check_codesize; 198b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das patcher.masm()->bind(&check_codesize); 199b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das#endif 200b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 201b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // Patch the code. 202b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das patcher.masm()->call(target, RelocInfo::NONE); 203b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 204b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // Check that the size of the code generated is as expected. 205b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das ASSERT_EQ(kCallCodeSize, 206b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 207b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 208b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // Add the requested number of int3 instructions after the call. 209b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das ASSERT_GE(guard_bytes, 0); 210b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das for (int i = 0; i < guard_bytes; i++) { 211b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das patcher.masm()->int3(); 212b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das } 213b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das} 214b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 215b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 216b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das// ----------------------------------------------------------------------------- 217b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das// Implementation of Operand 218b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 219b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata DasOperand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 220b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // [base + disp/r] 221b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) { 222b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // [base] 223b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das set_modrm(0, base); 224b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das if (base.is(esp)) set_sib(times_1, esp, base); 225b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das } else if (is_int8(disp) && rmode == RelocInfo::NONE) { 226b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // [base + disp8] 227b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das set_modrm(1, base); 228b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das if (base.is(esp)) set_sib(times_1, esp, base); 229b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das set_disp8(disp); 230b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das } else { 231b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das // [base + disp/r] 232b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das set_modrm(2, base); 233b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das if (base.is(esp)) set_sib(times_1, esp, base); 234b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das set_dispr(disp, rmode); 235b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das } 236b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das} 237b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 238b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das 239b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata DasOperand::Operand(Register base, 2407bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO Register index, 2417bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO ScaleFactor scale, 2427bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO int32_t disp, 2437bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO RelocInfo::Mode rmode) { 2447bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO ASSERT(!index.is(esp)); // illegal addressing mode 2457bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO // [base + index*scale + disp/r] 2467bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) { 2477bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO // [base + index*scale] 2487bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_modrm(0, esp); 2497bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_sib(scale, index, base); 2507bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO } else if (is_int8(disp) && rmode == RelocInfo::NONE) { 2517bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO // [base + index*scale + disp8] 2527bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_modrm(1, esp); 2537bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_sib(scale, index, base); 2547bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_disp8(disp); 2557bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO } else { 2567bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO // [base + index*scale + disp/r] 2577bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_modrm(2, esp); 2587bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_sib(scale, index, base); 2597bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_dispr(disp, rmode); 2607bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO } 2617bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO} 2627bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2637bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2647bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLAROOperand::Operand(Register index, 2657bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO ScaleFactor scale, 2667bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO int32_t disp, 2677bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO RelocInfo::Mode rmode) { 2687bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO ASSERT(!index.is(esp)); // illegal addressing mode 2697bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO // [index*scale + disp/r] 2707bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_modrm(0, esp); 2717bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_sib(scale, index, ebp); 2727bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO set_dispr(disp, rmode); 2737bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO} 2747bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2757bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2767bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARObool Operand::is_reg(Register reg) const { 2777bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. 2787bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO && ((buf_[0] & 0x07) == reg.code()); // register codes match. 2797bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO} 2807bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2817bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO// ----------------------------------------------------------------------------- 2827bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO// Implementation of Assembler. 2837bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2847bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO// Emit a single byte. Must always be inlined. 2857bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO#define EMIT(x) \ 2867bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO *pc_++ = (x) 2877bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2887bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2897bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO#ifdef GENERATED_CODE_COVERAGE 2907bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLAROstatic void InitCoverageLog(); 2917bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO#endif 2927bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2937bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO// Spare buffer. 2947bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARObyte* Assembler::spare_buffer_ = NULL; 2957bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 2967bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLAROAssembler::Assembler(void* buffer, int buffer_size) { 2977bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO if (buffer == NULL) { 2987bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO // Do our own buffer management. 2997bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO if (buffer_size <= kMinimalBufferSize) { 3007bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO buffer_size = kMinimalBufferSize; 3017bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO 3027bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO if (spare_buffer_ != NULL) { 3037bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO buffer = spare_buffer_; 3047bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO spare_buffer_ = NULL; 3057bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO } 30664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } 30764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper if (buffer == NULL) { 30864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper buffer_ = NewArray<byte>(buffer_size); 30964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } else { 31064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper buffer_ = static_cast<byte*>(buffer); 31164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } 31264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper buffer_size_ = buffer_size; 31364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper own_buffer_ = true; 31464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } else { 31564c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // Use externally provided buffer instead. 31664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper ASSERT(buffer_size > 0); 31764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper buffer_ = static_cast<byte*>(buffer); 31864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper buffer_size_ = buffer_size; 31964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper own_buffer_ = false; 32064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } 32164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 32264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // Clear the buffer in debug mode unless it was provided by the 32364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // caller in which case we can't be sure it's okay to overwrite 32464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // existing code in it; see CodePatcher::CodePatcher(...). 32564c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper#ifdef DEBUG 32664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper if (own_buffer_) { 32764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper memset(buffer_, 0xCC, buffer_size); // int3 32864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } 32964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper#endif 33064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 33164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // Setup buffer pointers. 33264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper ASSERT(buffer_ != NULL); 33364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper pc_ = buffer_; 33464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); 33564c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 33664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper last_pc_ = NULL; 33764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper current_statement_position_ = RelocInfo::kNoPosition; 33864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper current_position_ = RelocInfo::kNoPosition; 33964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper written_statement_position_ = current_statement_position_; 34064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper written_position_ = current_position_; 34164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper#ifdef GENERATED_CODE_COVERAGE 34264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper InitCoverageLog(); 34364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper#endif 34464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper} 34564c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 34664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 34764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al CooperAssembler::~Assembler() { 34864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper if (own_buffer_) { 34964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 35064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper spare_buffer_ = buffer_; 35164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } else { 35264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper DeleteArray(buffer_); 35364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } 35464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper } 35564c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper} 35664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 35764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 35864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Coopervoid Assembler::GetCode(CodeDesc* desc) { 35964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // Finalize code (at this point overflow() may be true, but the gap ensures 36064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // that we are still not overlapping instructions and relocation info). 36164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. 36264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper // Setup code descriptor. 36364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper desc->buffer = buffer_; 36464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper desc->buffer_size = buffer_size_; 36564c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper desc->instr_size = pc_offset(); 36664c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 36764c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper desc->origin = this; 36864c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 36964c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper Counters::reloc_info_size.Increment(desc->reloc_size); 37064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper} 37164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 37264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper 37364c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Coopervoid Assembler::Align(int m) { 37464c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper ASSERT(IsPowerOf2(m)); 375f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball while ((pc_offset() & (m - 1)) != 0) { 376f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball nop(); 377f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball } 378f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 379f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 380f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 381f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::CodeTargetAlign() { 382f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball Align(16); // Preferred alignment of jump targets on ia32. 383f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 384f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 385f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 386f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::cpuid() { 387f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball ASSERT(CpuFeatures::IsEnabled(CPUID)); 388f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EnsureSpace ensure_space(this); 389f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball last_pc_ = pc_; 390f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x0F); 391f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0xA2); 392f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 393f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 394f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 395f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::pushad() { 396f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EnsureSpace ensure_space(this); 397f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball last_pc_ = pc_; 398f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x60); 399f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 400f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 401f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 402f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::popad() { 403f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EnsureSpace ensure_space(this); 404f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball last_pc_ = pc_; 405f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x61); 406f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 407f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 408f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 409f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::pushfd() { 410f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EnsureSpace ensure_space(this); 411f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball last_pc_ = pc_; 412f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x9C); 413f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 414f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 415f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 416f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::popfd() { 417f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EnsureSpace ensure_space(this); 418f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball last_pc_ = pc_; 419f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x9D); 420f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 421f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 422f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball 423f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballvoid Assembler::push(const Immediate& x) { 424f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EnsureSpace ensure_space(this); 425f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball last_pc_ = pc_; 426f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball if (x.is_int8()) { 427f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x6a); 428f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(x.x_); 429f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball } else { 430f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball EMIT(0x68); 431f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball emit(x); 432f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball } 433f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball} 4348649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung 4358649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung 4368649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chungvoid Assembler::push(Register src) { 4378649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung EnsureSpace ensure_space(this); 4388649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung last_pc_ = pc_; 4398649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung EMIT(0x50 | src.code()); 4408649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung} 4418649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung 4428649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung 4438649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chungvoid Assembler::push(const Operand& src) { 4448649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung EnsureSpace ensure_space(this); 4458649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung last_pc_ = pc_; 4468649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung EMIT(0xFF); 4478649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung emit_operand(esi, src); 4488649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung} 4498649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung 4508649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung 4518649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chungvoid Assembler::pop(Register dst) { 4528649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung ASSERT(reloc_info_writer.last_pc() != NULL); 4538649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) { 4548649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung // (last_pc_ != NULL) is rolled into the above check. 4558649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung // If a last_pc_ is set, we need to make sure that there has not been any 4568649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung // relocation information generated between the last instruction and this 4578649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung // pop instruction. 4588649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung byte instr = last_pc_[0]; 4598649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung if ((instr & ~0x7) == 0x50) { 4608649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung int push_reg_code = instr & 0x7; 4618649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung if (push_reg_code == dst.code()) { 4628649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung pc_ = last_pc_; 4638649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung if (FLAG_print_peephole_optimization) { 4648649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung PrintF("%d push/pop (same reg) eliminated\n", pc_offset()); 4658649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung } 4668649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung } else { 4678649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung // Convert 'push src; pop dst' to 'mov dst, src'. 4688649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung last_pc_[0] = 0x8b; 4698649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung Register src = { push_reg_code }; 4708649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung EnsureSpace ensure_space(this); 4718649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung emit_operand(dst, Operand(src)); 47227c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner if (FLAG_print_peephole_optimization) { 47327c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset()); 47427c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner } 47527c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner } 47627c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner last_pc_ = NULL; 47727c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner return; 47827c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner } else if (instr == 0xff) { // push of an operand, convert to a move 47927c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner byte op1 = last_pc_[1]; 48027c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // Check if the operation is really a push. 48127c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner if ((op1 & 0x38) == (6 << 3)) { 48227c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3); 48327c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner last_pc_[0] = 0x8b; 48427c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner last_pc_[1] = op1; 48527c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner last_pc_ = NULL; 48627c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner if (FLAG_print_peephole_optimization) { 48727c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner PrintF("%d push/pop (op->reg) eliminated\n", pc_offset()); 48827c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner } 48927c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner return; 49027c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner } 49127c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner } else if ((instr == 0x89) && 49227c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner (last_pc_[1] == 0x04) && 49327c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner (last_pc_[2] == 0x24)) { 49427c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // 0x71283c 396 890424 mov [esp],eax 49527c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // 0x71283f 399 58 pop eax 49627c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner if (dst.is(eax)) { 49727c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // change to 49827c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner // 0x710fac 216 83c404 add esp,0x4 49927c357db04350b75b0fceaae8bfb9ce99c50866bBen Gardiner last_pc_[0] = 0x83; 5004e85023654b356511612547207a4cb643fb3db16Ben Gardiner last_pc_[1] = 0xc4; 5014e85023654b356511612547207a4cb643fb3db16Ben Gardiner last_pc_[2] = 0x04; 5024e85023654b356511612547207a4cb643fb3db16Ben Gardiner last_pc_ = NULL; 5034e85023654b356511612547207a4cb643fb3db16Ben Gardiner if (FLAG_print_peephole_optimization) { 5044e85023654b356511612547207a4cb643fb3db16Ben Gardiner PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset()); 5054e85023654b356511612547207a4cb643fb3db16Ben Gardiner } 5064e85023654b356511612547207a4cb643fb3db16Ben Gardiner return; 5074e85023654b356511612547207a4cb643fb3db16Ben Gardiner } 5084e85023654b356511612547207a4cb643fb3db16Ben Gardiner } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit 5094e85023654b356511612547207a4cb643fb3db16Ben Gardiner byte imm8 = last_pc_[1]; 5104e85023654b356511612547207a4cb643fb3db16Ben Gardiner if (imm8 == 0) { 5114e85023654b356511612547207a4cb643fb3db16Ben Gardiner // 6a00 push 0x0 5124e85023654b356511612547207a4cb643fb3db16Ben Gardiner // 58 pop eax 5134e85023654b356511612547207a4cb643fb3db16Ben Gardiner last_pc_[0] = 0x31; 5144e85023654b356511612547207a4cb643fb3db16Ben Gardiner last_pc_[1] = 0xc0; 515f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner // change to 516f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner // 31c0 xor eax,eax 517f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner last_pc_ = NULL; 518f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner if (FLAG_print_peephole_optimization) { 519f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 520f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner } 521f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner return; 522f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner } else { 523f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner // 6a00 push 0xXX 524f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner // 58 pop eax 525e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner last_pc_[0] = 0xb8; 526e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EnsureSpace ensure_space(this); 527e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner if ((imm8 & 0x80) != 0) { 528e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0xff); 529e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0xff); 530e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0xff); 531e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // change to 532e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // b8XXffffff mov eax,0xffffffXX 533e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } else { 534e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0x00); 535e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0x00); 536e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0x00); 537e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // change to 538e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // b8XX000000 mov eax,0x000000XX 539e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } 540e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner last_pc_ = NULL; 541e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner if (FLAG_print_peephole_optimization) { 542e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 543e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } 544e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner return; 545e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } 546e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit 547e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // 68XXXXXXXX push 0xXXXXXXXX 548e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // 58 pop eax 549e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner last_pc_[0] = 0xb8; 550e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner last_pc_ = NULL; 551e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // change to 552e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // b8XXXXXXXX mov eax,0xXXXXXXXX 553e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner if (FLAG_print_peephole_optimization) { 554e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 555e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } 556e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner return; 557e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } 558e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner 559e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // Other potential patterns for peephole: 560e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // 0x712716 102 890424 mov [esp], eax 561e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner // 0x712719 105 8b1424 mov edx, [esp] 562e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner } 563e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EnsureSpace ensure_space(this); 564e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner last_pc_ = pc_; 565e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner EMIT(0x58 | dst.code()); 566e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner} 567e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner 568e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner 569e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardinervoid Assembler::pop(const Operand& dst) { 5704afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 5714afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 5724afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x8F); 5734afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(eax, dst); 5744afc8c81685825461677311e79059cda15fba9d8Balaji T K} 5754afc8c81685825461677311e79059cda15fba9d8Balaji T K 5767891236d62ccd201054324b5298dd9529c6a764fBalaji T K 5774afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::enter(const Immediate& size) { 5784afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 5794afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 5804afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0xC8); 5814afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_w(size); 5824afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0); 5834afc8c81685825461677311e79059cda15fba9d8Balaji T K} 5844afc8c81685825461677311e79059cda15fba9d8Balaji T K 5854afc8c81685825461677311e79059cda15fba9d8Balaji T K 5864afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::leave() { 5874afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 5884afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 5894afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0xC9); 5904afc8c81685825461677311e79059cda15fba9d8Balaji T K} 5914afc8c81685825461677311e79059cda15fba9d8Balaji T K 5924afc8c81685825461677311e79059cda15fba9d8Balaji T K 5934afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov_b(Register dst, const Operand& src) { 5944afc8c81685825461677311e79059cda15fba9d8Balaji T K ASSERT(dst.code() < 4); 5954afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 5964afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 5974afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x8A); 5984afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(dst, src); 5994afc8c81685825461677311e79059cda15fba9d8Balaji T K} 6004afc8c81685825461677311e79059cda15fba9d8Balaji T K 6014afc8c81685825461677311e79059cda15fba9d8Balaji T K 6024afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov_b(const Operand& dst, int8_t imm8) { 6034afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 6044afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 6054afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0xC6); 6064afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(eax, dst); 6074afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(imm8); 6084afc8c81685825461677311e79059cda15fba9d8Balaji T K} 6094afc8c81685825461677311e79059cda15fba9d8Balaji T K 6104afc8c81685825461677311e79059cda15fba9d8Balaji T K 6114afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov_b(const Operand& dst, Register src) { 6124afc8c81685825461677311e79059cda15fba9d8Balaji T K ASSERT(src.code() < 4); 6134afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 6144afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 6154afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x88); 6164afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(src, dst); 6174afc8c81685825461677311e79059cda15fba9d8Balaji T K} 6184afc8c81685825461677311e79059cda15fba9d8Balaji T K 6194afc8c81685825461677311e79059cda15fba9d8Balaji T K 6204afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov_w(Register dst, const Operand& src) { 6214afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 6224afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 6234afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x66); 6244afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x8B); 6254afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(dst, src); 6264afc8c81685825461677311e79059cda15fba9d8Balaji T K} 6274afc8c81685825461677311e79059cda15fba9d8Balaji T K 6284afc8c81685825461677311e79059cda15fba9d8Balaji T K 6294afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov_w(const Operand& dst, Register src) { 6304afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 6314afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 6324afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x66); 6334afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x89); 6344afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(src, dst); 6354afc8c81685825461677311e79059cda15fba9d8Balaji T K} 6364afc8c81685825461677311e79059cda15fba9d8Balaji T K 6374afc8c81685825461677311e79059cda15fba9d8Balaji T K 6384afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov(Register dst, int32_t imm32) { 6394afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 6404afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 6414afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0xB8 | dst.code()); 6424afc8c81685825461677311e79059cda15fba9d8Balaji T K emit(imm32); 6434afc8c81685825461677311e79059cda15fba9d8Balaji T K} 6444afc8c81685825461677311e79059cda15fba9d8Balaji T K 6454afc8c81685825461677311e79059cda15fba9d8Balaji T K 6464afc8c81685825461677311e79059cda15fba9d8Balaji T Kvoid Assembler::mov(Register dst, const Immediate& x) { 6474afc8c81685825461677311e79059cda15fba9d8Balaji T K EnsureSpace ensure_space(this); 6484afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 6494afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0xB8 | dst.code()); 6507891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit(x); 6517891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 6527891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6537891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6547891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::mov(Register dst, Handle<Object> handle) { 6557891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 6567891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 6577891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xB8 | dst.code()); 6587891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit(handle); 6597891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 6607891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6617891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6627891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::mov(Register dst, const Operand& src) { 6637891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 6647891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 6657891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x8B); 6667891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(dst, src); 6677891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 6687891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6697891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6707891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::mov(Register dst, Register src) { 6717891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 6727891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 6737891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x89); 6747891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xC0 | src.code() << 3 | dst.code()); 6757891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 6767891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6777891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6787891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::mov(const Operand& dst, const Immediate& x) { 6797891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 6807891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 6817891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xC7); 6827891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(eax, dst); 6837891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit(x); 6847891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 6857891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6867891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6877891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::mov(const Operand& dst, Handle<Object> handle) { 6887891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 6897891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 6907891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xC7); 6917891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(eax, dst); 6927891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit(handle); 6937891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 6947891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6957891236d62ccd201054324b5298dd9529c6a764fBalaji T K 6967891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::mov(const Operand& dst, Register src) { 6977891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 6987891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 6997891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x89); 7007891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(src, dst); 7017891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7027891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7037891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7047891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::movsx_b(Register dst, const Operand& src) { 7057891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7067891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7077891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x0F); 7087891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xBE); 7097891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(dst, src); 7107891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7117891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7127891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7137891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::movsx_w(Register dst, const Operand& src) { 7147891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7157891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7167891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x0F); 7177891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xBF); 7187891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(dst, src); 7197891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7207891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7217891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7227891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::movzx_b(Register dst, const Operand& src) { 7237891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7247891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7257891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x0F); 7267891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xB6); 7277891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(dst, src); 7287891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7297891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7307891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7317891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::movzx_w(Register dst, const Operand& src) { 7327891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7337891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7347891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x0F); 7357891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xB7); 7367891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(dst, src); 7377891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7387891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7397891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7407891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::cmov(Condition cc, Register dst, int32_t imm32) { 7417891236d62ccd201054324b5298dd9529c6a764fBalaji T K ASSERT(CpuFeatures::IsEnabled(CMOV)); 7427891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7437891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7447891236d62ccd201054324b5298dd9529c6a764fBalaji T K UNIMPLEMENTED(); 7457891236d62ccd201054324b5298dd9529c6a764fBalaji T K USE(cc); 7467891236d62ccd201054324b5298dd9529c6a764fBalaji T K USE(dst); 7477891236d62ccd201054324b5298dd9529c6a764fBalaji T K USE(imm32); 7487891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7497891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7507891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7517891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::cmov(Condition cc, Register dst, Handle<Object> handle) { 7527891236d62ccd201054324b5298dd9529c6a764fBalaji T K ASSERT(CpuFeatures::IsEnabled(CMOV)); 7537891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7547891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7557891236d62ccd201054324b5298dd9529c6a764fBalaji T K UNIMPLEMENTED(); 7567891236d62ccd201054324b5298dd9529c6a764fBalaji T K USE(cc); 7577891236d62ccd201054324b5298dd9529c6a764fBalaji T K USE(dst); 7587891236d62ccd201054324b5298dd9529c6a764fBalaji T K USE(handle); 7597891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7607891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7617891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7627891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::cmov(Condition cc, Register dst, const Operand& src) { 7637891236d62ccd201054324b5298dd9529c6a764fBalaji T K ASSERT(CpuFeatures::IsEnabled(CMOV)); 7647891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7657891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7667891236d62ccd201054324b5298dd9529c6a764fBalaji T K // Opcode: 0f 40 + cc /r. 7677891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x0F); 7687891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0x40 + cc); 7697891236d62ccd201054324b5298dd9529c6a764fBalaji T K emit_operand(dst, src); 7707891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7717891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7727891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7737891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::cld() { 7747891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7757891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7767891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xFC); 7777891236d62ccd201054324b5298dd9529c6a764fBalaji T K} 7787891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7797891236d62ccd201054324b5298dd9529c6a764fBalaji T K 7807891236d62ccd201054324b5298dd9529c6a764fBalaji T Kvoid Assembler::rep_movs() { 7817891236d62ccd201054324b5298dd9529c6a764fBalaji T K EnsureSpace ensure_space(this); 7827891236d62ccd201054324b5298dd9529c6a764fBalaji T K last_pc_ = pc_; 7837891236d62ccd201054324b5298dd9529c6a764fBalaji T K EMIT(0xF3); 7844afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0xA5); 7854afc8c81685825461677311e79059cda15fba9d8Balaji T K} 7864afc8c81685825461677311e79059cda15fba9d8Balaji T K 7874afc8c81685825461677311e79059cda15fba9d8Balaji T K 788d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::rep_stos() { 789d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 790d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 791d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0xF3); 792d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0xAB); 793d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 794d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 795d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 796d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::stos() { 797d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 798d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 799d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0xAB); 800d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 801d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 802d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 803d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::xchg(Register dst, Register src) { 804d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 805d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 806d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 807d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 808d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner } else { 809d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x87); 810d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0xC0 | src.code() << 3 | dst.code()); 811d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner } 812d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 813d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 814d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 815d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::adc(Register dst, int32_t imm32) { 816d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 817d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 818d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_arith(2, Operand(dst), Immediate(imm32)); 819d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 820d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 821d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 822d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::adc(Register dst, const Operand& src) { 823d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 824d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 825d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x13); 826d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_operand(dst, src); 827d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 828d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 829d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 830d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::add(Register dst, const Operand& src) { 831d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 832d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 833d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x03); 834d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_operand(dst, src); 835d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 836d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 837d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 838d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::add(const Operand& dst, const Immediate& x) { 839d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner ASSERT(reloc_info_writer.last_pc() != NULL); 840d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) { 841d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner byte instr = last_pc_[0]; 842d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner if ((instr & 0xf8) == 0x50) { 843d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner // Last instruction was a push. Check whether this is a pop without a 844d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner // result. 845d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner if ((dst.is_reg(esp)) && 846d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) { 847d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner pc_ = last_pc_; 848d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = NULL; 849d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner if (FLAG_print_peephole_optimization) { 850d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner PrintF("%d push/pop(noreg) eliminated\n", pc_offset()); 851d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner } 852d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner return; 853d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner } 854d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner } 855d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner } 856d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 857d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 858d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_arith(0, dst, x); 859d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 860d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 861d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 862d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::and_(Register dst, int32_t imm32) { 863d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner and_(dst, Immediate(imm32)); 864d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 865d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 866d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 867d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::and_(Register dst, const Immediate& x) { 868d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 869d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 870d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_arith(4, Operand(dst), x); 871d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 872d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 873d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 874d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::and_(Register dst, const Operand& src) { 875d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 876d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 877d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x23); 878d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_operand(dst, src); 879d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 880d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 881d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 882d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::and_(const Operand& dst, const Immediate& x) { 883d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 884d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 885d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_arith(4, dst, x); 886d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 887d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 888d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 889d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::and_(const Operand& dst, Register src) { 890d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 891d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 892d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x21); 893d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_operand(src, dst); 894d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 895d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 896d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 897d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::cmpb(const Operand& op, int8_t imm8) { 898d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 899d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 900d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x80); 901d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_operand(edi, op); // edi == 7 902d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(imm8); 903d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 904d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 905d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 906d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::cmpb(const Operand& dst, Register src) { 907d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner ASSERT(src.is_byte_register()); 908d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 9094afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 9104afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x38); 911d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner emit_operand(src, dst); 912d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 913d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 914d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 915d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardinervoid Assembler::cmpb(Register dst, const Operand& src) { 916d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner ASSERT(dst.is_byte_register()); 917d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 9184afc8c81685825461677311e79059cda15fba9d8Balaji T K last_pc_ = pc_; 9194afc8c81685825461677311e79059cda15fba9d8Balaji T K EMIT(0x3A); 9204afc8c81685825461677311e79059cda15fba9d8Balaji T K emit_operand(dst, src); 9214afc8c81685825461677311e79059cda15fba9d8Balaji T K} 922e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardiner 923d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner 924e6e84e96ac031e261bda8d441aa9c4cade144437Ben Gardinervoid Assembler::cmpw(const Operand& op, Immediate imm16) { 925d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner ASSERT(imm16.is_int16()); 926d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EnsureSpace ensure_space(this); 927d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 928d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x66); 929d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner EMIT(0x81); 930196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_operand(edi, op); 931196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_w(imm16); 932196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 933196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 934196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 935196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmp(Register reg, int32_t imm32) { 936196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 937196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 938196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_arith(7, Operand(reg), Immediate(imm32)); 939196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 940196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 941196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 942196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmp(Register reg, Handle<Object> handle) { 943196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 944196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 945196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_arith(7, Operand(reg), Immediate(handle)); 946196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 947196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 948196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 949196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmp(Register reg, const Operand& op) { 950196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 951196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 952196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EMIT(0x3B); 953196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_operand(reg, op); 954196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 955196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 956196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 957196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmp(const Operand& op, const Immediate& imm) { 958196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 959196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 960196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_arith(7, op, imm); 961196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 962196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 963196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 964196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmp(const Operand& op, Handle<Object> handle) { 965196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 966196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 967196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_arith(7, op, Immediate(handle)); 968196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 969196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 970196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 971196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmpb_al(const Operand& op) { 972196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 973196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 974196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EMIT(0x38); // CMP r/m8, r8 975196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_operand(eax, op); // eax has same code as register al. 976196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 977196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 978196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 979196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::cmpw_ax(const Operand& op) { 980196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 981196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 982196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EMIT(0x66); 983196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EMIT(0x39); // CMP r/m16, r16 984196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner emit_operand(eax, op); // eax has same code as register ax. 985196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner} 986196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 987196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner 988196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardinervoid Assembler::dec_b(Register dst) { 989196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EnsureSpace ensure_space(this); 990196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner last_pc_ = pc_; 991196d0d29588867bed50cd28b8f03cbbb5e0e6608Ben Gardiner EMIT(0xFE); 992a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EMIT(0xC8 | dst.code()); 993a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM} 994a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 99511f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz 996a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMvoid Assembler::dec_b(const Operand& dst) { 997a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EnsureSpace ensure_space(this); 998a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 999a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EMIT(0xFE); 10008ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball emit_operand(ecx, dst); 10018ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball} 1002a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 1003a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 1004a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMvoid Assembler::dec(Register dst) { 1005a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EnsureSpace ensure_space(this); 1006a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM last_pc_ = pc_; 1007a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EMIT(0x48 | dst.code()); 1008a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM} 1009a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 1010a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 1011a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMvoid Assembler::dec(const Operand& dst) { 1012a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EnsureSpace ensure_space(this); 1013a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM last_pc_ = pc_; 1014a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM EMIT(0xFF); 1015a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM emit_operand(ecx, dst); 1016a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM} 1017a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1018a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1019a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::cdq() { 102064c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper EnsureSpace ensure_space(this); 102164c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper last_pc_ = pc_; 102264c2de8b1476c42ef9e9729b7ca0e436b5d90170Al Cooper EMIT(0x99); 1023a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1024a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1025a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1026a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::idiv(Register src) { 1027a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1028a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1029a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF7); 1030a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF8 | src.code()); 1031a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1032a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1033a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1034a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::imul(Register reg) { 1035a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1036a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1037a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF7); 1038a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE8 | reg.code()); 1039a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1040a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1041a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1042a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::imul(Register dst, const Operand& src) { 1043a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1044a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1045a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x0F); 1046a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xAF); 1047a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 1048a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1049a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1050a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1051a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::imul(Register dst, Register src, int32_t imm32) { 1052a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1053a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1054a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (is_int8(imm32)) { 1055a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x6B); 1056a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xC0 | dst.code() << 3 | src.code()); 1057a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm32); 1058b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball } else { 1059a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x69); 1060a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xC0 | dst.code() << 3 | src.code()); 1061a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit(imm32); 1062a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 1063a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1064b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 1065a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1066a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::inc(Register dst) { 1067a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1068a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1069a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x40 | dst.code()); 1070a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1071a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1072a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1073a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::inc(const Operand& dst) { 1074a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1075a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1076a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xFF); 1077a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(eax, dst); 1078a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1079a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1080a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1081a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::lea(Register dst, const Operand& src) { 1082a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1083a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1084a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x8D); 1085a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 1086a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1087a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1088a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1089a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::mul(Register src) { 1090a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1091a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1092a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF7); 1093a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE0 | src.code()); 1094a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1095a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1096a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1097a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::neg(Register dst) { 1098a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1099a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1100a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF7); 1101a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD8 | dst.code()); 1102a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1103b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball 1104a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1105a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::not_(Register dst) { 1106a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1107a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1108a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF7); 1109a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD0 | dst.code()); 1110a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1111a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1112a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1113a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::or_(Register dst, int32_t imm32) { 1114a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1115a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1116a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_arith(1, Operand(dst), Immediate(imm32)); 1117a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1118a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1119a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1120a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::or_(Register dst, const Operand& src) { 1121a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1122a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1123a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x0B); 1124b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball emit_operand(dst, src); 1125a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1126a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1127a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1128a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::or_(const Operand& dst, const Immediate& x) { 1129a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1130a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1131a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_arith(1, dst, x); 1132a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1133a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1134a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1135a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::or_(const Operand& dst, Register src) { 1136a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1137a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1138a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x09); 1139a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(src, dst); 1140a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1141a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1142a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1143a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::rcl(Register dst, uint8_t imm8) { 1144a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1145a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1146a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO ASSERT(is_uint5(imm8)); // illegal shift count 1147a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (imm8 == 1) { 1148a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD1); 1149a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD0 | dst.code()); 1150f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner } else { 1151f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(0xC1); 1152a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD0 | dst.code()); 1153f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(imm8); 1154f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner } 1155f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner} 1156a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1157a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1158a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::rcr(Register dst, uint8_t imm8) { 1159a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1160f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner last_pc_ = pc_; 1161f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner ASSERT(is_uint5(imm8)); // illegal shift count 1162a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (imm8 == 1) { 1163f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(0xD1); 1164f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(0xD8 | dst.code()); 1165f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner } else { 1166a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xC1); 1167a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD8 | dst.code()); 1168a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 1169a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 1170a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 11714e85023654b356511612547207a4cb643fb3db16Ben Gardiner 11724e85023654b356511612547207a4cb643fb3db16Ben Gardiner 11734e85023654b356511612547207a4cb643fb3db16Ben Gardinervoid Assembler::sar(Register dst, uint8_t imm8) { 11744e85023654b356511612547207a4cb643fb3db16Ben Gardiner EnsureSpace ensure_space(this); 11754e85023654b356511612547207a4cb643fb3db16Ben Gardiner last_pc_ = pc_; 11764e85023654b356511612547207a4cb643fb3db16Ben Gardiner ASSERT(is_uint5(imm8)); // illegal shift count 11774e85023654b356511612547207a4cb643fb3db16Ben Gardiner if (imm8 == 1) { 11784e85023654b356511612547207a4cb643fb3db16Ben Gardiner EMIT(0xD1); 1179a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF8 | dst.code()); 1180a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } else { 1181a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xC1); 1182a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF8 | dst.code()); 1183a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 1184a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 1185a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1186a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1187a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1188a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::sar_cl(Register dst) { 1189a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1190a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1191a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD3); 1192a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF8 | dst.code()); 1193a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1194a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1195a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1196a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::sbb(Register dst, const Operand& src) { 1197a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1198a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1199a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x1B); 1200a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 1201a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1202a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1203a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1204a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::shld(Register dst, const Operand& src) { 1205a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1206a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1207a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x0F); 1208a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xA5); 1209a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 121064f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi} 121164f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi 121264f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi 121364f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschivoid Assembler::shl(Register dst, uint8_t imm8) { 121464f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi EnsureSpace ensure_space(this); 121564f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi last_pc_ = pc_; 121664f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi ASSERT(is_uint5(imm8)); // illegal shift count 121764f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi if (imm8 == 1) { 121864f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi EMIT(0xD1); 1219a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE0 | dst.code()); 1220a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } else { 1221a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xC1); 1222a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE0 | dst.code()); 1223a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 1224a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 1225a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1226a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1227a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1228a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::shl_cl(Register dst) { 1229a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1230a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1231a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD3); 12328c0c40d477db2863e2746e6a995980113f725c0dMario Schuknecht EMIT(0xE0 | dst.code()); 1233a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1234a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1235a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1236a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::shrd(Register dst, const Operand& src) { 1237a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1238a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1239a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x0F); 1240a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xAD); 1241a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 1242a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1243a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1244a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1245a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::shr(Register dst, uint8_t imm8) { 1246a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1247a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1248a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO ASSERT(is_uint5(imm8)); // illegal shift count 1249a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (imm8 == 1) { 1250a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD1); 1251a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE8 | dst.code()); 1252a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } else { 1253a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xC1); 1254a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE8 | dst.code()); 1255a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 12568c0c40d477db2863e2746e6a995980113f725c0dMario Schuknecht } 12578c0c40d477db2863e2746e6a995980113f725c0dMario Schuknecht} 12588c0c40d477db2863e2746e6a995980113f725c0dMario Schuknecht 1259a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 12608c0c40d477db2863e2746e6a995980113f725c0dMario Schuknechtvoid Assembler::shr_cl(Register dst) { 1261a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1262a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1263a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xD3); 1264a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xE8 | dst.code()); 1265a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1266a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1267a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1268a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::subb(const Operand& op, int8_t imm8) { 1269a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1270d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner last_pc_ = pc_; 1271a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (op.is_reg(eax)) { 1272b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball EMIT(0x2c); 1273a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } else { 1274b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball EMIT(0x80); 1275a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(ebp, op); // ebp == 5 1276a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 1277a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 1278a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1279a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1280a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 12814da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardinervoid Assembler::sub(const Operand& dst, const Immediate& x) { 12824da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner EnsureSpace ensure_space(this); 12834da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner last_pc_ = pc_; 12844da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner emit_arith(5, dst, x); 12854da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner} 12864da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner 12874da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner 1288a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::sub(Register dst, const Operand& src) { 12894da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner EnsureSpace ensure_space(this); 12904da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner last_pc_ = pc_; 12914da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner EMIT(0x2B); 12924da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner emit_operand(dst, src); 12934da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner} 12944da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner 12954da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner 12964da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardinervoid Assembler::subb(Register dst, const Operand& src) { 12974da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner ASSERT(dst.code() < 4); 12984da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner EnsureSpace ensure_space(this); 1299a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 13004da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner EMIT(0x2A); 13014da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner emit_operand(dst, src); 13024da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner} 13034da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner 13044da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner 13054da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardinervoid Assembler::sub(const Operand& dst, Register src) { 13064da1c0dc8bb295993d05beebc0a6132af9713322Ben Gardiner EnsureSpace ensure_space(this); 1307a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1308a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x29); 1309a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(src, dst); 1310a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1311a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1312a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1313a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::test(Register reg, const Immediate& imm) { 131482bd9504b12160992309d6508dc5654b3db93c2bBen Gardiner EnsureSpace ensure_space(this); 1315a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1316a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO // Only use test against byte for registers that have a byte 131782bd9504b12160992309d6508dc5654b3db93c2bBen Gardiner // variant: eax, ebx, ecx, and edx. 1318a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (imm.rmode_ == RelocInfo::NONE && is_uint8(imm.x_) && reg.code() < 4) { 1319a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO uint8_t imm8 = imm.x_; 1320a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO if (reg.is(eax)) { 132182bd9504b12160992309d6508dc5654b3db93c2bBen Gardiner EMIT(0xA8); 1322a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 1323a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } else { 1324a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_arith_b(0xF6, 0xC0, reg, imm8); 1325a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 132611f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz } else { 132722f2641fe6155fe9fb8b38a8ebe2093ec3e2ec11Oliver Metz // This is not using emit_arith because test doesn't support 132822f2641fe6155fe9fb8b38a8ebe2093ec3e2ec11Oliver Metz // sign-extension of 8-bit operands. 132922f2641fe6155fe9fb8b38a8ebe2093ec3e2ec11Oliver Metz if (reg.is(eax)) { 1330a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xA9); 133111f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz } else { 1332f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(0xF7); 1333f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(0xC0 | reg.code()); 133411f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz } 1335f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner emit(imm); 1336a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO } 1337d91d3698c6464a83b7c301eb84da109f9f94b54cBen Gardiner} 1338a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner 1339a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1340a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::test(Register reg, const Operand& op) { 1341a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner EnsureSpace ensure_space(this); 1342a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner last_pc_ = pc_; 1343a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner EMIT(0x85); 1344a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner emit_operand(reg, op); 1345a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner} 1346a6cd98de8b158029ca6b9c1e961729dc83a7144cBen Gardiner 1347a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1348a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::test_b(Register reg, const Operand& op) { 1349a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1350a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1351a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x84); 1352a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(reg, op); 1353a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1354a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1355a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1356a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::test(const Operand& op, const Immediate& imm) { 135711f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz EnsureSpace ensure_space(this); 1358f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner last_pc_ = pc_; 1359f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner EMIT(0xF7); 1360a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(eax, op); 136111f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz emit(imm); 136211f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz} 1363f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner 1364f82e27a1b11e6fb52565b61827563316dcbb2cc4Ben Gardiner 136568f490b54b53c715db06e55f9595a672d1c0690eBen Gardinervoid Assembler::test_b(const Operand& op, uint8_t imm8) { 136611f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz EnsureSpace ensure_space(this); 136768f490b54b53c715db06e55f9595a672d1c0690eBen Gardiner last_pc_ = pc_; 136868f490b54b53c715db06e55f9595a672d1c0690eBen Gardiner EMIT(0xF6); 136968f490b54b53c715db06e55f9595a672d1c0690eBen Gardiner emit_operand(eax, op); 1370a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(imm8); 137111f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz} 13724e85023654b356511612547207a4cb643fb3db16Ben Gardiner 137311f2ceabc4ad3f0dd568e0ce68166e4803e0615bOliver Metz 1374a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::xor_(Register dst, int32_t imm32) { 1375a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1376a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1377a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_arith(6, Operand(dst), Immediate(imm32)); 1378a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1379a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1380a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1381a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::xor_(Register dst, const Operand& src) { 1382a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1383a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1384a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x33); 1385a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 1386a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1387a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1388a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1389a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::xor_(const Operand& src, Register dst) { 1390a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1391a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1392a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x31); 1393a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(dst, src); 1394a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1395a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1396a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1397a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::xor_(const Operand& dst, const Immediate& x) { 1398a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1399a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1400a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_arith(6, dst, x); 1401a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1402a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1403a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1404a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::bt(const Operand& dst, Register src) { 1405a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1406a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1407a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x0F); 1408a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xA3); 1409a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(src, dst); 1410a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1411a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1412a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1413a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::bts(const Operand& dst, Register src) { 1414a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1415a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1416a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0x0F); 1417a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xAB); 1418a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO emit_operand(src, dst); 1419a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1420a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1421a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO 1422a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::hlt() { 1423a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1424a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1425a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xF4); 1426a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 142764f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi 142864f63a3d2693e95b45c6ba743570b3374a45043bOleg Matcovschi 1429a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROvoid Assembler::int3() { 1430a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EnsureSpace ensure_space(this); 1431a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO last_pc_ = pc_; 1432a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO EMIT(0xCC); 1433a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO} 1434a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 1435a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM 143621bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardivoid Assembler::nop() { 143721bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EnsureSpace ensure_space(this); 143821bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi last_pc_ = pc_; 143921bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT(0x90); 144021bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi} 144121bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi 144221bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi 144321bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardivoid Assembler::rdtsc() { 144421bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi ASSERT(CpuFeatures::IsEnabled(RDTSC)); 144521bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EnsureSpace ensure_space(this); 144621bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi last_pc_ = pc_; 144721bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT(0x0F); 144821bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT(0x31); 144921bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi} 145021bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi 145121bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi 145221bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardivoid Assembler::ret(int imm16) { 145321bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EnsureSpace ensure_space(this); 145421bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi last_pc_ = pc_; 145521bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi ASSERT(is_uint16(imm16)); 145621bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi if (imm16 == 0) { 145721bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT(0xC3); 145821bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi } else { 145921bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT(0xC2); 146021bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT(imm16 & 0xFF); 146121bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi EMIT((imm16 >> 8) & 0xFF); 146221bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi } 146321bb473fc58366b872efe31e1da7831cad4b92faYaniv Gardi} 1464c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1465c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1466c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// Labels refer to positions in the (to be) generated code. 1467c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// There are bound, linked, and unused labels. 1468c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// 1469c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// Bound labels refer to known positions in the already 1470c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// generated code. pos() is the position the label refers to. 1471c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// 1472c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// Linked labels refer to unknown positions in the code 1473c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// to be generated; pos() is the position of the 32bit 1474c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// Displacement of the last instruction using the label. 1475c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1476c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1477c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::print(Label* L) { 1478c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (L->is_unused()) { 1479c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev PrintF("unused label\n"); 1480c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else if (L->is_bound()) { 1481c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev PrintF("bound label to %d\n", L->pos()); 1482c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else if (L->is_linked()) { 1483c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev Label l = *L; 1484c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev PrintF("unbound label"); 1485c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev while (l.is_linked()) { 1486c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev Displacement disp = disp_at(&l); 1487c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev PrintF("@ %d ", l.pos()); 1488c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev disp.print(); 1489c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev PrintF("\n"); 1490c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev disp.next(&l); 1491c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1492c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1493c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1494c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1495c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1496c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1497c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1498c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::bind_to(Label* L, int pos) { 1499c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1500c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = NULL; 1501c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1502c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev while (L->is_linked()) { 1503c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev Displacement disp = disp_at(L); 1504c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int fixup_pos = L->pos(); 1505c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (disp.type() == Displacement::CODE_RELATIVE) { 1506c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // Relative to Code* heap object pointer. 1507c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1508c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1509c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1510c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1511c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1512c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // Relative address, relative to point after address. 1513c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1514c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev long_at_put(fixup_pos, imm32); 1515c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1516c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev disp.next(L); 1517c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1518c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev L->bind_to(pos); 1519c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1520c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1521c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1522c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::bind(Label* L) { 1523c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1524c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = NULL; 1525c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(!L->is_bound()); // label can only be bound once 1526c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev bind_to(L, pc_offset()); 1527c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1528c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1529c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1530c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::bind(NearLabel* L) { 1531c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(!L->is_bound()); 1532c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = NULL; 1533c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev while (L->unresolved_branches_ > 0) { 1534c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; 1535c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int disp = pc_offset() - branch_pos; 1536c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(is_int8(disp)); 1537c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev set_byte_at(branch_pos - sizeof(int8_t), disp); 1538c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev L->unresolved_branches_--; 1539c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1540c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev L->bind_to(pc_offset()); 1541c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1542c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1543c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::call(Label* L) { 1544c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1545c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1546c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (L->is_bound()) { 1547c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int long_size = 5; 1548c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int offs = L->pos() - pc_offset(); 1549c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(offs <= 0); 1550c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 1110 1000 #32-bit disp. 1551c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE8); 1552c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(offs - long_size); 1553c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1554c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 1110 1000 #32-bit disp. 1555c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE8); 1556c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_disp(L, Displacement::OTHER); 1557c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1558c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1559c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1560c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1561c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::call(byte* entry, RelocInfo::Mode rmode) { 1562c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1563c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1564c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1565c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE8); 1566c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(entry - (pc_ + sizeof(int32_t)), rmode); 1567c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1568c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1569c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1570c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::call(const Operand& adr) { 1571c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1572c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1573c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xFF); 1574c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(edx, adr); 1575c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1576c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1577c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1578c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { 1579c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev WriteRecordedPositions(); 1580c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1581c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1582c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(RelocInfo::IsCodeTarget(rmode)); 1583c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE8); 1584c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(reinterpret_cast<intptr_t>(code.location()), rmode); 1585c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1586c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1587c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1588c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::jmp(Label* L) { 1589c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1590c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1591c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (L->is_bound()) { 1592c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int short_size = 2; 1593c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int long_size = 5; 1594c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int offs = L->pos() - pc_offset(); 1595c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(offs <= 0); 1596c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (is_int8(offs - short_size)) { 1597c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 1110 1011 #8-bit disp. 1598c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xEB); 1599c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT((offs - short_size) & 0xFF); 1600c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1601c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 1110 1001 #32-bit disp. 1602c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE9); 1603c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(offs - long_size); 1604c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1605c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1606c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 1110 1001 #32-bit disp. 1607c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE9); 1608c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1609c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1610c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1611c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1612c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1613c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1614c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1615c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1616c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1617c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE9); 1618c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(entry - (pc_ + sizeof(int32_t)), rmode); 1619c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1620c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1621c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1622c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::jmp(const Operand& adr) { 1623c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1624c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1625c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xFF); 1626c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(esp, adr); 1627c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1628c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1629c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1630c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1631c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1632c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1633c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(RelocInfo::IsCodeTarget(rmode)); 1634c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE9); 1635c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(reinterpret_cast<intptr_t>(code.location()), rmode); 1636c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1637c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1638c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1639c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::jmp(NearLabel* L) { 1640c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1641c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1642c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (L->is_bound()) { 1643c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int short_size = 2; 1644c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int offs = L->pos() - pc_offset(); 1645c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(offs <= 0); 1646c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(is_int8(offs - short_size)); 1647c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 1110 1011 #8-bit disp. 1648c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xEB); 1649c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT((offs - short_size) & 0xFF); 1650c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1651c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xEB); 1652c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x00); // The displacement will be resolved later. 1653c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev L->link_to(pc_offset()); 1654c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1655c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1656c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1657c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1658c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::j(Condition cc, Label* L, Hint hint) { 1659c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1660c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1661c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(0 <= cc && cc < 16); 1662c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1663c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (L->is_bound()) { 1664c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int short_size = 2; 1665c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int long_size = 6; 1666c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int offs = L->pos() - pc_offset(); 1667c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(offs <= 0); 1668c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (is_int8(offs - short_size)) { 1669c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 0111 tttn #8-bit disp 1670c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x70 | cc); 1671c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT((offs - short_size) & 0xFF); 1672c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1673c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 0000 1111 1000 tttn #32-bit disp 1674c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x0F); 1675c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x80 | cc); 1676c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(offs - long_size); 1677c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1678c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1679c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 0000 1111 1000 tttn #32-bit disp 1680c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // Note: could eliminate cond. jumps to this jump if condition 1681c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // is the same however, seems to be rather unlikely case. 1682c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x0F); 1683c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x80 | cc); 1684c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_disp(L, Displacement::OTHER); 1685c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1686c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1687c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1688c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1689c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint) { 1690c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1691c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1692c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT((0 <= cc) && (cc < 16)); 1693c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1694c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 0000 1111 1000 tttn #32-bit disp. 1695c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x0F); 1696c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x80 | cc); 1697c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(entry - (pc_ + sizeof(int32_t)), rmode); 1698c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1699c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1700c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1701c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::j(Condition cc, Handle<Code> code, Hint hint) { 1702c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1703c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1704c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1705c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 0000 1111 1000 tttn #32-bit disp 1706c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x0F); 1707c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x80 | cc); 1708c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit(reinterpret_cast<intptr_t>(code.location()), RelocInfo::CODE_TARGET); 1709c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1710c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1711c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1712c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::j(Condition cc, NearLabel* L, Hint hint) { 1713c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1714c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1715c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(0 <= cc && cc < 16); 1716c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); 1717c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev if (L->is_bound()) { 1718c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev const int short_size = 2; 1719c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev int offs = L->pos() - pc_offset(); 1720c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(offs <= 0); 1721c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(is_int8(offs - short_size)); 1722c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev // 0111 tttn #8-bit disp 1723c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x70 | cc); 1724c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT((offs - short_size) & 0xFF); 1725c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } else { 1726c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x70 | cc); 1727c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0x00); // The displacement will be resolved later. 1728c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev L->link_to(pc_offset()); 1729c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev } 1730c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1731c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1732c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1733c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev// FPU instructions. 1734c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1735c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fld(int i) { 1736c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1737c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1738c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xD9, 0xC0, i); 1739c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1740c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1741c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1742c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fstp(int i) { 1743c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1744c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1745c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDD, 0xD8, i); 1746c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1747c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1748c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1749c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fld1() { 1750c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1751c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1752c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1753c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE8); 1754c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1755c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1756c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1757c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fldpi() { 1758c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1759c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1760c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1761c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xEB); 1762c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1763c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1764c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1765c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fldz() { 1766c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1767c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1768c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1769c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xEE); 1770c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1771c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1772c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1773c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fld_s(const Operand& adr) { 1774c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1775c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1776c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1777c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(eax, adr); 1778c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1779c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1780c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1781c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fld_d(const Operand& adr) { 1782c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1783c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1784c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDD); 1785c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(eax, adr); 1786c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1787c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1788c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1789c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fstp_s(const Operand& adr) { 1790c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1791c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1792c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1793c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(ebx, adr); 1794c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1795c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1796c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1797c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fstp_d(const Operand& adr) { 1798c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1799c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1800c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDD); 1801c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(ebx, adr); 1802c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1803c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1804c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1805c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fst_d(const Operand& adr) { 1806c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1807c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1808c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDD); 1809c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(edx, adr); 1810c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1811c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1812c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1813c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fild_s(const Operand& adr) { 1814c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1815c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1816c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDB); 1817c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(eax, adr); 1818c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1819c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1820c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1821c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fild_d(const Operand& adr) { 1822c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1823c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1824c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDF); 1825c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(ebp, adr); 1826c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1827c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1828c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1829c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fistp_s(const Operand& adr) { 1830c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1831c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1832c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDB); 1833c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(ebx, adr); 1834c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1835c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1836c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1837c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fisttp_s(const Operand& adr) { 1838c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(CpuFeatures::IsEnabled(SSE3)); 1839c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1840c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1841c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDB); 1842c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(ecx, adr); 1843c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1844c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1845c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1846c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fisttp_d(const Operand& adr) { 1847c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev ASSERT(CpuFeatures::IsEnabled(SSE3)); 1848c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1849c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1850c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDD); 1851c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(ecx, adr); 1852c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1853c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1854c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1855c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fist_s(const Operand& adr) { 1856c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1857c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1858c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDB); 1859c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(edx, adr); 1860c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1861c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1862c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1863c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fistp_d(const Operand& adr) { 1864c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1865c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1866c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDF); 1867c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(edi, adr); 1868c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1869c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1870c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1871c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fabs() { 1872c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1873c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1874c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1875c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE1); 1876c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1877c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1878c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1879c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fchs() { 1880c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1881c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1882c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1883c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xE0); 1884c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1885c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1886c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1887c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fcos() { 1888c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1889c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1890c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1891c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xFF); 1892c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1893c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1894c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1895c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fsin() { 1896c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1897c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1898c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xD9); 1899c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xFE); 1900c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1901c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1902c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1903c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fadd(int i) { 1904c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1905c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1906c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDC, 0xC0, i); 1907c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1908c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1909c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1910c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fsub(int i) { 1911c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1912c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1913c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDC, 0xE8, i); 1914c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1915c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1916c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1917c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fisub_s(const Operand& adr) { 1918c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1919c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1920c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EMIT(0xDA); 1921c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_operand(esp, adr); 1922c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1923c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1924c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1925c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fmul(int i) { 1926c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1927c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1928c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDC, 0xC8, i); 1929c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1930c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1931c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1932c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fdiv(int i) { 1933c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1934c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1935c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDC, 0xF8, i); 1936c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1937c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1938c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1939c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::faddp(int i) { 1940c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1941c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1942c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDE, 0xC0, i); 1943c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1944c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1945c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1946c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fsubp(int i) { 1947c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1948c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1949c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDE, 0xE8, i); 1950c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1951c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1952c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1953c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fsubrp(int i) { 1954c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1955c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1956c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDE, 0xE0, i); 1957c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1958c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1959c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1960c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fmulp(int i) { 1961c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1962c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1963c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDE, 0xC8, i); 1964c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1965c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1966c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1967c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaevvoid Assembler::fdivp(int i) { 1968c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev EnsureSpace ensure_space(this); 1969c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev last_pc_ = pc_; 1970c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev emit_farith(0xDE, 0xF8, i); 1971c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev} 1972c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1973c6cb053ec59e7667e2140c320e2b7d5a90592a20Roman Peniaev 1974void Assembler::fprem() { 1975 EnsureSpace ensure_space(this); 1976 last_pc_ = pc_; 1977 EMIT(0xD9); 1978 EMIT(0xF8); 1979} 1980 1981 1982void Assembler::fprem1() { 1983 EnsureSpace ensure_space(this); 1984 last_pc_ = pc_; 1985 EMIT(0xD9); 1986 EMIT(0xF5); 1987} 1988 1989 1990void Assembler::fxch(int i) { 1991 EnsureSpace ensure_space(this); 1992 last_pc_ = pc_; 1993 emit_farith(0xD9, 0xC8, i); 1994} 1995 1996 1997void Assembler::fincstp() { 1998 EnsureSpace ensure_space(this); 1999 last_pc_ = pc_; 2000 EMIT(0xD9); 2001 EMIT(0xF7); 2002} 2003 2004 2005void Assembler::ffree(int i) { 2006 EnsureSpace ensure_space(this); 2007 last_pc_ = pc_; 2008 emit_farith(0xDD, 0xC0, i); 2009} 2010 2011 2012void Assembler::ftst() { 2013 EnsureSpace ensure_space(this); 2014 last_pc_ = pc_; 2015 EMIT(0xD9); 2016 EMIT(0xE4); 2017} 2018 2019 2020void Assembler::fucomp(int i) { 2021 EnsureSpace ensure_space(this); 2022 last_pc_ = pc_; 2023 emit_farith(0xDD, 0xE8, i); 2024} 2025 2026 2027void Assembler::fucompp() { 2028 EnsureSpace ensure_space(this); 2029 last_pc_ = pc_; 2030 EMIT(0xDA); 2031 EMIT(0xE9); 2032} 2033 2034 2035void Assembler::fucomi(int i) { 2036 EnsureSpace ensure_space(this); 2037 last_pc_ = pc_; 2038 EMIT(0xDB); 2039 EMIT(0xE8 + i); 2040} 2041 2042 2043void Assembler::fucomip() { 2044 EnsureSpace ensure_space(this); 2045 last_pc_ = pc_; 2046 EMIT(0xDF); 2047 EMIT(0xE9); 2048} 2049 2050 2051void Assembler::fcompp() { 2052 EnsureSpace ensure_space(this); 2053 last_pc_ = pc_; 2054 EMIT(0xDE); 2055 EMIT(0xD9); 2056} 2057 2058 2059void Assembler::fnstsw_ax() { 2060 EnsureSpace ensure_space(this); 2061 last_pc_ = pc_; 2062 EMIT(0xDF); 2063 EMIT(0xE0); 2064} 2065 2066 2067void Assembler::fwait() { 2068 EnsureSpace ensure_space(this); 2069 last_pc_ = pc_; 2070 EMIT(0x9B); 2071} 2072 2073 2074void Assembler::frndint() { 2075 EnsureSpace ensure_space(this); 2076 last_pc_ = pc_; 2077 EMIT(0xD9); 2078 EMIT(0xFC); 2079} 2080 2081 2082void Assembler::fnclex() { 2083 EnsureSpace ensure_space(this); 2084 last_pc_ = pc_; 2085 EMIT(0xDB); 2086 EMIT(0xE2); 2087} 2088 2089 2090void Assembler::sahf() { 2091 EnsureSpace ensure_space(this); 2092 last_pc_ = pc_; 2093 EMIT(0x9E); 2094} 2095 2096 2097void Assembler::setcc(Condition cc, Register reg) { 2098 ASSERT(reg.is_byte_register()); 2099 EnsureSpace ensure_space(this); 2100 last_pc_ = pc_; 2101 EMIT(0x0F); 2102 EMIT(0x90 | cc); 2103 EMIT(0xC0 | reg.code()); 2104} 2105 2106 2107void Assembler::cvttss2si(Register dst, const Operand& src) { 2108 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2109 EnsureSpace ensure_space(this); 2110 last_pc_ = pc_; 2111 EMIT(0xF3); 2112 EMIT(0x0F); 2113 EMIT(0x2C); 2114 emit_operand(dst, src); 2115} 2116 2117 2118void Assembler::cvttsd2si(Register dst, const Operand& src) { 2119 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2120 EnsureSpace ensure_space(this); 2121 last_pc_ = pc_; 2122 EMIT(0xF2); 2123 EMIT(0x0F); 2124 EMIT(0x2C); 2125 emit_operand(dst, src); 2126} 2127 2128 2129void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) { 2130 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2131 EnsureSpace ensure_space(this); 2132 last_pc_ = pc_; 2133 EMIT(0xF2); 2134 EMIT(0x0F); 2135 EMIT(0x2A); 2136 emit_sse_operand(dst, src); 2137} 2138 2139 2140void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { 2141 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2142 EnsureSpace ensure_space(this); 2143 last_pc_ = pc_; 2144 EMIT(0xF3); 2145 EMIT(0x0F); 2146 EMIT(0x5A); 2147 emit_sse_operand(dst, src); 2148} 2149 2150 2151void Assembler::addsd(XMMRegister dst, XMMRegister src) { 2152 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2153 EnsureSpace ensure_space(this); 2154 last_pc_ = pc_; 2155 EMIT(0xF2); 2156 EMIT(0x0F); 2157 EMIT(0x58); 2158 emit_sse_operand(dst, src); 2159} 2160 2161 2162void Assembler::mulsd(XMMRegister dst, XMMRegister src) { 2163 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2164 EnsureSpace ensure_space(this); 2165 last_pc_ = pc_; 2166 EMIT(0xF2); 2167 EMIT(0x0F); 2168 EMIT(0x59); 2169 emit_sse_operand(dst, src); 2170} 2171 2172 2173void Assembler::subsd(XMMRegister dst, XMMRegister src) { 2174 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2175 EnsureSpace ensure_space(this); 2176 last_pc_ = pc_; 2177 EMIT(0xF2); 2178 EMIT(0x0F); 2179 EMIT(0x5C); 2180 emit_sse_operand(dst, src); 2181} 2182 2183 2184void Assembler::divsd(XMMRegister dst, XMMRegister src) { 2185 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2186 EnsureSpace ensure_space(this); 2187 last_pc_ = pc_; 2188 EMIT(0xF2); 2189 EMIT(0x0F); 2190 EMIT(0x5E); 2191 emit_sse_operand(dst, src); 2192} 2193 2194 2195void Assembler::xorpd(XMMRegister dst, XMMRegister src) { 2196 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2197 EnsureSpace ensure_space(this); 2198 last_pc_ = pc_; 2199 EMIT(0x66); 2200 EMIT(0x0F); 2201 EMIT(0x57); 2202 emit_sse_operand(dst, src); 2203} 2204 2205 2206void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { 2207 EnsureSpace ensure_space(this); 2208 last_pc_ = pc_; 2209 EMIT(0xF2); 2210 EMIT(0x0F); 2211 EMIT(0x51); 2212 emit_sse_operand(dst, src); 2213} 2214 2215 2216void Assembler::andpd(XMMRegister dst, XMMRegister src) { 2217 EnsureSpace ensure_space(this); 2218 last_pc_ = pc_; 2219 EMIT(0x66); 2220 EMIT(0x0F); 2221 EMIT(0x54); 2222 emit_sse_operand(dst, src); 2223} 2224 2225 2226void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { 2227 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2228 EnsureSpace ensure_space(this); 2229 last_pc_ = pc_; 2230 EMIT(0x66); 2231 EMIT(0x0F); 2232 EMIT(0x2E); 2233 emit_sse_operand(dst, src); 2234} 2235 2236 2237void Assembler::movmskpd(Register dst, XMMRegister src) { 2238 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2239 EnsureSpace ensure_space(this); 2240 last_pc_ = pc_; 2241 EMIT(0x66); 2242 EMIT(0x0F); 2243 EMIT(0x50); 2244 emit_sse_operand(dst, src); 2245} 2246 2247 2248void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) { 2249 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2250 EnsureSpace ensure_space(this); 2251 last_pc_ = pc_; 2252 EMIT(0xF2); 2253 EMIT(0x0F); 2254 EMIT(0xC2); 2255 emit_sse_operand(dst, src); 2256 EMIT(1); // LT == 1 2257} 2258 2259 2260void Assembler::movaps(XMMRegister dst, XMMRegister src) { 2261 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2262 EnsureSpace ensure_space(this); 2263 last_pc_ = pc_; 2264 EMIT(0x0F); 2265 EMIT(0x28); 2266 emit_sse_operand(dst, src); 2267} 2268 2269 2270void Assembler::movdqa(const Operand& dst, XMMRegister src) { 2271 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2272 EnsureSpace ensure_space(this); 2273 last_pc_ = pc_; 2274 EMIT(0x66); 2275 EMIT(0x0F); 2276 EMIT(0x7F); 2277 emit_sse_operand(src, dst); 2278} 2279 2280 2281void Assembler::movdqa(XMMRegister dst, const Operand& src) { 2282 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2283 EnsureSpace ensure_space(this); 2284 last_pc_ = pc_; 2285 EMIT(0x66); 2286 EMIT(0x0F); 2287 EMIT(0x6F); 2288 emit_sse_operand(dst, src); 2289} 2290 2291 2292void Assembler::movdqu(const Operand& dst, XMMRegister src ) { 2293 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2294 EnsureSpace ensure_space(this); 2295 last_pc_ = pc_; 2296 EMIT(0xF3); 2297 EMIT(0x0F); 2298 EMIT(0x7F); 2299 emit_sse_operand(src, dst); 2300} 2301 2302 2303void Assembler::movdqu(XMMRegister dst, const Operand& src) { 2304 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2305 EnsureSpace ensure_space(this); 2306 last_pc_ = pc_; 2307 EMIT(0xF3); 2308 EMIT(0x0F); 2309 EMIT(0x6F); 2310 emit_sse_operand(dst, src); 2311} 2312 2313 2314void Assembler::movntdqa(XMMRegister dst, const Operand& src) { 2315 ASSERT(CpuFeatures::IsEnabled(SSE4_1)); 2316 EnsureSpace ensure_space(this); 2317 last_pc_ = pc_; 2318 EMIT(0x66); 2319 EMIT(0x0F); 2320 EMIT(0x38); 2321 EMIT(0x2A); 2322 emit_sse_operand(dst, src); 2323} 2324 2325 2326void Assembler::movntdq(const Operand& dst, XMMRegister src) { 2327 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2328 EnsureSpace ensure_space(this); 2329 last_pc_ = pc_; 2330 EMIT(0x66); 2331 EMIT(0x0F); 2332 EMIT(0xE7); 2333 emit_sse_operand(src, dst); 2334} 2335 2336 2337void Assembler::prefetch(const Operand& src, int level) { 2338 ASSERT(is_uint2(level)); 2339 EnsureSpace ensure_space(this); 2340 last_pc_ = pc_; 2341 EMIT(0x0F); 2342 EMIT(0x18); 2343 XMMRegister code = { level }; // Emit hint number in Reg position of RegR/M. 2344 emit_sse_operand(code, src); 2345} 2346 2347 2348void Assembler::movdbl(XMMRegister dst, const Operand& src) { 2349 EnsureSpace ensure_space(this); 2350 last_pc_ = pc_; 2351 movsd(dst, src); 2352} 2353 2354 2355void Assembler::movdbl(const Operand& dst, XMMRegister src) { 2356 EnsureSpace ensure_space(this); 2357 last_pc_ = pc_; 2358 movsd(dst, src); 2359} 2360 2361 2362void Assembler::movsd(const Operand& dst, XMMRegister src ) { 2363 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2364 EnsureSpace ensure_space(this); 2365 last_pc_ = pc_; 2366 EMIT(0xF2); // double 2367 EMIT(0x0F); 2368 EMIT(0x11); // store 2369 emit_sse_operand(src, dst); 2370} 2371 2372 2373void Assembler::movsd(XMMRegister dst, const Operand& src) { 2374 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2375 EnsureSpace ensure_space(this); 2376 last_pc_ = pc_; 2377 EMIT(0xF2); // double 2378 EMIT(0x0F); 2379 EMIT(0x10); // load 2380 emit_sse_operand(dst, src); 2381} 2382 2383void Assembler::movsd(XMMRegister dst, XMMRegister src) { 2384 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2385 EnsureSpace ensure_space(this); 2386 last_pc_ = pc_; 2387 EMIT(0xF2); 2388 EMIT(0x0F); 2389 EMIT(0x10); 2390 emit_sse_operand(dst, src); 2391} 2392 2393 2394void Assembler::movd(XMMRegister dst, const Operand& src) { 2395 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2396 EnsureSpace ensure_space(this); 2397 last_pc_ = pc_; 2398 EMIT(0x66); 2399 EMIT(0x0F); 2400 EMIT(0x6E); 2401 emit_sse_operand(dst, src); 2402} 2403 2404 2405void Assembler::pxor(XMMRegister dst, XMMRegister src) { 2406 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2407 EnsureSpace ensure_space(this); 2408 last_pc_ = pc_; 2409 EMIT(0x66); 2410 EMIT(0x0F); 2411 EMIT(0xEF); 2412 emit_sse_operand(dst, src); 2413} 2414 2415 2416void Assembler::ptest(XMMRegister dst, XMMRegister src) { 2417 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2418 EnsureSpace ensure_space(this); 2419 last_pc_ = pc_; 2420 EMIT(0x66); 2421 EMIT(0x0F); 2422 EMIT(0x38); 2423 EMIT(0x17); 2424 emit_sse_operand(dst, src); 2425} 2426 2427 2428void Assembler::psllq(XMMRegister reg, int8_t imm8) { 2429 ASSERT(CpuFeatures::IsEnabled(SSE2)); 2430 EnsureSpace ensure_space(this); 2431 last_pc_ = pc_; 2432 EMIT(0x66); 2433 EMIT(0x0F); 2434 EMIT(0x73); 2435 emit_sse_operand(esi, reg); // esi == 6 2436 EMIT(imm8); 2437} 2438 2439 2440void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2441 Register ireg = { reg.code() }; 2442 emit_operand(ireg, adr); 2443} 2444 2445 2446void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2447 EMIT(0xC0 | dst.code() << 3 | src.code()); 2448} 2449 2450 2451void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 2452 EMIT(0xC0 | dst.code() << 3 | src.code()); 2453} 2454 2455 2456void Assembler::Print() { 2457 Disassembler::Decode(stdout, buffer_, pc_); 2458} 2459 2460 2461void Assembler::RecordJSReturn() { 2462 WriteRecordedPositions(); 2463 EnsureSpace ensure_space(this); 2464 RecordRelocInfo(RelocInfo::JS_RETURN); 2465} 2466 2467 2468void Assembler::RecordDebugBreakSlot() { 2469 WriteRecordedPositions(); 2470 EnsureSpace ensure_space(this); 2471 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 2472} 2473 2474 2475void Assembler::RecordComment(const char* msg) { 2476 if (FLAG_debug_code) { 2477 EnsureSpace ensure_space(this); 2478 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 2479 } 2480} 2481 2482 2483void Assembler::RecordPosition(int pos) { 2484 ASSERT(pos != RelocInfo::kNoPosition); 2485 ASSERT(pos >= 0); 2486 current_position_ = pos; 2487} 2488 2489 2490void Assembler::RecordStatementPosition(int pos) { 2491 ASSERT(pos != RelocInfo::kNoPosition); 2492 ASSERT(pos >= 0); 2493 current_statement_position_ = pos; 2494} 2495 2496 2497bool Assembler::WriteRecordedPositions() { 2498 bool written = false; 2499 2500 // Write the statement position if it is different from what was written last 2501 // time. 2502 if (current_statement_position_ != written_statement_position_) { 2503 EnsureSpace ensure_space(this); 2504 RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_); 2505 written_statement_position_ = current_statement_position_; 2506 written = true; 2507 } 2508 2509 // Write the position if it is different from what was written last time and 2510 // also different from the written statement position. 2511 if (current_position_ != written_position_ && 2512 current_position_ != written_statement_position_) { 2513 EnsureSpace ensure_space(this); 2514 RecordRelocInfo(RelocInfo::POSITION, current_position_); 2515 written_position_ = current_position_; 2516 written = true; 2517 } 2518 2519 // Return whether something was written. 2520 return written; 2521} 2522 2523 2524void Assembler::GrowBuffer() { 2525 ASSERT(overflow()); 2526 if (!own_buffer_) FATAL("external code buffer is too small"); 2527 2528 // Compute new buffer size. 2529 CodeDesc desc; // the new buffer 2530 if (buffer_size_ < 4*KB) { 2531 desc.buffer_size = 4*KB; 2532 } else { 2533 desc.buffer_size = 2*buffer_size_; 2534 } 2535 // Some internal data structures overflow for very large buffers, 2536 // they must ensure that kMaximalBufferSize is not too large. 2537 if ((desc.buffer_size > kMaximalBufferSize) || 2538 (desc.buffer_size > Heap::MaxOldGenerationSize())) { 2539 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 2540 } 2541 2542 // Setup new buffer. 2543 desc.buffer = NewArray<byte>(desc.buffer_size); 2544 desc.instr_size = pc_offset(); 2545 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 2546 2547 // Clear the buffer in debug mode. Use 'int3' instructions to make 2548 // sure to get into problems if we ever run uninitialized code. 2549#ifdef DEBUG 2550 memset(desc.buffer, 0xCC, desc.buffer_size); 2551#endif 2552 2553 // Copy the data. 2554 int pc_delta = desc.buffer - buffer_; 2555 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2556 memmove(desc.buffer, buffer_, desc.instr_size); 2557 memmove(rc_delta + reloc_info_writer.pos(), 2558 reloc_info_writer.pos(), desc.reloc_size); 2559 2560 // Switch buffers. 2561 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 2562 spare_buffer_ = buffer_; 2563 } else { 2564 DeleteArray(buffer_); 2565 } 2566 buffer_ = desc.buffer; 2567 buffer_size_ = desc.buffer_size; 2568 pc_ += pc_delta; 2569 if (last_pc_ != NULL) { 2570 last_pc_ += pc_delta; 2571 } 2572 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2573 reloc_info_writer.last_pc() + pc_delta); 2574 2575 // Relocate runtime entries. 2576 for (RelocIterator it(desc); !it.done(); it.next()) { 2577 RelocInfo::Mode rmode = it.rinfo()->rmode(); 2578 if (rmode == RelocInfo::RUNTIME_ENTRY) { 2579 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2580 *p -= pc_delta; // relocate entry 2581 } else if (rmode == RelocInfo::INTERNAL_REFERENCE) { 2582 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2583 if (*p != 0) { // 0 means uninitialized. 2584 *p += pc_delta; 2585 } 2586 } 2587 } 2588 2589 ASSERT(!overflow()); 2590} 2591 2592 2593void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 2594 ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode 2595 ASSERT(is_uint8(imm8)); 2596 ASSERT((op1 & 0x01) == 0); // should be 8bit operation 2597 EMIT(op1); 2598 EMIT(op2 | dst.code()); 2599 EMIT(imm8); 2600} 2601 2602 2603void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 2604 ASSERT((0 <= sel) && (sel <= 7)); 2605 Register ireg = { sel }; 2606 if (x.is_int8()) { 2607 EMIT(0x83); // using a sign-extended 8-bit immediate. 2608 emit_operand(ireg, dst); 2609 EMIT(x.x_ & 0xFF); 2610 } else if (dst.is_reg(eax)) { 2611 EMIT((sel << 3) | 0x05); // short form if the destination is eax. 2612 emit(x); 2613 } else { 2614 EMIT(0x81); // using a literal 32-bit immediate. 2615 emit_operand(ireg, dst); 2616 emit(x); 2617 } 2618} 2619 2620 2621void Assembler::emit_operand(Register reg, const Operand& adr) { 2622 const unsigned length = adr.len_; 2623 ASSERT(length > 0); 2624 2625 // Emit updated ModRM byte containing the given register. 2626 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3); 2627 2628 // Emit the rest of the encoded operand. 2629 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 2630 pc_ += length; 2631 2632 // Emit relocation information if necessary. 2633 if (length >= sizeof(int32_t) && adr.rmode_ != RelocInfo::NONE) { 2634 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 2635 RecordRelocInfo(adr.rmode_); 2636 pc_ += sizeof(int32_t); 2637 } 2638} 2639 2640 2641void Assembler::emit_farith(int b1, int b2, int i) { 2642 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode 2643 ASSERT(0 <= i && i < 8); // illegal stack offset 2644 EMIT(b1); 2645 EMIT(b2 + i); 2646} 2647 2648 2649void Assembler::dd(uint32_t data, RelocInfo::Mode reloc_info) { 2650 EnsureSpace ensure_space(this); 2651 emit(data, reloc_info); 2652} 2653 2654 2655void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2656 ASSERT(rmode != RelocInfo::NONE); 2657 // Don't record external references unless the heap will be serialized. 2658 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 2659#ifdef DEBUG 2660 if (!Serializer::enabled()) { 2661 Serializer::TooLateToEnableNow(); 2662 } 2663#endif 2664 if (!Serializer::enabled() && !FLAG_debug_code) { 2665 return; 2666 } 2667 } 2668 RelocInfo rinfo(pc_, rmode, data); 2669 reloc_info_writer.Write(&rinfo); 2670} 2671 2672 2673#ifdef GENERATED_CODE_COVERAGE 2674static FILE* coverage_log = NULL; 2675 2676 2677static void InitCoverageLog() { 2678 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 2679 if (file_name != NULL) { 2680 coverage_log = fopen(file_name, "aw+"); 2681 } 2682} 2683 2684 2685void LogGeneratedCodeCoverage(const char* file_line) { 2686 const char* return_address = (&file_line)[-1]; 2687 char* push_insn = const_cast<char*>(return_address - 12); 2688 push_insn[0] = 0xeb; // Relative branch insn. 2689 push_insn[1] = 13; // Skip over coverage insns. 2690 if (coverage_log != NULL) { 2691 fprintf(coverage_log, "%s\n", file_line); 2692 fflush(coverage_log); 2693 } 2694} 2695 2696#endif 2697 2698} } // namespace v8::internal 2699 2700#endif // V8_TARGET_ARCH_IA32 2701