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