1// Copyright (c) 1994-2006 Sun Microsystems Inc.
2// All Rights Reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// - Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// - Redistribution in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// - Neither the name of Sun Microsystems or the names of contributors may
16// be used to endorse or promote products derived from this software without
17// specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// The original source code covered by the above license above has been
32// modified significantly by Google Inc.
33// Copyright 2011 the V8 project authors. All rights reserved.
34
35// A light-weight IA32 Assembler.
36
37#ifndef V8_X87_ASSEMBLER_X87_H_
38#define V8_X87_ASSEMBLER_X87_H_
39
40#include <deque>
41
42#include "src/assembler.h"
43#include "src/isolate.h"
44#include "src/utils.h"
45
46namespace v8 {
47namespace internal {
48
49#define GENERAL_REGISTERS(V) \
50  V(eax)                     \
51  V(ecx)                     \
52  V(edx)                     \
53  V(ebx)                     \
54  V(esp)                     \
55  V(ebp)                     \
56  V(esi)                     \
57  V(edi)
58
59#define ALLOCATABLE_GENERAL_REGISTERS(V) \
60  V(eax)                                 \
61  V(ecx)                                 \
62  V(edx)                                 \
63  V(ebx)                                 \
64  V(esi)                                 \
65  V(edi)
66
67#define DOUBLE_REGISTERS(V) \
68  V(stX_0)                  \
69  V(stX_1)                  \
70  V(stX_2)                  \
71  V(stX_3)                  \
72  V(stX_4)                  \
73  V(stX_5)                  \
74  V(stX_6)                  \
75  V(stX_7)
76
77#define FLOAT_REGISTERS DOUBLE_REGISTERS
78#define SIMD128_REGISTERS DOUBLE_REGISTERS
79
80#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
81  V(stX_0)                              \
82  V(stX_1)                              \
83  V(stX_2)                              \
84  V(stX_3)                              \
85  V(stX_4)                              \
86  V(stX_5)
87
88// CPU Registers.
89//
90// 1) We would prefer to use an enum, but enum values are assignment-
91// compatible with int, which has caused code-generation bugs.
92//
93// 2) We would prefer to use a class instead of a struct but we don't like
94// the register initialization to depend on the particular initialization
95// order (which appears to be different on OS X, Linux, and Windows for the
96// installed versions of C++ we tried). Using a struct permits C-style
97// "initialization". Also, the Register objects cannot be const as this
98// forces initialization stubs in MSVC, making us dependent on initialization
99// order.
100//
101// 3) By not using an enum, we are possibly preventing the compiler from
102// doing certain constant folds, which may significantly reduce the
103// code generated for some assembly instructions (because they boil down
104// to a few constants). If this is a problem, we could change the code
105// such that we use an enum in optimized mode, and the struct in debug
106// mode. This way we get the compile-time error checking in debug mode
107// and best performance in optimized code.
108//
109struct Register {
110  enum Code {
111#define REGISTER_CODE(R) kCode_##R,
112    GENERAL_REGISTERS(REGISTER_CODE)
113#undef REGISTER_CODE
114        kAfterLast,
115    kCode_no_reg = -1
116  };
117
118  static const int kNumRegisters = Code::kAfterLast;
119
120  static Register from_code(int code) {
121    DCHECK(code >= 0);
122    DCHECK(code < kNumRegisters);
123    Register r = {code};
124    return r;
125  }
126  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
127  bool is(Register reg) const { return reg_code == reg.reg_code; }
128  int code() const {
129    DCHECK(is_valid());
130    return reg_code;
131  }
132  int bit() const {
133    DCHECK(is_valid());
134    return 1 << reg_code;
135  }
136
137  bool is_byte_register() const { return reg_code <= 3; }
138
139  // Unfortunately we can't make this private in a struct.
140  int reg_code;
141};
142
143
144#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
145GENERAL_REGISTERS(DECLARE_REGISTER)
146#undef DECLARE_REGISTER
147const Register no_reg = {Register::kCode_no_reg};
148
149static const bool kSimpleFPAliasing = true;
150static const bool kSimdMaskRegisters = false;
151
152struct X87Register {
153  enum Code {
154#define REGISTER_CODE(R) kCode_##R,
155    DOUBLE_REGISTERS(REGISTER_CODE)
156#undef REGISTER_CODE
157        kAfterLast,
158    kCode_no_reg = -1
159  };
160
161  static const int kMaxNumRegisters = Code::kAfterLast;
162  static const int kMaxNumAllocatableRegisters = 6;
163
164  static X87Register from_code(int code) {
165    X87Register result = {code};
166    return result;
167  }
168
169  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
170
171  int code() const {
172    DCHECK(is_valid());
173    return reg_code;
174  }
175
176  bool is(X87Register reg) const { return reg_code == reg.reg_code; }
177
178  int reg_code;
179};
180
181typedef X87Register FloatRegister;
182
183typedef X87Register DoubleRegister;
184
185// TODO(x87) Define SIMD registers.
186typedef X87Register Simd128Register;
187
188#define DECLARE_REGISTER(R) \
189  const DoubleRegister R = {DoubleRegister::kCode_##R};
190DOUBLE_REGISTERS(DECLARE_REGISTER)
191#undef DECLARE_REGISTER
192const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
193
194enum Condition {
195  // any value < 0 is considered no_condition
196  no_condition  = -1,
197
198  overflow      =  0,
199  no_overflow   =  1,
200  below         =  2,
201  above_equal   =  3,
202  equal         =  4,
203  not_equal     =  5,
204  below_equal   =  6,
205  above         =  7,
206  negative      =  8,
207  positive      =  9,
208  parity_even   = 10,
209  parity_odd    = 11,
210  less          = 12,
211  greater_equal = 13,
212  less_equal    = 14,
213  greater       = 15,
214
215  // aliases
216  carry         = below,
217  not_carry     = above_equal,
218  zero          = equal,
219  not_zero      = not_equal,
220  sign          = negative,
221  not_sign      = positive
222};
223
224
225// Returns the equivalent of !cc.
226// Negation of the default no_condition (-1) results in a non-default
227// no_condition value (-2). As long as tests for no_condition check
228// for condition < 0, this will work as expected.
229inline Condition NegateCondition(Condition cc) {
230  return static_cast<Condition>(cc ^ 1);
231}
232
233
234// Commute a condition such that {a cond b == b cond' a}.
235inline Condition CommuteCondition(Condition cc) {
236  switch (cc) {
237    case below:
238      return above;
239    case above:
240      return below;
241    case above_equal:
242      return below_equal;
243    case below_equal:
244      return above_equal;
245    case less:
246      return greater;
247    case greater:
248      return less;
249    case greater_equal:
250      return less_equal;
251    case less_equal:
252      return greater_equal;
253    default:
254      return cc;
255  }
256}
257
258
259enum RoundingMode {
260  kRoundToNearest = 0x0,
261  kRoundDown = 0x1,
262  kRoundUp = 0x2,
263  kRoundToZero = 0x3
264};
265
266
267// -----------------------------------------------------------------------------
268// Machine instruction Immediates
269
270class Immediate BASE_EMBEDDED {
271 public:
272  inline explicit Immediate(int x);
273  inline explicit Immediate(const ExternalReference& ext);
274  inline explicit Immediate(Handle<Object> handle);
275  inline explicit Immediate(Smi* value);
276  inline explicit Immediate(Address addr);
277  inline explicit Immediate(Address x, RelocInfo::Mode rmode);
278
279  static Immediate CodeRelativeOffset(Label* label) {
280    return Immediate(label);
281  }
282
283  bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
284  bool is_int8() const {
285    return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
286  }
287  bool is_uint8() const {
288    return v8::internal::is_uint8(x_) && RelocInfo::IsNone(rmode_);
289  }
290  bool is_int16() const {
291    return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
292  }
293  bool is_uint16() const {
294    return v8::internal::is_uint16(x_) && RelocInfo::IsNone(rmode_);
295  }
296
297 private:
298  inline explicit Immediate(Label* value);
299
300  int x_;
301  RelocInfo::Mode rmode_;
302
303  friend class Operand;
304  friend class Assembler;
305  friend class MacroAssembler;
306};
307
308
309// -----------------------------------------------------------------------------
310// Machine instruction Operands
311
312enum ScaleFactor {
313  times_1 = 0,
314  times_2 = 1,
315  times_4 = 2,
316  times_8 = 3,
317  times_int_size = times_4,
318  times_half_pointer_size = times_2,
319  times_pointer_size = times_4,
320  times_twice_pointer_size = times_8
321};
322
323
324class Operand BASE_EMBEDDED {
325 public:
326  // reg
327  INLINE(explicit Operand(Register reg));
328
329  // [disp/r]
330  INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode));
331
332  // [disp/r]
333  INLINE(explicit Operand(Immediate imm));
334
335  // [base + disp/r]
336  explicit Operand(Register base, int32_t disp,
337                   RelocInfo::Mode rmode = RelocInfo::NONE32);
338
339  // [base + index*scale + disp/r]
340  explicit Operand(Register base,
341                   Register index,
342                   ScaleFactor scale,
343                   int32_t disp,
344                   RelocInfo::Mode rmode = RelocInfo::NONE32);
345
346  // [index*scale + disp/r]
347  explicit Operand(Register index,
348                   ScaleFactor scale,
349                   int32_t disp,
350                   RelocInfo::Mode rmode = RelocInfo::NONE32);
351
352  static Operand JumpTable(Register index, ScaleFactor scale, Label* table) {
353    return Operand(index, scale, reinterpret_cast<int32_t>(table),
354                   RelocInfo::INTERNAL_REFERENCE);
355  }
356
357  static Operand StaticVariable(const ExternalReference& ext) {
358    return Operand(reinterpret_cast<int32_t>(ext.address()),
359                   RelocInfo::EXTERNAL_REFERENCE);
360  }
361
362  static Operand StaticArray(Register index,
363                             ScaleFactor scale,
364                             const ExternalReference& arr) {
365    return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
366                   RelocInfo::EXTERNAL_REFERENCE);
367  }
368
369  static Operand ForCell(Handle<Cell> cell) {
370    AllowDeferredHandleDereference embedding_raw_address;
371    return Operand(reinterpret_cast<int32_t>(cell.location()),
372                   RelocInfo::CELL);
373  }
374
375  static Operand ForRegisterPlusImmediate(Register base, Immediate imm) {
376    return Operand(base, imm.x_, imm.rmode_);
377  }
378
379  // Returns true if this Operand is a wrapper for the specified register.
380  bool is_reg(Register reg) const;
381
382  // Returns true if this Operand is a wrapper for one register.
383  bool is_reg_only() const;
384
385  // Asserts that this Operand is a wrapper for one register and returns the
386  // register.
387  Register reg() const;
388
389 private:
390  // Set the ModRM byte without an encoded 'reg' register. The
391  // register is encoded later as part of the emit_operand operation.
392  inline void set_modrm(int mod, Register rm);
393
394  inline void set_sib(ScaleFactor scale, Register index, Register base);
395  inline void set_disp8(int8_t disp);
396  inline void set_dispr(int32_t disp, RelocInfo::Mode rmode);
397
398  byte buf_[6];
399  // The number of bytes in buf_.
400  unsigned int len_;
401  // Only valid if len_ > 4.
402  RelocInfo::Mode rmode_;
403
404  friend class Assembler;
405  friend class MacroAssembler;
406};
407
408
409// -----------------------------------------------------------------------------
410// A Displacement describes the 32bit immediate field of an instruction which
411// may be used together with a Label in order to refer to a yet unknown code
412// position. Displacements stored in the instruction stream are used to describe
413// the instruction and to chain a list of instructions using the same Label.
414// A Displacement contains 2 different fields:
415//
416// next field: position of next displacement in the chain (0 = end of list)
417// type field: instruction type
418//
419// A next value of null (0) indicates the end of a chain (note that there can
420// be no displacement at position zero, because there is always at least one
421// instruction byte before the displacement).
422//
423// Displacement _data field layout
424//
425// |31.....2|1......0|
426// [  next  |  type  |
427
428class Displacement BASE_EMBEDDED {
429 public:
430  enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE };
431
432  int data() const { return data_; }
433  Type type() const { return TypeField::decode(data_); }
434  void next(Label* L) const {
435    int n = NextField::decode(data_);
436    n > 0 ? L->link_to(n) : L->Unuse();
437  }
438  void link_to(Label* L) { init(L, type()); }
439
440  explicit Displacement(int data) { data_ = data; }
441
442  Displacement(Label* L, Type type) { init(L, type); }
443
444  void print() {
445    PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
446                       NextField::decode(data_));
447  }
448
449 private:
450  int data_;
451
452  class TypeField: public BitField<Type, 0, 2> {};
453  class NextField: public BitField<int,  2, 32-2> {};
454
455  void init(Label* L, Type type);
456};
457
458
459class Assembler : public AssemblerBase {
460 private:
461  // We check before assembling an instruction that there is sufficient
462  // space to write an instruction and its relocation information.
463  // The relocation writer's position must be kGap bytes above the end of
464  // the generated instructions. This leaves enough space for the
465  // longest possible ia32 instruction, 15 bytes, and the longest possible
466  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
467  // (There is a 15 byte limit on ia32 instruction length that rules out some
468  // otherwise valid instructions.)
469  // This allows for a single, fast space check per instruction.
470  static const int kGap = 32;
471
472 public:
473  // Create an assembler. Instructions and relocation information are emitted
474  // into a buffer, with the instructions starting from the beginning and the
475  // relocation information starting from the end of the buffer. See CodeDesc
476  // for a detailed comment on the layout (globals.h).
477  //
478  // If the provided buffer is NULL, the assembler allocates and grows its own
479  // buffer, and buffer_size determines the initial buffer size. The buffer is
480  // owned by the assembler and deallocated upon destruction of the assembler.
481  //
482  // If the provided buffer is not NULL, the assembler uses the provided buffer
483  // for code generation and assumes its size to be buffer_size. If the buffer
484  // is too small, a fatal error occurs. No deallocation of the buffer is done
485  // upon destruction of the assembler.
486  // TODO(vitalyr): the assembler does not need an isolate.
487  Assembler(Isolate* isolate, void* buffer, int buffer_size);
488  virtual ~Assembler() { }
489
490  // GetCode emits any pending (non-emitted) code and fills the descriptor
491  // desc. GetCode() is idempotent; it returns the same result if no other
492  // Assembler functions are invoked in between GetCode() calls.
493  void GetCode(CodeDesc* desc);
494
495  // Read/Modify the code target in the branch/call instruction at pc.
496  inline static Address target_address_at(Address pc, Address constant_pool);
497  inline static void set_target_address_at(
498      Isolate* isolate, Address pc, Address constant_pool, Address target,
499      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
500  static inline Address target_address_at(Address pc, Code* code);
501  static inline void set_target_address_at(
502      Isolate* isolate, Address pc, Code* code, Address target,
503      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
504
505  // Return the code target address at a call site from the return address
506  // of that call in the instruction stream.
507  inline static Address target_address_from_return_address(Address pc);
508
509  // This sets the branch destination (which is in the instruction on x86).
510  // This is for calls and branches within generated code.
511  inline static void deserialization_set_special_target_at(
512      Isolate* isolate, Address instruction_payload, Code* code,
513      Address target) {
514    set_target_address_at(isolate, instruction_payload, code, target);
515  }
516
517  // This sets the internal reference at the pc.
518  inline static void deserialization_set_target_internal_reference_at(
519      Isolate* isolate, Address pc, Address target,
520      RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
521
522  static const int kSpecialTargetSize = kPointerSize;
523
524  // Distance between the address of the code target in the call instruction
525  // and the return address
526  static const int kCallTargetAddressOffset = kPointerSize;
527
528  static const int kCallInstructionLength = 5;
529
530  // The debug break slot must be able to contain a call instruction.
531  static const int kDebugBreakSlotLength = kCallInstructionLength;
532
533  // Distance between start of patched debug break slot and the emitted address
534  // to jump to.
535  static const int kPatchDebugBreakSlotAddressOffset = 1;  // JMP imm32.
536
537  // One byte opcode for test al, 0xXX.
538  static const byte kTestAlByte = 0xA8;
539  // One byte opcode for nop.
540  static const byte kNopByte = 0x90;
541
542  // One byte opcode for a short unconditional jump.
543  static const byte kJmpShortOpcode = 0xEB;
544  // One byte prefix for a short conditional jump.
545  static const byte kJccShortPrefix = 0x70;
546  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
547  static const byte kJcShortOpcode = kJccShortPrefix | carry;
548  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
549  static const byte kJzShortOpcode = kJccShortPrefix | zero;
550
551
552  // ---------------------------------------------------------------------------
553  // Code generation
554  //
555  // - function names correspond one-to-one to ia32 instruction mnemonics
556  // - unless specified otherwise, instructions operate on 32bit operands
557  // - instructions on 8bit (byte) operands/registers have a trailing '_b'
558  // - instructions on 16bit (word) operands/registers have a trailing '_w'
559  // - naming conflicts with C++ keywords are resolved via a trailing '_'
560
561  // NOTE ON INTERFACE: Currently, the interface is not very consistent
562  // in the sense that some operations (e.g. mov()) can be called in more
563  // the one way to generate the same instruction: The Register argument
564  // can in some cases be replaced with an Operand(Register) argument.
565  // This should be cleaned up and made more orthogonal. The questions
566  // is: should we always use Operands instead of Registers where an
567  // Operand is possible, or should we have a Register (overloaded) form
568  // instead? We must be careful to make sure that the selected instruction
569  // is obvious from the parameters to avoid hard-to-find code generation
570  // bugs.
571
572  // Insert the smallest number of nop instructions
573  // possible to align the pc offset to a multiple
574  // of m. m must be a power of 2.
575  void Align(int m);
576  // Insert the smallest number of zero bytes possible to align the pc offset
577  // to a mulitple of m. m must be a power of 2 (>= 2).
578  void DataAlign(int m);
579  void Nop(int bytes = 1);
580  // Aligns code to something that's optimal for a jump target for the platform.
581  void CodeTargetAlign();
582
583  // Stack
584  void pushad();
585  void popad();
586
587  void pushfd();
588  void popfd();
589
590  void push(const Immediate& x);
591  void push_imm32(int32_t imm32);
592  void push(Register src);
593  void push(const Operand& src);
594
595  void pop(Register dst);
596  void pop(const Operand& dst);
597
598  void enter(const Immediate& size);
599  void leave();
600
601  // Moves
602  void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
603  void mov_b(Register dst, const Operand& src);
604  void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
605  void mov_b(const Operand& dst, int8_t imm8);
606  void mov_b(const Operand& dst, const Immediate& src);
607  void mov_b(const Operand& dst, Register src);
608
609  void mov_w(Register dst, const Operand& src);
610  void mov_w(const Operand& dst, Register src);
611  void mov_w(const Operand& dst, int16_t imm16);
612  void mov_w(const Operand& dst, const Immediate& src);
613
614
615  void mov(Register dst, int32_t imm32);
616  void mov(Register dst, const Immediate& x);
617  void mov(Register dst, Handle<Object> handle);
618  void mov(Register dst, const Operand& src);
619  void mov(Register dst, Register src);
620  void mov(const Operand& dst, const Immediate& x);
621  void mov(const Operand& dst, Handle<Object> handle);
622  void mov(const Operand& dst, Register src);
623
624  void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
625  void movsx_b(Register dst, const Operand& src);
626
627  void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
628  void movsx_w(Register dst, const Operand& src);
629
630  void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
631  void movzx_b(Register dst, const Operand& src);
632
633  void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
634  void movzx_w(Register dst, const Operand& src);
635
636  // Flag management.
637  void cld();
638
639  // Repetitive string instructions.
640  void rep_movs();
641  void rep_stos();
642  void stos();
643
644  // Exchange
645  void xchg(Register dst, Register src);
646  void xchg(Register dst, const Operand& src);
647  void xchg_b(Register reg, const Operand& op);
648  void xchg_w(Register reg, const Operand& op);
649
650  // Lock prefix
651  void lock();
652
653  // CompareExchange
654  void cmpxchg(const Operand& dst, Register src);
655  void cmpxchg_b(const Operand& dst, Register src);
656  void cmpxchg_w(const Operand& dst, Register src);
657
658  // Arithmetics
659  void adc(Register dst, int32_t imm32);
660  void adc(Register dst, const Operand& src);
661
662  void add(Register dst, Register src) { add(dst, Operand(src)); }
663  void add(Register dst, const Operand& src);
664  void add(const Operand& dst, Register src);
665  void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
666  void add(const Operand& dst, const Immediate& x);
667
668  void and_(Register dst, int32_t imm32);
669  void and_(Register dst, const Immediate& x);
670  void and_(Register dst, Register src) { and_(dst, Operand(src)); }
671  void and_(Register dst, const Operand& src);
672  void and_(const Operand& dst, Register src);
673  void and_(const Operand& dst, const Immediate& x);
674
675  void cmpb(Register reg, Immediate imm8) { cmpb(Operand(reg), imm8); }
676  void cmpb(const Operand& op, Immediate imm8);
677  void cmpb(Register reg, const Operand& op);
678  void cmpb(const Operand& op, Register reg);
679  void cmpb(Register dst, Register src) { cmpb(Operand(dst), src); }
680  void cmpb_al(const Operand& op);
681  void cmpw_ax(const Operand& op);
682  void cmpw(const Operand& dst, Immediate src);
683  void cmpw(Register dst, Immediate src) { cmpw(Operand(dst), src); }
684  void cmpw(Register dst, const Operand& src);
685  void cmpw(Register dst, Register src) { cmpw(Operand(dst), src); }
686  void cmpw(const Operand& dst, Register src);
687  void cmp(Register reg, int32_t imm32);
688  void cmp(Register reg, Handle<Object> handle);
689  void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
690  void cmp(Register reg, const Operand& op);
691  void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
692  void cmp(const Operand& op, Register reg);
693  void cmp(const Operand& op, const Immediate& imm);
694  void cmp(const Operand& op, Handle<Object> handle);
695
696  void dec_b(Register dst);
697  void dec_b(const Operand& dst);
698
699  void dec(Register dst);
700  void dec(const Operand& dst);
701
702  void cdq();
703
704  void idiv(Register src) { idiv(Operand(src)); }
705  void idiv(const Operand& src);
706  void div(Register src) { div(Operand(src)); }
707  void div(const Operand& src);
708
709  // Signed multiply instructions.
710  void imul(Register src);                               // edx:eax = eax * src.
711  void imul(Register dst, Register src) { imul(dst, Operand(src)); }
712  void imul(Register dst, const Operand& src);           // dst = dst * src.
713  void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
714  void imul(Register dst, const Operand& src, int32_t imm32);
715
716  void inc(Register dst);
717  void inc(const Operand& dst);
718
719  void lea(Register dst, const Operand& src);
720
721  // Unsigned multiply instruction.
722  void mul(Register src);                                // edx:eax = eax * reg.
723
724  void neg(Register dst);
725  void neg(const Operand& dst);
726
727  void not_(Register dst);
728  void not_(const Operand& dst);
729
730  void or_(Register dst, int32_t imm32);
731  void or_(Register dst, Register src) { or_(dst, Operand(src)); }
732  void or_(Register dst, const Operand& src);
733  void or_(const Operand& dst, Register src);
734  void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
735  void or_(const Operand& dst, const Immediate& x);
736
737  void rcl(Register dst, uint8_t imm8);
738  void rcr(Register dst, uint8_t imm8);
739
740  void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); }
741  void ror(const Operand& dst, uint8_t imm8);
742  void ror_cl(Register dst) { ror_cl(Operand(dst)); }
743  void ror_cl(const Operand& dst);
744
745  void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
746  void sar(const Operand& dst, uint8_t imm8);
747  void sar_cl(Register dst) { sar_cl(Operand(dst)); }
748  void sar_cl(const Operand& dst);
749
750  void sbb(Register dst, const Operand& src);
751
752  void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
753  void shl(const Operand& dst, uint8_t imm8);
754  void shl_cl(Register dst) { shl_cl(Operand(dst)); }
755  void shl_cl(const Operand& dst);
756  void shld(Register dst, Register src, uint8_t shift);
757  void shld_cl(Register dst, Register src);
758
759  void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); }
760  void shr(const Operand& dst, uint8_t imm8);
761  void shr_cl(Register dst) { shr_cl(Operand(dst)); }
762  void shr_cl(const Operand& dst);
763  void shrd(Register dst, Register src, uint8_t shift);
764  void shrd_cl(Register dst, Register src) { shrd_cl(Operand(dst), src); }
765  void shrd_cl(const Operand& dst, Register src);
766
767  void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
768  void sub(const Operand& dst, const Immediate& x);
769  void sub(Register dst, Register src) { sub(dst, Operand(src)); }
770  void sub(Register dst, const Operand& src);
771  void sub(const Operand& dst, Register src);
772
773  void test(Register reg, const Immediate& imm);
774  void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
775  void test(Register reg, const Operand& op);
776  void test(const Operand& op, const Immediate& imm);
777  void test(const Operand& op, Register reg) { test(reg, op); }
778  void test_b(Register reg, const Operand& op);
779  void test_b(Register reg, Immediate imm8);
780  void test_b(const Operand& op, Immediate imm8);
781  void test_b(const Operand& op, Register reg) { test_b(reg, op); }
782  void test_b(Register dst, Register src) { test_b(dst, Operand(src)); }
783  void test_w(Register reg, const Operand& op);
784  void test_w(Register reg, Immediate imm16);
785  void test_w(const Operand& op, Immediate imm16);
786  void test_w(const Operand& op, Register reg) { test_w(reg, op); }
787  void test_w(Register dst, Register src) { test_w(dst, Operand(src)); }
788
789  void xor_(Register dst, int32_t imm32);
790  void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
791  void xor_(Register dst, const Operand& src);
792  void xor_(const Operand& dst, Register src);
793  void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
794  void xor_(const Operand& dst, const Immediate& x);
795
796  // Bit operations.
797  void bt(const Operand& dst, Register src);
798  void bts(Register dst, Register src) { bts(Operand(dst), src); }
799  void bts(const Operand& dst, Register src);
800  void bsr(Register dst, Register src) { bsr(dst, Operand(src)); }
801  void bsr(Register dst, const Operand& src);
802  void bsf(Register dst, Register src) { bsf(dst, Operand(src)); }
803  void bsf(Register dst, const Operand& src);
804
805  // Miscellaneous
806  void hlt();
807  void int3();
808  void nop();
809  void ret(int imm16);
810  void ud2();
811
812  // Label operations & relative jumps (PPUM Appendix D)
813  //
814  // Takes a branch opcode (cc) and a label (L) and generates
815  // either a backward branch or a forward branch and links it
816  // to the label fixup chain. Usage:
817  //
818  // Label L;    // unbound label
819  // j(cc, &L);  // forward branch to unbound label
820  // bind(&L);   // bind label to the current pc
821  // j(cc, &L);  // backward branch to bound label
822  // bind(&L);   // illegal: a label may be bound only once
823  //
824  // Note: The same Label can be used for forward and backward branches
825  // but it may be bound only once.
826
827  void bind(Label* L);  // binds an unbound label L to the current code position
828
829  // Calls
830  void call(Label* L);
831  void call(byte* entry, RelocInfo::Mode rmode);
832  int CallSize(const Operand& adr);
833  void call(Register reg) { call(Operand(reg)); }
834  void call(const Operand& adr);
835  int CallSize(Handle<Code> code, RelocInfo::Mode mode);
836  void call(Handle<Code> code,
837            RelocInfo::Mode rmode,
838            TypeFeedbackId id = TypeFeedbackId::None());
839
840  // Jumps
841  // unconditional jump to L
842  void jmp(Label* L, Label::Distance distance = Label::kFar);
843  void jmp(byte* entry, RelocInfo::Mode rmode);
844  void jmp(Register reg) { jmp(Operand(reg)); }
845  void jmp(const Operand& adr);
846  void jmp(Handle<Code> code, RelocInfo::Mode rmode);
847
848  // Conditional jumps
849  void j(Condition cc,
850         Label* L,
851         Label::Distance distance = Label::kFar);
852  void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
853  void j(Condition cc, Handle<Code> code,
854         RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);
855
856  // Floating-point operations
857  void fld(int i);
858  void fstp(int i);
859
860  void fld1();
861  void fldz();
862  void fldpi();
863  void fldln2();
864
865  void fld_s(const Operand& adr);
866  void fld_d(const Operand& adr);
867
868  void fstp_s(const Operand& adr);
869  void fst_s(const Operand& adr);
870  void fstp_d(const Operand& adr);
871  void fst_d(const Operand& adr);
872
873  void fild_s(const Operand& adr);
874  void fild_d(const Operand& adr);
875
876  void fist_s(const Operand& adr);
877
878  void fistp_s(const Operand& adr);
879  void fistp_d(const Operand& adr);
880
881  // The fisttp instructions require SSE3.
882  void fisttp_s(const Operand& adr);
883  void fisttp_d(const Operand& adr);
884
885  void fabs();
886  void fchs();
887  void fsqrt();
888  void fcos();
889  void fsin();
890  void fptan();
891  void fyl2x();
892  void f2xm1();
893  void fscale();
894  void fninit();
895
896  void fadd(int i);
897  void fadd_i(int i);
898  void fadd_d(const Operand& adr);
899  void fsub(int i);
900  void fsub_i(int i);
901  void fsub_d(const Operand& adr);
902  void fsubr_d(const Operand& adr);
903  void fmul(int i);
904  void fmul_d(const Operand& adr);
905  void fmul_i(int i);
906  void fdiv(int i);
907  void fdiv_d(const Operand& adr);
908  void fdivr_d(const Operand& adr);
909  void fdiv_i(int i);
910
911  void fisub_s(const Operand& adr);
912
913  void faddp(int i = 1);
914  void fsubp(int i = 1);
915  void fsubr(int i = 1);
916  void fsubrp(int i = 1);
917  void fmulp(int i = 1);
918  void fdivp(int i = 1);
919  void fprem();
920  void fprem1();
921
922  void fxch(int i = 1);
923  void fincstp();
924  void ffree(int i = 0);
925
926  void ftst();
927  void fxam();
928  void fucomp(int i);
929  void fucompp();
930  void fucomi(int i);
931  void fucomip();
932  void fcompp();
933  void fnstsw_ax();
934  void fldcw(const Operand& adr);
935  void fnstcw(const Operand& adr);
936  void fwait();
937  void fnclex();
938  void fnsave(const Operand& adr);
939  void frstor(const Operand& adr);
940
941  void frndint();
942
943  void sahf();
944  void setcc(Condition cc, Register reg);
945
946  void cpuid();
947
948  // TODO(lrn): Need SFENCE for movnt?
949
950  // Check the code size generated from label to here.
951  int SizeOfCodeGeneratedSince(Label* label) {
952    return pc_offset() - label->pos();
953  }
954
955  // Mark address of a debug break slot.
956  void RecordDebugBreakSlot(RelocInfo::Mode mode);
957
958  // Record a comment relocation entry that can be used by a disassembler.
959  // Use --code-comments to enable.
960  void RecordComment(const char* msg);
961
962  // Record a deoptimization reason that can be used by a log or cpu profiler.
963  // Use --trace-deopt to enable.
964  void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
965                         int id);
966
967  // Writes a single byte or word of data in the code stream.  Used for
968  // inline tables, e.g., jump-tables.
969  void db(uint8_t data);
970  void dd(uint32_t data);
971  void dq(uint64_t data);
972  void dp(uintptr_t data) { dd(data); }
973  void dd(Label* label);
974
975  // Check if there is less than kGap bytes available in the buffer.
976  // If this is the case, we need to grow the buffer before emitting
977  // an instruction or relocation information.
978  inline bool buffer_overflow() const {
979    return pc_ >= reloc_info_writer.pos() - kGap;
980  }
981
982  // Get the number of bytes available in the buffer.
983  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
984
985  static bool IsNop(Address addr);
986
987  int relocation_writer_size() {
988    return (buffer_ + buffer_size_) - reloc_info_writer.pos();
989  }
990
991  // Avoid overflows for displacements etc.
992  static const int kMaximalBufferSize = 512*MB;
993
994  byte byte_at(int pos) { return buffer_[pos]; }
995  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
996
997  void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
998                                          ConstantPoolEntry::Access access,
999                                          ConstantPoolEntry::Type type) {
1000    // No embedded constant pool support.
1001    UNREACHABLE();
1002  }
1003
1004 protected:
1005  byte* addr_at(int pos) { return buffer_ + pos; }
1006
1007
1008 private:
1009  uint32_t long_at(int pos)  {
1010    return *reinterpret_cast<uint32_t*>(addr_at(pos));
1011  }
1012  void long_at_put(int pos, uint32_t x)  {
1013    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1014  }
1015
1016  // code emission
1017  void GrowBuffer();
1018  inline void emit(uint32_t x);
1019  inline void emit(Handle<Object> handle);
1020  inline void emit(uint32_t x,
1021                   RelocInfo::Mode rmode,
1022                   TypeFeedbackId id = TypeFeedbackId::None());
1023  inline void emit(Handle<Code> code,
1024                   RelocInfo::Mode rmode,
1025                   TypeFeedbackId id = TypeFeedbackId::None());
1026  inline void emit(const Immediate& x);
1027  inline void emit_b(Immediate x);
1028  inline void emit_w(const Immediate& x);
1029  inline void emit_q(uint64_t x);
1030
1031  // Emit the code-object-relative offset of the label's position
1032  inline void emit_code_relative_offset(Label* label);
1033
1034  // instruction generation
1035  void emit_arith_b(int op1, int op2, Register dst, int imm8);
1036
1037  // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
1038  // with a given destination expression and an immediate operand.  It attempts
1039  // to use the shortest encoding possible.
1040  // sel specifies the /n in the modrm byte (see the Intel PRM).
1041  void emit_arith(int sel, Operand dst, const Immediate& x);
1042
1043  void emit_operand(Register reg, const Operand& adr);
1044
1045  void emit_label(Label* label);
1046
1047  void emit_farith(int b1, int b2, int i);
1048
1049  // labels
1050  void print(Label* L);
1051  void bind_to(Label* L, int pos);
1052
1053  // displacements
1054  inline Displacement disp_at(Label* L);
1055  inline void disp_at_put(Label* L, Displacement disp);
1056  inline void emit_disp(Label* L, Displacement::Type type);
1057  inline void emit_near_disp(Label* L);
1058
1059  // record reloc info for current pc_
1060  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1061
1062  friend class CodePatcher;
1063  friend class EnsureSpace;
1064
1065  // Internal reference positions, required for (potential) patching in
1066  // GrowBuffer(); contains only those internal references whose labels
1067  // are already bound.
1068  std::deque<int> internal_reference_positions_;
1069
1070  // code generation
1071  RelocInfoWriter reloc_info_writer;
1072};
1073
1074
1075// Helper class that ensures that there is enough space for generating
1076// instructions and relocation information.  The constructor makes
1077// sure that there is enough space and (in debug mode) the destructor
1078// checks that we did not generate too much.
1079class EnsureSpace BASE_EMBEDDED {
1080 public:
1081  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1082    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1083#ifdef DEBUG
1084    space_before_ = assembler_->available_space();
1085#endif
1086  }
1087
1088#ifdef DEBUG
1089  ~EnsureSpace() {
1090    int bytes_generated = space_before_ - assembler_->available_space();
1091    DCHECK(bytes_generated < assembler_->kGap);
1092  }
1093#endif
1094
1095 private:
1096  Assembler* assembler_;
1097#ifdef DEBUG
1098  int space_before_;
1099#endif
1100};
1101
1102}  // namespace internal
1103}  // namespace v8
1104
1105#endif  // V8_X87_ASSEMBLER_X87_H_
1106