1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met:
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions of source code must retain the above copyright
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       notice, this list of conditions and the following disclaimer.
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions in binary form must reproduce the above
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       copyright notice, this list of conditions and the following
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       disclaimer in the documentation and/or other materials provided
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       with the distribution.
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       contributors may be used to endorse or promote products derived
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       from this software without specific prior written permission.
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define V8_IA32_LITHIUM_CODEGEN_IA32_H_
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "ia32/lithium-ia32.h"
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "checks.h"
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h"
35b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org#include "ia32/lithium-gap-resolver-ia32.h"
36d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org#include "lithium-codegen.h"
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "safepoint-table.h"
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "scopes.h"
39b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org#include "v8utils.h"
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Forward declarations.
45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LDeferredCode;
46c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgclass LGapNode;
47a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass SafepointGenerator;
48a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
49d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgclass LCodeGen: public LCodeGenBase {
50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
52d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      : LCodeGenBase(chunk, assembler, info),
535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deoptimizations_(4, info->zone()),
54a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        jump_table_(4, info->zone()),
555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deoptimization_literals_(8, info->zone()),
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        inlined_function_count_(0),
578f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        scope_(info->scope()),
585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        translations_(info->zone()),
595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deferred_(8, info->zone()),
607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        dynamic_frame_alignment_(false),
6194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        support_aligned_spilled_doubles_(false),
620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        osr_pc_offset_(-1),
63a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        frame_is_built_(false),
6432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org        x87_stack_(assembler),
655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        safepoints_(info->zone()),
6644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        resolver_(this),
6771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        expected_safepoint_kind_(Safepoint::kSimple) {
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PopulateDeoptimizationLiteralsWithInlinedFunctions();
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  int LookupDestination(int block_id) const {
7232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return chunk()->LookupDestination(block_id);
7332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
7432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
7532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool IsNextEmittedBlock(int block_id) const {
7632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return LookupDestination(block_id) == GetNextEmittedBlock();
7732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
7832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
79a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool NeedsEagerFrame() const {
80a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return GetStackSlotCount() > 0 ||
81a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        info()->is_non_deferred_calling() ||
8277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        !info()->IsStub() ||
8377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        info()->requires_frame();
84a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
85a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool NeedsDeferredFrame() const {
86a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return !NeedsEagerFrame() && info()->is_deferred_calling();
87a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
88a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Support for converting LOperands to assembler types.
900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Operand ToOperand(LOperand* op) const;
910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Register ToRegister(LOperand* op) const;
920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  XMMRegister ToDoubleRegister(LOperand* op) const;
93169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Register ToX87Register(LOperand* op) const;
94bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org
95bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org  bool IsInteger32(LConstantOperand* op) const;
96a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  bool IsSmi(LConstantOperand* op) const;
97fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  Immediate ToImmediate(LOperand* op, const Representation& r) const {
98fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return Immediate(ToRepresentation(LConstantOperand::cast(op), r));
99c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  }
100e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  double ToDouble(LConstantOperand* op) const;
101bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org
102e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Support for non-sse2 (x87) floating point stack handling.
103169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // These functions maintain the mapping of physical stack registers to our
104169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // virtual registers between instructions.
105169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  enum X87OperandType { kX87DoubleOperand, kX87FloatOperand, kX87IntOperand };
106169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
107169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void X87Mov(X87Register reg, Operand src,
108169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87OperandType operand = kX87DoubleOperand);
10932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  void X87Mov(Operand src, X87Register reg,
11032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      X87OperandType operand = kX87DoubleOperand);
111169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
112169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void X87PrepareBinaryOp(
113169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Register left, X87Register right, X87Register result);
114169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
115169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void X87LoadForUsage(X87Register reg);
1163d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  void X87LoadForUsage(X87Register reg1, X87Register reg2);
11732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  void X87PrepareToWrite(X87Register reg) { x87_stack_.PrepareToWrite(reg); }
11832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  void X87CommitWrite(X87Register reg) { x87_stack_.CommitWrite(reg); }
11932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
12032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  void X87Fxch(X87Register reg, int other_slot = 0) {
12132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    x87_stack_.Fxch(reg, other_slot);
12232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
12325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  void X87Free(X87Register reg) {
12425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    x87_stack_.Free(reg);
12525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
12625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
12732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
12832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  bool X87StackEmpty() {
12932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    return x87_stack_.depth() == 0;
13032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
1310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Handle<Object> ToHandle(LConstantOperand* op) const;
133a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // The operand denoting the second word (the one with a higher address) of
1350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // a double stack slot.
1360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Operand HighOperand(LOperand* op);
1370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Try to generate code for the entire chunk, but it may fail if the
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // chunk contains constructs we cannot handle. Returns true if the
140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // code generation attempt succeeded.
141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool GenerateCode();
142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Finish the code by setting stack height, safepoint, and bailout
144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // information on it.
145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void FinishCode(Handle<Code> code);
146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Deferred code support.
148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void DoDeferredNumberTagD(LNumberTagD* instr);
14946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
15046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
15146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void DoDeferredNumberTagI(LInstruction* instr,
15246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                            LOperand* value,
15346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                            IntegerSignedness signedness);
15446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
1558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
15704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  void DoDeferredStackCheck(LStackCheck* instr);
1580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
159b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
16094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  void DoDeferredAllocate(LAllocate* instr);
16127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
16227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                       Label* map_check);
163594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
164f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Parallel move support.
166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void DoParallelMove(LParallelMove* move);
1678e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void DoGap(LGap* instr);
168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
169c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Emit frame translation commands for an environment.
170b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  void WriteTranslation(LEnvironment* environment, Translation* translation);
171c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
1723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void EnsureRelocSpaceForDeoptimization();
1733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Declare methods that deal with the individual node types.
175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define DECLARE_DO(type) void Do##type(L##type* node);
176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef DECLARE_DO
178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
180394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StrictModeFlag strict_mode_flag() const {
1811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
18249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
18349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Scope* scope() const { return scope_; }
185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
186528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  XMMRegister double_scratch0() const { return xmm0; }
187528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void EmitClassOfTest(Label* if_true,
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       Label* if_false,
190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       Handle<String> class_name,
191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       Register input,
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       Register temporary,
193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       Register temporary2);
194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
195160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
197594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Abort(BailoutReason reason);
198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
201f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void SaveCallerDoubles();
202f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void RestoreCallerDoubles();
203f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Code generation passes.  Returns true if code generation should
205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // continue.
206d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
207d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void GenerateBodyInstructionPost(LInstruction* instr) V8_OVERRIDE;
208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool GeneratePrologue();
209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool GenerateDeferredCode();
210a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool GenerateJumpTable();
211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool GenerateSafepointTable();
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
213c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Generates the custom OSR entrypoint and sets the osr_pc_offset.
214c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void GenerateOsrPrologue();
215c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
21644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  enum SafepointMode {
21744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    RECORD_SIMPLE_SAFEPOINT,
21844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
21944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  };
22044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
22144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallCode(Handle<Code> code,
22244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                RelocInfo::Mode mode,
223ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                LInstruction* instr);
22444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
22544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallCodeGeneric(Handle<Code> code,
22644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       RelocInfo::Mode mode,
22744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       LInstruction* instr,
22844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       SafepointMode safepoint_mode);
22944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
23044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallRuntime(const Runtime::Function* fun,
23144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                   int argc,
232fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   LInstruction* instr,
233fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
23444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
23544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallRuntime(Runtime::FunctionId id,
23644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                   int argc,
237ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                   LInstruction* instr) {
238ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
239ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    CallRuntime(function, argc, instr);
240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
24244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallRuntimeFromDeferred(Runtime::FunctionId id,
24344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                               int argc,
244ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                               LInstruction* instr,
245ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                               LOperand* context);
24644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
24794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  void LoadContextFromDeferred(LOperand* context);
24894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
249fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  enum EDIState {
250fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    EDI_UNINITIALIZED,
251fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    EDI_CONTAINS_TARGET
252fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  };
253fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org
254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Generate a direct call to a known function.  Expects the function
255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // to be in edi.
256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void CallKnownFunction(Handle<JSFunction> function,
25732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         int formal_parameter_count,
258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                         int arity,
25940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                         LInstruction* instr,
260fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                         CallKind call_kind,
261fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                         EDIState edi_state);
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RecordSafepointWithLazyDeopt(LInstruction* instr,
26427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    SafepointMode safepoint_mode);
26544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
26627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
26727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                            Safepoint::DeoptMode mode);
268aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  void DeoptimizeIf(Condition cc,
269aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                    LEnvironment* environment,
270aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                    Deoptimizer::BailoutType bailout_type);
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void DeoptimizeIf(Condition cc, LEnvironment* environment);
272fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void ApplyCheckIf(Condition cc, LBoundsCheck* check);
273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
274935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool DeoptEveryNTimes() {
275935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
276935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  }
277935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
278594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void AddToTranslation(LEnvironment* environment,
279594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        Translation* translation,
280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                        LOperand* op,
28146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                        bool is_tagged,
282594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        bool is_uint32,
283594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        int* object_index_pointer,
284594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        int* dematerialized_index_pointer);
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PopulateDeoptimizationData(Handle<Code> code);
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int DefineDeoptimizationLiteral(Handle<Object> literal);
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PopulateDeoptimizationLiteralsWithInlinedFunctions();
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register ToRegister(int index) const;
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  XMMRegister ToDoubleRegister(int index) const;
292169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Register ToX87Register(int index) const;
293594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
294fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int32_t ToInteger32(LConstantOperand* op) const;
295d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ExternalReference ToExternalReference(LConstantOperand* op) const;
296bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org
297b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Operand BuildFastArrayOperand(LOperand* elements_pointer,
298717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org                                LOperand* key,
299304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                                Representation key_representation,
30083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                ElementsKind elements_kind,
3010e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org                                uint32_t offset,
3020e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org                                uint32_t additional_index = 0);
303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
304e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Operand BuildSeqStringOperand(Register string,
305e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                LOperand* index,
306e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                String::Encoding encoding);
307e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
308e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void EmitIntegerMathAbs(LMathAbs* instr);
309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Support for recording safepoint and position information.
311378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void RecordSafepoint(LPointerMap* pointers,
312378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                       Safepoint::Kind kind,
313378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                       int arguments,
31427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                       Safepoint::DeoptMode mode);
31527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
31627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RecordSafepoint(Safepoint::DeoptMode mode);
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RecordSafepointWithRegisters(LPointerMap* pointers,
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                    int arguments,
31927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    Safepoint::DeoptMode mode);
320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
32171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void RecordAndWritePosition(int position) V8_OVERRIDE;
322594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Condition TokenToCondition(Token::Value op, bool is_unsigned);
32404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  void EmitGoto(int block);
3250cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
3260cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // EmitBranch expects to be the last instruction of a block.
3271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class InstrType>
3281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void EmitBranch(InstrType instr, Condition cc);
329c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  template<class InstrType>
330c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  void EmitFalseBranch(InstrType instr, Condition cc);
33194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  void EmitNumberUntagD(
33294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      Register input,
33394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      Register temp,
33494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      XMMRegister result,
335b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      bool allow_undefined_as_nan,
33694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      bool deoptimize_on_minus_zero,
33794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      LEnvironment* env,
33894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED);
339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
340e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void EmitNumberUntagDNoSSE2(
341e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Register input,
342e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Register temp,
343169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Register res_reg,
344b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      bool allow_undefined_as_nan,
345e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      bool deoptimize_on_minus_zero,
346e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      LEnvironment* env,
347e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED);
348e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Emits optimized code for typeof x == "y".  Modifies input register.
350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns the condition on which a final split to
351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // true and false label should be made, to optimize fallthrough.
352af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input);
353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Emits optimized code for %_IsObject(x).  Preserves input register.
3555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Returns the condition on which a final split to
3565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // true and false label should be made, to optimize fallthrough.
3575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  Condition EmitIsObject(Register input,
3585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                         Register temp1,
3595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                         Label* is_not_object,
3605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                         Label* is_object);
3615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
3620ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // Emits optimized code for %_IsString(x).  Preserves input register.
3630ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // Returns the condition on which a final split to
3640ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // true and false label should be made, to optimize fallthrough.
3650ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  Condition EmitIsString(Register input,
3660ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                         Register temp1,
3671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         Label* is_not_string,
3681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         SmiCheck check_needed);
3690ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
370d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Emits optimized code for %_IsConstructCall().
371d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Caller should branch on equal condition.
372d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  void EmitIsConstructCall(Register temp);
373d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
3741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Emits optimized code to deep-copy the contents of statically known
3751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // object graphs (e.g. object literal boilerplate).
3761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  void EmitDeepCopy(Handle<JSObject> object,
3771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                    Register result,
3781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                    Register source,
37946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                    int* offset,
38046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                    AllocationSiteMode mode);
3811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
382d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
383e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoLoadKeyedExternalArray(LLoadKeyed* instr);
384e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
385e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoLoadKeyedFixedArray(LLoadKeyed* instr);
386e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoStoreKeyedExternalArray(LStoreKeyed* instr);
387e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
388e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoStoreKeyedFixedArray(LStoreKeyed* instr);
389d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
3906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  void EmitReturn(LReturn* instr, bool dynamic_frame_alignment);
3916e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
39264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Emits code for pushing either a tagged constant, a (non-double)
39364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // register, or a stack slot operand.
39464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void EmitPushTaggedOperand(LOperand* operand);
39564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
396169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void X87Fld(Operand src, X87OperandType opts);
397169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
398169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void EmitFlushX87ForDeopt();
39932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  void FlushX87StackIfNecessary(LInstruction* instr) {
40032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    x87_stack_.FlushIfNecessary(instr, this);
40132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
40232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  friend class LGapResolver;
403169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
404d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER
405d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // On windows, you may not access the stack more than one page below
406d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // the most recently mapped page. To make the allocated area randomly
407d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // accessible, we write an arbitrary value to each page in range
408d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // esp + offset - page_size .. esp in turn.
409d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  void MakeSureStackPagesMapped(int offset);
410d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif
411d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LEnvironment*> deoptimizations_;
413aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<Handle<Object> > deoptimization_literals_;
415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int inlined_function_count_;
416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Scope* const scope_;
417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  TranslationBuffer translations_;
418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LDeferredCode*> deferred_;
4197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  bool dynamic_frame_alignment_;
42094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  bool support_aligned_spilled_doubles_;
421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int osr_pc_offset_;
422a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool frame_is_built_;
42332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
42432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  class X87Stack {
42532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org   public:
4268fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    explicit X87Stack(MacroAssembler* masm)
4278fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        : stack_depth_(0), is_mutable_(true), masm_(masm) { }
42832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    explicit X87Stack(const X87Stack& other)
4298fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        : stack_depth_(other.stack_depth_), is_mutable_(false), masm_(masm()) {
43032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      for (int i = 0; i < stack_depth_; i++) {
43132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org        stack_[i] = other.stack_[i];
43232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      }
43332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    }
43432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    bool operator==(const X87Stack& other) const {
43532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      if (stack_depth_ != other.stack_depth_) return false;
43632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      for (int i = 0; i < stack_depth_; i++) {
43732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org        if (!stack_[i].is(other.stack_[i])) return false;
43832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      }
43932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      return true;
44032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    }
44132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    bool Contains(X87Register reg);
44232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    void Fxch(X87Register reg, int other_slot = 0);
44332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    void Free(X87Register reg);
44432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    void PrepareToWrite(X87Register reg);
44532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    void CommitWrite(X87Register reg);
44632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen);
4474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    void LeavingBlock(int current_block_id, LGoto* goto_instr);
44832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    int depth() const { return stack_depth_; }
4498fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    void pop() {
4508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      ASSERT(is_mutable_);
4518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      stack_depth_--;
4528fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    }
45332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    void push(X87Register reg) {
4548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      ASSERT(is_mutable_);
45532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      ASSERT(stack_depth_ < X87Register::kNumAllocatableRegisters);
45632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      stack_[stack_depth_] = reg;
45732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      stack_depth_++;
45832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    }
45932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
46032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    MacroAssembler* masm() const { return masm_; }
46132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
46232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org   private:
46332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    int ArrayIndex(X87Register reg);
46432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    int st2idx(int pos);
4658fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
46632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    X87Register stack_[X87Register::kNumAllocatableRegisters];
46732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    int stack_depth_;
4688fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    bool is_mutable_;
4698fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    MacroAssembler* masm_;
47032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  };
47132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  X87Stack x87_stack_;
4723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Builder that keeps track of safepoints in the code. The table
474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // itself is emitted at the end of the generated code.
475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SafepointTableBuilder safepoints_;
476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
477c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Compiler from a set of parallel moves to a sequential list of moves.
478c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  LGapResolver resolver_;
479c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
48044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  Safepoint::Kind expected_safepoint_kind_;
48144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
48232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  class PushSafepointRegistersScope V8_FINAL  BASE_EMBEDDED {
48344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org   public:
48444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    explicit PushSafepointRegistersScope(LCodeGen* codegen)
48544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        : codegen_(codegen) {
48644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
48744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->masm_->PushSafepointRegisters();
48844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
489a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ASSERT(codegen_->info()->is_calling());
49044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
49144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
49244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    ~PushSafepointRegistersScope() {
49344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
49444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->masm_->PopSafepointRegisters();
49544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
49644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
49744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
49844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org   private:
49944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    LCodeGen* codegen_;
50044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  };
50144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class LDeferredCode;
503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class LEnvironment;
504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class SafepointGenerator;
505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(LCodeGen);
506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
50932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass LDeferredCode : public ZoneObject {
510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
5118fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  explicit LDeferredCode(LCodeGen* codegen, const LCodeGen::X87Stack& x87_stack)
512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      : codegen_(codegen),
513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        external_exit_(NULL),
5148fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        instruction_index_(codegen->current_instruction_),
5158fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        x87_stack_(x87_stack) {
516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    codegen->AddDeferredCode(this);
517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
51932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual ~LDeferredCode() {}
520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual void Generate() = 0;
521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual LInstruction* instr() = 0;
522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
523f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void SetExit(Label* exit) { external_exit_ = exit; }
524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label* entry() { return &entry_; }
525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
526c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int instruction_index() const { return instruction_index_; }
5288fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  const LCodeGen::X87Stack& x87_stack() const { return x87_stack_; }
529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org protected:
531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LCodeGen* codegen() const { return codegen_; }
532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  MacroAssembler* masm() const { return codegen_->masm(); }
533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LCodeGen* codegen_;
536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label entry_;
537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label exit_;
538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label* external_exit_;
5398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Label done_;
540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int instruction_index_;
5418fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  LCodeGen::X87Stack x87_stack_;
542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif  // V8_IA32_LITHIUM_CODEGEN_IA32_H_
547