13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without
3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are
4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met:
5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//     * Redistributions of source code must retain the above copyright
7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       notice, this list of conditions and the following disclaimer.
8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//     * Redistributions in binary form must reproduce the above
9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       copyright notice, this list of conditions and the following
10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       disclaimer in the documentation and/or other materials provided
11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       with the distribution.
12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       contributors may be used to endorse or promote products derived
14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       from this software without specific prior written permission.
15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_
29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_IA32_LITHIUM_CODEGEN_IA32_H_
30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ia32/lithium-ia32.h"
32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "checks.h"
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h"
35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "safepoint-table.h"
36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "scopes.h"
37b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "ia32/lithium-gap-resolver-ia32.h"
38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations.
43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LDeferredCode;
44b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass LGapNode;
45b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass SafepointGenerator;
46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LCodeGen BASE_EMBEDDED {
48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : chunk_(chunk),
51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        masm_(assembler),
52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        info_(info),
53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        current_block_(-1),
54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        current_instruction_(-1),
55b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        instructions_(chunk->instructions()),
56b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        deoptimizations_(4),
57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        deoptimization_literals_(8),
58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        inlined_function_count_(0),
59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        scope_(info->scope()),
60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        status_(UNUSED),
61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        deferred_(8),
62b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        osr_pc_offset_(-1),
632b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch        last_lazy_deopt_pc_(0),
648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        resolver_(this),
658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        expected_safepoint_kind_(Safepoint::kSimple) {
66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PopulateDeoptimizationLiteralsWithInlinedFunctions();
67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
69b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Simple accessors.
70b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  MacroAssembler* masm() const { return masm_; }
71e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  CompilationInfo* info() const { return info_; }
7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate() const { return info_->isolate(); }
7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Factory* factory() const { return isolate()->factory(); }
7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap() const { return isolate()->heap(); }
75b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
76b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Support for converting LOperands to assembler types.
77b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Operand ToOperand(LOperand* op) const;
78b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Register ToRegister(LOperand* op) const;
79b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  XMMRegister ToDoubleRegister(LOperand* op) const;
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsInteger32(LConstantOperand* op) const;
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Immediate ToInteger32Immediate(LOperand* op) const {
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Immediate(ToInteger32(LConstantOperand::cast(op)));
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> ToHandle(LConstantOperand* op) const;
87b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
88b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // The operand denoting the second word (the one with a higher address) of
89b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // a double stack slot.
90b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Operand HighOperand(LOperand* op);
91b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Try to generate code for the entire chunk, but it may fail if the
93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // chunk contains constructs we cannot handle. Returns true if the
94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // code generation attempt succeeded.
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool GenerateCode();
96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Finish the code by setting stack height, safepoint, and bailout
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // information on it.
99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void FinishCode(Handle<Code> code);
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Deferred code support.
102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoDeferredNumberTagD(LNumberTagD* instr);
103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoDeferredNumberTagI(LNumberTagI* instr);
104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoDeferredTaggedToI(LTaggedToI* instr);
105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void DoDeferredStackCheck(LStackCheck* instr);
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DoDeferredRandom(LRandom* instr);
1081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DoDeferredAllocateObject(LAllocateObject* instr);
1112b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
1122b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                                       Label* map_check);
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DoCheckMapCommon(Register reg, Handle<Map> map,
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        CompareMapMode mode, LEnvironment* env);
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Parallel move support.
118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoParallelMove(LParallelMove* move);
119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void DoGap(LGap* instr);
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
121b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Emit frame translation commands for an environment.
122b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void WriteTranslation(LEnvironment* environment, Translation* translation);
123b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
124e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void EnsureRelocSpaceForDeoptimization();
125e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Declare methods that deal with the individual node types.
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DECLARE_DO(type) void Do##type(L##type* node);
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_DO
130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum Status {
133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    UNUSED,
134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    GENERATING,
135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    DONE,
136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ABORTED
137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_unused() const { return status_ == UNUSED; }
140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_generating() const { return status_ == GENERATING; }
141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_done() const { return status_ == DONE; }
142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_aborted() const { return status_ == ABORTED; }
143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StrictModeFlag strict_mode_flag() const {
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
146592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LChunk* chunk() const { return chunk_; }
149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Scope* scope() const { return scope_; }
150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph() const { return chunk_->graph(); }
151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetNextEmittedBlock(int block);
153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EmitClassOfTest(Label* if_true,
155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Label* if_false,
156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Handle<String> class_name,
157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Register input,
158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Register temporary,
159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Register temporary2);
160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int GetParameterCount() const { return scope()->num_parameters(); }
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Abort(const char* format, ...);
165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Comment(const char* format, ...);
166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code); }
168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Code generation passes.  Returns true if code generation should
170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // continue.
171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool GeneratePrologue();
172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool GenerateBody();
173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool GenerateDeferredCode();
174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Pad the reloc info to ensure that we have enough space to patch during
175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // deoptimization.
176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  bool GenerateRelocPadding();
177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool GenerateSafepointTable();
178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  enum SafepointMode {
1808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    RECORD_SIMPLE_SAFEPOINT,
1818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
1828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  };
1838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void CallCode(Handle<Code> code,
1858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                RelocInfo::Mode mode,
1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                LInstruction* instr);
1878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void CallCodeGeneric(Handle<Code> code,
1898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                       RelocInfo::Mode mode,
1908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                       LInstruction* instr,
1918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                       SafepointMode safepoint_mode);
1928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void CallRuntime(const Runtime::Function* fun,
1948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                   int argc,
1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                   LInstruction* instr);
1968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void CallRuntime(Runtime::FunctionId id,
1988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                   int argc,
1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                   LInstruction* instr) {
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    const Runtime::Function* function = Runtime::FunctionForId(id);
2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CallRuntime(function, argc, instr);
202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void CallRuntimeFromDeferred(Runtime::FunctionId id,
2058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                               int argc,
2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                               LInstruction* instr,
2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                               LOperand* context);
2088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Generate a direct call to a known function.  Expects the function
210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // to be in edi.
211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CallKnownFunction(Handle<JSFunction> function,
212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         int arity,
213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                         LInstruction* instr,
214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                         CallKind call_kind);
215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2162b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void RecordSafepointWithLazyDeopt(LInstruction* instr,
2172b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                                    SafepointMode safepoint_mode);
2188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2192b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
2202b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                                            Safepoint::DeoptMode mode);
221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DeoptimizeIf(Condition cc, LEnvironment* environment);
222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddToTranslation(Translation* translation,
224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                        LOperand* op,
225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                        bool is_tagged);
226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PopulateDeoptimizationData(Handle<Code> code);
227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int DefineDeoptimizationLiteral(Handle<Object> literal);
228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PopulateDeoptimizationLiteralsWithInlinedFunctions();
230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Register ToRegister(int index) const;
232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  XMMRegister ToDoubleRegister(int index) const;
233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int ToInteger32(LConstantOperand* op) const;
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  double ToDouble(LConstantOperand* op) const;
23669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Operand BuildFastArrayOperand(LOperand* elements_pointer,
2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                LOperand* key,
238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                ElementsKind elements_kind,
2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                uint32_t offset);
240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Specific math operations - used from DoUnaryMathOperation.
2421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EmitIntegerMathAbs(LUnaryMathOperation* instr);
243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathAbs(LUnaryMathOperation* instr);
244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathFloor(LUnaryMathOperation* instr);
245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathRound(LUnaryMathOperation* instr);
246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathSqrt(LUnaryMathOperation* instr);
247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathLog(LUnaryMathOperation* instr);
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DoMathTan(LUnaryMathOperation* instr);
249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathCos(LUnaryMathOperation* instr);
250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoMathSin(LUnaryMathOperation* instr);
251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Support for recording safepoint and position information.
2531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void RecordSafepoint(LPointerMap* pointers,
2541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                       Safepoint::Kind kind,
2551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                       int arguments,
2562b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                       Safepoint::DeoptMode mode);
2572b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
2582b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void RecordSafepoint(Safepoint::DeoptMode mode);
259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordSafepointWithRegisters(LPointerMap* pointers,
260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    int arguments,
2612b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                                    Safepoint::DeoptMode mode);
262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordPosition(int position);
263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static Condition TokenToCondition(Token::Value op, bool is_unsigned);
2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void EmitGoto(int block);
266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EmitBranch(int left_block, int right_block, Condition cc);
2677d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  void EmitNumberUntagD(Register input,
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Register temp,
2697d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch                        XMMRegister result,
2707d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch                        bool deoptimize_on_undefined,
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        bool deoptimize_on_minus_zero,
2727d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch                        LEnvironment* env);
273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Emits optimized code for typeof x == "y".  Modifies input register.
275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Returns the condition on which a final split to
276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // true and false label should be made, to optimize fallthrough.
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Condition EmitTypeofIs(Label* true_label,
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Label* false_label,
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Register input,
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Handle<String> type_name);
281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Emits optimized code for %_IsObject(x).  Preserves input register.
283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Returns the condition on which a final split to
284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // true and false label should be made, to optimize fallthrough.
285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Condition EmitIsObject(Register input,
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         Register temp1,
287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         Label* is_not_object,
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         Label* is_object);
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Emits optimized code for %_IsString(x).  Preserves input register.
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the condition on which a final split to
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // true and false label should be made, to optimize fallthrough.
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Condition EmitIsString(Register input,
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Register temp1,
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Label* is_not_string);
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Emits optimized code for %_IsConstructCall().
2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Caller should branch on equal condition.
2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EmitIsConstructCall(Register temp);
3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void EmitLoadFieldOrConstantFunction(Register result,
302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                       Register object,
303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                       Handle<Map> type,
304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                       Handle<String> name);
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Emits optimized code to deep-copy the contents of statically known
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // object graphs (e.g. object literal boilerplate).
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void EmitDeepCopy(Handle<JSObject> object,
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    Register result,
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    Register source,
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    int* offset);
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3132b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void EnsureSpaceForLazyDeopt();
3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Emits code for pushing either a tagged constant, a (non-double)
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // register, or a stack slot operand.
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void EmitPushTaggedOperand(LOperand* operand);
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LChunk* const chunk_;
320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  MacroAssembler* const masm_;
321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CompilationInfo* const info_;
322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int current_block_;
324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int current_instruction_;
325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<LInstruction*>* instructions_;
326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<LEnvironment*> deoptimizations_;
327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<Handle<Object> > deoptimization_literals_;
328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int inlined_function_count_;
329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Scope* const scope_;
330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Status status_;
331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TranslationBuffer translations_;
332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<LDeferredCode*> deferred_;
333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int osr_pc_offset_;
3342b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  int last_lazy_deopt_pc_;
335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Builder that keeps track of safepoints in the code. The table
337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // itself is emitted at the end of the generated code.
338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SafepointTableBuilder safepoints_;
339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
340b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Compiler from a set of parallel moves to a sequential list of moves.
341b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LGapResolver resolver_;
342b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
3438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Safepoint::Kind expected_safepoint_kind_;
3448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  class PushSafepointRegistersScope BASE_EMBEDDED {
3468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch   public:
3478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    explicit PushSafepointRegistersScope(LCodeGen* codegen)
3488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        : codegen_(codegen) {
3498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
3508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      codegen_->masm_->PushSafepointRegisters();
3518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
3528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
3538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ~PushSafepointRegistersScope() {
3558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
3568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      codegen_->masm_->PopSafepointRegisters();
3578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
3588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
3598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch   private:
3618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    LCodeGen* codegen_;
3628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  };
3638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  friend class LDeferredCode;
365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  friend class LEnvironment;
366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  friend class SafepointGenerator;
367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LCodeGen);
368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LDeferredCode: public ZoneObject {
372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit LDeferredCode(LCodeGen* codegen)
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : codegen_(codegen),
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        external_exit_(NULL),
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        instruction_index_(codegen->current_instruction_) {
377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    codegen->AddDeferredCode(this);
378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~LDeferredCode() { }
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void Generate() = 0;
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual LInstruction* instr() = 0;
383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetExit(Label* exit) { external_exit_ = exit; }
385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label* entry() { return &entry_; }
386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int instruction_index() const { return instruction_index_; }
388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LCodeGen* codegen() const { return codegen_; }
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  MacroAssembler* masm() const { return codegen_->masm(); }
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LCodeGen* codegen_;
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label entry_;
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label exit_;
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label* external_exit_;
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int instruction_index_;
399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} }  // namespace v8::internal
402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif  // V8_IA32_LITHIUM_CODEGEN_IA32_H_
404